Skip to content

Instantly share code, notes, and snippets.

@kristinabrown
Created February 20, 2015 00:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kristinabrown/d6bcb5d171f2ad5aeda2 to your computer and use it in GitHub Desktop.
Save kristinabrown/d6bcb5d171f2ad5aeda2 to your computer and use it in GitHub Desktop.
chisel up through level 2
require 'pry'
class Chisel
attr_accessor :paragraph, :header, :stars
def initialize
@stars = 0
end
def parse(text)
stars?(text)
if @stars > 0
star_eval(text)
else
text
end
split_text = splitter(text)
split_text.map do |line|
if line.include? "#"
@header = parse_header(line)
else
@paragraph = parse_paragraph(line)
end
end
end
def parse_header(text)
hash_count = text.chars.count do |char|
char == "#"
end
text.delete!("#").sub!(" ", "")
front = "<h#{hash_count}>"
back = "</h#{hash_count}>"
output_line(front, text, back)
end
def output_line(front, text, back)
"#{front}#{text}#{back}"
end
def parse_paragraph(text)
front = "<p>\n"
back = "\n</p>"
output_line(front, text, back)
end
def splitter(text)
text.split(/^\n/).flat_map do |line|
if line.include?("#")
line.split("\n")
else
line
end
end
end
def stars?(text)
@stars = text.chars.count do |star|
star == "*"
end
end
def star_eval(text)
while @stars >= 0
if text.include?("**")
if text.include?(" **")
text.sub!("**", "<strong>")
@stars -= 2
else
text.sub!("**", "</strong>")
@stars -= 2
end
else
if text.include?("\s*")
text.sub!("*", "<em>")
@stars -= 1
else
text.sub!("*", "</em>")
@stars -= 1
end
end
# else text.include?(" * ")
# "unordered list"
end
text
end
end
parser = Chisel.new
#passes
#puts parser.star_eval("My *emphasized and **stronged** text* is awesome")
#passes
#puts parser.star_eval("this is a **bold** word and *italics* word")
puts parser.parse(File.read("./chisel_sample.md"))
@BobGu
Copy link

BobGu commented Feb 20, 2015

At first blush this looks like a good working solution. I think it is really important to have working code first and pretty code second. One thing I notice is you created a method called stars?. When we create a method with a ? we want to return a boolean by convention. So the method stars?(text) should return either true or false.

The way I approach it might be like this...
You probably haven't gotten into regular expressions, but what is commonly known as regex is great for data sanitation and parsers such as this one. Regular expression allows us to find specific patterns in our text, then either modify that text or just return matches.

There is a method called scan which you can call on a string object that returns an array of arrays of matching text that follow a specific regex pattern. Here is an example of finding all words or phrases that are surrounded by two stars. http://rubular.com/r/j82JzPgTED

We might then write a method like this which we call in our parse method.

https://gist.github.com/BobGu/144030229bfc6184cb03

You could then use this similar pattern for * after you've parsed for ** so you don't get any pattern matching collisions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment