summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Allen <dan.j.allen@gmail.com>2012-12-13 04:23:36 -0700
committerDan Allen <dan.j.allen@gmail.com>2012-12-13 04:29:07 -0700
commitb4e0f2a9014d9667e6104a5c44bab1744a77f252 (patch)
treec84027bf5c6f77469ad4fb9a35c66d8749ecf777
parent01a771e6280447dc2609de85a03ee346a77a64dd (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-xlib/asciidoctor.rb4
-rw-r--r--lib/asciidoctor/document.rb50
-rw-r--r--lib/asciidoctor/render_templates.rb31
-rw-r--r--lib/asciidoctor/section.rb8
-rw-r--r--test/document_test.rb20
-rw-r--r--test/test_helper.rb11
-rw-r--r--test/text_test.rb3
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