aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rdoc/markup.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rdoc/markup.rb')
-rw-r--r--lib/rdoc/markup.rb286
1 files changed, 17 insertions, 269 deletions
diff --git a/lib/rdoc/markup.rb b/lib/rdoc/markup.rb
index a584a79b75..c3c5213943 100644
--- a/lib/rdoc/markup.rb
+++ b/lib/rdoc/markup.rb
@@ -27,9 +27,9 @@ require 'rdoc'
# convert multiple input strings.
#
# require 'rdoc/markup/to_html'
-#
+#
# h = RDoc::Markup::ToHtml.new
-#
+#
# puts h.convert(input_string)
#
# You can extend the RDoc::Markup parser to recognise new markup
@@ -41,22 +41,22 @@ require 'rdoc'
#
# require 'rdoc/markup'
# require 'rdoc/markup/to_html'
-#
+#
# class WikiHtml < RDoc::Markup::ToHtml
# def handle_special_WIKIWORD(special)
# "<font color=red>" + special.text + "</font>"
# end
# end
-#
+#
# m = RDoc::Markup.new
# m.add_word_pair("{", "}", :STRIKE)
# m.add_html("no", :STRIKE)
-#
+#
# m.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
-#
+#
# wh = WikiHtml.new
# wh.add_tag(:STRIKE, "<strike>", "</strike>")
-#
+#
# puts "<body>#{wh.convert ARGF.read}</body>"
#
#--
@@ -65,30 +65,7 @@ require 'rdoc'
class RDoc::Markup
- SPACE = ?\s
-
- # List entries look like:
- # * text
- # 1. text
- # [label] text
- # label:: text
- #
- # Flag it as a list entry, and work out the indent for subsequent lines
-
- SIMPLE_LIST_RE = /^(
- ( \* (?# bullet)
- |- (?# bullet)
- |\d+\. (?# numbered )
- |[A-Za-z]\. (?# alphabetically numbered )
- )
- \s+
- )\S/x
-
- LABEL_LIST_RE = /^(
- ( \[.*?\] (?# labeled )
- |\S.*:: (?# note )
- )(?:\s+|$)
- )/x
+ attr_reader :attribute_manager
##
# Take a block of text and use various heuristics to determine it's
@@ -96,7 +73,7 @@ class RDoc::Markup
# identify significant chunks.
def initialize
- @am = RDoc::Markup::AttributeManager.new
+ @attribute_manager = RDoc::Markup::AttributeManager.new
@output = nil
end
@@ -106,14 +83,14 @@ class RDoc::Markup
# formatters can recognize by their +name+.
def add_word_pair(start, stop, name)
- @am.add_word_pair(start, stop, name)
+ @attribute_manager.add_word_pair(start, stop, name)
end
##
# Add to the sequences recognized as general markup.
def add_html(tag, name)
- @am.add_html(tag, name)
+ @attribute_manager.add_html(tag, name)
end
##
@@ -126,7 +103,7 @@ class RDoc::Markup
# accept_special method.
def add_special(pattern, name)
- @am.add_special(pattern, name)
+ @attribute_manager.add_special(pattern, name)
end
##
@@ -136,243 +113,14 @@ class RDoc::Markup
# display the result.
def convert(str, op)
- lines = str.split(/\r?\n/).map { |line| Line.new line }
- @lines = Lines.new lines
-
- return "" if @lines.empty?
- @lines.normalize
- assign_types_to_lines
- group = group_lines
- # call the output formatter to handle the result
- #group.each { |line| p line }
- group.accept @am, op
- end
-
- private
-
- ##
- # Look through the text at line indentation. We flag each line as being
- # Blank, a paragraph, a list element, or verbatim text.
-
- def assign_types_to_lines(margin = 0, level = 0)
- while line = @lines.next
- if line.blank? then
- line.stamp :BLANK, level
- next
- end
-
- # if a line contains non-blanks before the margin, then it must belong
- # to an outer level
-
- text = line.text
-
- for i in 0...margin
- if text[i] != SPACE
- @lines.unget
- return
- end
- end
-
- active_line = text[margin..-1]
-
- # Rules (horizontal lines) look like
- #
- # --- (three or more hyphens)
- #
- # The more hyphens, the thicker the rule
- #
-
- if /^(---+)\s*$/ =~ active_line
- line.stamp :RULE, level, $1.length-2
- next
- end
-
- # Then look for list entries. First the ones that have to have
- # text following them (* xxx, - xxx, and dd. xxx)
-
- if SIMPLE_LIST_RE =~ active_line
- offset = margin + $1.length
- prefix = $2
- prefix_length = prefix.length
-
- flag = case prefix
- when "*","-" then :BULLET
- when /^\d/ then :NUMBER
- when /^[A-Z]/ then :UPPERALPHA
- when /^[a-z]/ then :LOWERALPHA
- else raise "Invalid List Type: #{self.inspect}"
- end
-
- line.stamp :LIST, level+1, prefix, flag
- text[margin, prefix_length] = " " * prefix_length
- assign_types_to_lines(offset, level + 1)
- next
- end
-
- if LABEL_LIST_RE =~ active_line
- offset = margin + $1.length
- prefix = $2
- prefix_length = prefix.length
-
- next if handled_labeled_list(line, level, margin, offset, prefix)
- end
-
- # Headings look like
- # = Main heading
- # == Second level
- # === Third
- #
- # Headings reset the level to 0
-
- if active_line[0] == ?= and active_line =~ /^(=+)\s*(.*)/
- prefix_length = $1.length
- prefix_length = 6 if prefix_length > 6
- line.stamp :HEADING, 0, prefix_length
- line.strip_leading(margin + prefix_length)
- next
- end
-
- # If the character's a space, then we have verbatim text,
- # otherwise
-
- if active_line[0] == SPACE
- line.strip_leading(margin) if margin > 0
- line.stamp :VERBATIM, level
- else
- line.stamp :PARAGRAPH, level
- end
- end
- end
-
- ##
- # Handle labeled list entries, We have a special case to deal with.
- # Because the labels can be long, they force the remaining block of text
- # over the to right:
- #
- # this is a long label that I wrote:: and here is the
- # block of text with
- # a silly margin
- #
- # So we allow the special case. If the label is followed by nothing, and
- # if the following line is indented, then we take the indent of that line
- # as the new margin.
- #
- # this is a long label that I wrote::
- # here is a more reasonably indented block which
- # will be attached to the label.
- #
-
- def handled_labeled_list(line, level, margin, offset, prefix)
- prefix_length = prefix.length
- text = line.text
- flag = nil
-
- case prefix
- when /^\[/ then
- flag = :LABELED
- prefix = prefix[1, prefix.length-2]
- when /:$/ then
- flag = :NOTE
- prefix.chop!
- else
- raise "Invalid List Type: #{self.inspect}"
- end
+ document = RDoc::Markup::Parser.parse str
- # body is on the next line
- if text.length <= offset then
- original_line = line
- line = @lines.next
- return false unless line
- text = line.text
-
- for i in 0..margin
- if text[i] != SPACE
- @lines.unget
- return false
- end
- end
-
- i = margin
- i += 1 while text[i] == SPACE
-
- if i >= text.length then
- @lines.unget
- return false
- else
- offset = i
- prefix_length = 0
-
- if text[offset..-1] =~ SIMPLE_LIST_RE then
- @lines.unget
- line = original_line
- line.text = ''
- else
- @lines.delete original_line
- end
- end
- end
-
- line.stamp :LIST, level+1, prefix, flag
- text[margin, prefix_length] = " " * prefix_length
- assign_types_to_lines(offset, level + 1)
- return true
+ document.accept op
end
- ##
- # Return a block consisting of fragments which are paragraphs, list
- # entries or verbatim text. We merge consecutive lines of the same type
- # and level together. We are also slightly tricky with lists: the lines
- # following a list introduction look like paragraph lines at the next
- # level, and we remap them into list entries instead.
-
- def group_lines
- @lines.rewind
-
- in_list = false
- wanted_type = wanted_level = nil
-
- block = LineCollection.new
- group = nil
-
- while line = @lines.next
- if line.level == wanted_level and line.type == wanted_type
- group.add_text(line.text)
- else
- group = block.fragment_for(line)
- block.add(group)
-
- if line.type == :LIST
- wanted_type = :PARAGRAPH
- else
- wanted_type = line.type
- end
-
- wanted_level = line.type == :HEADING ? line.param : line.level
- end
- end
-
- block.normalize
- block
- end
-
- ##
- # For debugging, we allow access to our line contents as text.
-
- def content
- @lines.as_text
- end
- public :content
-
- ##
- # For debugging, return the list of line types.
-
- def get_line_types
- @lines.line_types
- end
- public :get_line_types
-
end
-require 'rdoc/markup/fragments'
+require 'rdoc/markup/parser'
+require 'rdoc/markup/attribute_manager'
require 'rdoc/markup/inline'
-require 'rdoc/markup/lines'
+