Skip to content

Commit

Permalink
Add basic inline code segment support. Man I suck at parsing things
Browse files Browse the repository at this point in the history
  • Loading branch information
practicingruby committed May 13, 2011
1 parent 8c8be91 commit b5eae5c
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 5 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ Gemfile.lock
*.pdf
*.epub
*.mobi
*.html
.DS_Store
4 changes: 3 additions & 1 deletion examples/basic-features.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
book.chapter "Preformatted text blocks", "#{fixture_dir}/preformatted_blocks.md"
book.chapter "Section headings", "#{fixture_dir}/document_with_headings.md"
book.chapter "Unordered lists", "#{fixture_dir}/lists.md"
book.chapter "Inline Formatting", "#{fixture_dir}/inline_formatting.md"

book.render("bookie-basic-feature", [Bookie::Emitters::PDF.new,
Bookie::Emitters::EPUB.new,
Bookie::Emitters::MOBI.new])
Bookie::Emitters::MOBI.new,
Bookie::Emitters::HTML.new])
1 change: 1 addition & 0 deletions lib/bookie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require "fileutils"
require "tempfile"
require "erb"
require "strscan"

require "prawn"
require "eeepub"
Expand Down
13 changes: 12 additions & 1 deletion lib/bookie/emitters/html.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,18 @@ def start_new_chapter(params)
end

def build_paragraph(paragraph)
@body << "<p>#{paragraph.contents}</p>"
@body << "<p>#{convert_inlines(paragraph.contents)}</p>"
end

def convert_inlines(contents)
contents.map do |c|
case c
when Bookie::NormalText
c.contents
when Bookie::CodeText
"<tt>#{c.contents}</tt>"
end
end.join.strip
end

def build_raw_text(raw_text)
Expand Down
15 changes: 14 additions & 1 deletion lib/bookie/emitters/pdf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,27 @@ def build_section_heading(section_text)
end

def build_paragraph(paragraph)
para_text = convert_inlines(paragraph.contents)

draw do
font("serif", size: 9) do
text(paragraph.contents.strip, align: :justify, leading: 2)
text(para_text, align: :justify, leading: 2, inline_format: true)
end
move_down in2pt(0.1)
end
end

def convert_inlines(contents)
contents.map do |c|
case c
when Bookie::NormalText
c.contents
when Bookie::CodeText
"<color rgb='660000'><font name='mono' size='9'>#{c.contents}</font></color>"
end
end.join.strip
end

def build_raw_text(raw_text)
sanitized_text = raw_text.contents.gsub(" ", Prawn::Text::NBSP).strip

Expand Down
21 changes: 20 additions & 1 deletion lib/bookie/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ module Bookie
RawText = Struct.new(:contents)
SectionHeading = Struct.new(:contents)
List = Struct.new(:contents)
NormalText = Struct.new(:contents)
CodeText = Struct.new(:contents)

class Parser
def self.parse(raw_data, emitter=Bookie::Emitters::Null.new)
Expand All @@ -19,8 +21,25 @@ def initialize(raw_data, emitter)
parse_contents(raw_data)
end

def extract_inlines(paragraph_text)
scanner = StringScanner.new(paragraph_text)
modes = [NormalText, CodeText].cycle
output = []

current_mode = modes.next
current_mode = modes.next if scanner.scan(/`/)

until scanner.eos?
output << current_mode.new(scanner.scan(/[^`]+/m))
current_mode = modes.next if scanner.scan(/`/)
end

output
end

def extract_paragraph(paragraph_text)
paragraph = Paragraph.new(paragraph_text.gsub(/\s+/," "))
text_segments = extract_inlines(paragraph_text.gsub(/\s+/," "))
paragraph = Paragraph.new(text_segments)
@emitter.build_paragraph(paragraph)
parsed_content << paragraph
end
Expand Down
17 changes: 17 additions & 0 deletions test/fixtures/inline_formatting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
As you can see in the code above, I decided that my `Piece#paint` method was
probably better off as `Canvas#paint_shape`, just to collect the presentation
logic in one place. Here’s what the updated code ended up looking like.

class Canvas
# ...

def paint_shape(shape, position)
shape.translated_points(position).each do |point|
paint(point, Piece::SYMBOL)
end
end
end

This new code does not rely directly on the `Piece#points` method anymore, but
instead, passes a position to the newly created `Piece#translated_points` to get a
set of coordinates anchored by the specified position.
2 changes: 1 addition & 1 deletion test/units/parser_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
assert_equal 8, parsed_content.length

actual_paragraph = parsed_content[4]
actual_paragraph_text = actual_paragraph.first
actual_paragraph_text = actual_paragraph.first[0].contents

assert_equal sample_paragraph_text, actual_paragraph_text
end
Expand Down

0 comments on commit b5eae5c

Please sign in to comment.