1
# markup.rb: simple markup system used wirhin the documentation.
2
# copyright (c) 2009 by Vincent Fourmond
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU General Public License for more details (in the COPYING file).
14
require 'ctioga2/utils'
19
Version::register_svn_info('$Revision: 216 $', '$Date: 2010-12-31 16:18:17 +0100 (Fri, 31 Dec 2010) $')
25
# The documentation strings are written in a simple markup
28
# \todo we should provide tags to specifically mark TODO items
29
# in documentation, in such a way that it would be easy to make
30
# a list of them, and possibly ignore it for output.
33
# Do we really need logging ?
36
# The base class for markup items.
38
# The documentation object
54
# A markup item representing plain text.
55
class MarkupText < MarkupItem
59
# The kind of markup, nil means no markup
62
def initialize(doc, text = "", strip = true,
68
@text.gsub!(/\n/, " ")
77
return "text: #{@text}"
82
# A markup item representing verbatim text, with the given
84
class MarkupVerbatim < MarkupItem
88
# The verbatim text class
91
def initialize(doc, text, cls)
102
return "#{@cls}: #{@text}"
107
# A link to a type/group/command
108
class MarkupLink < MarkupItem
109
# The object target of the link
110
attr_accessor :target
112
# _target_ is the name of the target, which can be of _type_
113
# 'group', 'command', 'backend', 'type' and 'url'
114
def initialize(doc, target, type)
119
@target = doc.send("#{type}s")[target]
136
return "link: #{@target}"
141
class MarkupItemize < MarkupItem
143
# An array of arrays of MarkupItem, each representing an
144
# element of the itemize object.
147
def initialize(doc, items = [])
165
return @items.map {|x|
166
"* #{x.map do |y| y.dump_string; end}\n"
172
# An item that contains a paragraph
173
class MarkupParagraph < MarkupItem
174
attr_accessor :elements
176
def initialize(doc, elements)
182
return @elements.map {|x| x.to_s }.join('')
186
return "par: " + @elements.map {|x|
187
" #{x.dump_string}\n"
193
# The reference Doc object
196
# The elements that make up the MarkedUpText
197
attr_accessor :elements
199
# Creates a MarkedUpText object.
200
def initialize(doc, text = nil)
204
parse_from_string(text)
210
puts "Number of elements: #{@elements.size}"
212
puts "#{el.class} -> #{el.to_s}"
217
# Parses the given _string_ and append the results to the
218
# MarkedUpText's elements.
222
# * a line beginning with '> ' is an example for command-line
223
# * a line beginning with '# ' is an example for use within a
225
# * a line beginning with '@ ' is a generic verbatim text.
226
# * a line beginning with ' *' is an element of an
227
# itemize. The itemize finishes when a new paragraph is
229
# * a {group: ...} or {type: ...} or {command: ...} is a link
231
# * a blank line marks a paragraph break.
233
# \todo Add elements to do some inline markup (such as bold,
234
# code, italics; mostly code for now will do very fine)
235
def parse_from_string(string)
239
lines = string.split(/[ \t]*\n/)
243
when /^[#>@]\s(.*)/ # a verbatim line
252
if @last_type == type
253
@last_string << "#{$1}\n"
257
@last_string = "#{$1}\n"
262
@last_string = "#{$1}\n"
263
when /^\s*$/ # Blank line:
269
when :item, :paragraph # simply go on
270
@last_string << "#{l}\n"
273
@last_type = :paragraph
274
@last_string = "#{l}\n"
283
# A few constants to help writing out the paragraph markup
284
LinkRE = /\{(group|type|command|backend|url):\s*([^}]+?)\s*\}/
286
MarkOnceRE = /@([^@]+)@/
289
# Parses the markup found within a paragraph (ie: links and
290
# other text attributes, but not verbatim, list or other
291
# markings) and returns an array containing the MarkupItem
293
def parse_paragraph_markup(doc, string)
295
while string =~ /#{LinkRE}|#{MarkOnceRE}/
296
els << MarkupText.new(doc, $`)
298
els << MarkupLink.new(doc, $2, $1)
300
els << MarkupText.new(doc, $3, true, :code)
304
els << MarkupText.new(doc, string)
308
# Adds the element accumulated so far to the @elements array.
311
when :cmdline, :cmdfile
312
@elements << MarkupVerbatim.new(@doc, @last_string,
313
"examples-#{@last_type}")
315
@elements << MarkupVerbatim.new(@doc, @last_string, "examples")
318
MarkupParagraph.new(@doc,
319
parse_paragraph_markup(doc, @last_string))
321
if @elements.last.is_a?(MarkupItemize)
322
@elements.last.items <<
323
parse_paragraph_markup(doc, @last_string)
326
MarkupItemize.new(@doc,
327
[ parse_paragraph_markup(doc, @last_string)])
329
else # In principle, nil
337
# A class dumping markup information to standard output
339
# The Doc object the Markup class should dump
346
# Dumps the markup of all commands
347
def write_commands(out = STDOUT)
348
cmds, groups = @doc.documented_commands
351
out.puts "Group markup: #{g.name}"
352
out.puts dump_markup(g.description)
354
commands = cmds[g].sort {|a,b|
359
out.puts "Command: #{cmd.name}"
360
out.puts dump_markup(cmd.long_description)
365
# Dumps the markup of all types
366
def write_types(out = STDOUT)
367
types = @doc.types.sort.map { |d| d[1]}
369
out.puts "Type: #{t.name}"
370
out.puts dump_markup(t.description)
374
def dump_markup(items)
375
if items.is_a? String
376
mup = MarkedUpText.new(@doc, items)
377
return dump_markup(mup.elements)
379
return items.map { |x| "-> #{x.dump_string}\n"}