source: extensions/gsdl-video/trunk/installed/cmdline/lib/ruby/1.8/rdoc/markup/simple_markup/to_flow.rb@ 18425

Last change on this file since 18425 was 18425, checked in by davidb, 15 years ago

Video extension to Greenstone

File size: 4.4 KB
Line 
1require 'rdoc/markup/simple_markup/fragments'
2require 'rdoc/markup/simple_markup/inline'
3require 'cgi'
4
5module SM
6
7 module Flow
8 P = Struct.new(:body)
9 VERB = Struct.new(:body)
10 RULE = Struct.new(:width)
11 class LIST
12 attr_reader :type, :contents
13 def initialize(type)
14 @type = type
15 @contents = []
16 end
17 def <<(stuff)
18 @contents << stuff
19 end
20 end
21 LI = Struct.new(:label, :body)
22 H = Struct.new(:level, :text)
23 end
24
25 class ToFlow
26 LIST_TYPE_TO_HTML = {
27 SM::ListBase::BULLET => [ "<ul>", "</ul>" ],
28 SM::ListBase::NUMBER => [ "<ol>", "</ol>" ],
29 SM::ListBase::UPPERALPHA => [ "<ol>", "</ol>" ],
30 SM::ListBase::LOWERALPHA => [ "<ol>", "</ol>" ],
31 SM::ListBase::LABELED => [ "<dl>", "</dl>" ],
32 SM::ListBase::NOTE => [ "<table>", "</table>" ],
33 }
34
35 InlineTag = Struct.new(:bit, :on, :off)
36
37 def initialize
38 init_tags
39 end
40
41 ##
42 # Set up the standard mapping of attributes to HTML tags
43 #
44 def init_tags
45 @attr_tags = [
46 InlineTag.new(SM::Attribute.bitmap_for(:BOLD), "<b>", "</b>"),
47 InlineTag.new(SM::Attribute.bitmap_for(:TT), "<tt>", "</tt>"),
48 InlineTag.new(SM::Attribute.bitmap_for(:EM), "<em>", "</em>"),
49 ]
50 end
51
52 ##
53 # Add a new set of HTML tags for an attribute. We allow
54 # separate start and end tags for flexibility
55 #
56 def add_tag(name, start, stop)
57 @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop)
58 end
59
60 ##
61 # Given an HTML tag, decorate it with class information
62 # and the like if required. This is a no-op in the base
63 # class, but is overridden in HTML output classes that
64 # implement style sheets
65
66 def annotate(tag)
67 tag
68 end
69
70 ##
71 # Here's the client side of the visitor pattern
72
73 def start_accepting
74 @res = []
75 @list_stack = []
76 end
77
78 def end_accepting
79 @res
80 end
81
82 def accept_paragraph(am, fragment)
83 @res << Flow::P.new((convert_flow(am.flow(fragment.txt))))
84 end
85
86 def accept_verbatim(am, fragment)
87 @res << Flow::VERB.new((convert_flow(am.flow(fragment.txt))))
88 end
89
90 def accept_rule(am, fragment)
91 size = fragment.param
92 size = 10 if size > 10
93 @res << Flow::RULE.new(size)
94 end
95
96 def accept_list_start(am, fragment)
97 @list_stack.push(@res)
98 list = Flow::LIST.new(fragment.type)
99 @res << list
100 @res = list
101 end
102
103 def accept_list_end(am, fragment)
104 @res = @list_stack.pop
105 end
106
107 def accept_list_item(am, fragment)
108 @res << Flow::LI.new(fragment.param, convert_flow(am.flow(fragment.txt)))
109 end
110
111 def accept_blank_line(am, fragment)
112 # @res << annotate("<p />") << "\n"
113 end
114
115 def accept_heading(am, fragment)
116 @res << Flow::H.new(fragment.head_level, convert_flow(am.flow(fragment.txt)))
117 end
118
119
120 #######################################################################
121
122 private
123
124 #######################################################################
125
126 def on_tags(res, item)
127 attr_mask = item.turn_on
128 return if attr_mask.zero?
129
130 @attr_tags.each do |tag|
131 if attr_mask & tag.bit != 0
132 res << annotate(tag.on)
133 end
134 end
135 end
136
137 def off_tags(res, item)
138 attr_mask = item.turn_off
139 return if attr_mask.zero?
140
141 @attr_tags.reverse_each do |tag|
142 if attr_mask & tag.bit != 0
143 res << annotate(tag.off)
144 end
145 end
146 end
147
148 def convert_flow(flow)
149 res = ""
150 flow.each do |item|
151 case item
152 when String
153 res << convert_string(item)
154 when AttrChanger
155 off_tags(res, item)
156 on_tags(res, item)
157 when Special
158 res << convert_special(item)
159 else
160 raise "Unknown flow element: #{item.inspect}"
161 end
162 end
163 res
164 end
165
166 # some of these patterns are taken from SmartyPants...
167
168 def convert_string(item)
169 CGI.escapeHTML(item)
170 end
171
172 def convert_special(special)
173 handled = false
174 Attribute.each_name_of(special.type) do |name|
175 method_name = "handle_special_#{name}"
176 if self.respond_to? method_name
177 special.text = send(method_name, special)
178 handled = true
179 end
180 end
181 raise "Unhandled special: #{special}" unless handled
182 special.text
183 end
184
185
186 end
187
188end
Note: See TracBrowser for help on using the repository browser.