my_wiki_generator 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. data/my_wiki/grep.txt +238 -0
  2. data/my_wiki/my_wiki_generator.rb +248 -0
  3. data/my_wiki/templates/POST_GENERATION_REMINDER +1 -0
  4. data/my_wiki/templates/app/controllers/application.rb +75 -0
  5. data/my_wiki/templates/app/controllers/content_history_controller.rb +49 -0
  6. data/my_wiki/templates/app/controllers/login_controller.rb +93 -0
  7. data/my_wiki/templates/app/controllers/my_wiki_admin_controller.rb +26 -0
  8. data/my_wiki/templates/app/controllers/my_wiki_controller.rb +250 -0
  9. data/my_wiki/templates/app/controllers/page_admin_controller.rb +51 -0
  10. data/my_wiki/templates/app/controllers/user_admin_controller.rb +34 -0
  11. data/my_wiki/templates/app/helpers/application_helper.rb +3 -0
  12. data/my_wiki/templates/app/helpers/content_history_helper.rb +2 -0
  13. data/my_wiki/templates/app/helpers/login_helper.rb +2 -0
  14. data/my_wiki/templates/app/helpers/my_wiki_admin_helper.rb +2 -0
  15. data/my_wiki/templates/app/helpers/my_wiki_helper.rb +94 -0
  16. data/my_wiki/templates/app/helpers/page_admin_helper.rb +2 -0
  17. data/my_wiki/templates/app/helpers/user_admin_helper.rb +2 -0
  18. data/my_wiki/templates/app/models/attachment.rb +55 -0
  19. data/my_wiki/templates/app/models/content.rb +32 -0
  20. data/my_wiki/templates/app/models/content_history.rb +49 -0
  21. data/my_wiki/templates/app/models/content_sweeper.rb +7 -0
  22. data/my_wiki/templates/app/models/my_wiki_mailer.rb +29 -0
  23. data/my_wiki/templates/app/models/role.rb +18 -0
  24. data/my_wiki/templates/app/models/setting.rb +7 -0
  25. data/my_wiki/templates/app/models/user.rb +60 -0
  26. data/my_wiki/templates/app/views/content_history/_form.rhtml +19 -0
  27. data/my_wiki/templates/app/views/content_history/edit.rhtml +9 -0
  28. data/my_wiki/templates/app/views/content_history/list.rhtml +27 -0
  29. data/my_wiki/templates/app/views/content_history/new.rhtml +8 -0
  30. data/my_wiki/templates/app/views/content_history/show.rhtml +21 -0
  31. data/my_wiki/templates/app/views/layouts/my_wiki.rhtml +105 -0
  32. data/my_wiki/templates/app/views/login/edit.rhtml +25 -0
  33. data/my_wiki/templates/app/views/login/login.rhtml +23 -0
  34. data/my_wiki/templates/app/views/login/logout.rhtml +10 -0
  35. data/my_wiki/templates/app/views/login/signup.rhtml +23 -0
  36. data/my_wiki/templates/app/views/login/welcome.rhtml +13 -0
  37. data/my_wiki/templates/app/views/my_wiki/_form.rhtml +11 -0
  38. data/my_wiki/templates/app/views/my_wiki/css.rhtml +224 -0
  39. data/my_wiki/templates/app/views/my_wiki/diff.rhtml +4 -0
  40. data/my_wiki/templates/app/views/my_wiki/edit.rhtml +34 -0
  41. data/my_wiki/templates/app/views/my_wiki/fileinfo.rhtml +22 -0
  42. data/my_wiki/templates/app/views/my_wiki/list.rhtml +1 -0
  43. data/my_wiki/templates/app/views/my_wiki/mails.rhtml +1 -0
  44. data/my_wiki/templates/app/views/my_wiki/new.rhtml +6 -0
  45. data/my_wiki/templates/app/views/my_wiki/recent.rhtml +3 -0
  46. data/my_wiki/templates/app/views/my_wiki/search.rhtml +5 -0
  47. data/my_wiki/templates/app/views/my_wiki/search_result.rhtml +10 -0
  48. data/my_wiki/templates/app/views/my_wiki/show.rhtml +31 -0
  49. data/my_wiki/templates/app/views/my_wiki_admin/index.rhtml +5 -0
  50. data/my_wiki/templates/app/views/my_wiki_admin/setting.rhtml +64 -0
  51. data/my_wiki/templates/app/views/my_wiki_mailer/inform.rhtml +3 -0
  52. data/my_wiki/templates/app/views/page_admin/_form.rhtml +22 -0
  53. data/my_wiki/templates/app/views/page_admin/edit.rhtml +9 -0
  54. data/my_wiki/templates/app/views/page_admin/list.rhtml +55 -0
  55. data/my_wiki/templates/app/views/page_admin/new.rhtml +8 -0
  56. data/my_wiki/templates/app/views/page_admin/show.rhtml +8 -0
  57. data/my_wiki/templates/app/views/user_admin/_form.rhtml +10 -0
  58. data/my_wiki/templates/app/views/user_admin/change_password.rhtml +9 -0
  59. data/my_wiki/templates/app/views/user_admin/list.rhtml +25 -0
  60. data/my_wiki/templates/app/views/user_admin/signup.rhtml +20 -0
  61. data/my_wiki/templates/components/admin/menu/menu.rhtml +5 -0
  62. data/my_wiki/templates/components/admin/menu_controller.rb +3 -0
  63. data/my_wiki/templates/components/list/list/list.rhtml +11 -0
  64. data/my_wiki/templates/components/list/list_controller.rb +11 -0
  65. data/my_wiki/templates/components/sidebar/sidebar/show.rhtml +7 -0
  66. data/my_wiki/templates/components/sidebar/sidebar_controller.rb +9 -0
  67. data/my_wiki/templates/config/routes.rb +35 -0
  68. data/my_wiki/templates/db/migrate/001_my_wiki_migration.rb +75 -0
  69. data/my_wiki/templates/lib/diff/lcs.rb +1105 -0
  70. data/my_wiki/templates/lib/diff/lcs/array.rb +21 -0
  71. data/my_wiki/templates/lib/diff/lcs/block.rb +51 -0
  72. data/my_wiki/templates/lib/diff/lcs/callbacks.rb +322 -0
  73. data/my_wiki/templates/lib/diff/lcs/change.rb +169 -0
  74. data/my_wiki/templates/lib/diff/lcs/hunk.rb +257 -0
  75. data/my_wiki/templates/lib/diff/lcs/ldiff.rb +226 -0
  76. data/my_wiki/templates/lib/diff/lcs/string.rb +19 -0
  77. data/my_wiki/templates/lib/login_system.rb +87 -0
  78. data/my_wiki/templates/lib/markup/simple_markup.rb +489 -0
  79. data/my_wiki/templates/lib/markup/simple_markup/fragments.rb +329 -0
  80. data/my_wiki/templates/lib/markup/simple_markup/inline.rb +338 -0
  81. data/my_wiki/templates/lib/markup/simple_markup/lines.rb +151 -0
  82. data/my_wiki/templates/lib/markup/simple_markup/preprocess.rb +68 -0
  83. data/my_wiki/templates/lib/markup/simple_markup/to_flow.rb +188 -0
  84. data/my_wiki/templates/lib/markup/simple_markup/to_html.rb +302 -0
  85. data/my_wiki/templates/lib/markup/simple_markup/to_latex.rb +333 -0
  86. data/my_wiki/templates/lib/my_wiki_plugin.rb +60 -0
  87. data/my_wiki/templates/lib/my_wiki_plugins/christel.rb +5 -0
  88. data/my_wiki/templates/lib/my_wiki_plugins/join.rb +3 -0
  89. data/my_wiki/templates/lib/my_wiki_plugins/link_to_attach.rb +17 -0
  90. data/my_wiki/templates/lib/my_wiki_plugins/recent.rb +8 -0
  91. data/my_wiki/templates/public/javascripts/my_wiki.js +8 -0
  92. data/my_wiki/templates/public/stylesheets/my_wiki/back.jpg +0 -0
  93. data/my_wiki/templates/public/stylesheets/my_wiki/back1.jpg +0 -0
  94. data/my_wiki/templates/public/stylesheets/my_wiki/back2.jpg +0 -0
  95. data/my_wiki/templates/public/stylesheets/my_wiki/foot.jpg +0 -0
  96. data/my_wiki/templates/public/stylesheets/my_wiki/h1.gif +0 -0
  97. data/my_wiki/templates/public/stylesheets/my_wiki/h1.jpg +0 -0
  98. data/my_wiki/templates/public/stylesheets/my_wiki/menu.jpg +0 -0
  99. data/my_wiki/templates/public/stylesheets/my_wiki/menu2.jpg +0 -0
  100. data/my_wiki/templates/public/stylesheets/my_wiki/menu_c.jpg +0 -0
  101. data/my_wiki/templates/public/stylesheets/my_wiki/my_wiki.css +336 -0
  102. data/my_wiki/templates/public/stylesheets/my_wiki/title.jpg +0 -0
  103. metadata +181 -0
@@ -0,0 +1,151 @@
1
+ ##########################################################################
2
+ #
3
+ # We store the lines we're working on as objects of class Line.
4
+ # These contain the text of the line, along with a flag indicating the
5
+ # line type, and an indentation level
6
+
7
+ module SM
8
+
9
+ class Line
10
+ INFINITY = 9999
11
+
12
+ BLANK = :BLANK
13
+ HEADING = :HEADING
14
+ LIST = :LIST
15
+ RULE = :RULE
16
+ PARAGRAPH = :PARAGRAPH
17
+ VERBATIM = :VERBATIM
18
+
19
+ # line type
20
+ attr_accessor :type
21
+
22
+ # The indentation nesting level
23
+ attr_accessor :level
24
+
25
+ # The contents
26
+ attr_accessor :text
27
+
28
+ # A prefix or parameter. For LIST lines, this is
29
+ # the text that introduced the list item (the label)
30
+ attr_accessor :param
31
+
32
+ # A flag. For list lines, this is the type of the list
33
+ attr_accessor :flag
34
+
35
+ # the number of leading spaces
36
+ attr_accessor :leading_spaces
37
+
38
+ # true if this line has been deleted from the list of lines
39
+ attr_accessor :deleted
40
+
41
+
42
+ def initialize(text)
43
+ @text = text.dup
44
+ @deleted = false
45
+
46
+ # expand tabs
47
+ 1 while @text.gsub!(/\t+/) { ' ' * (8*$&.length - $`.length % 8)} && $~ #`
48
+
49
+ # Strip trailing whitespace
50
+ @text.sub!(/\s+$/, '')
51
+
52
+ # and look for leading whitespace
53
+ if @text.length > 0
54
+ @text =~ /^(\s*)/
55
+ @leading_spaces = $1.length
56
+ else
57
+ @leading_spaces = INFINITY
58
+ end
59
+ end
60
+
61
+ # Return true if this line is blank
62
+ def isBlank?
63
+ @text.length.zero?
64
+ end
65
+
66
+ # stamp a line with a type, a level, a prefix, and a flag
67
+ def stamp(type, level, param="", flag=nil)
68
+ @type, @level, @param, @flag = type, level, param, flag
69
+ end
70
+
71
+ ##
72
+ # Strip off the leading margin
73
+ #
74
+
75
+ def strip_leading(size)
76
+ if @text.size > size
77
+ @text[0,size] = ""
78
+ else
79
+ @text = ""
80
+ end
81
+ end
82
+
83
+ def to_s
84
+ "#@type#@level: #@text"
85
+ end
86
+ end
87
+
88
+ ###############################################################################
89
+ #
90
+ # A container for all the lines
91
+ #
92
+
93
+ class Lines
94
+ include Enumerable
95
+
96
+ attr_reader :lines # for debugging
97
+
98
+ def initialize(lines)
99
+ @lines = lines
100
+ rewind
101
+ end
102
+
103
+ def empty?
104
+ @lines.size.zero?
105
+ end
106
+
107
+ def each
108
+ @lines.each do |line|
109
+ yield line unless line.deleted
110
+ end
111
+ end
112
+
113
+ # def [](index)
114
+ # @lines[index]
115
+ # end
116
+
117
+ def rewind
118
+ @nextline = 0
119
+ end
120
+
121
+ def next
122
+ begin
123
+ res = @lines[@nextline]
124
+ @nextline += 1 if @nextline < @lines.size
125
+ end while res and res.deleted and @nextline < @lines.size
126
+ res
127
+ end
128
+
129
+ def unget
130
+ @nextline -= 1
131
+ end
132
+
133
+ def delete(a_line)
134
+ a_line.deleted = true
135
+ end
136
+
137
+ def normalize
138
+ margin = @lines.collect{|l| l.leading_spaces}.min
139
+ margin = 0 if margin == Line::INFINITY
140
+ @lines.each {|line| line.strip_leading(margin) } if margin > 0
141
+ end
142
+
143
+ def as_text
144
+ @lines.map {|l| l.text}.join("\n")
145
+ end
146
+
147
+ def line_types
148
+ @lines.map {|l| l.type }
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,68 @@
1
+ module SM
2
+
3
+ ##
4
+ # Handle common directives that can occur in a block of text:
5
+ #
6
+ # : include : filename
7
+ #
8
+
9
+ class PreProcess
10
+
11
+ def initialize(input_file_name, include_path)
12
+ @input_file_name = input_file_name
13
+ @include_path = include_path
14
+ end
15
+
16
+ # Look for common options in a chunk of text. Options that
17
+ # we don't handle are passed back to our caller
18
+ # as |directive, param|
19
+
20
+ def handle(text)
21
+ text.gsub!(/^([ \t#]*):(\w+):\s*(.+)?\n/) do
22
+ prefix = $1
23
+ directive = $2.downcase
24
+ param = $3
25
+
26
+ case directive
27
+ when "include"
28
+ filename = param.split[0]
29
+ include_file(filename, prefix)
30
+
31
+ else
32
+ yield(directive, param)
33
+ end
34
+ end
35
+ end
36
+
37
+ #######
38
+ private
39
+ #######
40
+
41
+ # Include a file, indenting it correctly
42
+
43
+ def include_file(name, indent)
44
+ if (full_name = find_include_file(name))
45
+ content = File.open(full_name) {|f| f.read}
46
+ res = content.gsub(/^#?/, indent)
47
+ else
48
+ $stderr.puts "Couldn't find file to include: '#{name}'"
49
+ ''
50
+ end
51
+ end
52
+
53
+ # Look for the given file in the directory containing the current
54
+ # file, and then in each of the directories specified in the
55
+ # RDOC_INCLUDE path
56
+
57
+ def find_include_file(name)
58
+ to_search = [ File.dirname(@input_file_name) ].concat @include_path
59
+ to_search.each do |dir|
60
+ full_name = File.join(dir, name)
61
+ stat = File.stat(full_name) rescue next
62
+ return full_name if stat.readable?
63
+ end
64
+ nil
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,188 @@
1
+ require 'markup/simple_markup/fragments'
2
+ require 'markup/simple_markup/inline'
3
+ require 'cgi'
4
+
5
+ module 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
+
188
+ end
@@ -0,0 +1,302 @@
1
+ require 'markup/simple_markup/fragments'
2
+ require 'markup/simple_markup/inline'
3
+
4
+ require 'cgi'
5
+
6
+ module SM
7
+
8
+ class ToHtml
9
+
10
+ LIST_TYPE_TO_HTML = {
11
+ ListBase::BULLET => [ "<ul>", "</ul>" ],
12
+ ListBase::NUMBER => [ "<ol>", "</ol>" ],
13
+ ListBase::UPPERALPHA => [ "<ol>", "</ol>" ],
14
+ ListBase::LOWERALPHA => [ "<ol>", "</ol>" ],
15
+ ListBase::LABELED => [ "<dl>", "</dl>" ],
16
+ ListBase::NOTE => [ "<table>", "</table>" ],
17
+ ListBase::TABLE => [ '<table class="table" cellspacing="1" border="0">', "</table>" ], # added by ando
18
+ }
19
+
20
+ InlineTag = Struct.new(:bit, :on, :off)
21
+
22
+ def initialize
23
+ init_tags
24
+ end
25
+
26
+ ##
27
+ # Set up the standard mapping of attributes to HTML tags
28
+ #
29
+ def init_tags
30
+ @attr_tags = [
31
+ InlineTag.new(SM::Attribute.bitmap_for(:BOLD), "<b>", "</b>"),
32
+ InlineTag.new(SM::Attribute.bitmap_for(:TT), "<tt>", "</tt>"),
33
+ InlineTag.new(SM::Attribute.bitmap_for(:EM), "<em>", "</em>"),
34
+ ]
35
+ end
36
+
37
+ ##
38
+ # Add a new set of HTML tags for an attribute. We allow
39
+ # separate start and end tags for flexibility
40
+ #
41
+ def add_tag(name, start, stop)
42
+ @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop)
43
+ end
44
+
45
+ ##
46
+ # Given an HTML tag, decorate it with class information
47
+ # and the like if required. This is a no-op in the base
48
+ # class, but is overridden in HTML output classes that
49
+ # implement style sheets
50
+
51
+ def annotate(tag)
52
+ tag
53
+ end
54
+
55
+ ##
56
+ # Here's the client side of the visitor pattern
57
+
58
+ def start_accepting
59
+ @res = ""
60
+ @in_list_entry = []
61
+ end
62
+
63
+ def end_accepting
64
+ @res
65
+ end
66
+
67
+ def accept_paragraph(am, fragment)
68
+ @res << annotate("<p>") + "\n"
69
+ @res << wrap(convert_flow(am.flow(fragment.txt)))
70
+ @res << annotate("</p>") + "\n"
71
+ end
72
+
73
+ def accept_verbatim(am, fragment)
74
+ @res << annotate("<pre>") + "\n"
75
+ @res << CGI.escapeHTML(fragment.txt)
76
+ @res << annotate("</pre>") << "\n"
77
+ end
78
+
79
+ def accept_rule(am, fragment)
80
+ size = fragment.param
81
+ size = 10 if size > 10
82
+ @res << "<hr size=\"#{size}\"></hr>"
83
+ end
84
+
85
+ def accept_list_start(am, fragment)
86
+ @res << html_list_name(fragment.type, true) <<"\n"
87
+ @in_list_entry.push false
88
+ end
89
+
90
+ def accept_list_end(am, fragment)
91
+ if tag = @in_list_entry.pop
92
+ @res << annotate(tag) << "\n"
93
+ end
94
+ @res << html_list_name(fragment.type, false) <<"\n"
95
+ end
96
+
97
+ def accept_list_item(am, fragment)
98
+ if tag = @in_list_entry.last
99
+ @res << annotate(tag) << "\n"
100
+ end
101
+ @res << list_item_start(am, fragment)
102
+ @res << wrap(convert_flow(am.flow(fragment.txt))) << "\n"
103
+ @in_list_entry[-1] = list_end_for(fragment.type)
104
+ end
105
+
106
+ def accept_blank_line(am, fragment)
107
+ # @res << annotate("<p />") << "\n"
108
+ end
109
+
110
+ def accept_heading(am, fragment)
111
+ @res << convert_heading(fragment.head_level, am.flow(fragment.txt))
112
+ end
113
+
114
+ # This is a higher speed (if messier) version of wrap
115
+
116
+ def wrap(txt, line_len = 76)
117
+ res = ""
118
+ sp = 0
119
+ ep = txt.length
120
+ while sp < ep
121
+ # scan back for a space
122
+ p = sp + line_len - 1
123
+ if p >= ep
124
+ p = ep
125
+ else
126
+ while p > sp and txt[p] != ?\s
127
+ p -= 1
128
+ end
129
+ if p <= sp
130
+ p = sp + line_len
131
+ while p < ep and txt[p] != ?\s
132
+ p += 1
133
+ end
134
+ end
135
+ end
136
+ res << txt[sp...p] << "\n"
137
+ sp = p
138
+ sp += 1 while sp < ep and txt[sp] == ?\s
139
+ end
140
+ res
141
+ end
142
+
143
+ #######################################################################
144
+
145
+ private
146
+
147
+ #######################################################################
148
+
149
+ def on_tags(res, item)
150
+ attr_mask = item.turn_on
151
+ return if attr_mask.zero?
152
+
153
+ @attr_tags.each do |tag|
154
+ if attr_mask & tag.bit != 0
155
+ res << annotate(tag.on)
156
+ end
157
+ end
158
+ end
159
+
160
+ def off_tags(res, item)
161
+ attr_mask = item.turn_off
162
+ return if attr_mask.zero?
163
+
164
+ @attr_tags.reverse_each do |tag|
165
+ if attr_mask & tag.bit != 0
166
+ res << annotate(tag.off)
167
+ end
168
+ end
169
+ end
170
+
171
+ def convert_flow(flow)
172
+ res = ""
173
+ flow.each do |item|
174
+ case item
175
+ when String
176
+ res << convert_string(item)
177
+ when AttrChanger
178
+ off_tags(res, item)
179
+ on_tags(res, item)
180
+ when Special
181
+ res << convert_special(item)
182
+ else
183
+ raise "Unknown flow element: #{item.inspect}"
184
+ end
185
+ end
186
+ res
187
+ end
188
+
189
+ # some of these patterns are taken from SmartyPants...
190
+
191
+ def convert_string(item)
192
+ item = CGI.escapeHTML(item).
193
+
194
+ # convert -- to em-dash, (-- to en-dash)
195
+ gsub(/---?/, '&#8212;'). #gsub(/--/, '&#8211;').
196
+
197
+ # convert ... to elipsis (and make sure .... becomes .<elipsis>)
198
+ gsub(/\.\.\.\./, '.&#8230;').gsub(/\.\.\./, '&#8230;').
199
+
200
+ # convert single closing quote
201
+ gsub(%r{([^ \t\r\n\[\{\(])\'}) { "#$1&#8217;" }.
202
+ gsub(%r{\'(?=\W|s\b)}) { "&#8217;" }.
203
+
204
+ # convert single opening quote
205
+ gsub(/'/, '&#8216;').
206
+
207
+ # convert double closing quote
208
+ gsub(%r{([^ \t\r\n\[\{\(])\'(?=\W)}) { "#$1&#8221;" }.
209
+
210
+ # convert double opening quote
211
+ gsub(/'/, '&#8220;').
212
+
213
+ # convert copyright
214
+ gsub(/\(c\)/, '&#169;').
215
+
216
+ # convert and registered trademark
217
+ gsub(/\(r\)/, '&#174;')
218
+
219
+ # convert column separator (by ando)
220
+ if item =~ /^\|\|(.*)/
221
+ #item = item.sub(/^\|\|/, '').gsub('||', '</td><td>')
222
+ item = $1.gsub('||', '</td><td>')
223
+ end
224
+
225
+ item
226
+ end
227
+
228
+ def convert_special(special)
229
+ handled = false
230
+ Attribute.each_name_of(special.type) do |name|
231
+ method_name = "handle_special_#{name}"
232
+ if self.respond_to? method_name
233
+ special.text = send(method_name, special)
234
+ handled = true
235
+ end
236
+ end
237
+ raise "Unhandled special: #{special}" unless handled
238
+ special.text
239
+ end
240
+
241
+ def convert_heading(level, flow)
242
+ res =
243
+ annotate("<h#{level}>") +
244
+ convert_flow(flow) +
245
+ annotate("</h#{level}>\n")
246
+ end
247
+
248
+ def html_list_name(list_type, is_open_tag)
249
+ tags = LIST_TYPE_TO_HTML[list_type] || raise("Invalid list type: #{list_type.inspect}")
250
+ annotate(tags[ is_open_tag ? 0 : 1])
251
+ end
252
+
253
+ def list_item_start(am, fragment)
254
+ case fragment.type
255
+ when ListBase::BULLET, ListBase::NUMBER
256
+ annotate("<li>")
257
+
258
+ when ListBase::UPPERALPHA
259
+ annotate("<li type=\"A\">")
260
+
261
+ when ListBase::LOWERALPHA
262
+ annotate("<li type=\"a\">")
263
+
264
+ when ListBase::LABELED
265
+ annotate("<dt>") +
266
+ convert_flow(am.flow(fragment.param)) +
267
+ annotate("</dt>") +
268
+ annotate("<dd>")
269
+
270
+ when ListBase::NOTE
271
+ annotate("<tr>") +
272
+ annotate("<td valign=\"top\">") +
273
+ convert_flow(am.flow(fragment.param)) +
274
+ annotate("</td>") +
275
+ annotate("<td>")
276
+
277
+ when ListBase::TABLE # added by ando
278
+ annotate("<tr><td>")
279
+
280
+ else
281
+ raise "Invalid list type"
282
+ end
283
+ end
284
+
285
+ def list_end_for(fragment_type)
286
+ case fragment_type
287
+ when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA, ListBase::LOWERALPHA
288
+ "</li>"
289
+ when ListBase::LABELED
290
+ "</dd>"
291
+ when ListBase::NOTE
292
+ "</td></tr>"
293
+ when ListBase::TABLE # added by ando
294
+ "</td></tr>"
295
+ else
296
+ raise "Invalid list type"
297
+ end
298
+ end
299
+
300
+ end
301
+
302
+ end