From 72212cb1f771ce1bb7f757c6c24bdccd0ab971f7 Mon Sep 17 00:00:00 2001 From: wilkie Date: Thu, 28 Feb 2013 00:48:38 -0500 Subject: [PATCH] Adds tables property to Book and renders Table to Tables page. Adds tables property to MarkdownRenderer, Chapter, and Book. This property will collect the tables per chapter and the aggregate them together in the Book. The book layout engine then renders the table of tables. --- lib/gutenberg/book.rb | 5 +++++ lib/gutenberg/chapter.rb | 7 +++++++ lib/gutenberg/markdown_renderer.rb | 12 ++++++++++-- lib/gutenberg/styles/basic/book.haml | 10 ++++++++++ spec/book_spec.rb | 24 ++++++++++++++++++++---- spec/chapter_spec.rb | 7 +++++++ spec/markdown_renderer_spec.rb | 14 ++++++++++++++ 7 files changed, 73 insertions(+), 6 deletions(-) diff --git a/lib/gutenberg/book.rb b/lib/gutenberg/book.rb index 9a4ef00..756053b 100644 --- a/lib/gutenberg/book.rb +++ b/lib/gutenberg/book.rb @@ -25,6 +25,9 @@ class Book # The images used throughout the book. attr_reader :images + # The tables used throughout the book. + attr_reader :tables + # Will create the book class and organize all metadata. Can be passed the # following options: # :yaml - the filename of YAML that describes the book @@ -59,11 +62,13 @@ def initialize(options = {}) chapters = options[:chapters] || [] @images = [] + @tables = [] @chapters = [] chapters.each_with_index do |c,i| chapter = Chapter.new(:markdown_file => c, :style => @style, :index => i+1) @chapters << chapter @images.concat chapter.images + @tables.concat chapter.tables end end end diff --git a/lib/gutenberg/chapter.rb b/lib/gutenberg/chapter.rb index bde884e..60f3d08 100644 --- a/lib/gutenberg/chapter.rb +++ b/lib/gutenberg/chapter.rb @@ -31,6 +31,9 @@ class Chapter # The images contained in this chapter. Default: [] attr_reader :images + # The tables contained in this chapter. Default: [] + attr_reader :tables + # The language this chapter is written in. Default: "en_us" # Creates a new representation of a Chapter where options may be specified: @@ -49,6 +52,7 @@ class Chapter def initialize(options = {}) @format = options[:format] || :text @images = [] + @tables = [] # Look for and load any special files if options[:markdown_file] @@ -113,6 +117,9 @@ def initialize(options = {}) # Get the image list @images = renderer.images + + # Get the table list + @tables = renderer.tables when :html @html = @content else diff --git a/lib/gutenberg/markdown_renderer.rb b/lib/gutenberg/markdown_renderer.rb index eea522e..67ea3d9 100644 --- a/lib/gutenberg/markdown_renderer.rb +++ b/lib/gutenberg/markdown_renderer.rb @@ -22,6 +22,9 @@ class MarkdownRenderer < Redcarpet::Render::HTML # The images contained within this chapter. Default: [] attr_reader :images + # The tables contained within this chapter. Default: [] + attr_reader :tables + # Creates a new renderer that can be given to Redcarpet. It expects to # receive a slug to use as a safe anchor and the chapter name in case a # primary header is not used. The name is overriden by a primary header. @@ -30,6 +33,7 @@ class MarkdownRenderer < Redcarpet::Render::HTML # be an empty string whenever it is meant to be omitted. def initialize(slug, name, language, style, index, *args) @images = [] + @tables = [] @outline = Node.new(name || "Untitled") @last = @outline @slug = slug @@ -94,11 +98,15 @@ def parse_table(text) @table_count += 1 id = "table-#{@slug}-#{@table_count}" + tag = "table-#{@index}-#{@table_count}" if tag == "" + # Add slug to reference lookup @lookup[tag] = {:slug => id, :index => @table_count, :caption => caption, :full_index => "#{@index}-#{@table_count}"} + + @tables << @lookup[tag] "
\n#{table_renderer.to_html}
Table #{@index}-#{@table_count}: #{caption}
" end @@ -124,7 +132,7 @@ def codespan(code) # Generates HTML for a markdown code block. def block_code(code, language) - code = CGI::escapeHTML(code); + code = CGI::escapeHTML(code) new_code = "" last_number = -1 code.lines do |l| @@ -148,7 +156,7 @@ def block_code(code, language) new_code << l end "
#{language}#{new_code}
" - end + end # Generates HTML for a markdown image. def image(link, title, alt_text) diff --git a/lib/gutenberg/styles/basic/book.haml b/lib/gutenberg/styles/basic/book.haml index ca05328..8f91211 100644 --- a/lib/gutenberg/styles/basic/book.haml +++ b/lib/gutenberg/styles/basic/book.haml @@ -19,6 +19,16 @@ Figure #{i[:full_index]} \: #{i[:caption]} +%h1#table-of-tables + Table of Tables +%div.tot + %ul + - book.tables.each do |i| + %li< + %a{:href=>"##{i[:slug]}"}< + Table #{i[:full_index]} + \: #{i[:caption]} + %h1#acknowledgements Acknowledgements %div.acknowledgements diff --git a/spec/book_spec.rb b/spec/book_spec.rb index 4ed70c6..b91515f 100644 --- a/spec/book_spec.rb +++ b/spec/book_spec.rb @@ -6,6 +6,7 @@ Gutenberg::Style.stubs(:new).returns(mock('style')) @chapter = mock('chapter') @chapter.stubs(:images).returns([]) + @chapter.stubs(:tables).returns([]) end it "can be created with no arguments" do @@ -148,11 +149,26 @@ it "combines all images from all chapters into images property" do chapter_1 = mock('chapter') chapter_2 = mock('chapter') - chapter_1.stubs(:images).returns(["foo", "bar"]) - chapter_2.stubs(:images).returns(["baz", "caz"]) - Gutenberg::Chapter.expects(:new).with(has_entry(:markdown_file, "foo")).returns(chapter_1) - Gutenberg::Chapter.expects(:new).with(has_entry(:markdown_file, "boo")).returns(chapter_2) + chapter_1.expects(:images).returns(["foo", "bar"]) + chapter_2.expects(:images).returns(["baz", "caz"]) + chapter_1.stubs(:tables).returns([]) + chapter_2.stubs(:tables).returns([]) + Gutenberg::Chapter.stubs(:new).with(has_entry(:markdown_file, "foo")).returns(chapter_1) + Gutenberg::Chapter.stubs(:new).with(has_entry(:markdown_file, "boo")).returns(chapter_2) Gutenberg::Book.new({:chapters => ["foo", "boo"]}) .images.must_equal ["foo", "bar", "baz", "caz"] end + + it "combines all tables from all chapters into tables property" do + chapter_1 = mock('chapter') + chapter_2 = mock('chapter') + chapter_1.stubs(:images).returns([]) + chapter_2.stubs(:images).returns([]) + chapter_1.expects(:tables).returns(["foo", "bar"]) + chapter_2.expects(:tables).returns(["baz", "caz"]) + Gutenberg::Chapter.stubs(:new).with(has_entry(:markdown_file, "foo")).returns(chapter_1) + Gutenberg::Chapter.stubs(:new).with(has_entry(:markdown_file, "boo")).returns(chapter_2) + Gutenberg::Book.new({:chapters => ["foo", "boo"]}) + .tables.must_equal ["foo", "bar", "baz", "caz"] + end end diff --git a/spec/chapter_spec.rb b/spec/chapter_spec.rb index 74e6754..0a57d2e 100644 --- a/spec/chapter_spec.rb +++ b/spec/chapter_spec.rb @@ -51,6 +51,7 @@ @md_renderer.stubs(:title).returns("") @md_renderer.stubs(:outline).returns(nil) @md_renderer.stubs(:images).returns([]) + @md_renderer.stubs(:tables).returns([]) Gutenberg::MarkdownRenderer.stubs(:new).returns(@md_renderer) @renderer = mock('renderer') @@ -69,6 +70,11 @@ Gutenberg::Chapter.new(:markdown_file => "foo.md") end + it "pulls the tables from the markdown renderer" do + @md_renderer.expects(:tables).returns([]) + Gutenberg::Chapter.new(:markdown_file => "foo.md") + end + it "makes use of the custom renderer" do Gutenberg::MarkdownRenderer.expects(:new).returns(@md_renderer) Gutenberg::Chapter.new(:markdown_file => "foo.md") @@ -128,6 +134,7 @@ md_renderer = mock('md_renderer') md_renderer.stubs(:title).returns("hello") md_renderer.stubs(:images).returns([]) + md_renderer.stubs(:tables).returns([]) md_renderer.stubs(:outline).returns(nil) Gutenberg::MarkdownRenderer.stubs(:new).returns(md_renderer) Gutenberg::Chapter.new(:markdown_file => "foo.md").title.must_equal("hello") diff --git a/spec/markdown_renderer_spec.rb b/spec/markdown_renderer_spec.rb index 0b618ca..9697aaa 100644 --- a/spec/markdown_renderer_spec.rb +++ b/spec/markdown_renderer_spec.rb @@ -264,4 +264,18 @@ @renderer.images.first[:slug].must_equal "figure-slug-1" end end + + describe "#tables" do + it "contains a table when the table is parsed without a tag" do + @renderer.parse_table("!table \"foo\"") + @renderer.tables.count.must_equal 1 + @renderer.tables.first[:slug].must_equal "table-slug-1" + end + + it "contains a table when the table is parsed with a tag" do + @renderer.parse_table("!table tag \"foo\"") + @renderer.tables.count.must_equal 1 + @renderer.tables.first[:slug].must_equal "table-slug-1" + end + end end