[DRE-commits] [ruby-org] 200/303: New pretty indentation of HTML output done, code essentially simplified. Currently, supports ordered and unordered lists, can broke Textile output.

Jérémy Bobbio lunar at alioth.debian.org
Fri Aug 9 17:33:57 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 8482368b7f78ca5add55edce9cd3da754ef27564
Author: vonavi <ivvl82 at gmail.com>
Date:   Sat Dec 15 00:59:10 2012 +0200

    New pretty indentation of HTML output done, code essentially simplified. Currently, supports ordered and unordered lists, can broke Textile output.
---
 lib/org-ruby/html_output_buffer.rb |  105 +++++++-------------------------
 lib/org-ruby/output_buffer.rb      |  116 ++++++++++++++++--------------------
 lib/org-ruby/parser.rb             |   10 ++--
 3 files changed, 81 insertions(+), 150 deletions(-)

diff --git a/lib/org-ruby/html_output_buffer.rb b/lib/org-ruby/html_output_buffer.rb
index 2340ca0..db9ee6b 100644
--- a/lib/org-ruby/html_output_buffer.rb
+++ b/lib/org-ruby/html_output_buffer.rb
@@ -15,12 +15,20 @@ module Orgmode
 
     HtmlBlockTag = {
       :paragraph => "p",
-      :ordered_list => "li",
-      :unordered_list => "li",
+      :unordered_list => "ul",
+      :ordered_list => "ol",
+      :list_item => "li",
+      :definition_list => "dl",
       :definition_term => "dt",
       :definition_descr => "dd",
+      :table => "table",
       :table_row => "tr",
       :table_header => "tr",
+      :blockquote => "blockquote",
+      :example => "pre",
+      :src => "pre",
+      :inline_example => "pre",
+      :center => "div",
       :heading1 => "h1",
       :heading2 => "h2",
       :heading3 => "h3",
@@ -29,18 +37,6 @@ module Orgmode
       :heading6 => "h6"
     }
 
-    ModeTag = {
-      :unordered_list => "ul",
-      :ordered_list => "ol",
-      :definition_list => "dl",
-      :table => "table",
-      :blockquote => "blockquote",
-      :example => "pre",
-      :src => "pre",
-      :inline_example => "pre",
-      :center => "div"
-    }
-
     attr_reader :options
 
     def initialize(output, opts = {})
@@ -57,12 +53,13 @@ module Orgmode
     end
 
     # Output buffer is entering a new mode. Use this opportunity to
-    # write out one of the block tags in the ModeTag constant to put
-    # this information in the HTML stream.
-    def push_mode(mode)
-      if ModeTag[mode] then
+    # write out one of the block tags in the HtmlBlockTag constant to
+    # put this information in the HTML stream.
+    def push_mode(mode, line)
+      @list_indent_stack.push(line.indent)
+      if HtmlBlockTag[mode] then
         output_indentation
-        css_class = ""
+        css_class = @title_decoration
         css_class = " class=\"src\"" if mode == :src and @block_lang.empty?
         css_class = " class=\"src src-#{@block_lang}\"" if mode == :src and not @block_lang.empty?
         css_class = " class=\"example\"" if (mode == :example || mode == :inline_example)
@@ -70,8 +67,8 @@ module Orgmode
 
         unless ((mode == :table and skip_tables?) or
                 (mode == :src and defined? Pygments))
-          @logger.debug "#{mode}: <#{ModeTag[mode]}#{css_class}>\n"
-          @output << "<#{ModeTag[mode]}#{css_class}>\n"
+          @logger.debug "#{mode}: <#{HtmlBlockTag[mode]}#{css_class}>\n"
+          @output << "<#{HtmlBlockTag[mode]}#{css_class}>"
         end
         # Entering a new mode obliterates the title decoration
         @title_decoration = ""
@@ -83,29 +80,18 @@ module Orgmode
     # entering this mode.
     def pop_mode(mode = nil)
       m = super(mode)
-      if ModeTag[m] then
+      if HtmlBlockTag[m] then
         output_indentation
-        # Need to close the floating li elements before closing the list
-        if (m == :unordered_list or
-            m == :ordered_list or
-            m == :definition_list) and
-            (not @unclosed_tags.empty?)
-          close_floating_li_tags
-        end
-
         unless ((mode == :table and skip_tables?) or
                 (mode == :src and defined? Pygments))
-          @logger.debug "</#{ModeTag[m]}>\n"
-          @output << "</#{ModeTag[m]}>\n"
+          @logger.debug "</#{HtmlBlockTag[m]}>\n"
+          @output << "</#{HtmlBlockTag[m]}>\n"
         end
-
-        # In case it was a sublist, close it here
-        close_last_li_tag_maybe
       end
+      @list_indent_stack.pop
     end
 
     def flush!
-      @buffer = @buffer.rstrip
       if buffer_mode_is_src_block?
 
         # Only try to colorize #+BEGIN_SRC blocks with a specified language,
@@ -166,13 +152,6 @@ module Orgmode
         elsif @buffer.length > 0 then
           unless buffer_mode_is_table? and skip_tables?
             @logger.debug "FLUSH      ==========> #{@buffer_mode}"
-            output_indentation
-            if ((@buffered_lines[0].plain_list?) and
-                (@unclosed_tags.count == @list_indent_stack.count))
-              @output << @unclosed_tags.pop
-              output_indentation
-            end
-            @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
@@ -187,19 +166,6 @@ module Orgmode
               end
             end
             @output << inline_formatting(@buffer)
-
-            # Only close the list when it is the last element from that list,
-            # or when starting another list
-            if (@output_type == :unordered_list or
-                @output_type == :ordered_list   or
-                @output_type == :definition_list) and
-                (not @list_indent_stack.empty?)
-              @unclosed_tags.push("</#{HtmlBlockTag[@output_type]}>\n")
-              @output << "\n"
-            else
-              @output << "</#{HtmlBlockTag[@output_type]}>\n"
-            end
-            @title_decoration = ""
           else
             @logger.debug "SKIP       ==========> #{@buffer_mode}"
           end
@@ -248,7 +214,7 @@ module Orgmode
     end
 
     def output_indentation
-      indent = "  " * (@mode_stack.length - 1)
+      indent = "  " * (@list_indent_stack.length - 1)
       @output << indent
     end
 
@@ -264,7 +230,6 @@ module Orgmode
 
     # Applies inline formatting rules to a string.
     def inline_formatting(str)
-      str.rstrip!
       str = @re_help.rewrite_emphasis(str) do |marker, s|
         "#{Tags[marker][:open]}#{s}#{Tags[marker][:close]}"
       end
@@ -320,30 +285,6 @@ module Orgmode
       str
     end
 
-    def close_floating_li_tags
-      unless @final_list_node
-        unless @unclosed_tags.empty?
-          @output << "  " << @unclosed_tags.pop
-          output_indentation
-        end
-      end
-
-      @final_list_node = false
-    end
-
-    def close_last_li_tag_maybe
-      if (@list_indent_stack.count < @unclosed_tags.count) and not
-          (@list_indent_stack.empty? and @unclosed_tags.empty?)
-        output_indentation
-        @output << @unclosed_tags.pop
-        if (@list_indent_stack.count == @unclosed_tags.count) and not
-            (@list_indent_stack.empty? and @unclosed_tags.empty?)
-          @final_list_node = true
-          pop_mode
-        end
-      end
-    end
-
     def normalize_lang(lang)
       case lang
       when 'emacs-lisp', 'common-lisp', 'lisp'
diff --git a/lib/org-ruby/output_buffer.rb b/lib/org-ruby/output_buffer.rb
index c7f9730..e41d8da 100644
--- a/lib/org-ruby/output_buffer.rb
+++ b/lib/org-ruby/output_buffer.rb
@@ -51,10 +51,9 @@ module Orgmode
       end
 
       @re_help = RegexpHelper.new
-      push_mode(:normal)
     end
 
-    Modes = [:normal, :ordered_list, :unordered_list, :definition_list, :blockquote, :src, :example, :table, :inline_example, :center, :property_drawer]
+    HeadingModes = [:heading1, :heading2, :heading3, :heading4, :heading5, :heading6]
 
     def current_mode
       @mode_stack.last
@@ -65,7 +64,6 @@ module Orgmode
     end
 
     def push_mode(mode)
-      raise "Not a recognized mode: #{mode}" unless Modes.include?(mode)
       @mode_stack.push(mode)
     end
 
@@ -83,20 +81,18 @@ module Orgmode
         flush!
         # We try to get the lang from #+BEGIN_SRC blocks
         @block_lang = line.block_lang
-        @output_type = line.paragraph_type
       elsif current_mode == :example and line.end_block?
         flush!
-        @output_type = line.paragraph_type
       elsif not should_accumulate_output?(line)
         flush!
-        maintain_list_indent_stack(line)
-        @output_type = line.paragraph_type
+        maintain_mode_stack(line)
       end
-      push_mode(:inline_example) if line.inline_example? and current_mode != :inline_example and not line.property_drawer?
+      @output_type = line.paragraph_type
+      push_mode(:inline_example, line) if line.inline_example? and current_mode != :inline_example and not line.property_drawer?
       pop_mode(:inline_example) if current_mode == :inline_example and !line.inline_example?
-      push_mode(:property_drawer) if line.property_drawer? and current_mode != :property_drawer
+      push_mode(:property_drawer, line) if line.property_drawer? and current_mode != :property_drawer
       pop_mode(:property_drawer) if current_mode == :property_drawer and line.property_drawer_end_block?
-      push_mode(:table) if enter_table?
+      push_mode(:table, line) if enter_table?
       pop_mode(:table) if exit_table?
       @buffered_lines.push(line)
     end
@@ -171,36 +167,43 @@ module Orgmode
       end
     end
 
-    def maintain_list_indent_stack(line)
-      if (line.plain_list?) then
-        while (not @list_indent_stack.empty? \
-               and (@list_indent_stack.last > line.indent))
-          @list_indent_stack.pop
-          pop_mode
+    def maintain_mode_stack(line)
+      # Always close heading line
+      pop_mode if HeadingModes.include?(current_mode)
+
+      if ((not line.paragraph_type == :blank) or
+          @output_type == :blank)
+        # Close previous tags on demand. Two blank lines close all tags.
+        while ((not @list_indent_stack.empty?) and
+               @list_indent_stack.last >= line.indent)
+          unless (line.plain_list? and
+                  current_mode == line.paragraph_type and
+                  @list_indent_stack.last == line.indent)
+            pop_mode
+          else
+            break
+          end
         end
-        if (@list_indent_stack.empty? \
-            or @list_indent_stack.last < line.indent)
-          @list_indent_stack.push(line.indent)
-          push_mode line.paragraph_type
+        # Open plain list.
+        if line.plain_list?
+          if (@list_indent_stack.empty? or
+              @list_indent_stack.last < line.indent)
+            push_mode(line.paragraph_type, line)
+            @output << "\n"
+          end
         end
-      elsif line.blank? then
-
-        # Nothing
-
-      elsif ((not line.plain_list?) and
-             (not @list_indent_stack.empty?) and
-             (line.indent > @list_indent_stack.last))
-
-        # Nothing -- output this paragraph inside
-        # the list block (ul/ol)
-
-      else
-        @list_indent_stack = []
-        while ((current_mode == :ordered_list) or
-               (current_mode == :definition_list) or
-               (current_mode == :unordered_list))
-          pop_mode
+        # Open tag preceding text, including list item.
+        if (@list_indent_stack.empty? or
+            @list_indent_stack.last <= line.indent)
+          if (line.paragraph_type == :ordered_list or
+              line.paragraph_type == :unordered_list)
+            push_mode(:list_item, line)
+          elsif not line.paragraph_type == :blank
+            push_mode(line.paragraph_type, line)
+          end
         end
+      else # If blank line, close preceding paragraph
+        pop_mode if current_mode == :paragraph
       end
     end
 
@@ -209,39 +212,26 @@ module Orgmode
     end
 
     # Tests if the current line should be accumulated in the current
-    # output buffer.  (Extraneous line breaks in the orgmode buffer
-    # are removed by accumulating lines in the output buffer without
-    # line breaks.)
+    # output buffer.
     def should_accumulate_output?(line)
+      # Special case: Assing mode if not yet done.
+      return false if not current_mode
 
       # Special case: We are accumulating source code block content for colorizing
       return true if line.paragraph_type == :src and @output_type == :src
 
-      # Special case: Preserve line breaks in block code mode.
-      return false if preserve_whitespace?
+      # Special case: Multiple "paragraphs" get accumulated.
+      return true if (line.paragraph_type == :paragraph and
+                      current_mode == :paragraph)
 
-      # Special case: Multiple blank lines get accumulated.
-      return true if line.paragraph_type == :blank and @output_type == :blank
-
-      # Currently only "paragraphs" get accumulated with previous output.
-      return false unless line.paragraph_type == :paragraph
-      if ((@output_type == :ordered_list) or
-          (@output_type == :definition_list) or
-          (@output_type == :unordered_list)) then
-
-        # If the previous output type was a list item, then we only put a paragraph in it
-        # if its indent level is greater than the list indent level.
-
-        return false unless line.indent > @list_indent_stack.last
-      end
+      # If the current mode is not paragraph, then we only put a
+      # paragraph in it if its indent level is greater than the indent
+      # level of the current mode and no blank lines before.
+      return true if (line.paragraph_type == :paragraph and
+                      (not @output_type == :blank) and
+                      line.indent > @list_indent_stack.last)
 
-      # Only accumulate paragraphs with lists & paragraphs.
-      return false unless
-        ((@output_type == :paragraph) or
-         (@output_type == :ordered_list) or
-         (@output_type == :definition_list) or
-         (@output_type == :unordered_list))
-      true
+      false
     end
   end                           # class OutputBuffer
 end                             # module Orgmode
diff --git a/lib/org-ruby/parser.rb b/lib/org-ruby/parser.rb
index 312300d..659a5af 100644
--- a/lib/org-ruby/parser.rb
+++ b/lib/org-ruby/parser.rb
@@ -262,10 +262,10 @@ module Orgmode
 
         when :begin_block
 
-          output_buffer.push_mode(:blockquote) if line.block_type.casecmp("QUOTE") == 0
-          output_buffer.push_mode(:src) if line.block_type.casecmp("SRC") == 0
-          output_buffer.push_mode(:example) if line.block_type.casecmp("EXAMPLE") == 0
-          output_buffer.push_mode(:center) if line.block_type.casecmp("CENTER") == 0
+          output_buffer.push_mode(:blockquote, line) if line.block_type.casecmp("QUOTE") == 0
+          output_buffer.push_mode(:src, line) if line.block_type.casecmp("SRC") == 0
+          output_buffer.push_mode(:example, line) if line.block_type.casecmp("EXAMPLE") == 0
+          output_buffer.push_mode(:center, line) if line.block_type.casecmp("CENTER") == 0
 
         when :end_block
 
@@ -295,7 +295,7 @@ module Orgmode
         end
       end
       output_buffer.flush!
-      output_buffer.pop_mode until output_buffer.current_mode == :normal
+      output_buffer.pop_mode while output_buffer.current_mode
       output_buffer.output_footnotes!
       output_buffer.output
     end

-- 
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