diff options
| author | Dan Allen <dan.j.allen@gmail.com> | 2012-12-13 04:23:36 -0700 |
|---|---|---|
| committer | Dan Allen <dan.j.allen@gmail.com> | 2012-12-13 04:29:07 -0700 |
| commit | b4e0f2a9014d9667e6104a5c44bab1744a77f252 (patch) | |
| tree | c84027bf5c6f77469ad4fb9a35c66d8749ecf777 | |
| parent | 01a771e6280447dc2609de85a03ee346a77a64dd (diff) | |
make header/footer optional, set intrinsic attributes
- make header/footer optional using option :header_footer
- set intrinsic attributes such as date/time, doctype and asciidoctor version
- expose doctitle and title accessors in Document (preferred over header)
- fill in the template for Document more completely to be consistent w/ AsciiDoc
| -rwxr-xr-x | lib/asciidoctor.rb | 4 | ||||
| -rw-r--r-- | lib/asciidoctor/document.rb | 50 | ||||
| -rw-r--r-- | lib/asciidoctor/render_templates.rb | 31 | ||||
| -rw-r--r-- | lib/asciidoctor/section.rb | 8 | ||||
| -rw-r--r-- | test/document_test.rb | 20 | ||||
| -rw-r--r-- | test/test_helper.rb | 11 | ||||
| -rw-r--r-- | test/text_test.rb | 3 |
7 files changed, 94 insertions, 33 deletions
diff --git a/lib/asciidoctor.rb b/lib/asciidoctor.rb index b157c79f..9d749024 100755 --- a/lib/asciidoctor.rb +++ b/lib/asciidoctor.rb @@ -47,6 +47,10 @@ $:.unshift(File.join(File.dirname(__FILE__), '..', 'vendor')) # file.puts html # end module Asciidoctor + # The default document type + # Can influence markup generated by render templates + DEFAULT_DOCTYPE = 'article' + REGEXP = { # [[Foo]] (also allows, say, [[[]] or [[[Foo[f]], but I don't think it is supposed to (TODO)) :anchor => /^\[(\[.+\])\]\s*$/, diff --git a/lib/asciidoctor/document.rb b/lib/asciidoctor/document.rb index 64f4595e..6ddf706b 100644 --- a/lib/asciidoctor/document.rb +++ b/lib/asciidoctor/document.rb @@ -10,7 +10,7 @@ class Asciidoctor::Document # Public: Get the Hash of document references attr_reader :references - # Need these for pseudo-template yum + # The section level 0 element attr_reader :header # Public: Get the Array of elements (really Blocks or Sections) for the document @@ -29,6 +29,7 @@ class Asciidoctor::Document def initialize(data, options = {}, &block) @elements = [] @options = options + @options[:header_footer] = @options.fetch(:header_footer, true) @reader = Reader.new(data, &block) @@ -36,6 +37,13 @@ class Asciidoctor::Document @attributes = @reader.attributes @references = @reader.references + # dynamic intrinstic attribute values + @attributes['doctype'] ||= DEFAULT_DOCTYPE + now = Time.new + @attributes['localdate'] ||= now.strftime('%Y-%m-%d') + @attributes['localtime'] ||= now.strftime('%H:%m:%S %Z') + @attributes['asciidoctor-version'] = VERSION + # Now parse @lines into elements while @reader.has_lines? @reader.skip_blank @@ -48,11 +56,11 @@ class Asciidoctor::Document Asciidoctor.debug el end + # split off the level 0 section, if present root = @elements.first - # Try to find a @header from the Section blocks we have (if any). if root.is_a?(Section) && root.level == 0 @header = @elements.shift - @elements = @header.blocks + @elements + @elements = @header.blocks @header.clear_blocks end @@ -63,21 +71,33 @@ class Asciidoctor::Document @reader.source if @reader end - # We need to be able to return some semblance of a title + def level + 0 + end + + # The title explicitly defined in the document attributes def title - return @title if @title + @attributes['title'] + end + + # We need to be able to return some semblance of a title + def doctitle + # cached value + return @doctitle if @doctitle if @header - @title = @header.title || @header.name + @doctitle = @header.title elsif @elements.first - @title = @elements.first.title - # Blocks don't have a :name method, but Sections do - @title ||= @elements.first.name if @elements.first.respond_to? :name + @doctitle = @elements.first.title end - @title + @doctitle + end + alias :name :doctitle + + def notitle + @attributes.has_key? 'notitle' end - alias :name :title def splain if @header @@ -110,11 +130,13 @@ class Asciidoctor::Document @renderer = Renderer.new(render_options) end - # Public: Render the Asciidoc document using erb templates - # + # Public: Render the Asciidoc document using the templates + # loaded by Renderer. If a :template_dir is not specified, + # or a template is missing, the renderer will fall back to + # using the appropriate built-in template. def render(options = {}) r = renderer(options) - html = r.render('document', self, :header => @header) + @options.merge(options)[:header_footer] ? r.render('document', self) : content end def content diff --git a/lib/asciidoctor/render_templates.rb b/lib/asciidoctor/render_templates.rb index 928bd219..b10d3425 100644 --- a/lib/asciidoctor/render_templates.rb +++ b/lib/asciidoctor/render_templates.rb @@ -24,14 +24,29 @@ end class DocumentTemplate < BaseTemplate def template @template ||= ::ERB.new <<-EOF - <div class='man-page'> - <div id='header'> - <% if header %> - <h1><%= header.name %></h1> - <% end %> - </div> - <%= content %> - </div> + <!DOCTYPE html> + <html lang='en'> + <head> + <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'> + <meta name='generator' content='Asciidoctor <%= attributes["asciidoctor-version"] %>'> + <title><%= title ? title : (doctitle ? doctitle : '') %></title> + </head> + <body class='<%= attributes["doctype"] %>'> + <div id='header'> + <% if doctitle %> + <h1><%= doctitle %></h1> + <% end %> + </div> + <div id='content'> + <%= content %> + </div> + <div id='footer'> + <div id='footer-text'> + Last updated <%= [attributes['localdate'], attributes['localtime']].join(' ') %> + </div> + </div> + </body> + </html> EOF end end diff --git a/lib/asciidoctor/section.rb b/lib/asciidoctor/section.rb index 82f45b45..49c2f48e 100644 --- a/lib/asciidoctor/section.rb +++ b/lib/asciidoctor/section.rb @@ -24,9 +24,6 @@ class Asciidoctor::Section # Public: Set the String section name. attr_writer :name - # Public: Get/Set the String section title. - attr_accessor :title - # Public: Get/Set the String section caption. attr_accessor :caption @@ -109,6 +106,11 @@ class Asciidoctor::Section end.join end + # Public: The title of this section, an alias of the section name + def title + @name + end + # Public: Get the Integer number of blocks in the section. # # Examples diff --git a/test/document_test.rb b/test/document_test.rb index 1548ee8a..cea43e83 100644 --- a/test/document_test.rb +++ b/test/document_test.rb @@ -7,7 +7,7 @@ class DocumentTest < Test::Unit::TestCase end def test_title - assert_equal "AsciiDoc Home Page", @doc.title + assert_equal "AsciiDoc Home Page", @doc.doctitle assert_equal 14, @doc.elements.size assert_equal :preamble, @doc.elements[0].context assert_true @doc.elements[1].is_a? ::Asciidoctor::Section @@ -15,6 +15,22 @@ class DocumentTest < Test::Unit::TestCase def test_with_no_title d = Asciidoctor::Document.new(["Snorf"]) - assert_nil d.title + assert_nil d.doctitle + end + + def test_with_header_footer + result = render_string("= Title\n\npreamble") + assert_xpath '/html', result, 1 + assert_xpath '//*[@id="header"]', result, 1 + assert_xpath '//*[@id="footer"]', result, 1 + assert_xpath '//*[@id="preamble"]', result, 1 + end + + def test_with_no_header_footer + result = render_string("= Title\n\npreamble", :header_footer => false) + assert_xpath '/html', result, 0 + assert_xpath '/*[@id="header"]', result, 0 + assert_xpath '/*[@id="footer"]', result, 0 + assert_xpath '/*[@id="preamble"]', result, 1 end end diff --git a/test/test_helper.rb b/test/test_helper.rb index c69b0b12..0e2f7b9d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -50,7 +50,8 @@ class Test::Unit::TestCase end def assert_xpath(xpath, html, count = nil) - results = Nokogiri::HTML::DocumentFragment.parse(html).xpath("#{xpath.sub('/', './')}") + doc = (html =~ /\s*<!DOCTYPE/) ? Nokogiri::HTML::Document.parse(html) : Nokogiri::HTML::DocumentFragment.parse(html) + results = doc.xpath("#{xpath.sub('/', './')}") if (count && results.length != count) flunk "XPath #{xpath} yielded #{results.length} elements rather than #{count} for:\n#{html}" @@ -61,12 +62,12 @@ class Test::Unit::TestCase end end - def document_from_string(src) - Asciidoctor::Document.new(src.split("\n")) + def document_from_string(src, opts = {}) + Asciidoctor::Document.new(src.split("\n"), opts) end - def render_string(src) - document_from_string(src).render + def render_string(src, opts = {}) + document_from_string(src, opts).render end end diff --git a/test/text_test.rb b/test/text_test.rb index 4616db9e..f892398a 100644 --- a/test/text_test.rb +++ b/test/text_test.rb @@ -16,7 +16,8 @@ context "Text" do end test "separator" do - assert_xpath "//hr", render_string("This is separated.\n\n'''\n\n...from this!"), 1 + # for some reason, the html enclosure breaks the xpath //*[@id='content']//hr + assert_xpath "//*[@id='content']//hr", render_string("This is separated.\n\n'''\n\n...from this!"), 1 end test "emphasized text" do |
