[DRE-commits] [ruby-org] 81/303: Big layering/refactoring
Jérémy Bobbio
lunar at alioth.debian.org
Fri Aug 9 17:33:32 UTC 2013
This is an automated email from the git hooks/post-receive script.
lunar pushed a commit to branch master
in repository ruby-org.
commit a02d0fddf9f01b04b300eae26bf390718d61d0e4
Author: Brian Dewey <bdewey at gmail.com>
Date: Wed Jan 6 00:59:29 2010 -0800
Big layering/refactoring
---
lib/org-ruby/headline.rb | 44 ++++++--------------
lib/org-ruby/html_output_buffer.rb | 30 ++++++++++---
lib/org-ruby/line.rb | 11 ++++-
lib/org-ruby/output_buffer.rb | 36 ++++++++++++++++
lib/org-ruby/parser.rb | 74 ++++++++++++++-------------------
lib/org-ruby/textile_output_buffer.rb | 3 +-
spec/output_buffer_spec.rb | 19 +++++++++
spec/parser_spec.rb | 18 +-------
8 files changed, 137 insertions(+), 98 deletions(-)
diff --git a/lib/org-ruby/headline.rb b/lib/org-ruby/headline.rb
index deaaae1..8f33364 100644
--- a/lib/org-ruby/headline.rb
+++ b/lib/org-ruby/headline.rb
@@ -44,6 +44,7 @@ module Orgmode
def initialize(line, parser = nil)
super(line, parser)
@body_lines = []
+ @body_lines << self # Make @body_lines contain the headline?
@tags = []
@export_state = :exclude
if (@line =~ LineRegexp) then
@@ -61,52 +62,33 @@ module Orgmode
end
end
+ # Override Line.output_text. For a heading, @headline_text
+ # is what we should output.
+ def output_text
+ return @headline_text
+ end
+
# Determines if a line is an orgmode "headline":
# A headline begins with one or more asterisks.
def self.headline?(line)
line =~ LineRegexp
end
+ # Overrides Line.paragraph_type.
+ def paragraph_type
+ :"heading#{@level}"
+ end
+
# Converts this headline and its body to textile.
def to_textile
output = "h#{@level}. #{@headline_text}\n"
- output << Line.to_textile(@body_lines)
- output
- end
-
- def to_html(opts = {})
- return "" if @export_state == :exclude
- if opts[:decorate_title]
- decoration = " class=\"title\""
- opts.delete(:decorate_title)
- else
- decoration = ""
- end
- output = "<h#{@level}#{decoration}>"
- if @parser and @parser.export_heading_number? then
- heading_number = @parser.get_next_headline_number(@level)
- output << "<span class=\"heading-number heading-number-#{@level}\">#{heading_number} </span>"
- end
- if @parser and @parser.export_todo? and @keyword then
- output << "<span class=\"todo-keyword #{@keyword}\">#{@keyword} </span>"
- end
- output << "#{escape(@headline_text)}</h#{@level}>\n"
- return output if @export_state == :headline_only
- output << Line.to_html(@body_lines, opts)
+ output << Line.to_textile(@body_lines[1..-1])
output
end
######################################################################
private
- # TODO 2009-12-29 This duplicates escape_buffer! in html_output_buffer. DRY.
- def escape(str)
- str = str.gsub(/&/, "&")
- str = str.gsub(/</, "<")
- str = str.gsub(/>/, ">")
- str
- end
-
def parse_keywords
re = @parser.custom_keyword_regexp if @parser
re ||= KeywordsRegexp
diff --git a/lib/org-ruby/html_output_buffer.rb b/lib/org-ruby/html_output_buffer.rb
index e31c2b1..6199d7e 100644
--- a/lib/org-ruby/html_output_buffer.rb
+++ b/lib/org-ruby/html_output_buffer.rb
@@ -9,7 +9,13 @@ module Orgmode
:ordered_list => "li",
:unordered_list => "li",
:table_row => "tr",
- :table_header => "tr"
+ :table_header => "tr",
+ :heading1 => "h1",
+ :heading2 => "h2",
+ :heading3 => "h3",
+ :heading4 => "h4",
+ :heading5 => "h5",
+ :heading6 => "h6"
}
ModeTag = {
@@ -75,17 +81,29 @@ module Orgmode
unless buffer_mode_is_table? and skip_tables?
@logger.debug "FLUSH ==========> #{@buffer_mode}"
output_indentation
- @output << "<#{HtmlBlockTag[@output_type]}#{@title_decoration}>" \
- << inline_formatting(@buffer) \
- << "</#{HtmlBlockTag[@output_type]}>\n"
+ @output << "<#{HtmlBlockTag[@output_type]}#{@title_decoration}>"
+ if (@buffered_lines[0].kind_of?(Headline)) then
+ headline = @buffered_lines[0]
+ raise "Cannot be more than one headline!" if @buffered_lines.length > 1
+ if @options[:export_heading_number] then
+ level = headline.level
+ heading_number = get_next_headline_number(level)
+ output << "<span class=\"heading-number heading-number-#{level}\">#{heading_number} </span>"
+ end
+ if @options[:export_todo] and headline.keyword then
+ keyword = headline.keyword
+ output << "<span class=\"todo-keyword #{keyword}\">#{keyword} </span>"
+ end
+ end
+ @output << inline_formatting(@buffer)
+ @output << "</#{HtmlBlockTag[@output_type]}>\n"
@title_decoration = ""
else
@logger.debug "SKIP ==========> #{@buffer_mode}"
end
end
end
- @buffer = ""
- @buffer_mode = nil
+ clear_accumulation_buffer!
end
######################################################################
diff --git a/lib/org-ruby/line.rb b/lib/org-ruby/line.rb
index 472dd1b..58e9525 100644
--- a/lib/org-ruby/line.rb
+++ b/lib/org-ruby/line.rb
@@ -76,6 +76,15 @@ module Orgmode
@line.sub(OrderedListRegexp, "")
end
+ # Extracts meaningful text and excludes org-mode markup,
+ # like identifiers for lists or headings.
+ def output_text
+ return strip_ordered_list_tag if ordered_list?
+ return strip_unordered_list_tag if unordered_list?
+ return @line.sub(InlineExampleRegexp, "") if inline_example?
+ return line
+ end
+
def plain_text?
not metadata? and not blank? and not plain_list?
end
@@ -167,7 +176,7 @@ module Orgmode
def self.to_textile(lines)
output = ""
output_buffer = TextileOutputBuffer.new(output)
- translate(lines, output_buffer)
+ Parser.translate(lines, output_buffer)
end
######################################################################
diff --git a/lib/org-ruby/output_buffer.rb b/lib/org-ruby/output_buffer.rb
index 4fbd114..4c704ba 100644
--- a/lib/org-ruby/output_buffer.rb
+++ b/lib/org-ruby/output_buffer.rb
@@ -13,6 +13,10 @@ module Orgmode
# without intervening newlines.
attr_reader :buffer
+ # These are the Line objects that are currently in the accumulation
+ # buffer.
+ attr_reader :buffered_lines
+
# This is the output mode of the accumulation buffer.
attr_reader :buffer_mode
@@ -22,17 +26,22 @@ module Orgmode
# This is the current type of output being accumulated.
attr_accessor :output_type
+ # This stack is used to do proper outline numbering of headlines.
+ attr_accessor :headline_number_stack
+
# Creates a new OutputBuffer object that is bound to an output object.
# The output will get flushed to =output=.
def initialize(output)
@output = output
@buffer = ""
+ @buffered_lines = []
@buffer_mode = nil
@output_type = :start
@list_indent_stack = []
@paragraph_modifier = nil
@cancel_modifier = false
@mode_stack = []
+ @headline_number_stack = []
@logger = Logger.new(STDERR)
if ENV['DEBUG']
@@ -79,6 +88,33 @@ module Orgmode
pop_mode(:inline_example) if current_mode == :inline_example && !line.inline_example?
push_mode(:table) if enter_table?
pop_mode(:table) if exit_table?
+ @buffered_lines.push(line)
+ end
+
+ # Flushes everything currently in the accumulation buffer into the
+ # output buffer. Derived classes must override this to actually move
+ # content into the output buffer with the appropriate markup. This
+ # method just does common bookkeeping cleanup.
+ def clear_accumulation_buffer!
+ @buffer = ""
+ @buffer_mode = nil
+ @buffered_lines = []
+ end
+
+ # Gets the next headline number for a given level. The intent is
+ # this function is called sequentially for each headline that
+ # needs to get numbered. It does standard outline numbering.
+ def get_next_headline_number(level)
+ raise "Headline level not valid: #{level}" if level <= 0
+ while level > @headline_number_stack.length do
+ @headline_number_stack.push 0
+ end
+ while level < @headline_number_stack.length do
+ @headline_number_stack.pop
+ end
+ raise "Oops, shouldn't happen" unless level == @headline_number_stack.length
+ @headline_number_stack[@headline_number_stack.length - 1] += 1
+ @headline_number_stack.join(".")
end
# Tests if we are entering a table mode.
diff --git a/lib/org-ruby/parser.rb b/lib/org-ruby/parser.rb
index 4b35d3e..86ba9a1 100644
--- a/lib/org-ruby/parser.rb
+++ b/lib/org-ruby/parser.rb
@@ -53,9 +53,6 @@ module Orgmode
"t" == @options["todo"]
end
- # This stack is used to do proper outline numbering of headlines.
- attr_accessor :headline_number_stack
-
# Returns true if we are to export heading numbers.
def export_heading_number?
"t" == @options["num"]
@@ -72,22 +69,6 @@ module Orgmode
"nil" != @options["|"]
end
- # Gets the next headline number for a given level. The intent is
- # this function is called sequentially for each headline that
- # needs to get numbered. It does standard outline numbering.
- def get_next_headline_number(level)
- raise "Headline level not valid: #{level}" if level <= 0
- while level > @headline_number_stack.length do
- @headline_number_stack.push 0
- end
- while level < @headline_number_stack.length do
- @headline_number_stack.pop
- end
- raise "Oops, shouldn't happen" unless level == @headline_number_stack.length
- @headline_number_stack[@headline_number_stack.length - 1] += 1
- @headline_number_stack.join(".")
- end
-
# I can construct a parser object either with an array of lines
# or with a single string that I will split along \n boundaries.
def initialize(lines)
@@ -104,7 +85,6 @@ module Orgmode
@current_headline = nil
@header_lines = []
@in_buffer_settings = { }
- @headline_number_stack = []
@options = { }
mode = :normal
previous_line = nil
@@ -136,7 +116,7 @@ module Orgmode
# As long as we stay in code mode, force lines to be either blank or paragraphs.
# Don't try to interpret structural items, like headings and tables.
- line = Line.new line
+ line = Line.new line, self
if line.end_block? and line.block_type == "EXAMPLE"
mode = :normal
else
@@ -171,23 +151,36 @@ module Orgmode
# Converts the loaded org-mode file to HTML.
def to_html
mark_trees_for_export
- @headline_number_stack = []
- export_options = { }
+ export_options = {
+ :decorate_title => true,
+ :export_heading_number => export_heading_number?,
+ :export_todo => export_todo?
+ }
export_options[:skip_tables] = true if not export_tables?
output = ""
+ output_buffer = HtmlOutputBuffer.new(output, export_options)
+
if @in_buffer_settings["TITLE"] then
- output << "<p class=\"title\">#{@in_buffer_settings["TITLE"]}</p>\n"
- else
- export_options[:decorate_title] = true
+
+ # If we're given a new title, then just create a new line
+ # for that title.
+ title = Line.new(@in_buffer_settings["TITLE"], self)
+ Parser.translate([title], output_buffer)
end
- output_buffer = HtmlOutputBuffer.new(output, export_options)
- output << translate(@header_lines, output_buffer) unless skip_header_lines?
+ Parser.translate(@header_lines, output_buffer) unless skip_header_lines?
# If we've output anything at all, remove the :decorate_title option.
export_options.delete(:decorate_title) if (output.length > 0)
@headlines.each do |headline|
- output << headline.to_html(export_options)
- export_options.delete(:decorate_title) if (output.length > 0)
+ next if headline.export_state == :exclude
+ case headline.export_state
+ when :exclude
+ # NOTHING
+ when :headline_only
+ Parser.translate(headline.body_lines[0, 1], output_buffer)
+ when :all
+ Parser.translate(headline.body_lines, output_buffer)
+ end
end
rp = RubyPants.new(output)
rp.to_html
@@ -197,7 +190,8 @@ module Orgmode
private
# Converts an array of lines to the appropriate format.
- def translate(lines, output_buffer)
+ # Writes the output to +output_buffer+.
+ def self.translate(lines, output_buffer)
lines.each do |line|
# See if we're carrying paragraph payload, and output
@@ -227,24 +221,20 @@ module Orgmode
output_buffer << line.line.lstrip
- when :ordered_list
-
- output_buffer << line.strip_ordered_list_tag << " "
-
- when :unordered_list
+ when :unordered_list, :ordered_list
- output_buffer << line.strip_unordered_list_tag << " "
+ output_buffer << line.output_text << " "
when :inline_example
- output_buffer << line.line.sub(InlineExampleRegexp, "")
-
- when :paragraph
+ output_buffer << line.output_text
+
+ else
if output_buffer.preserve_whitespace? then
- output_buffer << line.line
+ output_buffer << line.output_text
else
- output_buffer << line.line.strip << " "
+ output_buffer << line.output_text.strip << " "
end
end
end
diff --git a/lib/org-ruby/textile_output_buffer.rb b/lib/org-ruby/textile_output_buffer.rb
index d02bcd1..6fe85f5 100644
--- a/lib/org-ruby/textile_output_buffer.rb
+++ b/lib/org-ruby/textile_output_buffer.rb
@@ -59,8 +59,7 @@ module Orgmode
@output << "*" * @list_indent_stack.length << " " if @output_type == :unordered_list
@output << inline_formatting(@buffer) << "\n"
end
- @buffer = ""
- @buffer_mode = nil
+ clear_accumulation_buffer!
end
diff --git a/spec/output_buffer_spec.rb b/spec/output_buffer_spec.rb
new file mode 100644
index 0000000..533d359
--- /dev/null
+++ b/spec/output_buffer_spec.rb
@@ -0,0 +1,19 @@
+require File.join(File.dirname(__FILE__), %w[spec_helper])
+
+describe Orgmode::OutputBuffer do
+
+ it "computes outline level numbering" do
+ output_buffer = Orgmode::OutputBuffer.new ""
+ output_buffer.get_next_headline_number(1).should eql("1")
+ output_buffer.get_next_headline_number(1).should eql("2")
+ output_buffer.get_next_headline_number(1).should eql("3")
+ output_buffer.get_next_headline_number(1).should eql("4")
+ output_buffer.get_next_headline_number(2).should eql("4.1")
+ output_buffer.get_next_headline_number(2).should eql("4.2")
+ output_buffer.get_next_headline_number(1).should eql("5")
+ output_buffer.get_next_headline_number(2).should eql("5.1")
+ output_buffer.get_next_headline_number(2).should eql("5.2")
+ output_buffer.get_next_headline_number(4).should eql("5.2.0.1")
+ end
+
+end
diff --git a/spec/parser_spec.rb b/spec/parser_spec.rb
index 6c5d3c7..a3b80e1 100644
--- a/spec/parser_spec.rb
+++ b/spec/parser_spec.rb
@@ -33,8 +33,8 @@ describe Orgmode::Parser do
it "should put body lines in headlines" do
parser = Orgmode::Parser.load(RememberFile)
- parser.headlines[0].should have(0).body_lines
- parser.headlines[1].should have(6).body_lines
+ parser.headlines[0].should have(1).body_lines
+ parser.headlines[1].should have(7).body_lines
end
it "should understand lines before the first headline" do
@@ -61,20 +61,6 @@ describe Orgmode::Parser do
parser.export_todo?.should be_false
end
- it "computes outline level numbering" do
- parser = Orgmode::Parser.new ""
- parser.get_next_headline_number(1).should eql("1")
- parser.get_next_headline_number(1).should eql("2")
- parser.get_next_headline_number(1).should eql("3")
- parser.get_next_headline_number(1).should eql("4")
- parser.get_next_headline_number(2).should eql("4.1")
- parser.get_next_headline_number(2).should eql("4.2")
- parser.get_next_headline_number(1).should eql("5")
- parser.get_next_headline_number(2).should eql("5.1")
- parser.get_next_headline_number(2).should eql("5.2")
- parser.get_next_headline_number(4).should eql("5.2.0.1")
- end
-
it "should skip in-buffer settings inside EXAMPLE blocks" do
parser = Orgmode::Parser.load(FreeformExampleFile)
parser.should have(0).in_buffer_settings
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-org.git
More information about the Pkg-ruby-extras-commits
mailing list