1##
2# RDoc::Markup parses plain text documents and attempts to decompose them into
3# their constituent parts.  Some of these parts are high-level: paragraphs,
4# chunks of verbatim text, list entries and the like.  Other parts happen at
5# the character level: a piece of bold text, a word in code font.  This markup
6# is similar in spirit to that used on WikiWiki webs, where folks create web
7# pages using a simple set of formatting rules.
8#
9# RDoc::Markup and other markup formats do no output formatting, this is
10# handled by the RDoc::Markup::Formatter subclasses.
11#
12# = Supported Formats
13#
14# Besides the RDoc::Markup format, the following formats are built in to RDoc:
15#
16# markdown::
17#   The markdown format as described by
18#   http://daringfireball.net/projects/markdown/.  See RDoc::Markdown for
19#   details on the parser and supported extensions.
20# rd::
21#   The rdtool format.  See RDoc::RD for details on the parser and format.
22# tomdoc::
23#   The TomDoc format as described by http://tomdoc.org/.  See RDoc::TomDoc
24#   for details on the parser and supported extensions.
25#
26# You can choose a markup format using the following methods:
27#
28# per project::
29#   If you build your documentation with rake use RDoc::Task#markup.
30#
31#   If you build your documentation by hand run:
32#
33#      rdoc --markup your_favorite_format --write-options
34#
35#   and commit <tt>.rdoc_options</tt> and ship it with your packaged gem.
36# per file::
37#   At the top of the file use the <tt>:markup:</tt> directive to set the
38#   default format for the rest of the file.
39# per comment::
40#   Use the <tt>:markup:</tt> directive at the top of a comment you want
41#   to write in a different format.
42#
43# = RDoc::Markup
44#
45# RDoc::Markup is extensible at runtime: you can add \new markup elements to
46# be recognized in the documents that RDoc::Markup parses.
47#
48# RDoc::Markup is intended to be the basis for a family of tools which share
49# the common requirement that simple, plain-text should be rendered in a
50# variety of different output formats and media.  It is envisaged that
51# RDoc::Markup could be the basis for formatting RDoc style comment blocks,
52# Wiki entries, and online FAQs.
53#
54# == Synopsis
55#
56# This code converts +input_string+ to HTML.  The conversion takes place in
57# the +convert+ method, so you can use the same RDoc::Markup converter to
58# convert multiple input strings.
59#
60#   require 'rdoc'
61#
62#   h = RDoc::Markup::ToHtml.new
63#
64#   puts h.convert(input_string)
65#
66# You can extend the RDoc::Markup parser to recognize new markup
67# sequences, and to add special processing for text that matches a
68# regular expression.  Here we make WikiWords significant to the parser,
69# and also make the sequences {word} and \<no>text...</no> signify
70# strike-through text.  We then subclass the HTML output class to deal
71# with these:
72#
73#   require 'rdoc'
74#
75#   class WikiHtml < RDoc::Markup::ToHtml
76#     def handle_special_WIKIWORD(special)
77#       "<font color=red>" + special.text + "</font>"
78#     end
79#   end
80#
81#   markup = RDoc::Markup.new
82#   markup.add_word_pair("{", "}", :STRIKE)
83#   markup.add_html("no", :STRIKE)
84#
85#   markup.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
86#
87#   wh = WikiHtml.new markup
88#   wh.add_tag(:STRIKE, "<strike>", "</strike>")
89#
90#   puts "<body>#{wh.convert ARGF.read}</body>"
91#
92# == Encoding
93#
94# Where Encoding support is available, RDoc will automatically convert all
95# documents to the same output encoding.  The output encoding can be set via
96# RDoc::Options#encoding and defaults to Encoding.default_external.
97#
98# = \RDoc Markup Reference
99#
100# == Block Markup
101#
102# === Paragraphs and Verbatim
103#
104# The markup engine looks for a document's natural left margin.  This is
105# used as the initial margin for the document.
106#
107# Consecutive lines starting at this margin are considered to be a
108# paragraph. Empty lines separate paragraphs.
109#
110# Any line that starts to the right of the current margin is treated
111# as verbatim text.  This is useful for code listings:
112#
113#   3.times { puts "Ruby" }
114#
115# In verbatim text, two or more blank lines are collapsed into one,
116# and trailing blank lines are removed:
117#
118#   This is the first line
119#
120#
121#   This is the second non-blank line,
122#   after 2 blank lines in the source markup.
123#
124#
125# There were two trailing blank lines right above this paragraph, that
126# have been removed. In addition, the verbatim text has been shifted
127# left, so the amount of indentation of verbatim text is unimportant.
128#
129# For HTML output RDoc makes a small effort to determine if a verbatim section
130# contains ruby source code.  If so, the verbatim block will be marked up as
131# HTML.  Triggers include "def", "class", "module", "require", the "hash
132# rocket"# (=>) or a block call with a parameter.
133#
134# === Headers
135#
136# A line starting with an equal sign (=) is treated as a
137# heading.  Level one headings have one equals sign, level two headings
138# have two, and so on until level six, which is the maximum
139# (seven hyphens or more result in a level six heading).
140#
141# For example, the above header was obtained with:
142#
143#   === Headers
144#
145# In HTML output headers have an id matching their name.  The above example's
146# HTML is:
147#
148#   <h3 id="label-Headers">Headers</h3>
149#
150# If a heading is inside a method body the id will be prefixed with the
151# method's id.  If the above header where in the documentation for a method
152# such as:
153#
154#   ##
155#   # This method does fun things
156#   #
157#   # = Example
158#   #
159#   #   Example of fun things goes here ...
160#
161#   def do_fun_things
162#   end
163#
164# The header's id would be:
165#
166#   <h1 id="method-i-do_fun_things-label-Example">Example</h3>
167#
168# The label can be linked-to using <tt>SomeClass@Headers</tt>.  See
169# {Links}[RDoc::Markup@Links] for further details.
170#
171# === Rules
172#
173# A line starting with three or more hyphens (at the current indent)
174# generates a horizontal rule.  The more hyphens, the thicker the rule
175# (within reason, and if supported by the output device).
176#
177# In the case of HTML output, three dashes generate a 1-pixel high rule,
178# four dashes result in 2 pixels, and so on. The actual height is limited
179# to 10 pixels:
180#
181#   ---
182#   -----
183#   -----------------------------------------------------
184#
185# produces:
186#
187# ---
188# -----
189# -----------------------------------------------------
190#
191# === Simple Lists
192#
193# If a paragraph starts with a "*", "-", "<digit>." or "<letter>.",
194# then it is taken to be the start of a list.  The margin is increased to be
195# the first non-space following the list start flag.  Subsequent lines
196# should be indented to this new margin until the list ends.  For example:
197#
198#   * this is a list with three paragraphs in
199#     the first item.  This is the first paragraph.
200#
201#     And this is the second paragraph.
202#
203#     1. This is an indented, numbered list.
204#     2. This is the second item in that list
205#
206#     This is the third conventional paragraph in the
207#     first list item.
208#
209#   * This is the second item in the original list
210#
211# produces:
212#
213# * this is a list with three paragraphs in
214#   the first item.  This is the first paragraph.
215#
216#   And this is the second paragraph.
217#
218#   1. This is an indented, numbered list.
219#   2. This is the second item in that list
220#
221#   This is the third conventional paragraph in the
222#   first list item.
223#
224# * This is the second item in the original list
225#
226# === Labeled Lists
227#
228# You can also construct labeled lists, sometimes called description
229# or definition lists.  Do this by putting the label in square brackets
230# and indenting the list body:
231#
232#   [cat]  a small furry mammal
233#          that seems to sleep a lot
234#
235#   [ant]  a little insect that is known
236#          to enjoy picnics
237#
238# produces:
239#
240# [cat]  a small furry mammal
241#        that seems to sleep a lot
242#
243# [ant]  a little insect that is known
244#        to enjoy picnics
245#
246# If you want the list bodies to line up to the left of the labels,
247# use two colons:
248#
249#   cat::  a small furry mammal
250#          that seems to sleep a lot
251#
252#   ant::  a little insect that is known
253#          to enjoy picnics
254#
255# produces:
256#
257# cat::  a small furry mammal
258#        that seems to sleep a lot
259#
260# ant::  a little insect that is known
261#        to enjoy picnics
262#
263# Notice that blank lines right after the label are ignored in labeled lists:
264#
265#   [one]
266#
267#       definition 1
268#
269#   [two]
270#
271#       definition 2
272#
273# produces the same output as
274#
275#   [one]  definition 1
276#   [two]  definition 2
277#
278#
279# === Lists and Verbatim
280#
281# If you want to introduce a verbatim section right after a list, it has to be
282# less indented than the list item bodies, but more indented than the list
283# label, letter, digit or bullet. For instance:
284#
285#   *   point 1
286#
287#   *   point 2, first paragraph
288#
289#       point 2, second paragraph
290#         verbatim text inside point 2
291#       point 2, third paragraph
292#     verbatim text outside of the list (the list is therefore closed)
293#   regular paragraph after the list
294#
295# produces:
296#
297# *   point 1
298#
299# *   point 2, first paragraph
300#
301#     point 2, second paragraph
302#       verbatim text inside point 2
303#     point 2, third paragraph
304#   verbatim text outside of the list (the list is therefore closed)
305# regular paragraph after the list
306#
307# == Text Markup
308#
309# === Bold, Italic, Typewriter Text
310#
311# You can use markup within text (except verbatim) to change the
312# appearance of parts of that text.  Out of the box, RDoc::Markup
313# supports word-based and general markup.
314#
315# Word-based markup uses flag characters around individual words:
316#
317# <tt>\*_word_\*</tt>::  displays _word_ in a *bold* font
318# <tt>\__word_\_</tt>::  displays _word_ in an _emphasized_ font
319# <tt>\+_word_\+</tt>::  displays _word_ in a +code+ font
320#
321# General markup affects text between a start delimiter and an end
322# delimiter.  Not surprisingly, these delimiters look like HTML markup.
323#
324# <tt>\<b>_text_</b></tt>::    displays _text_ in a *bold* font
325# <tt>\<em>_text_</em></tt>::  displays _text_ in an _emphasized_ font
326#                              (alternate tag: <tt>\<i></tt>)
327# <tt>\<tt>_text_\</tt></tt>:: displays _text_ in a +code+ font
328#                              (alternate tag: <tt>\<code></tt>)
329#
330# Unlike conventional Wiki markup, general markup can cross line
331# boundaries.  You can turn off the interpretation of markup by
332# preceding the first character with a backslash (see <i>Escaping
333# Text Markup</i>, below).
334#
335# === Links
336#
337# Links to starting with +http:+, +https:+, +mailto:+, +ftp:+ or +www.+
338# are recognized.  An HTTP url that references an external image is converted
339# into an inline image element.
340#
341# Classes and methods will be automatically linked to their definition.  For
342# example, <tt>RDoc::Markup</tt> will link to this documentation.  By default
343# methods will only be automatically linked if they contain an <tt>_</tt> (all
344# methods can be automatically linked through the <tt>--hyperlink-all</tt>
345# command line option).
346#
347# Single-word methods can be linked by using the <tt>#</tt> character for
348# instance methods or <tt>::</tt> for class methods.  For example,
349# <tt>#convert</tt> links to #convert.  A class or method may be combined like
350# <tt>RDoc::Markup#convert</tt>.
351#
352# A heading inside the documentation can be linked by following the class
353# or method by an <tt>@</tt> then the heading name.
354# <tt>RDoc::Markup@Links</tt> will link to this section like this:
355# RDoc::Markup@Links.  Spaces in headings with multiple words must be escaped
356# with <tt>+</tt> like <tt>RDoc::Markup@Escaping+Text+Markup</tt>.
357# Punctuation and other special characters must be escaped like CGI.escape.
358#
359# Links can also be of the form <tt>label[url]</tt>, in which case +label+ is
360# used in the displayed text, and +url+ is used as the target.  If +label+
361# contains multiple words, put it in braces: <tt>{multi word label}[url]</tt>.
362# The +url+ may be an +http:+-type link or a cross-reference to a class,
363# module or method with a label.
364#
365# Links with the <tt>rdoc-ref:</tt> scheme will link to the referenced class,
366# module, method, file, etc.  If the referenced item is does not exist
367# no link will be generated and <tt>rdoc-ref:</tt> will be removed from the
368# resulting text.
369#
370# Links starting with <tt>rdoc-label:label_name</tt> will link to the
371# +label_name+.  You can create a label for the current link (for
372# bidirectional links) by supplying a name for the current link like
373# <tt>rdoc-label:label-other:label-mine</tt>.
374#
375# Links starting with +link:+ refer to local files whose path is relative to
376# the <tt>--op</tt> directory.  Use <tt>rdoc-ref:</tt> instead of
377# <tt>link:</tt> to link to files generated by RDoc as the link target may
378# be different across RDoc generators.
379#
380# Example links:
381#
382#   https://github.com/rdoc/rdoc
383#   mailto:user@example.com
384#   {RDoc Documentation}[http://rdoc.rubyforge.org]
385#   {RDoc Markup}[rdoc-ref:RDoc::Markup]
386#
387# === Escaping Text Markup
388#
389# Text markup can be escaped with a backslash, as in \<tt>, which was obtained
390# with <tt>\\<tt></tt>.  Except in verbatim sections and between \<tt> tags,
391# to produce a backslash you have to double it unless it is followed by a
392# space, tab or newline. Otherwise, the HTML formatter will discard it, as it
393# is used to escape potential links:
394#
395#   * The \ must be doubled if not followed by white space: \\.
396#   * But not in \<tt> tags: in a Regexp, <tt>\S</tt> matches non-space.
397#   * This is a link to {ruby-lang}[www.ruby-lang.org].
398#   * This is not a link, however: \{ruby-lang.org}[www.ruby-lang.org].
399#   * This will not be linked to \RDoc::RDoc#document
400#
401# generates:
402#
403# * The \ must be doubled if not followed by white space: \\.
404# * But not in \<tt> tags: in a Regexp, <tt>\S</tt> matches non-space.
405# * This is a link to {ruby-lang}[www.ruby-lang.org]
406# * This is not a link, however: \{ruby-lang.org}[www.ruby-lang.org]
407# * This will not be linked to \RDoc::RDoc#document
408#
409# Inside \<tt> tags, more precisely, leading backslashes are removed only if
410# followed by a markup character (<tt><*_+</tt>), a backslash, or a known link
411# reference (a known class or method). So in the example above, the backslash
412# of <tt>\S</tt> would be removed if there was a class or module named +S+ in
413# the current context.
414#
415# This behavior is inherited from RDoc version 1, and has been kept for
416# compatibility with existing RDoc documentation.
417#
418# === Conversion of characters
419#
420# HTML will convert two/three dashes to an em-dash. Other common characters are
421# converted as well:
422#
423#   em-dash::  -- or ---
424#   ellipsis:: ...
425#
426#   single quotes:: 'text' or `text'
427#   double quotes:: "text" or ``text''
428#
429#   copyright:: (c)
430#   registered trademark:: (r)
431#
432# produces:
433#
434# em-dash::  -- or ---
435# ellipsis:: ...
436#
437# single quotes:: 'text' or `text'
438# double quotes:: "text" or ``text''
439#
440# copyright:: (c)
441# registered trademark:: (r)
442#
443#
444# == Documenting Source Code
445#
446# Comment blocks can be written fairly naturally, either using <tt>#</tt> on
447# successive lines of the comment, or by including the comment in
448# a <tt>=begin</tt>/<tt>=end</tt> block.  If you use the latter form,
449# the <tt>=begin</tt> line _must_ be flagged with an +rdoc+ tag:
450#
451#   =begin rdoc
452#   Documentation to be processed by RDoc.
453#
454#   ...
455#   =end
456#
457# RDoc stops processing comments if it finds a comment line starting
458# with <tt>--</tt> right after the <tt>#</tt> character (otherwise,
459# it will be treated as a rule if it has three dashes or more).
460# This can be used to separate external from internal comments,
461# or to stop a comment being associated with a method, class, or module.
462# Commenting can be turned back on with a line that starts with <tt>++</tt>.
463#
464#   ##
465#   # Extract the age and calculate the date-of-birth.
466#   #--
467#   # FIXME: fails if the birthday falls on February 29th
468#   #++
469#   # The DOB is returned as a Time object.
470#
471#   def get_dob(person)
472#     # ...
473#   end
474#
475# Names of classes, files, and any method names containing an underscore or
476# preceded by a hash character are automatically linked from comment text to
477# their description. This linking works inside the current class or module,
478# and with ancestor methods (in included modules or in the superclass).
479#
480# Method parameter lists are extracted and displayed with the method
481# description.  If a method calls +yield+, then the parameters passed to yield
482# will also be displayed:
483#
484#   def fred
485#     ...
486#     yield line, address
487#
488# This will get documented as:
489#
490#   fred() { |line, address| ... }
491#
492# You can override this using a comment containing ':yields: ...' immediately
493# after the method definition
494#
495#   def fred # :yields: index, position
496#     # ...
497#
498#     yield line, address
499#
500# which will get documented as
501#
502#    fred() { |index, position| ... }
503#
504# +:yields:+ is an example of a documentation directive.  These appear
505# immediately after the start of the document element they are modifying.
506#
507# RDoc automatically cross-references words with underscores or camel-case.
508# To suppress cross-references, prefix the word with a \ character.  To
509# include special characters like "<tt>\n</tt>", you'll need to use
510# two \ characters in normal text, but only one in \<tt> text:
511#
512#   "\\n" or "<tt>\n</tt>"
513#
514# produces:
515#
516# "\\n" or "<tt>\n</tt>"
517#
518# == Directives
519#
520# Directives are keywords surrounded by ":" characters.
521#
522# === Controlling what is documented
523#
524# [+:nodoc:+ / <tt>:nodoc: all</tt>]
525#   This directive prevents documentation for the element from
526#   being generated.  For classes and modules, methods, aliases,
527#   constants, and attributes directly within the affected class or
528#   module also will be omitted.  By default, though, modules and
529#   classes within that class or module _will_ be documented.  This is
530#   turned off by adding the +all+ modifier.
531#
532#     module MyModule # :nodoc:
533#       class Input
534#       end
535#     end
536#
537#     module OtherModule # :nodoc: all
538#       class Output
539#       end
540#     end
541#
542#   In the above code, only class <tt>MyModule::Input</tt> will be documented.
543#
544#   The +:nodoc:+ directive, like +:enddoc:+, +:stopdoc:+ and +:startdoc:+
545#   presented below, is local to the current file: if you do not want to
546#   document a module that appears in several files, specify +:nodoc:+ on each
547#   appearance, at least once per file.
548#
549# [+:stopdoc:+ / +:startdoc:+]
550#   Stop and start adding new documentation elements to the current container.
551#   For example, if a class has a number of constants that you don't want to
552#   document, put a +:stopdoc:+ before the first, and a +:startdoc:+ after the
553#   last.  If you don't specify a +:startdoc:+ by the end of the container,
554#   disables documentation for the rest of the current file.
555#
556# [+:doc:+]
557#   Forces a method or attribute to be documented even if it wouldn't be
558#   otherwise.  Useful if, for example, you want to include documentation of a
559#   particular private method.
560#
561# [+:enddoc:+]
562#   Document nothing further at the current level: directives +:startdoc:+ and
563#   +:doc:+ that appear after this will not be honored for the current container
564#   (file, class or module), in the current file.
565#
566# [+:notnew:+ / +:not_new:+ / +:not-new:+ ]
567#   Only applicable to the +initialize+ instance method.  Normally RDoc
568#   assumes that the documentation and parameters for +initialize+ are
569#   actually for the +new+ method, and so fakes out a +new+ for the class.
570#   The +:notnew:+ directive stops this.  Remember that +initialize+ is private,
571#   so you won't see the documentation unless you use the +-a+ command line
572#   option.
573#
574# === Method arguments
575#
576# [+:arg:+ or +:args:+ _parameters_]
577#   Overrides the default argument handling with exactly these parameters.
578#
579#     ##
580#     #  :args: a, b
581#
582#     def some_method(*a)
583#     end
584#
585# [+:yield:+ or +:yields:+ _parameters_]
586#   Overrides the default yield discovery with these parameters.
587#
588#     ##
589#     # :yields: key, value
590#
591#     def each_thing &block
592#       @things.each(&block)
593#     end
594#
595# [+:call-seq:+]
596#   Lines up to the next blank line or lines with a common prefix in the
597#   comment are treated as the method's calling sequence, overriding the
598#   default parsing of method parameters and yield arguments.
599#
600#   Multiple lines may be used.
601#
602#     # :call-seq:
603#     #   ARGF.readlines(sep=$/)     -> array
604#     #   ARGF.readlines(limit)      -> array
605#     #   ARGF.readlines(sep, limit) -> array
606#     #
607#     #   ARGF.to_a(sep=$/)     -> array
608#     #   ARGF.to_a(limit)      -> array
609#     #   ARGF.to_a(sep, limit) -> array
610#     #
611#     # The remaining lines are documentation ...
612#
613# === Sections
614#
615# Sections allow you to group methods in a class into sensible containers.  If
616# you use the sections 'Public', 'Internal' and 'Deprecated' (the three
617# allowed method statuses from TomDoc) the sections will be displayed in that
618# order placing the most useful methods at the top.  Otherwise, sections will
619# be displayed in alphabetical order.
620#
621# [+:category:+ _section_]
622#   Adds this item to the named +section+ overriding the current section.  Use
623#   this to group methods by section in RDoc output while maintaining a
624#   sensible ordering (like alphabetical).
625#
626#     # :category: Utility Methods
627#     #
628#     # CGI escapes +text+
629#
630#     def convert_string text
631#       CGI.escapeHTML text
632#     end
633#
634#   An empty category will place the item in the default category:
635#
636#     # :category:
637#     #
638#     # This method is in the default category
639#
640#     def some_method
641#       # ...
642#     end
643#
644#   Unlike the :section: directive, :category: is not sticky.  The category
645#   only applies to the item immediately following the comment.
646#
647#   Use the :section: directive to provide introductory text for a section of
648#   documentation.
649#
650# [+:section:+ _title_]
651#   Provides section introductory text in RDoc output.  The title following
652#   +:section:+ is used as the section name and the remainder of the comment
653#   containing the section is used as introductory text.  A section's comment
654#   block must be separated from following comment blocks.  Use an empty title
655#   to switch to the default section.
656#
657#   The :section: directive is sticky, so subsequent methods, aliases,
658#   attributes, and classes will be contained in this section until the
659#   section is changed.  The :category: directive will override the :section:
660#   directive.
661#
662#   A :section: comment block may have one or more lines before the :section:
663#   directive.  These will be removed, and any identical lines at the end of
664#   the block are also removed.  This allows you to add visual cues to the
665#   section.
666#
667#   Example:
668#
669#     # ----------------------------------------
670#     # :section: My Section
671#     # This is the section that I wrote.
672#     # See it glisten in the noon-day sun.
673#     # ----------------------------------------
674#
675#     ##
676#     # Comment for some_method
677#
678#     def some_method
679#       # ...
680#     end
681#
682# === Other directives
683#
684# [+:markup:+ _type_]
685#   Overrides the default markup type for this comment with the specified
686#   markup type.  For ruby files, if the first comment contains this directive
687#   it is applied automatically to all comments in the file.
688#
689#   Unless you are converting between markup formats you should use a
690#   <code>.rdoc_options</code> file to specify the default documentation
691#   format for your entire project.  See RDoc::Options@Saved+Options for
692#   instructions.
693#
694#   At the top of a file the +:markup:+ directive applies to the entire file:
695#
696#     # coding: UTF-8
697#     # :markup: TomDoc
698#
699#     # TomDoc comment here ...
700#
701#     class MyClass
702#       # ...
703#
704#   For just one comment:
705#
706#       # ...
707#     end
708#
709#     # :markup: RDoc
710#     #
711#     # This is a comment in RDoc markup format ...
712#
713#     def some_method
714#       # ...
715#
716#   See Markup@DEVELOPERS for instructions on adding a new markup format.
717#
718# [+:include:+ _filename_]
719#   Include the contents of the named file at this point. This directive
720#   must appear alone on one line, possibly preceded by spaces. In this
721#   position, it can be escaped with a \ in front of the first colon.
722#
723#   The file will be searched for in the directories listed by the +--include+
724#   option, or in the current directory by default.  The contents of the file
725#   will be shifted to have the same indentation as the ':' at the start of
726#   the +:include:+ directive.
727#
728# [+:title:+ _text_]
729#   Sets the title for the document.  Equivalent to the <tt>--title</tt>
730#   command line parameter.  (The command line parameter overrides any :title:
731#   directive in the source).
732#
733# [+:main:+ _name_]
734#   Equivalent to the <tt>--main</tt> command line parameter.
735#
736#--
737# Original Author:: Dave Thomas,  dave@pragmaticprogrammer.com
738# License:: Ruby license
739
740class RDoc::Markup
741
742  ##
743  # An AttributeManager which handles inline markup.
744
745  attr_reader :attribute_manager
746
747  ##
748  # Parses +str+ into an RDoc::Markup::Document.
749
750  def self.parse str
751    RDoc::Markup::Parser.parse str
752  rescue RDoc::Markup::Parser::Error => e
753    $stderr.puts <<-EOF
754While parsing markup, RDoc encountered a #{e.class}:
755
756#{e}
757\tfrom #{e.backtrace.join "\n\tfrom "}
758
759---8<---
760#{text}
761---8<---
762
763RDoc #{RDoc::VERSION}
764
765Ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} #{RUBY_RELEASE_DATE}
766
767Please file a bug report with the above information at:
768
769https://github.com/rdoc/rdoc/issues
770
771    EOF
772    raise
773  end
774
775  ##
776  # Take a block of text and use various heuristics to determine its
777  # structure (paragraphs, lists, and so on).  Invoke an event handler as we
778  # identify significant chunks.
779
780  def initialize attribute_manager = nil
781    @attribute_manager = attribute_manager || RDoc::Markup::AttributeManager.new
782    @output = nil
783  end
784
785  ##
786  # Add to the sequences used to add formatting to an individual word (such
787  # as *bold*).  Matching entries will generate attributes that the output
788  # formatters can recognize by their +name+.
789
790  def add_word_pair(start, stop, name)
791    @attribute_manager.add_word_pair(start, stop, name)
792  end
793
794  ##
795  # Add to the sequences recognized as general markup.
796
797  def add_html(tag, name)
798    @attribute_manager.add_html(tag, name)
799  end
800
801  ##
802  # Add to other inline sequences.  For example, we could add WikiWords using
803  # something like:
804  #
805  #    parser.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
806  #
807  # Each wiki word will be presented to the output formatter via the
808  # accept_special method.
809
810  def add_special(pattern, name)
811    @attribute_manager.add_special(pattern, name)
812  end
813
814  ##
815  # We take +input+, parse it if necessary, then invoke the output +formatter+
816  # using a Visitor to render the result.
817
818  def convert input, formatter
819    document = case input
820               when RDoc::Markup::Document then
821                 input
822               else
823                 RDoc::Markup::Parser.parse input
824               end
825
826    document.accept formatter
827  end
828
829  autoload :Parser,                'rdoc/markup/parser'
830  autoload :PreProcess,            'rdoc/markup/pre_process'
831
832  # Inline markup classes
833  autoload :AttrChanger,           'rdoc/markup/attr_changer'
834  autoload :AttrSpan,              'rdoc/markup/attr_span'
835  autoload :Attributes,            'rdoc/markup/attributes'
836  autoload :AttributeManager,      'rdoc/markup/attribute_manager'
837  autoload :Special,               'rdoc/markup/special'
838
839  # RDoc::Markup AST
840  autoload :BlankLine,             'rdoc/markup/blank_line'
841  autoload :BlockQuote,            'rdoc/markup/block_quote'
842  autoload :Document,              'rdoc/markup/document'
843  autoload :HardBreak,             'rdoc/markup/hard_break'
844  autoload :Heading,               'rdoc/markup/heading'
845  autoload :Include,               'rdoc/markup/include'
846  autoload :IndentedParagraph,     'rdoc/markup/indented_paragraph'
847  autoload :List,                  'rdoc/markup/list'
848  autoload :ListItem,              'rdoc/markup/list_item'
849  autoload :Paragraph,             'rdoc/markup/paragraph'
850  autoload :Raw,                   'rdoc/markup/raw'
851  autoload :Rule,                  'rdoc/markup/rule'
852  autoload :Verbatim,              'rdoc/markup/verbatim'
853
854  # Formatters
855  autoload :Formatter,             'rdoc/markup/formatter'
856  autoload :FormatterTestCase,     'rdoc/markup/formatter_test_case'
857  autoload :TextFormatterTestCase, 'rdoc/markup/text_formatter_test_case'
858
859  autoload :ToAnsi,                'rdoc/markup/to_ansi'
860  autoload :ToBs,                  'rdoc/markup/to_bs'
861  autoload :ToHtml,                'rdoc/markup/to_html'
862  autoload :ToHtmlCrossref,        'rdoc/markup/to_html_crossref'
863  autoload :ToHtmlSnippet,         'rdoc/markup/to_html_snippet'
864  autoload :ToLabel,               'rdoc/markup/to_label'
865  autoload :ToMarkdown,            'rdoc/markup/to_markdown'
866  autoload :ToRdoc,                'rdoc/markup/to_rdoc'
867  autoload :ToTableOfContents,     'rdoc/markup/to_table_of_contents'
868  autoload :ToTest,                'rdoc/markup/to_test'
869  autoload :ToTtOnly,              'rdoc/markup/to_tt_only'
870
871end
872
873