docgenerator 1.0.4 → 1.1.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 (231) hide show
  1. data/lib/creole/creole2doc.rb +777 -0
  2. data/lib/creole/creole_inclusion_and_plugins.rb +236 -0
  3. data/lib/creole/creole_placeholder.rb +74 -0
  4. data/lib/creole/creole_tabular.rb +170 -0
  5. data/lib/docgenerator.rb +15 -6
  6. data/lib/docgenerator_attribute.rb +2 -2
  7. data/lib/docgenerator_characters.rb +20 -4
  8. data/lib/docgenerator_document.rb +132 -42
  9. data/lib/docgenerator_element.rb +531 -524
  10. data/lib/docgenerator_elements.rb +408 -399
  11. data/lib/docgenerator_environments.rb +28 -2
  12. data/lib/docgenerator_footnote.rb +72 -79
  13. data/lib/docgenerator_sections.rb +1 -1
  14. data/lib/docgenerator_tabular.rb +8 -3
  15. data/lib/packages/docgenerator_beamer.rb +253 -0
  16. data/lib/packages/docgenerator_scrlettr2.rb +53 -9
  17. data/lib/templates/docgenerator_template_css.rb +4 -0
  18. data/lib/wiki2doc/wiki2docgenerator.rb +1087 -970
  19. data/lib/yaml2presentation/yaml2presentation.rb +1091 -0
  20. data/self_docgenerator.rb +8 -6
  21. data/unittest/Red_Flower.jpg +0 -0
  22. data/unittest/creole1.0test.txt +128 -0
  23. data/unittest/expected/beamer_01_doc.html +1 -1
  24. data/unittest/expected/beamer_02_doc.html +1 -1
  25. data/unittest/expected/beamer_doc_html_overview_with_detailpic_and_text_doc.html +34 -0
  26. data/unittest/expected/beamer_doc_html_overview_with_detailpic_doc.html +34 -0
  27. data/unittest/expected/beamer_doc_key_doc.html +1 -1
  28. data/unittest/expected/beamer_doc_note_doc.html +1 -1
  29. data/unittest/expected/beamer_doc_pic_bottom_doc.html +1 -1
  30. data/unittest/expected/beamer_doc_pic_doc.html +1 -1
  31. data/unittest/expected/beamer_doc_pic_left_doc.html +1 -1
  32. data/unittest/expected/beamer_doc_pic_right_doc.html +1 -1
  33. data/unittest/expected/beamer_doc_pic_top_doc.html +1 -1
  34. data/unittest/expected/test_footnote.html +2 -2
  35. data/unittest/expected/test_footnote.latex +1 -1
  36. data/unittest/expected/test_footnote_group.html +3 -3
  37. data/unittest/expected/test_footnote_group.latex +2 -2
  38. data/unittest/expected_creole/test_creole.html +3 -0
  39. data/unittest/expected_creole/test_creole_characters_all.html +10 -0
  40. data/unittest/expected_creole/test_creole_characters_all.latex +20 -0
  41. data/unittest/expected_creole/test_creole_characters_special.html +10 -0
  42. data/unittest/expected_creole/test_creole_characters_special.latex +18 -0
  43. data/unittest/expected_creole/test_creole_countdown.html +3 -0
  44. data/unittest/expected_creole/test_creole_countdown.latex +4 -0
  45. data/unittest/expected_creole/test_creole_creole1.0test.html +182 -0
  46. data/unittest/expected_creole/test_creole_creole1.0test.latex +253 -0
  47. data/unittest/expected_creole/test_creole_creole1.0test.text +160 -0
  48. data/unittest/expected_creole/test_creole_footnotes.html +9 -0
  49. data/unittest/expected_creole/test_creole_footnotes.latex +14 -0
  50. data/unittest/expected_creole/test_creole_footnotes_label.html +9 -0
  51. data/unittest/expected_creole/test_creole_headings.html +17 -0
  52. data/unittest/expected_creole/test_creole_headings.latex +19 -0
  53. data/unittest/expected_creole/test_creole_headings.text +48 -0
  54. data/unittest/expected_creole/test_creole_headings.wiki +37 -0
  55. data/unittest/expected_creole/test_creole_hr.html +7 -0
  56. data/unittest/expected_creole/test_creole_hr.latex +9 -0
  57. data/unittest/expected_creole/test_creole_hr.text +4 -0
  58. data/unittest/expected_creole/test_creole_inline.html +3 -0
  59. data/unittest/expected_creole/test_creole_inline.latex +4 -0
  60. data/unittest/expected_creole/test_creole_inline.text +2 -0
  61. data/unittest/expected_creole/test_creole_inline_ruby.html +12 -0
  62. data/unittest/expected_creole/test_creole_inline_ruby.latex +20 -0
  63. data/unittest/expected_creole/test_creole_inline_ruby_raw.html +6 -0
  64. data/unittest/expected_creole/test_creole_inline_ruby_raw.latex +8 -0
  65. data/unittest/expected_creole/test_creole_input.normsource +23 -0
  66. data/unittest/expected_creole/test_creole_label.html +12 -0
  67. data/unittest/expected_creole/test_creole_label.latex +15 -0
  68. data/unittest/expected_creole/test_creole_line_break.html +6 -0
  69. data/unittest/expected_creole/test_creole_line_break.latex +8 -0
  70. data/unittest/expected_creole/test_creole_links_explicit_internal.html +6 -0
  71. data/unittest/expected_creole/test_creole_links_explicit_internal.text +4 -0
  72. data/unittest/expected_creole/test_creole_links_explicit_with_em.html +3 -0
  73. data/unittest/expected_creole/test_creole_links_explicit_with_em.latex +4 -0
  74. data/unittest/expected_creole/test_creole_links_explicit_with_em.text +2 -0
  75. data/unittest/expected_creole/test_creole_links_external.html +6 -0
  76. data/unittest/expected_creole/test_creole_links_external.latex +8 -0
  77. data/unittest/expected_creole/test_creole_links_external.text +4 -0
  78. data/unittest/expected_creole/test_creole_links_external_implicit.html +9 -0
  79. data/unittest/expected_creole/test_creole_links_external_implicit.latex +12 -0
  80. data/unittest/expected_creole/test_creole_links_external_implicit.text +6 -0
  81. data/unittest/expected_creole/test_creole_links_file.html +6 -0
  82. data/unittest/expected_creole/test_creole_links_file.latex +8 -0
  83. data/unittest/expected_creole/test_creole_links_file.text +4 -0
  84. data/unittest/expected_creole/test_creole_list_ol.html +12 -0
  85. data/unittest/expected_creole/test_creole_list_ol.latex +22 -0
  86. data/unittest/expected_creole/test_creole_list_ol_after_ul.html +12 -0
  87. data/unittest/expected_creole/test_creole_list_ol_after_ul.latex +20 -0
  88. data/unittest/expected_creole/test_creole_list_ol_after_ul.text +6 -0
  89. data/unittest/expected_creole/test_creole_list_ol_ul.html +15 -0
  90. data/unittest/expected_creole/test_creole_list_ol_ul.latex +26 -0
  91. data/unittest/expected_creole/test_creole_list_ul.html +22 -0
  92. data/unittest/expected_creole/test_creole_list_ul.latex +40 -0
  93. data/unittest/expected_creole/test_creole_list_ul.normsource +83 -0
  94. data/unittest/expected_creole/test_creole_list_ul_too_much.html +24 -0
  95. data/unittest/expected_creole/test_creole_list_ul_too_much.latex +44 -0
  96. data/unittest/expected_creole/test_creole_newline.html +9 -0
  97. data/unittest/expected_creole/test_creole_newline.latex +11 -0
  98. data/unittest/expected_creole/test_creole_newline.text +7 -0
  99. data/unittest/expected_creole/test_creole_paragraphs.html +6 -0
  100. data/unittest/expected_creole/test_creole_paragraphs.latex +8 -0
  101. data/unittest/expected_creole/test_creole_paragraphs.normsource +27 -0
  102. data/unittest/expected_creole/test_creole_paragraphs.text +4 -0
  103. data/unittest/expected_creole/test_creole_paragraphs.wiki +4 -0
  104. data/unittest/expected_creole/test_creole_paragraphs_wrap.html +5 -0
  105. data/unittest/expected_creole/test_creole_paragraphs_wrap.latex +6 -0
  106. data/unittest/expected_creole/test_creole_paragraphs_wrap.text +4 -0
  107. data/unittest/expected_creole/test_creole_paragraphs_wrap.wiki +4 -0
  108. data/unittest/expected_creole/test_creole_paragraphs_wrap0.html +9 -0
  109. data/unittest/expected_creole/test_creole_paragraphs_wrap0.latex +11 -0
  110. data/unittest/expected_creole/test_creole_paragraphs_wrap0.text +7 -0
  111. data/unittest/expected_creole/test_creole_paragraphs_wrap0.wiki +7 -0
  112. data/unittest/expected_creole/test_creole_paragraphs_wrap60.html +5 -0
  113. data/unittest/expected_creole/test_creole_paragraphs_wrap60.latex +6 -0
  114. data/unittest/expected_creole/test_creole_paragraphs_wrap60.text +4 -0
  115. data/unittest/expected_creole/test_creole_paragraphs_wrap60.wiki +4 -0
  116. data/unittest/expected_creole/test_creole_picture_link.html +6 -0
  117. data/unittest/expected_creole/test_creole_pictures.html +10 -0
  118. data/unittest/expected_creole/test_creole_pictures.latex +13 -0
  119. data/unittest/expected_creole/test_creole_pictures_css.html +3 -0
  120. data/unittest/expected_creole/test_creole_pictures_css.latex +4 -0
  121. data/unittest/expected_creole/test_creole_pictures_imgclass.html +6 -0
  122. data/unittest/expected_creole/test_creole_pictures_imgclass.latex +8 -0
  123. data/unittest/expected_creole/test_creole_placeholders_html.html +7 -0
  124. data/unittest/expected_creole/test_creole_placeholders_html.latex +8 -0
  125. data/unittest/expected_creole/test_creole_placeholders_html.text +4 -0
  126. data/unittest/expected_creole/test_creole_placeholders_latex.html +6 -0
  127. data/unittest/expected_creole/test_creole_placeholders_latex.latex +9 -0
  128. data/unittest/expected_creole/test_creole_placeholders_latex.text +4 -0
  129. data/unittest/expected_creole/test_creole_tabular.html +20 -0
  130. data/unittest/expected_creole/test_creole_tabular.latex +22 -0
  131. data/unittest/expected_creole/test_creole_tabular_creole.html +18 -0
  132. data/unittest/expected_creole/test_creole_tabular_creole.latex +19 -0
  133. data/unittest/expected_creole/test_creole_tabular_css.html +20 -0
  134. data/unittest/expected_creole/test_creole_tabular_css.latex +22 -0
  135. data/unittest/expected_creole/test_creole_toc.html +11 -0
  136. data/unittest/expected_creole/test_creole_toc.latex +22 -0
  137. data/unittest/expected_creole/test_creole_toc.text +4 -0
  138. data/unittest/expected_creole/test_creole_toc_text.html +5 -0
  139. data/unittest/expected_creole/test_creole_toc_text.latex +5 -0
  140. data/unittest/expected_creole/test_creole_ul_multiple_line.html +7 -0
  141. data/unittest/expected_creole/test_creole_ul_multiple_line.latex +14 -0
  142. data/unittest/expected_creole/test_creole_ul_with_blank.html +11 -0
  143. data/unittest/expected_creole/test_creole_ul_with_blank.latex +20 -0
  144. data/unittest/expected_creole/test_creole_ul_with_bold.creole +0 -0
  145. data/unittest/expected_creole/test_creole_ul_with_bold.html +11 -0
  146. data/unittest/expected_creole/test_creole_ul_with_bold.latex +18 -0
  147. data/unittest/expected_creole/test_creole_ul_with_bold.text +7 -0
  148. data/unittest/expected_creole/test_creole_verbatim.html +25 -0
  149. data/unittest/expected_creole/test_creole_verbatim.latex +33 -0
  150. data/unittest/expected_creole/test_creole_verbatim.text +17 -0
  151. data/unittest/expected_creole/test_creole_verbatim_inline.html +6 -0
  152. data/unittest/expected_creole/test_creole_verbatim_inline.latex +8 -0
  153. data/unittest/expected_creole/test_creole_verbatim_inline_at_start.html +6 -0
  154. data/unittest/expected_creole/test_creole_verbatim_inline_at_start.latex +8 -0
  155. data/unittest/expected_privat/test_creole_test_document.html +6 -0
  156. data/unittest/{expected → expected_wiki}/test_wiki.html +0 -0
  157. data/unittest/{expected → expected_wiki}/test_wiki.latex +0 -0
  158. data/unittest/{expected → expected_wiki}/test_wiki.text +0 -0
  159. data/unittest/{expected → expected_wiki}/test_wiki.wiki +0 -0
  160. data/unittest/{expected → expected_wiki}/test_wiki_amazon.html +0 -0
  161. data/unittest/{expected → expected_wiki}/test_wiki_description.html +0 -0
  162. data/unittest/{expected → expected_wiki}/test_wiki_description.latex +0 -0
  163. data/unittest/{expected → expected_wiki}/test_wiki_description.text +0 -0
  164. data/unittest/{expected → expected_wiki}/test_wiki_description.wiki +0 -0
  165. data/unittest/expected_wiki/test_wiki_footnote.html +8 -0
  166. data/unittest/expected_wiki/test_wiki_footnote.latex +17 -0
  167. data/unittest/{expected → expected_wiki}/test_wiki_footnote.text +2 -4
  168. data/unittest/expected_wiki/test_wiki_footnote.wiki +10 -0
  169. data/unittest/expected_wiki/test_wiki_footnote_2.html +8 -0
  170. data/unittest/expected_wiki/test_wiki_footnote_groupid.html +21 -0
  171. data/unittest/{expected → expected_wiki}/test_wiki_html_code.html +0 -0
  172. data/unittest/{expected → expected_wiki}/test_wiki_html_code.latex +0 -0
  173. data/unittest/{expected → expected_wiki}/test_wiki_html_code.text +0 -0
  174. data/unittest/{expected → expected_wiki}/test_wiki_html_code.wiki +0 -0
  175. data/unittest/{expected → expected_wiki}/test_wiki_inline.html +0 -0
  176. data/unittest/{expected → expected_wiki}/test_wiki_inline.latex +0 -0
  177. data/unittest/{expected → expected_wiki}/test_wiki_inline.text +0 -0
  178. data/unittest/{expected → expected_wiki}/test_wiki_inline.wiki +0 -0
  179. data/unittest/{expected → expected_wiki}/test_wiki_label.html +0 -0
  180. data/unittest/{expected → expected_wiki}/test_wiki_link.html +0 -0
  181. data/unittest/{expected → expected_wiki}/test_wiki_link.latex +0 -0
  182. data/unittest/{expected → expected_wiki}/test_wiki_link.log +0 -0
  183. data/unittest/{expected → expected_wiki}/test_wiki_link.wiki +0 -0
  184. data/unittest/{expected → expected_wiki}/test_wiki_list_ol.html +0 -0
  185. data/unittest/{expected → expected_wiki}/test_wiki_list_ol.latex +0 -0
  186. data/unittest/{expected → expected_wiki}/test_wiki_list_ol.text +0 -0
  187. data/unittest/{expected → expected_wiki}/test_wiki_list_ol.wiki +0 -0
  188. data/unittest/{expected → expected_wiki}/test_wiki_list_ol_after_ul.html +0 -0
  189. data/unittest/{expected → expected_wiki}/test_wiki_list_ol_after_ul.latex +0 -0
  190. data/unittest/{expected → expected_wiki}/test_wiki_list_ol_after_ul.text +0 -0
  191. data/unittest/{expected → expected_wiki}/test_wiki_list_ol_after_ul.wiki +0 -0
  192. data/unittest/{expected → expected_wiki}/test_wiki_list_ol_ul.html +0 -0
  193. data/unittest/{expected → expected_wiki}/test_wiki_list_ol_ul.latex +0 -0
  194. data/unittest/{expected → expected_wiki}/test_wiki_list_ol_ul.text +0 -0
  195. data/unittest/{expected → expected_wiki}/test_wiki_list_ol_ul.wiki +0 -0
  196. data/unittest/{expected → expected_wiki}/test_wiki_list_ul.html +0 -0
  197. data/unittest/{expected → expected_wiki}/test_wiki_list_ul.latex +0 -0
  198. data/unittest/{expected → expected_wiki}/test_wiki_list_ul.text +0 -0
  199. data/unittest/{expected → expected_wiki}/test_wiki_list_ul.wiki +0 -0
  200. data/unittest/{expected → expected_wiki}/test_wiki_list_ul_too_much.html +0 -0
  201. data/unittest/{expected → expected_wiki}/test_wiki_list_ul_too_much.latex +0 -0
  202. data/unittest/{expected → expected_wiki}/test_wiki_list_ul_too_much.text +0 -0
  203. data/unittest/{expected → expected_wiki}/test_wiki_list_ul_too_much.wiki +0 -0
  204. data/unittest/{expected → expected_wiki}/test_wiki_picture.html +0 -0
  205. data/unittest/{expected → expected_wiki}/test_wiki_picture.latex +0 -0
  206. data/unittest/{expected → expected_wiki}/test_wiki_picture_thumb.html +0 -0
  207. data/unittest/{expected → expected_wiki}/test_wiki_tab1.html +0 -0
  208. data/unittest/{expected → expected_wiki}/test_wiki_tab1.latex +0 -0
  209. data/unittest/{expected → expected_wiki}/test_wiki_tab1.wiki +0 -0
  210. data/unittest/{expected → expected_wiki}/test_wiki_textformatting.html +0 -0
  211. data/unittest/{expected → expected_wiki}/test_wiki_textformatting.latex +0 -0
  212. data/unittest/{expected → expected_wiki}/test_wiki_textformatting.text +0 -0
  213. data/unittest/{expected → expected_wiki}/test_wiki_textformatting.wiki +0 -0
  214. data/unittest/{expected → expected_wiki}/test_wiki_toc.html +0 -0
  215. data/unittest/{expected → expected_wiki}/test_wiki_toc.latex +0 -0
  216. data/unittest/{expected → expected_wiki}/test_wiki_toc.text +0 -0
  217. data/unittest/{expected → expected_wiki}/test_wiki_toc.wiki +0 -0
  218. data/unittest/{expected → expected_wiki}/test_wiki_ul_multiple_line.html +0 -0
  219. data/unittest/{expected → expected_wiki}/test_wiki_ul_multiple_line.latex +0 -0
  220. data/unittest/{expected → expected_wiki}/test_wiki_ul_multiple_line.text +0 -0
  221. data/unittest/{expected → expected_wiki}/test_wiki_ul_multiple_line.wiki +0 -0
  222. data/unittest/test_docgenerator.rb +1 -2
  223. data/unittest/unittest_creole2doc.rb +1024 -0
  224. data/unittest/unittest_docgenerator.rb +17 -8
  225. data/unittest/unittest_wiki2doc.rb +92 -88
  226. data/unittest/unittest_yaml2pres.rb +336 -0
  227. metadata +202 -70
  228. data/unittest/expected/test_wiki_footnote.html +0 -8
  229. data/unittest/expected/test_wiki_footnote.latex +0 -15
  230. data/unittest/expected/test_wiki_footnote.wiki +0 -12
  231. data/unittest/expected/test_wiki_footnote_groupid.html +0 -21
@@ -0,0 +1,777 @@
1
+ #
2
+ #This is a Creole-to-Docgenerator converter.
3
+ #The Docgenerator-data can be exported as
4
+ #- HTML
5
+ #- LaTeX
6
+ #- Creole
7
+ #- Wikimedia-like wiki
8
+ #- Plain text
9
+ #
10
+ #For another Creole-to-XHTML converter see
11
+ #https://rubyforge.org/projects/wikicreole/
12
+ #
13
+ #More about creole at http://www.wikicreole.org/
14
+ #
15
+
16
+ require 'docgenerator'
17
+
18
+ #
19
+ #Some class definitions for the Creole-class.
20
+ #
21
+ class Creole
22
+ #Little structure to store the parsing result.
23
+ Creole_line = Struct.new('Creole_line', :type, :content, :add_info)
24
+ #Define Placeholders
25
+ #Placeholders are used via <<<...>>>
26
+ #Default: Creole_dummy_placeholder (set in class definition Creole_dummy_placeholder)
27
+ Placeholders = Hash.new()
28
+ #Define Inclusions
29
+ #Inclusions are used via {{...}}
30
+ #Default: Creole_inclusion_img (defined in class definition Creole_inclusion_img)
31
+ Inclusions = Hash.new()
32
+ #Define Plugins
33
+ #Plugins are used via <<...>>
34
+ Plugins = Hash.new()
35
+
36
+ #Hash with Characters.
37
+ #This characters will be converted into elements.
38
+ CHARACTERS = {
39
+ '%' => element(:'%'),
40
+ '$' => element(:'$'),
41
+ '&' => element(:ampersand),
42
+ '->' => element(:rightarrow),
43
+ '=>' => element(:Rightarrow),
44
+ '<-' => element(:leftarrow),
45
+ '<=' => element(:Leftarrow),
46
+ '_' => element(:underscore),
47
+ #~ '...' => element(:ldots), . maskieren?
48
+ }
49
+
50
+ #Add a quick online-help.
51
+ def self.help( option = :syntax)
52
+ hlp = []
53
+ hlp << "==Creole help #{option}"
54
+ case option
55
+ when :syntax
56
+ hlp << <<Syntax
57
+ Headings:
58
+ = Level 1 (largest) =
59
+ == Level 2 ==
60
+ see also Creole.help(:headings)
61
+
62
+ Bold And Italics:
63
+ ** Bold
64
+ // Italics
65
+ You can close them. If not, the markup end with the paragraph.
66
+
67
+ Links: See Creole.help(:links)
68
+
69
+ Comming from Wikimedia/wiki2docgenerator? Check Creole.help(:wikimedia)
70
+ Familiar with Creole? Check Creole.help(:creole) for differences.
71
+ Syntax
72
+ when :creole
73
+ hlp << <<creole
74
+ creole2doc has some special features:
75
+ *headings allows labels ([key] direct after the =)
76
+ *line breaks are ignored, the text is wrapped.
77
+ (you can set it off with option :wrap_at => 0)
78
+ creole
79
+ when :wikimedia
80
+ hlp << <<tripfalls
81
+ Main Trippfalls when you used wiki2docgenerator before:
82
+
83
+ Lists: You need an empty line after a list.
84
+ #Listentry 2
85
+
86
+ Text afterwords
87
+ tripfalls
88
+ when :headings
89
+ hlp << <<headings
90
+ Headings:
91
+ = Level 1 (largest) =
92
+ == Level 2 ==
93
+ === Level 3 ===
94
+ ==== Level 4 ====
95
+ ===== Level 5 =====
96
+ ====== Level 6 ======
97
+ === Also level 3
98
+ === Also level 3 =
99
+ === Also level 3 ==
100
+ === **not** //parsed// ===
101
+ Headings with label:
102
+ =[lev1] Level 1 (largest) =
103
+ ==[lev1.1] Level 2 ==
104
+
105
+ The content is not parsed.
106
+ Details see http://www.wikicreole.org/wiki/Headings
107
+ headings
108
+ when :links
109
+ hlp << <<links
110
+ Explicit:
111
+ * [[http://ruby.lickert.net/docgenerator]]
112
+ * [[http://ruby.lickert.net/docgenerator|Details on docgenerator.rb]]
113
+
114
+ Implicit:
115
+ * http://ruby.lickert.net/docgenerator
116
+ links
117
+ when :tabular
118
+ hlp << <<tabular
119
+ Wikimedia-like syntax:
120
+ <<<tabular
121
+ |!columns=3
122
+ |!columndescription=ccc
123
+ |=1
124
+ |=2
125
+ |=3
126
+ |-
127
+ |eins
128
+ |zwei
129
+ |drei
130
+ |-
131
+ |one
132
+ |two
133
+ |three
134
+ >>>
135
+ tabular
136
+ else
137
+ hlp << "Undefined help for #{option.inspect}"
138
+ end
139
+ return hlp.join("\n")
140
+ end
141
+ end #Creole
142
+
143
+ #Load sub-classes.
144
+ Dir.chdir(File.dirname(__FILE__)){
145
+ require 'creole_placeholder.rb'
146
+ require 'creole_tabular.rb'
147
+ require 'creole_inclusion_and_plugins.rb'
148
+ #~ begin require '../../privat/creole_privat.rb'; rescue LoadError; end #fixme
149
+ begin require 'creole_privat.rb'; rescue LoadError; end #Just some privat extension
150
+ }
151
+
152
+ Dir.chdir('..'){
153
+ require 'docgenerator'
154
+ }
155
+ require 'log4r'
156
+
157
+ #
158
+ #Build a document.
159
+ #This is just a little combination of the classes Document and Creole.
160
+ #
161
+ #For the future: This class could allow features t build one TeX-file and
162
+ #multiple HTML (corresponding to pages).
163
+ #
164
+ #HTML-pagebreak could be forced with ======== or something similar.
165
+ class Creole_document
166
+ #Define a creole document. The settings are forwarded to Document#new()
167
+ #
168
+ #Some settings are used only directly in Creole_document.
169
+ #- :with_toc: Add a table of contents at the beginning of the document.
170
+ #- :content: Wiki-text. Same as Creole_document#<<
171
+ def initialize( settings = {} )
172
+ @with_toc = settings[:with_toc ]
173
+ settings.delete(:with_toc) #Avoid error message in Document.new
174
+
175
+ @creole = Creole.new(
176
+ #Get content if available and delete setting to avoid error message in Document.new
177
+ :content => settings.delete(:content),
178
+ :targetdir => settings.delete(:targetdir)
179
+ )
180
+
181
+ #fixme/ideen parameter
182
+ #preamble -> vor wiki-texten
183
+ #post -> nach wiki-texten
184
+ #plugins/inclusions
185
+ #replacements (schon teil von document?)
186
+
187
+ @doc = Document.new(settings)
188
+ @log = @doc.log
189
+
190
+ @doc.body << creole
191
+
192
+ end
193
+ #The related document
194
+ attr_reader :doc
195
+ #The related creole-object
196
+ attr_reader :creole
197
+ #Add content to the wiki.
198
+ def << (content)
199
+ @creole << content
200
+ end
201
+ #Save the creole document
202
+ def save( filename, options = {} )
203
+ if @with_toc
204
+ @doc.body.insertbefore(creole, creole.toc)
205
+ @with_toc = false #Add it only once
206
+ end
207
+
208
+ @doc.save(filename, options )
209
+ end
210
+ #Use runtex if available.
211
+ def runtex=(option)
212
+ @doc.runtex = option
213
+ end
214
+ end
215
+ #Creole is a standard wiki-syntax for wikitexts.
216
+ #Definition see http://www.wikicreole.org
217
+ #
218
+ #I liked this definition.
219
+ #When you look at the website, you get a definition and
220
+ #you get an explanation, why it is like this. - great!
221
+ #
222
+ #This class gets a creole-text and translate it to elements of the docgenerator,
223
+ #they can be used by Document or directly like Element#to_doc.
224
+ #
225
+ #Example:
226
+ # wiki = Creole.new()
227
+ # wiki << <<txt
228
+ # =Test document
229
+ # This is a little test text with **bold** and //italic// text.
230
+ # txt
231
+ # puts wiki.to_latex()
232
+ class Creole
233
+ #Define the Creole-object.
234
+ #
235
+ #Options:
236
+ #- :log => Logger to catch information.
237
+ # Alternativ you have access to the default logger via Creole#log
238
+ #- :targetdir => directory, where you want to save the result.
239
+ # This directory is important for checks for internal links.
240
+ def initialize( options = {} )
241
+ @options = {
242
+ :name => 'Creole', #Just a name for easier debugging/logging
243
+ :targetdir => '.',
244
+ :wrap_at => 75, #Default line wrapping
245
+ #~ :parsetest => false #Make an immediate test for parsing #fixme
246
+ #~ :placeholders =
247
+ #Definition how to handle the sectioning.
248
+ :title_levels => {
249
+ 0 => nil,
250
+ 1 => :h1,
251
+ 2 => :h2,
252
+ 3 => :h3,
253
+ 4 => :h4,
254
+ 5 => :h5,
255
+ 6 => :h6,
256
+ },
257
+ }.update(options)
258
+ @placeholders = Placeholders.dup
259
+ @inclusions = Inclusions.dup
260
+ @plugins = Plugins.dup
261
+
262
+ #Store the given source text
263
+ @source = []
264
+ #Store the pre-parsed content
265
+ @normsource = []
266
+ @toc = [] #Collection of all heading lines
267
+ @footnotegroups = {} #Collection of footnote groups
268
+
269
+
270
+ @targetdir = @options[:targetdir]
271
+ @log = @options[:log]
272
+ @log = Log4r::Logger.new(@options[:name], Log4r::INFO) unless @log
273
+ @log.outputters = Log4r::StdoutOutputter.new('log_stdout') if @log.outputters.empty?
274
+
275
+ self << @options[:content] if @options[:content]
276
+ end
277
+
278
+ #Hash with placeholders.
279
+ #
280
+ #Placeholders are used with <<<'name'.
281
+ #This accessor is needed to add more placeholders for specific wikis.
282
+ #Default: Creole::Placeholders
283
+ attr_reader :placeholders
284
+ attr_reader :options
285
+
286
+ #Hash with inclusions.
287
+ #This accessor is needed to add more inclusions for specific wikis.
288
+ #Default: Creole::Inclusions
289
+ attr_reader :inclusions
290
+ #Hash with all plugins
291
+ #This accessor is needed to add more plugins for specific wikis.
292
+ #Default: Creole::Plugins
293
+ attr_reader :plugins
294
+ #All footnotegroups of the wiki
295
+ attr_reader :footnotegroups
296
+
297
+ #Get some content.
298
+ #Strings are taken like strings.
299
+ #
300
+ #It is possible to add the content of a file. Just add the open file handle.
301
+ #In case of ruby scripts, the part after __END__ is used as input.
302
+ #
303
+ #Content added with << starts always with a new paragraph, but it may contain
304
+ #multiple paragraphs, lists...
305
+ def << ( input )
306
+ if input.is_a?(String)
307
+ source = input
308
+ elsif input.is_a?(File)
309
+ #If file is a ruby script, then use the wiki-code after __END__
310
+ #
311
+ #Often scripts contains there own text content after __END__.
312
+ #So we have to catch, if << is called with DATA
313
+ if /\.rb\Z/ =~ input.path and $0 != input.path
314
+ @log.info("Take content of #{input.inspect} after __END__") if @log.info?
315
+ begin
316
+ line = input.readline while line != "__END__\n"
317
+ rescue EOFError
318
+ @log.error("No __END__ found in #{input.inspect}") if @log.error?
319
+ end
320
+ end
321
+ #Read the code
322
+ source = input.readlines.to_s
323
+ end
324
+
325
+ @source << source
326
+ #Parse the given source.
327
+ #This is done immediate, so you have a chance to localize the line, where an error occurs.
328
+ #(Some errors are reported later during to_doc).
329
+ #fixme: optional sofort bei << oder sp�ter.
330
+ #immediate_parse => true...
331
+ @normsource.push( *parse( source ) )
332
+ end #<< ( input )
333
+
334
+ #Parse the given creole code and build a "normalized source"
335
+ def parse( source = @source )
336
+
337
+ normsource = []
338
+ statusflag = nil #Variable to store the actual status. nil = nothing special.
339
+ normsource << Creole_line.new(:dummy)
340
+ #
341
+ #Check code line by line
342
+ #
343
+ source.each_with_index{|line, lineno|
344
+ #Check special status
345
+ case statusflag
346
+ when nil #Nothing to do
347
+ when :pre
348
+ line =~ /\}\}\}/ ? statusflag = nil : normsource.last.content << line
349
+ next
350
+ when :placeholder
351
+ if line =~ /^>>>$/
352
+ statusflag = nil
353
+ normsource.last.content.close
354
+ else
355
+ normsource.last.content << line
356
+ end
357
+ next
358
+ else
359
+ @log.fatal("Undefind status #{statusflag}: #{line.inspect}" ) if @log.fatal?
360
+ end #statusflag
361
+
362
+ #
363
+ #Parse the wiki text on line level (main structure)
364
+ case line
365
+ #Headings
366
+ #http://www.wikicreole.org/wiki/Headings
367
+ #
368
+ #Modification of standard: Labels are possible.
369
+ when /^(=+)(?:\[(.*)\])?(.+?)(=*)\s*$/
370
+ normsource << Creole_line.new(:title, $3, :level => $1.size, :label => $2 )
371
+ @toc << normsource.last
372
+ #Creole doesn't need a trailing ===, but when it is ther, it should be correct
373
+ if $1.size != $4.size and $4.size > 0
374
+ @log.warn("Heading problem #{$1} doesn't match <#{$4}>: #{line.inspect}" ) if @log.warn?
375
+ end
376
+ if $~.post_match !~ /\s*/
377
+ @log.warn("Ignore text #{$~.post_match.inspect} after title <#{line.inspect}>" ) if @log.warn?
378
+ end
379
+ #Empty line
380
+ when /^\s*$/
381
+ normsource << Creole_line.new(:dummy )
382
+ when /^----\s*$/
383
+ normsource << Creole_line.new(:hr )
384
+ #List entry
385
+ when /^\s*((\*|\#)+)/
386
+ normsource << Creole_line.new(:list, $~.post_match, :listtype => $1 )
387
+ #Tabular
388
+ when /^\|/
389
+ #fixme tab soll in par...
390
+ #~ normsource.last << Creole_line.new(:placeholder,
391
+ #~ ... unless anpassen...
392
+ normsource << Creole_line.new(:placeholder,
393
+ @placeholders['creole_tabular'].new(self),
394
+ :start => lineno
395
+ ) unless normsource.last.content.is_a?(Creole_creoletab)
396
+ normsource.last.content << line
397
+ #http://www.wikicreole.org/wiki/PreformattedAndNowiki
398
+ when /^\{\{\{\s*$/
399
+ normsource << Creole_line.new(:pre, [], :start => lineno )
400
+ statusflag = :pre
401
+ #~ when /^<<<(.*)\|?(.*?)/ #fixme optionen f�r placeholder?
402
+ when /^<<<(.*)/
403
+ placeholder = @placeholders[$1].new(self)
404
+ if placeholder.is_a?(Creole_dummy_placeholder)
405
+ @log.warn("Unknown placeholder #{$1.inspect} used in line #{lineno}" ) if @log.warn?
406
+ end
407
+ normsource << Creole_line.new(:placeholder, placeholder, :start => lineno )
408
+ statusflag = :placeholder
409
+ else
410
+ case normsource.last.type
411
+ when :par, :list
412
+ normsource.last.content << line
413
+ else
414
+ normsource << Creole_line.new(:par, line )
415
+ end
416
+ end
417
+ }
418
+ case statusflag
419
+ when nil #ok
420
+ when :pre
421
+ @log.warn("Unclosed verbatim found (start at #{normsource.last.add_info[:start]})" ) if @log.warn?
422
+ #~ raise ''
423
+ when :placeholder
424
+ @log.warn("Unclosed placeholder #{normsource.last.type} (start at #{normsource.last.add_info[:start]})" ) if @log.warn?
425
+ else
426
+ @log.warn("Wiki ends with status #{statusflag.inspect}" ) if @log.warn?
427
+ end
428
+ return normsource
429
+ end #parse
430
+ #Logger to collect messages.
431
+ attr_reader :log
432
+ #Returns the source as it was received
433
+ attr_reader :source
434
+ #The pre-parsed content.
435
+ attr_reader :normsource
436
+ #Directory for the target.
437
+ #Can be used to check internal links (images, local files...)
438
+ attr_reader :targetdir
439
+ #Wrap some text after this lines.
440
+ #See http://forum.ruby-portal.de/viewtopic.php?t=3844
441
+ #
442
+
443
+ #
444
+ #Return a table of contents.
445
+ #
446
+ def toc( i_options = {})
447
+ options = {
448
+ :listtype => :ul,
449
+ :level => 4,
450
+ #~ :startlevel => 1,
451
+ }.update(i_options)
452
+ toclist = []
453
+ toclabel = [0] #help variable to construct labels
454
+ listtype = '*'
455
+ case options[:listtype]
456
+ when '*', :ul, :itemize
457
+ listtype = '*'
458
+ when '#', :ol, :enumerate
459
+ listtype = '#'
460
+ else
461
+ @log.error("Toc: Unknown listtype #{options[:listtype]}") if @log.error?
462
+ end
463
+
464
+ @toc.each{|tocentry|
465
+ level = tocentry.add_info[:level]
466
+
467
+ #Build the label
468
+ if level > toclabel.size
469
+ toclabel << 0
470
+ elsif level < toclabel.size
471
+ toclabel.pop
472
+ end
473
+ toclabel[level-1] = toclabel[level-1] + 1
474
+
475
+ #Check if there was already a label.
476
+ #If yes: use it. If not: build a new one with the help of toclabel.
477
+ if tocentry.add_info[:label]
478
+ label = tocentry.add_info[:label]
479
+ else
480
+ label = tocentry.add_info[:label] = toclabel.join('-')
481
+ end
482
+ #Skip deeper levels then wanted.
483
+ next if level > options[:level]
484
+
485
+ #Feature to create the toc if higher levels are missing /start at h3...)
486
+ #~ if level < options[:startlevel]
487
+ #~ @log.warn( "toc: TOC starts not at #{options[:startlevel]}, but level #{level}" ) if @log.warn?
488
+ #~ next
489
+ #~ end
490
+
491
+ toclist << "#{listtype * level}[[##{label}|#{tocentry.content}]]"
492
+ }
493
+ return Creole.new( :content => toclist.join("\n") )
494
+ end #toc
495
+
496
+ #Don't do anything, if line_width is 0.
497
+ def word_wrap(text, line_width = @options[:wrap_at] )
498
+ return text if line_width <= 0
499
+ text.gsub(/\n/, ' ').gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip
500
+ end
501
+ #
502
+ #Prepare document.
503
+ def to_doc( target, options = {} )
504
+ options[:log] = @log unless options[:log]
505
+ #
506
+ #Delete again all footnotegroups.
507
+ #Else you get footnotes doubled.
508
+ @footnotegroups = {} #Collection of footnote groups
509
+ return normsource2elements( @normsource, options ).to_doc(target, options)
510
+ end #to_doc
511
+ #Take the given normsource and build a list of elements.
512
+ #Used by
513
+ #- Creole#to_doc
514
+ #- Creole_ruby#to_doc
515
+ def normsource2elements( normsource, options )
516
+ doc = []
517
+ elements = {} #little collector for lists
518
+ normsource.each{|line|
519
+ case line.type
520
+ when :dummy
521
+ elements = {}
522
+ #Here we define the sectioning.
523
+ #line.add_info[:level] contains the number of = from the wiki.
524
+ #
525
+ when :title
526
+
527
+ doc << element(@options[:title_levels][line.add_info[:level]], {
528
+ :id => line.add_info[:label]
529
+ #inline or not?
530
+ #Required for filenames with _
531
+ #But: http://www.wikicreole.org/wiki/Headings says no.
532
+ #Make decision depending on a setting?
533
+ }, line.content ).cr
534
+ #~ }, inline(line.content, options ) ).cr
535
+ when :list
536
+ #~ puts line[:add_info].inspect
537
+ key = line.add_info[:listtype]
538
+ if ! elements[key]
539
+ case key[-1,1]
540
+ when '*'; elements[key] = element(:ul).cR
541
+ when '#'; elements[key] = element(:ol).cR
542
+ else
543
+ options[:log].error("Undefined listtype #{key[-1,1]}") if options[:log].error?
544
+ end
545
+ if key.size == 1 #new list, add to document
546
+ doc << elements[key]
547
+ elsif parent_list = elements[key[0,key.size-1]] #new sublist, add to "parent"
548
+ parent_list << element(:li).cr unless parent_list.content.last.is_a?(:li)
549
+ parent_list.content.last << elements[key]
550
+ else #sublist without parent.
551
+ options[:log].error("List #{key} with missing sublist") if options[:log].error?
552
+ end
553
+ end
554
+ elements.each{|ekey, list|
555
+ case ekey
556
+ when key
557
+ list << element(:li,{}, inline(line.content, options) ).cr
558
+ else
559
+ elements.delete(ekey) if ekey.size >= key.size
560
+ end
561
+ }
562
+ when :pre
563
+ doc << element(:pre, {}, line.content ).cR
564
+ when :hr
565
+ doc << element(:hr).cr
566
+ when :placeholder
567
+ doc << line.content
568
+ when :par
569
+ doc << element(:par, {}, inline(line.content, options)).cR
570
+ else
571
+ options[:log].error("Wrong line type #{ line.type.inspect }") if options[:log].error?
572
+ end
573
+ }
574
+
575
+ return doc
576
+ end #to_doc_internal
577
+ #
578
+ #Parse the inline text.
579
+ def inline( text, options )
580
+
581
+ res = [] #result
582
+ stack = [] #
583
+
584
+ #~ http_regex =
585
+ #fixme: Only once to reduce runtime
586
+ splitregex = Regexp.new(
587
+ '(' + [
588
+ '\[\[.+?\]\]', # [[...links]]
589
+ 'http:\/\/.+?\s', #including the next space!!
590
+ '\*\*', #bold
591
+ '\/\/', #emph
592
+ '\\\\\\\\', #newline
593
+ '\{\{\{.*\}\}\}', #inline verbatim
594
+ '\{\{.*\}\}', #images/inclusion
595
+ '<<.*>>', #Plugins
596
+ CHARACTERS.keys.join('|')
597
+ ].join('|') + ')'
598
+ )
599
+ #Splitt along 'active' elements.
600
+ #~ @options[:wrap_at]
601
+ #~ text.gsub(/\n/, ' ').split(splitregex).each{|el|
602
+ text.split(splitregex).each{|el|
603
+ case el
604
+ when '**' #bold
605
+ if stack.last.is_a?(:textbf)
606
+ stack.pop #leave bold area
607
+ else
608
+ stack << newel = element(:textbf) #enter bold area
609
+ if stack.size > 1
610
+ stack[-2] << newel
611
+ else
612
+ res << newel
613
+ end
614
+ end
615
+ when '//' #italic
616
+ if stack.last.is_a?(:emph)
617
+ stack.pop #leave italic area
618
+ else
619
+ stack << newel = element(:emph) #enter italic area
620
+ if stack.size > 1
621
+ stack[-2] << newel
622
+ else
623
+ res << newel
624
+ end
625
+ end
626
+ when '\\\\' #newline
627
+ ( stack.last ? stack.last : res ) << element(:newline).cr
628
+ #Something like [[http:...]]
629
+ when %r{^\[\[(.+?)(?:\|(.*?))?\]\]} #Link
630
+ link = $1
631
+ linktext = $2 ? $2 : $1
632
+ case link
633
+ when /^(https?|ftp):\/\/.+?/
634
+ link = link
635
+ when /^\./ #lokal file
636
+ link = link
637
+ check_link_existence( link, options[:log] )
638
+ when /^#/ #internal link
639
+ link = link
640
+ #fixme tex?
641
+ else #internal link
642
+ #This is normally the wiki-links.
643
+ #But this is no wiki, it's a documentgenerator with wiki syntax.
644
+ options[:log].warn("Unclear link <#{el}>") if options[:log].warn?
645
+ link = link
646
+ end
647
+ if link == linktext #Avoid replacement of // inside linktext
648
+ href = element(:a, {:href=>link}, linktext )
649
+ else
650
+ href = element(:a, {:href=>link}, inline(linktext, options) )
651
+ end
652
+ if stack.last
653
+ stack.last << href
654
+ else
655
+ res << href
656
+ end
657
+ #All links should be catched before
658
+ when %r{\[\[(.*)\]\]}
659
+ options[:log].error("Lost link <#{el}>") if options[:log].error?
660
+ when /^http/ #implicit link
661
+ href = element(:a, {:href=>el.strip}, el.strip )
662
+ if stack.last
663
+ stack.last << href
664
+ stack.last << ' ' #add again the end-space
665
+ else
666
+ res << href
667
+ res << ' ' #add again the end-space
668
+ end
669
+ #No-wiki inline: {{{text}}}
670
+ when /\{\{\{(.*)\}\}\}/
671
+ if stack.last
672
+ stack.last << element(:verb,{},$1)
673
+ else
674
+ res << element(:verb,{},$1)
675
+ end
676
+ #Inclusion
677
+ #creole2doc implements a general inclusion.
678
+ #Main usage are pictures/images ({{picname|alt}}),
679
+ #but it can be more...
680
+ #
681
+ #Available inclusions are defined in Creole::Inclusions resp. Creole#inclusions,
682
+ when /\{\{(.+?)(?:\|(.*))?\}\}/
683
+ if stack.last
684
+ stack.last << inclusion_or_plugin($1, $2, @inclusions)
685
+ else
686
+ res << inclusion_or_plugin($1, $2, @inclusions)
687
+ end
688
+ #Plugin
689
+ #Used like Inclusions.
690
+ #
691
+ #available plugins are defined in Creole::Plugins resp. Creole#plugins
692
+ when /<<(.+?)(?:\|(.*))?>>/
693
+ if stack.last
694
+ stack.last << inclusion_or_plugin($1, $2, @plugins)
695
+ else
696
+ res << inclusion_or_plugin($1, $2, @plugins)
697
+ end
698
+ #No special wiki command. The text is "normal" text.
699
+ else #text to add
700
+ #Replace characters.
701
+ if CHARACTERS[el]
702
+ insertion = CHARACTERS[el] if CHARACTERS[el]
703
+ startspace = endspace = nil
704
+ else
705
+ startspace = ( el[0,1] =~ /\s/ )
706
+ endspace = ( el[-1,1] =~ /\s/ )
707
+ insertion = word_wrap( el ) #wrap content
708
+ end
709
+ if stack.last
710
+ stack.last << insertion
711
+ #This adds some obsolete spaces in case of newlines at the end.
712
+ #But if I compare with ' ', then words will be concatenated without separator.
713
+ stack.last << ' ' if endspace
714
+ else #Just some text without any format
715
+ res << ' ' if startspace #Keep space
716
+ res << insertion
717
+ res << ' ' if endspace #Keep space
718
+ end
719
+ end
720
+ }
721
+ res
722
+ end #inline
723
+ #Inclusion or Plugin.
724
+ #creole2doc implements a general inclusion.
725
+ #Main usage are pictures/images ({{picname|alt}}),
726
+ #but it can be more...
727
+ #
728
+ #The last paramter contains a hash with the supported inclusions/plugins.
729
+ #
730
+ def inclusion_or_plugin( link, p_additions, inclusions )
731
+
732
+ addition, additions = nil
733
+ #Splitt additions at |
734
+ if p_additions
735
+ addition, *additions = p_additions.split(/\|/)
736
+ end
737
+
738
+ inclusion = inclusions[link]
739
+ #check inclusion.ancestors?
740
+ if inclusion.superclass != Creole_inclusion_and_plugin
741
+ @log.error( "Wrong inclusion/plugin definition for #{link} (#{inclusion.inspect}, expected #{inclusions.default.superclass})") if @log.error?
742
+ return nil
743
+ end
744
+ ip = inclusion.new( link, addition, additions, self )
745
+ return ip
746
+ end #inclusion
747
+
748
+ #Check for linkes and pictures if the target exist.
749
+ def check_link_existence( filename, log )
750
+ path = "#{@options[:targetdir]}/#{filename}"
751
+ if ! File.exist?(path)
752
+ log.warn("Reference not found: <#{filename}> (looking at #{@options[:targetdir]})") if log.warn?
753
+ log.debug("Reference not found: <#{path}>") if log.debug?
754
+ fpath = File.expand_path("#{Dir.pwd}/#{path}")
755
+ log.debug("Reference not found: <#{fpath}>") if log.debug?
756
+ end
757
+ end #check_link_existence
758
+ end #Creole
759
+
760
+ if [__FILE__, 'creole_tabular.rb'].include?($0)
761
+
762
+ #~ [
763
+ #~ :syntax,
764
+ #~ :creole,
765
+ #~ :wikimedia,
766
+ #~ :trippfall,
767
+ #~ :headings,
768
+ #~ :links,
769
+ #~ ].each{|key|
770
+ #~ puts '='*50
771
+ #~ puts Creole.help(key)
772
+ #~ puts '='*50
773
+ #~ }
774
+
775
+ #~ puts `call "../../unittest/unittest_creole2doc.rb"`
776
+ require 'quicktest'
777
+ end