rpeg-multimarkdown2 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (269) hide show
  1. data/LICENSE +96 -0
  2. data/README.markdown +52 -0
  3. data/Rakefile +167 -0
  4. data/bin/rpeg-multimarkdown2 +128 -0
  5. data/ext/extconf.h +3 -0
  6. data/ext/extconf.rb +15 -0
  7. data/ext/markdown.c +102 -0
  8. data/ext/markdown_lib.c +265 -0
  9. data/ext/markdown_lib.h +33 -0
  10. data/ext/markdown_output.c +2832 -0
  11. data/ext/markdown_parser.c +9091 -0
  12. data/ext/markdown_peg.h +144 -0
  13. data/ext/odf.c +183 -0
  14. data/ext/odf.h +3 -0
  15. data/ext/parsing_functions.c +199 -0
  16. data/ext/utility_functions.c +566 -0
  17. data/lib/multimarkdown2.rb +1 -0
  18. data/lib/peg_multimarkdown.rb +74 -0
  19. data/test/MultiMarkdownTest/BeamerTests/Beamer-Tables.html +76 -0
  20. data/test/MultiMarkdownTest/BeamerTests/Beamer-Tables.tex +64 -0
  21. data/test/MultiMarkdownTest/BeamerTests/Beamer-Tables.text +38 -0
  22. data/test/MultiMarkdownTest/CompatibilityTests/Automatic Labels.html +35 -0
  23. data/test/MultiMarkdownTest/CompatibilityTests/Automatic Labels.text +45 -0
  24. data/test/MultiMarkdownTest/CompatibilityTests/Base Header Level.html +14 -0
  25. data/test/MultiMarkdownTest/CompatibilityTests/Base Header Level.text +16 -0
  26. data/test/MultiMarkdownTest/CompatibilityTests/BibTeX.html +9 -0
  27. data/test/MultiMarkdownTest/CompatibilityTests/BibTeX.text +10 -0
  28. data/test/MultiMarkdownTest/CompatibilityTests/Citations.html +40 -0
  29. data/test/MultiMarkdownTest/CompatibilityTests/Citations.text +42 -0
  30. data/test/MultiMarkdownTest/CompatibilityTests/Definition Lists.html +40 -0
  31. data/test/MultiMarkdownTest/CompatibilityTests/Definition Lists.text +39 -0
  32. data/test/MultiMarkdownTest/CompatibilityTests/Dutch.html +17 -0
  33. data/test/MultiMarkdownTest/CompatibilityTests/Dutch.text +17 -0
  34. data/test/MultiMarkdownTest/CompatibilityTests/Email.html +40 -0
  35. data/test/MultiMarkdownTest/CompatibilityTests/Email.text +31 -0
  36. data/test/MultiMarkdownTest/CompatibilityTests/English.html +17 -0
  37. data/test/MultiMarkdownTest/CompatibilityTests/English.text +17 -0
  38. data/test/MultiMarkdownTest/CompatibilityTests/Errors.html +9 -0
  39. data/test/MultiMarkdownTest/CompatibilityTests/Errors.text +11 -0
  40. data/test/MultiMarkdownTest/CompatibilityTests/Footnotes.html +23 -0
  41. data/test/MultiMarkdownTest/CompatibilityTests/Footnotes.text +25 -0
  42. data/test/MultiMarkdownTest/CompatibilityTests/French.html +17 -0
  43. data/test/MultiMarkdownTest/CompatibilityTests/French.text +17 -0
  44. data/test/MultiMarkdownTest/CompatibilityTests/German.html +17 -0
  45. data/test/MultiMarkdownTest/CompatibilityTests/German.text +17 -0
  46. data/test/MultiMarkdownTest/CompatibilityTests/GermanGuillemets.html +17 -0
  47. data/test/MultiMarkdownTest/CompatibilityTests/GermanGuillemets.text +17 -0
  48. data/test/MultiMarkdownTest/CompatibilityTests/Glossary.html +29 -0
  49. data/test/MultiMarkdownTest/CompatibilityTests/Glossary.text +28 -0
  50. data/test/MultiMarkdownTest/CompatibilityTests/Headers.html +42 -0
  51. data/test/MultiMarkdownTest/CompatibilityTests/Headers.text +51 -0
  52. data/test/MultiMarkdownTest/CompatibilityTests/Line Breaks.html +13 -0
  53. data/test/MultiMarkdownTest/CompatibilityTests/Line Breaks.text +15 -0
  54. data/test/MultiMarkdownTest/CompatibilityTests/Link Attributes.html +35 -0
  55. data/test/MultiMarkdownTest/CompatibilityTests/Link Attributes.text +51 -0
  56. data/test/MultiMarkdownTest/CompatibilityTests/List Parsing.html +13 -0
  57. data/test/MultiMarkdownTest/CompatibilityTests/List Parsing.text +11 -0
  58. data/test/MultiMarkdownTest/CompatibilityTests/MarkdownInHTML.html +13 -0
  59. data/test/MultiMarkdownTest/CompatibilityTests/MarkdownInHTML.text +19 -0
  60. data/test/MultiMarkdownTest/CompatibilityTests/Math.html +14 -0
  61. data/test/MultiMarkdownTest/CompatibilityTests/Math.text +15 -0
  62. data/test/MultiMarkdownTest/CompatibilityTests/MetaData.html +14 -0
  63. data/test/MultiMarkdownTest/CompatibilityTests/MetaData.text +14 -0
  64. data/test/MultiMarkdownTest/CompatibilityTests/NotMetaData.html +3 -0
  65. data/test/MultiMarkdownTest/CompatibilityTests/NotMetaData.text +4 -0
  66. data/test/MultiMarkdownTest/CompatibilityTests/Sanity.html +77 -0
  67. data/test/MultiMarkdownTest/CompatibilityTests/Sanity.text +77 -0
  68. data/test/MultiMarkdownTest/CompatibilityTests/SmartQuotes.html +22 -0
  69. data/test/MultiMarkdownTest/CompatibilityTests/SmartQuotes.text +22 -0
  70. data/test/MultiMarkdownTest/CompatibilityTests/Swedish.html +17 -0
  71. data/test/MultiMarkdownTest/CompatibilityTests/Swedish.text +17 -0
  72. data/test/MultiMarkdownTest/CompatibilityTests/Tables.html +65 -0
  73. data/test/MultiMarkdownTest/CompatibilityTests/Tables.text +71 -0
  74. data/test/MultiMarkdownTest/MarkdownTest.pl +182 -0
  75. data/test/MultiMarkdownTest/MemoirTests/Automatic Labels.html +42 -0
  76. data/test/MultiMarkdownTest/MemoirTests/Automatic Labels.tex +47 -0
  77. data/test/MultiMarkdownTest/MemoirTests/Automatic Labels.text +46 -0
  78. data/test/MultiMarkdownTest/MemoirTests/Base Header Level.html +20 -0
  79. data/test/MultiMarkdownTest/MemoirTests/Base Header Level.tex +19 -0
  80. data/test/MultiMarkdownTest/MemoirTests/Base Header Level.text +16 -0
  81. data/test/MultiMarkdownTest/MemoirTests/BibTeX.html +17 -0
  82. data/test/MultiMarkdownTest/MemoirTests/BibTeX.tex +12 -0
  83. data/test/MultiMarkdownTest/MemoirTests/BibTeX.text +11 -0
  84. data/test/MultiMarkdownTest/MemoirTests/Citations.html +63 -0
  85. data/test/MultiMarkdownTest/MemoirTests/Citations.tex +48 -0
  86. data/test/MultiMarkdownTest/MemoirTests/Citations.text +43 -0
  87. data/test/MultiMarkdownTest/MemoirTests/Definition Lists.html +61 -0
  88. data/test/MultiMarkdownTest/MemoirTests/Definition Lists.tex +58 -0
  89. data/test/MultiMarkdownTest/MemoirTests/Definition Lists.text +40 -0
  90. data/test/MultiMarkdownTest/MemoirTests/Dutch.html +23 -0
  91. data/test/MultiMarkdownTest/MemoirTests/Dutch.tex +18 -0
  92. data/test/MultiMarkdownTest/MemoirTests/Dutch.text +17 -0
  93. data/test/MultiMarkdownTest/MemoirTests/Email.html +48 -0
  94. data/test/MultiMarkdownTest/MemoirTests/Email.tex +61 -0
  95. data/test/MultiMarkdownTest/MemoirTests/Email.text +32 -0
  96. data/test/MultiMarkdownTest/MemoirTests/English.html +23 -0
  97. data/test/MultiMarkdownTest/MemoirTests/English.tex +18 -0
  98. data/test/MultiMarkdownTest/MemoirTests/English.text +17 -0
  99. data/test/MultiMarkdownTest/MemoirTests/Footnotes.html +47 -0
  100. data/test/MultiMarkdownTest/MemoirTests/Footnotes.tex +28 -0
  101. data/test/MultiMarkdownTest/MemoirTests/Footnotes.text +26 -0
  102. data/test/MultiMarkdownTest/MemoirTests/French.html +23 -0
  103. data/test/MultiMarkdownTest/MemoirTests/French.tex +18 -0
  104. data/test/MultiMarkdownTest/MemoirTests/French.text +17 -0
  105. data/test/MultiMarkdownTest/MemoirTests/German.html +23 -0
  106. data/test/MultiMarkdownTest/MemoirTests/German.tex +18 -0
  107. data/test/MultiMarkdownTest/MemoirTests/German.text +17 -0
  108. data/test/MultiMarkdownTest/MemoirTests/GermanGuillemets.html +23 -0
  109. data/test/MultiMarkdownTest/MemoirTests/GermanGuillemets.tex +18 -0
  110. data/test/MultiMarkdownTest/MemoirTests/GermanGuillemets.text +17 -0
  111. data/test/MultiMarkdownTest/MemoirTests/Glossary.html +47 -0
  112. data/test/MultiMarkdownTest/MemoirTests/Glossary.tex +30 -0
  113. data/test/MultiMarkdownTest/MemoirTests/Glossary.text +29 -0
  114. data/test/MultiMarkdownTest/MemoirTests/Line Breaks.html +21 -0
  115. data/test/MultiMarkdownTest/MemoirTests/Line Breaks.tex +16 -0
  116. data/test/MultiMarkdownTest/MemoirTests/Line Breaks.text +16 -0
  117. data/test/MultiMarkdownTest/MemoirTests/Link Attributes.html +40 -0
  118. data/test/MultiMarkdownTest/MemoirTests/Link Attributes.tex +61 -0
  119. data/test/MultiMarkdownTest/MemoirTests/Link Attributes.text +51 -0
  120. data/test/MultiMarkdownTest/MemoirTests/Math.html +22 -0
  121. data/test/MultiMarkdownTest/MemoirTests/Math.tex +16 -0
  122. data/test/MultiMarkdownTest/MemoirTests/Math.text +16 -0
  123. data/test/MultiMarkdownTest/MemoirTests/Memoir Mode.html +24 -0
  124. data/test/MultiMarkdownTest/MemoirTests/Memoir Mode.tex +23 -0
  125. data/test/MultiMarkdownTest/MemoirTests/Memoir Mode.text +20 -0
  126. data/test/MultiMarkdownTest/MemoirTests/MetaData.html +22 -0
  127. data/test/MultiMarkdownTest/MemoirTests/MetaData.tex +14 -0
  128. data/test/MultiMarkdownTest/MemoirTests/MetaData.text +15 -0
  129. data/test/MultiMarkdownTest/MemoirTests/Sanity.html +100 -0
  130. data/test/MultiMarkdownTest/MemoirTests/Sanity.tex +101 -0
  131. data/test/MultiMarkdownTest/MemoirTests/Sanity.text +78 -0
  132. data/test/MultiMarkdownTest/MemoirTests/SmartQuotes.html +26 -0
  133. data/test/MultiMarkdownTest/MemoirTests/SmartQuotes.tex +21 -0
  134. data/test/MultiMarkdownTest/MemoirTests/SmartQuotes.text +19 -0
  135. data/test/MultiMarkdownTest/MemoirTests/Swedish.html +23 -0
  136. data/test/MultiMarkdownTest/MemoirTests/Swedish.tex +18 -0
  137. data/test/MultiMarkdownTest/MemoirTests/Swedish.text +17 -0
  138. data/test/MultiMarkdownTest/MemoirTests/Tables.html +221 -0
  139. data/test/MultiMarkdownTest/MemoirTests/Tables.tex +134 -0
  140. data/test/MultiMarkdownTest/MemoirTests/Tables.text +64 -0
  141. data/test/MultiMarkdownTest/MultiMarkdownTests/Automatic Labels.html +43 -0
  142. data/test/MultiMarkdownTest/MultiMarkdownTests/Automatic Labels.tex +46 -0
  143. data/test/MultiMarkdownTest/MultiMarkdownTests/Automatic Labels.text +45 -0
  144. data/test/MultiMarkdownTest/MultiMarkdownTests/Base Header Level.html +22 -0
  145. data/test/MultiMarkdownTest/MultiMarkdownTests/Base Header Level.tex +19 -0
  146. data/test/MultiMarkdownTest/MultiMarkdownTests/Base Header Level.text +16 -0
  147. data/test/MultiMarkdownTest/MultiMarkdownTests/BibTeX.html +18 -0
  148. data/test/MultiMarkdownTest/MultiMarkdownTests/BibTeX.tex +11 -0
  149. data/test/MultiMarkdownTest/MultiMarkdownTests/BibTex.text +10 -0
  150. data/test/MultiMarkdownTest/MultiMarkdownTests/Citations.html +64 -0
  151. data/test/MultiMarkdownTest/MultiMarkdownTests/Citations.tex +47 -0
  152. data/test/MultiMarkdownTest/MultiMarkdownTests/Citations.text +42 -0
  153. data/test/MultiMarkdownTest/MultiMarkdownTests/Definition Lists.html +57 -0
  154. data/test/MultiMarkdownTest/MultiMarkdownTests/Definition Lists.tex +57 -0
  155. data/test/MultiMarkdownTest/MultiMarkdownTests/Definition Lists.text +39 -0
  156. data/test/MultiMarkdownTest/MultiMarkdownTests/Dutch.html +25 -0
  157. data/test/MultiMarkdownTest/MultiMarkdownTests/Dutch.tex +18 -0
  158. data/test/MultiMarkdownTest/MultiMarkdownTests/Dutch.text +17 -0
  159. data/test/MultiMarkdownTest/MultiMarkdownTests/Email.html +49 -0
  160. data/test/MultiMarkdownTest/MultiMarkdownTests/Email.tex +54 -0
  161. data/test/MultiMarkdownTest/MultiMarkdownTests/Email.text +31 -0
  162. data/test/MultiMarkdownTest/MultiMarkdownTests/English.html +25 -0
  163. data/test/MultiMarkdownTest/MultiMarkdownTests/English.tex +18 -0
  164. data/test/MultiMarkdownTest/MultiMarkdownTests/English.text +17 -0
  165. data/test/MultiMarkdownTest/MultiMarkdownTests/Errors.html +18 -0
  166. data/test/MultiMarkdownTest/MultiMarkdownTests/Errors.tex +11 -0
  167. data/test/MultiMarkdownTest/MultiMarkdownTests/Errors.text +11 -0
  168. data/test/MultiMarkdownTest/MultiMarkdownTests/Footnotes.html +48 -0
  169. data/test/MultiMarkdownTest/MultiMarkdownTests/Footnotes.tex +24 -0
  170. data/test/MultiMarkdownTest/MultiMarkdownTests/Footnotes.text +25 -0
  171. data/test/MultiMarkdownTest/MultiMarkdownTests/French.html +25 -0
  172. data/test/MultiMarkdownTest/MultiMarkdownTests/French.tex +18 -0
  173. data/test/MultiMarkdownTest/MultiMarkdownTests/French.text +17 -0
  174. data/test/MultiMarkdownTest/MultiMarkdownTests/German.html +25 -0
  175. data/test/MultiMarkdownTest/MultiMarkdownTests/German.tex +18 -0
  176. data/test/MultiMarkdownTest/MultiMarkdownTests/German.text +17 -0
  177. data/test/MultiMarkdownTest/MultiMarkdownTests/GermanGuillemets.html +25 -0
  178. data/test/MultiMarkdownTest/MultiMarkdownTests/GermanGuillemets.tex +18 -0
  179. data/test/MultiMarkdownTest/MultiMarkdownTests/GermanGuillemets.text +17 -0
  180. data/test/MultiMarkdownTest/MultiMarkdownTests/Glossary.html +48 -0
  181. data/test/MultiMarkdownTest/MultiMarkdownTests/Glossary.tex +26 -0
  182. data/test/MultiMarkdownTest/MultiMarkdownTests/Glossary.text +28 -0
  183. data/test/MultiMarkdownTest/MultiMarkdownTests/Headers.html +50 -0
  184. data/test/MultiMarkdownTest/MultiMarkdownTests/Headers.tex +54 -0
  185. data/test/MultiMarkdownTest/MultiMarkdownTests/Headers.text +51 -0
  186. data/test/MultiMarkdownTest/MultiMarkdownTests/Line Breaks.html +22 -0
  187. data/test/MultiMarkdownTest/MultiMarkdownTests/Line Breaks.tex +15 -0
  188. data/test/MultiMarkdownTest/MultiMarkdownTests/Line Breaks.text +15 -0
  189. data/test/MultiMarkdownTest/MultiMarkdownTests/Link Attributes.html +56 -0
  190. data/test/MultiMarkdownTest/MultiMarkdownTests/Link Attributes.tex +60 -0
  191. data/test/MultiMarkdownTest/MultiMarkdownTests/Link Attributes.text +50 -0
  192. data/test/MultiMarkdownTest/MultiMarkdownTests/List Parsing.html +22 -0
  193. data/test/MultiMarkdownTest/MultiMarkdownTests/List Parsing.tex +17 -0
  194. data/test/MultiMarkdownTest/MultiMarkdownTests/List Parsing.text +11 -0
  195. data/test/MultiMarkdownTest/MultiMarkdownTests/MarkdownInHTML.html +21 -0
  196. data/test/MultiMarkdownTest/MultiMarkdownTests/MarkdownInHTML.tex +13 -0
  197. data/test/MultiMarkdownTest/MultiMarkdownTests/MarkdownInHTML.text +19 -0
  198. data/test/MultiMarkdownTest/MultiMarkdownTests/Math.html +23 -0
  199. data/test/MultiMarkdownTest/MultiMarkdownTests/Math.tex +15 -0
  200. data/test/MultiMarkdownTest/MultiMarkdownTests/Math.text +15 -0
  201. data/test/MultiMarkdownTest/MultiMarkdownTests/MetaData.html +23 -0
  202. data/test/MultiMarkdownTest/MultiMarkdownTests/MetaData.tex +13 -0
  203. data/test/MultiMarkdownTest/MultiMarkdownTests/MetaData.text +14 -0
  204. data/test/MultiMarkdownTest/MultiMarkdownTests/NotMetaData.html +3 -0
  205. data/test/MultiMarkdownTest/MultiMarkdownTests/NotMetaData.tex +3 -0
  206. data/test/MultiMarkdownTest/MultiMarkdownTests/NotMetaData.text +4 -0
  207. data/test/MultiMarkdownTest/MultiMarkdownTests/Sanity.html +106 -0
  208. data/test/MultiMarkdownTest/MultiMarkdownTests/Sanity.tex +100 -0
  209. data/test/MultiMarkdownTest/MultiMarkdownTests/Sanity.text +77 -0
  210. data/test/MultiMarkdownTest/MultiMarkdownTests/SmartQuotes.html +31 -0
  211. data/test/MultiMarkdownTest/MultiMarkdownTests/SmartQuotes.tex +24 -0
  212. data/test/MultiMarkdownTest/MultiMarkdownTests/SmartQuotes.text +22 -0
  213. data/test/MultiMarkdownTest/MultiMarkdownTests/Swedish.html +25 -0
  214. data/test/MultiMarkdownTest/MultiMarkdownTests/Swedish.tex +18 -0
  215. data/test/MultiMarkdownTest/MultiMarkdownTests/Swedish.text +17 -0
  216. data/test/MultiMarkdownTest/MultiMarkdownTests/Tables.html +273 -0
  217. data/test/MultiMarkdownTest/MultiMarkdownTests/Tables.tex +155 -0
  218. data/test/MultiMarkdownTest/MultiMarkdownTests/Tables.text +71 -0
  219. data/test/MultiMarkdownTest/MultiMarkdownTests/bibtex.bib +119 -0
  220. data/test/MultiMarkdownTest/README.md +58 -0
  221. data/test/MultiMarkdownTest/Tests/Amps and angle encoding.html +17 -0
  222. data/test/MultiMarkdownTest/Tests/Amps and angle encoding.text +21 -0
  223. data/test/MultiMarkdownTest/Tests/Auto links.html +18 -0
  224. data/test/MultiMarkdownTest/Tests/Auto links.text +13 -0
  225. data/test/MultiMarkdownTest/Tests/Backslash escapes.html +118 -0
  226. data/test/MultiMarkdownTest/Tests/Backslash escapes.text +120 -0
  227. data/test/MultiMarkdownTest/Tests/Blockquotes with code blocks.html +15 -0
  228. data/test/MultiMarkdownTest/Tests/Blockquotes with code blocks.text +11 -0
  229. data/test/MultiMarkdownTest/Tests/Code Blocks.html +18 -0
  230. data/test/MultiMarkdownTest/Tests/Code Blocks.text +14 -0
  231. data/test/MultiMarkdownTest/Tests/Code Spans.html +6 -0
  232. data/test/MultiMarkdownTest/Tests/Code Spans.text +6 -0
  233. data/test/MultiMarkdownTest/Tests/Compatibility.html +5 -0
  234. data/test/MultiMarkdownTest/Tests/Compatibility.text +9 -0
  235. data/test/MultiMarkdownTest/Tests/Hard-wrapped paragraphs with list-like lines.html +8 -0
  236. data/test/MultiMarkdownTest/Tests/Hard-wrapped paragraphs with list-like lines.text +8 -0
  237. data/test/MultiMarkdownTest/Tests/Horizontal rules.html +71 -0
  238. data/test/MultiMarkdownTest/Tests/Horizontal rules.text +67 -0
  239. data/test/MultiMarkdownTest/Tests/Inline HTML (Advanced).html +15 -0
  240. data/test/MultiMarkdownTest/Tests/Inline HTML (Advanced).text +15 -0
  241. data/test/MultiMarkdownTest/Tests/Inline HTML (Simple).html +72 -0
  242. data/test/MultiMarkdownTest/Tests/Inline HTML (Simple).text +69 -0
  243. data/test/MultiMarkdownTest/Tests/Inline HTML comments.html +13 -0
  244. data/test/MultiMarkdownTest/Tests/Inline HTML comments.text +13 -0
  245. data/test/MultiMarkdownTest/Tests/Links, inline style.html +11 -0
  246. data/test/MultiMarkdownTest/Tests/Links, inline style.text +12 -0
  247. data/test/MultiMarkdownTest/Tests/Links, reference style.html +52 -0
  248. data/test/MultiMarkdownTest/Tests/Links, reference style.text +71 -0
  249. data/test/MultiMarkdownTest/Tests/Links, shortcut references.html +9 -0
  250. data/test/MultiMarkdownTest/Tests/Links, shortcut references.text +20 -0
  251. data/test/MultiMarkdownTest/Tests/Literal quotes in titles.html +3 -0
  252. data/test/MultiMarkdownTest/Tests/Literal quotes in titles.text +7 -0
  253. data/test/MultiMarkdownTest/Tests/Markdown Documentation - Basics.html +314 -0
  254. data/test/MultiMarkdownTest/Tests/Markdown Documentation - Basics.text +306 -0
  255. data/test/MultiMarkdownTest/Tests/Markdown Documentation - Syntax.html +942 -0
  256. data/test/MultiMarkdownTest/Tests/Markdown Documentation - Syntax.text +888 -0
  257. data/test/MultiMarkdownTest/Tests/Nested blockquotes.html +9 -0
  258. data/test/MultiMarkdownTest/Tests/Nested blockquotes.text +5 -0
  259. data/test/MultiMarkdownTest/Tests/Ordered and unordered lists.html +148 -0
  260. data/test/MultiMarkdownTest/Tests/Ordered and unordered lists.text +131 -0
  261. data/test/MultiMarkdownTest/Tests/Strong and em together.html +7 -0
  262. data/test/MultiMarkdownTest/Tests/Strong and em together.text +7 -0
  263. data/test/MultiMarkdownTest/Tests/Tabs.html +25 -0
  264. data/test/MultiMarkdownTest/Tests/Tabs.text +21 -0
  265. data/test/MultiMarkdownTest/Tests/Tidyness.html +8 -0
  266. data/test/MultiMarkdownTest/Tests/Tidyness.text +5 -0
  267. data/test/benchmark.rb +49 -0
  268. data/test/multimarkdown_test.rb +89 -0
  269. metadata +318 -0
@@ -0,0 +1,2832 @@
1
+ /**********************************************************************
2
+
3
+ markdown_output.c - functions for printing Elements parsed by
4
+ markdown_peg.
5
+ (c) 2008 John MacFarlane (jgm at berkeley dot edu).
6
+
7
+ portions Copyright (c) 2010-2011 Fletcher T. Penney
8
+
9
+ This program is free software; you can redistribute it and/or modify
10
+ it under the terms of the GNU General Public License or the MIT
11
+ license. See LICENSE for details.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ ***********************************************************************/
19
+
20
+ #include <stdbool.h>
21
+ #include <stdio.h>
22
+ #include <stdlib.h>
23
+ #include <string.h>
24
+ #include <assert.h>
25
+ #include "glib.h"
26
+ #include "markdown_peg.h"
27
+ #include "utility_functions.c"
28
+ #include "odf.c"
29
+
30
+ static int extensions;
31
+ static int base_header_level = 1;
32
+ static char *latex_footer;
33
+ static int table_column = 0;
34
+ static char *table_alignment;
35
+ static char cell_type = 'd';
36
+ static int language = ENGLISH;
37
+ static bool html_footer = FALSE;
38
+ static int odf_type = 0;
39
+ static bool no_latex_footnote = FALSE;
40
+ static bool am_printing_html_footnote = FALSE;
41
+ static int footnote_counter_to_print = 0;
42
+ static int odf_list_needs_end_p = 0;
43
+
44
+ static void print_html_string(GString *out, char *str, bool obfuscate);
45
+ static void print_html_element_list(GString *out, element *list, bool obfuscate);
46
+ static void print_html_element(GString *out, element *elt, bool obfuscate);
47
+ static void print_latex_string(GString *out, char *str);
48
+ static void print_latex_element_list(GString *out, element *list);
49
+ static void print_latex_element(GString *out, element *elt);
50
+ static void print_groff_string(GString *out, char *str);
51
+ static void print_groff_mm_element_list(GString *out, element *list);
52
+ static void print_groff_mm_element(GString *out, element *elt, int count);
53
+ static void print_odf_code_string(GString *out, char *str);
54
+ static void print_odf_string(GString *out, char *str);
55
+ static void print_odf_element_list(GString *out, element *list);
56
+ static void print_odf_element(GString *out, element *elt);
57
+ static void print_odf_body_element_list(GString *out, element *list);
58
+ static bool list_contains_key(element *list, int key);
59
+
60
+
61
+ /* MultiMarkdown Routines */
62
+ static void print_html_header(GString *out, element *elt, bool obfuscate);
63
+ static void print_html_footer(GString *out, bool obfuscate);
64
+
65
+ static void print_latex_header(GString *out, element *elt);
66
+ static void print_latex_footer(GString *out);
67
+
68
+ static void print_memoir_element_list(GString *out, element *list);
69
+ static void print_memoir_element(GString *out, element *elt);
70
+
71
+ static void print_beamer_element_list(GString *out, element *list);
72
+ static void print_beamer_element(GString *out, element *elt);
73
+
74
+ static void print_opml_string(GString *out, char *str);
75
+ static void print_opml_element_list(GString *out, element *list);
76
+ static void print_opml_element(GString *out, element *elt);
77
+ static void print_opml_metadata(GString *out, element *elt);
78
+ static void print_opml_section_and_children(GString *out, element *list);
79
+
80
+ element * print_html_headingsection(GString *out, element *list, bool obfuscate);
81
+
82
+ static bool is_html_complete_doc(element *meta);
83
+ static int find_latex_mode(int format, element *list);
84
+ element * metadata_for_key(char *key, element *list);
85
+ char * metavalue_for_key(char *key, element *list);
86
+
87
+ element * element_for_attribute(char *querystring, element *list);
88
+ char * dimension_for_attribute(char *querystring, element *list);
89
+
90
+ element * locator_for_citation(element *elt);
91
+
92
+ /**********************************************************************
93
+
94
+ Utility functions for printing
95
+
96
+ ***********************************************************************/
97
+
98
+ static int padded = 2; /* Number of newlines after last output.
99
+ Starts at 2 so no newlines are needed at start.
100
+ */
101
+
102
+ static GSList *endnotes = NULL; /* List of endnotes to print after main content. */
103
+ static int notenumber = 0; /* Number of footnote. */
104
+
105
+ /* pad - add newlines if needed */
106
+ static void pad(GString *out, int num) {
107
+ while (num-- > padded)
108
+ g_string_append_printf(out, "\n");;
109
+ padded = num;
110
+ }
111
+
112
+ /* determine whether a certain element is contained within a given list */
113
+ bool list_contains_key(element *list, int key) {
114
+ element *step = NULL;
115
+
116
+ step = list;
117
+ while ( step != NULL ) {
118
+ if (step->key == key) {
119
+ return TRUE;
120
+ }
121
+ if (step->children != NULL) {
122
+ if (list_contains_key(step->children, key)) {
123
+ return TRUE;
124
+ }
125
+ }
126
+ step = step->next;
127
+ }
128
+ return FALSE;
129
+ }
130
+
131
+ /**********************************************************************
132
+
133
+ Functions for printing Elements as HTML
134
+
135
+ ***********************************************************************/
136
+
137
+ /* print_html_string - print string, escaping for HTML
138
+ * If obfuscate selected, convert characters to hex or decimal entities at random */
139
+ static void print_html_string(GString *out, char *str, bool obfuscate) {
140
+ while (*str != '\0') {
141
+ switch (*str) {
142
+ case '&':
143
+ g_string_append_printf(out, "&amp;");
144
+ break;
145
+ case '<':
146
+ g_string_append_printf(out, "&lt;");
147
+ break;
148
+ case '>':
149
+ g_string_append_printf(out, "&gt;");
150
+ break;
151
+ case '"':
152
+ g_string_append_printf(out, "&quot;");
153
+ break;
154
+ default:
155
+ if (obfuscate && ((int) *str < 128) && ((int) *str >= 0)){
156
+ if (rand() % 2 == 0)
157
+ g_string_append_printf(out, "&#%d;", (int) *str);
158
+ else
159
+ g_string_append_printf(out, "&#x%x;", (unsigned int) *str);
160
+ }
161
+ else
162
+ g_string_append_c(out, *str);
163
+ }
164
+ str++;
165
+ }
166
+ }
167
+
168
+ /* print_html_element_list - print a list of elements as HTML */
169
+ static void print_html_element_list(GString *out, element *list, bool obfuscate) {
170
+ while (list != NULL) {
171
+ if (list->key == HEADINGSECTION) {
172
+ list = print_html_headingsection(out, list, obfuscate);
173
+ } else {
174
+ print_html_element(out, list, obfuscate);
175
+ list = list->next;
176
+ }
177
+ }
178
+ }
179
+
180
+ /* add_endnote - add an endnote to global endnotes list. */
181
+ static void add_endnote(element *elt) {
182
+ endnotes = g_slist_prepend(endnotes, elt);
183
+ }
184
+
185
+ /* print_html_element - print an element as HTML */
186
+ static void print_html_element(GString *out, element *elt, bool obfuscate) {
187
+ int lev;
188
+ char *label;
189
+ element *attribute;
190
+ element *locator = NULL;
191
+ char *height;
192
+ char *width;
193
+ switch (elt->key) {
194
+ case SPACE:
195
+ g_string_append_printf(out, "%s", elt->contents.str);
196
+ break;
197
+ case LINEBREAK:
198
+ g_string_append_printf(out, "<br/>\n");
199
+ break;
200
+ case STR:
201
+ print_html_string(out, elt->contents.str, obfuscate);
202
+ break;
203
+ case ELLIPSIS:
204
+ localize_typography(out, ELLIP, language, HTMLOUT);
205
+ break;
206
+ case EMDASH:
207
+ localize_typography(out, MDASH, language, HTMLOUT);
208
+ break;
209
+ case ENDASH:
210
+ localize_typography(out, NDASH, language, HTMLOUT);
211
+ break;
212
+ case APOSTROPHE:
213
+ localize_typography(out, APOS, language, HTMLOUT);
214
+ break;
215
+ case SINGLEQUOTED:
216
+ localize_typography(out, LSQUOTE, language, HTMLOUT);
217
+ print_html_element_list(out, elt->children, obfuscate);
218
+ localize_typography(out, RSQUOTE, language, HTMLOUT);
219
+ break;
220
+ case DOUBLEQUOTED:
221
+ localize_typography(out, LDQUOTE, language, HTMLOUT);
222
+ print_html_element_list(out, elt->children, obfuscate);
223
+ localize_typography(out, RDQUOTE, language, HTMLOUT);
224
+ break;
225
+ case CODE:
226
+ g_string_append_printf(out, "<code>");
227
+ print_html_string(out, elt->contents.str, obfuscate);
228
+ g_string_append_printf(out, "</code>");
229
+ break;
230
+ case HTML:
231
+ g_string_append_printf(out, "%s", elt->contents.str);
232
+ break;
233
+ case LINK:
234
+ if (strstr(elt->contents.link->url, "mailto:") == elt->contents.link->url)
235
+ obfuscate = true; /* obfuscate mailto: links */
236
+ g_string_append_printf(out, "<a href=\"");
237
+ print_html_string(out, elt->contents.link->url, obfuscate);
238
+ g_string_append_printf(out, "\"");
239
+ if (strlen(elt->contents.link->title) > 0) {
240
+ g_string_append_printf(out, " title=\"");
241
+ print_html_string(out, elt->contents.link->title, obfuscate);
242
+ g_string_append_printf(out, "\"");
243
+ }
244
+ print_html_element_list(out, elt->contents.link->attr, obfuscate);
245
+ g_string_append_printf(out, ">");
246
+ print_html_element_list(out, elt->contents.link->label, obfuscate);
247
+ g_string_append_printf(out, "</a>");
248
+ break;
249
+ case IMAGEBLOCK:
250
+ pad(out, 2);
251
+ case IMAGE:
252
+ if (elt->key == IMAGEBLOCK) {
253
+ g_string_append_printf(out, "<figure>\n");
254
+ }
255
+ g_string_append_printf(out, "<img src=\"");
256
+ print_html_string(out, elt->contents.link->url, obfuscate);
257
+ g_string_append_printf(out, "\" alt=\"");
258
+ print_raw_element_list(out,elt->contents.link->label);
259
+ if ( (extension(EXT_COMPATIBILITY)) ||
260
+ (strcmp(elt->contents.link->identifier, "") == 0) ) {
261
+ g_string_append_printf(out, "\"");
262
+ } else {
263
+ if (!(extension(EXT_COMPATIBILITY))) {
264
+ g_string_append_printf(out, "\" id=\"%s\"",elt->contents.link->identifier);
265
+ }
266
+ }
267
+ if (strlen(elt->contents.link->title) > 0) {
268
+ g_string_append_printf(out, " title=\"");
269
+ print_html_string(out, elt->contents.link->title, obfuscate);
270
+ g_string_append_printf(out, "\"");
271
+ }
272
+ width = NULL;
273
+ height = NULL;
274
+ attribute = element_for_attribute("height", elt->contents.link->attr);
275
+ if (attribute != NULL) {
276
+ height = strdup(attribute->children->contents.str);
277
+ }
278
+ attribute = element_for_attribute("width", elt->contents.link->attr);
279
+ if (attribute != NULL) {
280
+ width = strdup(attribute->children->contents.str);
281
+ }
282
+ if ((height != NULL) || (width != NULL)) {
283
+ g_string_append_printf(out, " style=\"");
284
+ if (height != NULL)
285
+ g_string_append_printf(out, "height:%s;", height);
286
+ if (width != NULL)
287
+ g_string_append_printf(out, "width:%s;", width);
288
+ g_string_append_printf(out, "\"");
289
+ }
290
+ print_html_element_list(out, elt->contents.link->attr, obfuscate);
291
+ g_string_append_printf(out, " />");
292
+ if (elt->key == IMAGEBLOCK) {
293
+ if (elt->contents.link->label != NULL) {
294
+ g_string_append_printf(out, "\n<figcaption>");
295
+ print_html_element_list(out, elt->contents.link->label, obfuscate);
296
+ g_string_append_printf(out, "</figcaption>");
297
+ }
298
+ g_string_append_printf(out, "</figure>\n");
299
+ }
300
+ free(height);
301
+ free(width);
302
+ break;
303
+ case EMPH:
304
+ g_string_append_printf(out, "<em>");
305
+ print_html_element_list(out, elt->children, obfuscate);
306
+ g_string_append_printf(out, "</em>");
307
+ break;
308
+ case STRONG:
309
+ g_string_append_printf(out, "<strong>");
310
+ print_html_element_list(out, elt->children, obfuscate);
311
+ g_string_append_printf(out, "</strong>");
312
+ break;
313
+ case LIST:
314
+ print_html_element_list(out, elt->children, obfuscate);
315
+ break;
316
+ case RAW:
317
+ /* Shouldn't occur - these are handled by process_raw_blocks() */
318
+ assert(elt->key != RAW);
319
+ break;
320
+ case H1: case H2: case H3: case H4: case H5: case H6:
321
+ lev = elt->key - H1 + base_header_level; /* assumes H1 ... H6 are in order */
322
+ if (lev > 6)
323
+ lev = 6;
324
+ pad(out, 2);
325
+ if ( extension(EXT_COMPATIBILITY)) {
326
+ /* Use regular Markdown header format */
327
+ g_string_append_printf(out, "<h%1d>", lev);
328
+ print_html_element_list(out, elt->children, obfuscate);
329
+ } else if (elt->children->key == AUTOLABEL) {
330
+ /* use label for header since one was specified (MMD)*/
331
+ g_string_append_printf(out, "<h%d id=\"%s\">", lev,elt->children->contents.str);
332
+ print_html_element_list(out, elt->children->next, obfuscate);
333
+ } else if ( extension(EXT_NO_LABELS)) {
334
+ /* Don't generate a label */
335
+ g_string_append_printf(out, "<h%1d>", lev);
336
+ print_html_element_list(out, elt->children, obfuscate);
337
+ } else {
338
+ /* generate a label by default for MMD */
339
+ label = label_from_element_list(elt->children, obfuscate);
340
+ g_string_append_printf(out, "<h%d id=\"%s\">", lev, label);
341
+ print_html_element_list(out, elt->children, obfuscate);
342
+ free(label);
343
+ }
344
+ g_string_append_printf(out, "</h%1d>", lev);
345
+ padded = 0;
346
+ break;
347
+ case PLAIN:
348
+ pad(out, 1);
349
+ print_html_element_list(out, elt->children, obfuscate);
350
+ padded = 0;
351
+ break;
352
+ case PARA:
353
+ pad(out, 2);
354
+ g_string_append_printf(out, "<p>");
355
+ print_html_element_list(out, elt->children, obfuscate);
356
+ if (am_printing_html_footnote && ( elt->next == NULL)) {
357
+ g_string_append_printf(out, " <a href=\"#fnref:%d\" title=\"return to article\" class=\"reversefootnote\">&#160;&#8617;</a>", footnote_counter_to_print);
358
+ /* Only print once. For now, it's the first paragraph, until
359
+ I can figure out to make it the last paragraph */
360
+ am_printing_html_footnote = FALSE;
361
+ }
362
+ g_string_append_printf(out, "</p>");
363
+ padded = 0;
364
+ break;
365
+ case HRULE:
366
+ pad(out, 2);
367
+ g_string_append_printf(out, "<hr />");
368
+ padded = 0;
369
+ break;
370
+ case HTMLBLOCK:
371
+ pad(out, 2);
372
+ g_string_append_printf(out, "%s", elt->contents.str);
373
+ padded = 0;
374
+ break;
375
+ case VERBATIM:
376
+ pad(out, 2);
377
+ g_string_append_printf(out, "%s", "<pre><code>");
378
+ print_html_string(out, elt->contents.str, obfuscate);
379
+ g_string_append_printf(out, "%s", "</code></pre>");
380
+ padded = 0;
381
+ break;
382
+ case BULLETLIST:
383
+ pad(out, 2);
384
+ g_string_append_printf(out, "%s", "<ul>");
385
+ padded = 0;
386
+ print_html_element_list(out, elt->children, obfuscate);
387
+ pad(out, 1);
388
+ g_string_append_printf(out, "%s", "</ul>");
389
+ padded = 0;
390
+ break;
391
+ case ORDEREDLIST:
392
+ pad(out, 2);
393
+ g_string_append_printf(out, "%s", "<ol>");
394
+ padded = 0;
395
+ print_html_element_list(out, elt->children, obfuscate);
396
+ pad(out, 1);
397
+ g_string_append_printf(out, "</ol>");
398
+ padded = 0;
399
+ break;
400
+ case LISTITEM:
401
+ pad(out, 1);
402
+ g_string_append_printf(out, "<li>");
403
+ padded = 2;
404
+ print_html_element_list(out, elt->children, obfuscate);
405
+ g_string_append_printf(out, "</li>");
406
+ padded = 0;
407
+ break;
408
+ case BLOCKQUOTE:
409
+ pad(out, 2);
410
+ g_string_append_printf(out, "<blockquote>\n");
411
+ padded = 2;
412
+ print_html_element_list(out, elt->children, obfuscate);
413
+ pad(out, 1);
414
+ g_string_append_printf(out, "</blockquote>");
415
+ padded = 0;
416
+ break;
417
+ case REFERENCE:
418
+ /* Nonprinting */
419
+ break;
420
+ case NOTELABEL:
421
+ /* Nonprinting */
422
+ break;
423
+ case NOTE:
424
+ /* if contents.str == 0, then print note; else ignore, since this
425
+ * is a note block that has been incorporated into the notes list */
426
+ if (elt->contents.str == 0) {
427
+ if (elt->children->contents.str == 0) {
428
+ /* The referenced note has not been used before */
429
+ add_endnote(elt->children);
430
+ ++notenumber;
431
+ char buf[5];
432
+ sprintf(buf,"%d",notenumber);
433
+ /* Assign footnote number for future use */
434
+ elt->children->contents.str = strdup(buf);
435
+ if (elt->children->key == GLOSSARYTERM) {
436
+ g_string_append_printf(out, "<a href=\"#fn:%d\" id=\"fnref:%d\" title=\"see footnote\" class=\"footnote glossary\">[%d]</a>",
437
+ notenumber, notenumber, notenumber);
438
+ } else {
439
+ g_string_append_printf(out, "<a href=\"#fn:%d\" id=\"fnref:%d\" title=\"see footnote\" class=\"footnote\">[%d]</a>",
440
+ notenumber, notenumber, notenumber);
441
+ }
442
+ } else {
443
+ /* The referenced note has already been used */
444
+ g_string_append_printf(out, "<a href=\"#fn:%s\" title=\"see footnote\" class=\"footnote\">[%s]</a>",
445
+ elt->children->contents.str, elt->children->contents.str);
446
+ }
447
+ }
448
+ elt->children = NULL;
449
+ break;
450
+ case GLOSSARY:
451
+ /* Shouldn't do anything */
452
+ break;
453
+ case GLOSSARYTERM:
454
+ g_string_append_printf(out,"<span class=\"glossary name\">");
455
+ print_html_string(out, elt->children->contents.str, obfuscate);
456
+ g_string_append_printf(out, "</span>");
457
+ if ((elt->next != NULL) && (elt->next->key == GLOSSARYSORTKEY) ) {
458
+ g_string_append_printf(out, "<span class=\"glossary sort\" style=\"display:none\">");
459
+ print_html_string(out, elt->next->contents.str, obfuscate);
460
+ g_string_append_printf(out, "</span>");
461
+ }
462
+ g_string_append_printf(out, ": ");
463
+ break;
464
+ case GLOSSARYSORTKEY:
465
+ break;
466
+ case NOCITATION:
467
+ case CITATION:
468
+ /* Get locator, if present */
469
+ locator = locator_for_citation(elt);
470
+
471
+ if (strncmp(elt->contents.str,"[#",2) == 0) {
472
+ /* reference specified externally */
473
+ if ( elt->key == NOCITATION ) {
474
+ /* work not cited, but used in bibliography for LaTeX */
475
+ g_string_append_printf(out, "<span class=\"notcited\" id=\"%s\"/>", elt->contents.str);
476
+ } else {
477
+ /* work was cited, so output normally */
478
+ g_string_append_printf(out, "<span class=\"externalcitation\">");
479
+ if (locator != NULL) {
480
+ g_string_append_printf(out, "[");
481
+ print_html_element(out,locator,obfuscate);
482
+ g_string_append_printf(out, "]");
483
+ }
484
+ g_string_append_printf(out, "%s",elt->contents.str);
485
+ g_string_append_printf(out, "</span>");
486
+ }
487
+ } else {
488
+ /* reference specified within the MMD document,
489
+ so will output as footnote */
490
+ if (elt->children->contents.str == NULL) {
491
+ /* Work not previously cited in this document,
492
+ so create "endnote" */
493
+ elt->children->key = CITATION;
494
+ add_endnote(elt->children);
495
+ ++notenumber;
496
+ char buf[5];
497
+ sprintf(buf,"%d",notenumber);
498
+ /* Store the number for future reference */
499
+ elt->children->contents.str = strdup(buf);
500
+ }
501
+ if (locator != NULL) {
502
+ if ( elt->key == NOCITATION ) {
503
+ g_string_append_printf(out, "<span class=\"notcited\" id=\"%s\">",
504
+ elt->children->contents.str);
505
+ } else {
506
+ g_string_append_printf(out, "<a class=\"citation\" href=\"#fn:%s\" title=\"Jump to citation\">[<span class=\"locator\">", elt->children->contents.str);
507
+ print_html_element(out,locator,obfuscate);
508
+ g_string_append_printf(out,"</span>, %s]",
509
+ elt->children->contents.str);
510
+ }
511
+ } else {
512
+ g_string_append_printf(out, "<a class=\"citation\" href=\"#fn:%s\" title=\"Jump to citation\">[%s]",
513
+ elt->children->contents.str, elt->children->contents.str);
514
+ }
515
+ /* Now prune children since will likely be shared elsewhere */
516
+ elt->children = NULL;
517
+
518
+ g_string_append_printf(out, "<span class=\"citekey\" style=\"display:none\">%s</span>", elt->contents.str);
519
+ if ((locator != NULL) && (elt->key == NOCITATION)) {
520
+ g_string_append_printf(out,"</span>");
521
+ } else {
522
+ g_string_append_printf(out,"</a>");
523
+ }
524
+ }
525
+ break;
526
+ case LOCATOR:
527
+ print_html_element_list(out, elt->children, obfuscate);
528
+ break;
529
+ case DEFLIST:
530
+ pad(out,1);
531
+ padded = 1;
532
+ g_string_append_printf(out, "<dl>\n");
533
+ print_html_element_list(out, elt->children, obfuscate);
534
+ g_string_append_printf(out, "</dl>\n");
535
+ padded = 0;
536
+ break;
537
+ case TERM:
538
+ pad(out,1);
539
+ g_string_append_printf(out, "<dt>");
540
+ print_html_element_list(out, elt->children, obfuscate);
541
+ g_string_append_printf(out, "</dt>\n");
542
+ padded = 1;
543
+ break;
544
+ case DEFINITION:
545
+ pad(out,1);
546
+ padded = 1;
547
+ g_string_append_printf(out, "<dd>");
548
+ print_html_element_list(out, elt->children, obfuscate);
549
+ g_string_append_printf(out, "</dd>\n");
550
+ padded = 0;
551
+ break;
552
+ case METADATA:
553
+ /* Metadata is present, so this should be a "complete" document */
554
+ html_footer = is_html_complete_doc(elt);
555
+ if (html_footer) {
556
+ print_html_header(out, elt, obfuscate);
557
+ } else {
558
+ print_html_element_list(out, elt->children, obfuscate);
559
+ }
560
+ break;
561
+ case METAKEY:
562
+ if (strcmp(elt->contents.str, "title") == 0) {
563
+ g_string_append_printf(out, "\t<title>");
564
+ print_html_element(out, elt->children, obfuscate);
565
+ g_string_append_printf(out, "</title>\n");
566
+ } else if (strcmp(elt->contents.str, "css") == 0) {
567
+ g_string_append_printf(out, "\t<link type=\"text/css\" rel=\"stylesheet\" href=\"");
568
+ print_html_element(out, elt->children, obfuscate);
569
+ g_string_append_printf(out, "\"/>\n");
570
+ } else if (strcmp(elt->contents.str, "xhtmlheader") == 0) {
571
+ print_raw_element(out, elt->children);
572
+ g_string_append_printf(out, "\n");
573
+ } else if (strcmp(elt->contents.str, "htmlheader") == 0) {
574
+ print_raw_element(out, elt->children);
575
+ g_string_append_printf(out, "\n");
576
+ } else if (strcmp(elt->contents.str, "baseheaderlevel") == 0) {
577
+ base_header_level = atoi(elt->children->contents.str);
578
+ } else if (strcmp(elt->contents.str, "xhtmlheaderlevel") == 0) {
579
+ base_header_level = atoi(elt->children->contents.str);
580
+ } else if (strcmp(elt->contents.str, "htmlheaderlevel") == 0) {
581
+ base_header_level = atoi(elt->children->contents.str);
582
+ } else if (strcmp(elt->contents.str, "quoteslanguage") == 0) {
583
+ label = label_from_element_list(elt->children, 0);
584
+ if (strcmp(label, "dutch") == 0) { language = DUTCH; } else
585
+ if (strcmp(label, "german") == 0) { language = GERMAN; } else
586
+ if (strcmp(label, "germanguillemets") == 0) { language = GERMANGUILL; } else
587
+ if (strcmp(label, "french") == 0) { language = FRENCH; } else
588
+ if (strcmp(label, "swedish") == 0) { language = SWEDISH; }
589
+ free(label);
590
+ } else {
591
+ g_string_append_printf(out, "\t<meta name=\"");
592
+ print_html_string(out, elt->contents.str, obfuscate);
593
+ g_string_append_printf(out, "\" content=\"");
594
+ print_html_element(out, elt->children, obfuscate);
595
+ g_string_append_printf(out, "\"/>\n");
596
+ }
597
+ break;
598
+ case METAVALUE:
599
+ print_html_string(out, elt->contents.str, obfuscate);
600
+ break;
601
+ case FOOTER:
602
+ break;
603
+ case HEADINGSECTION:
604
+ print_html_element_list(out, elt->children, obfuscate);
605
+ break;
606
+ case TABLE:
607
+ g_string_append_printf(out, "\n\n<table>\n");
608
+ print_html_element_list(out, elt->children, obfuscate);
609
+ g_string_append_printf(out, "</table>\n");
610
+ break;
611
+ case TABLESEPARATOR:
612
+ table_alignment = elt->contents.str;
613
+ break;
614
+ case TABLECAPTION:
615
+ if (elt->children->key == TABLELABEL) {
616
+ label = label_from_element_list(elt->children->children,obfuscate);
617
+ } else {
618
+ label = label_from_element_list(elt->children,obfuscate);
619
+ }
620
+ g_string_append_printf(out, "<caption id=\"%s\">", label);
621
+ print_html_element_list(out, elt->children, obfuscate);
622
+ g_string_append_printf(out, "</caption>\n");
623
+ free(label);
624
+ break;
625
+ case TABLELABEL:
626
+ break;
627
+ case TABLEHEAD:
628
+ /* print column alignment for XSLT processing if needed */
629
+ g_string_append_printf(out, "<colgroup>\n");
630
+ for (table_column=0;table_column<strlen(table_alignment);table_column++) {
631
+ if ( strncmp(&table_alignment[table_column],"r",1) == 0) {
632
+ g_string_append_printf(out, "<col style=\"text-align:right;\"/>\n");
633
+ } else if ( strncmp(&table_alignment[table_column],"R",1) == 0) {
634
+ g_string_append_printf(out, "<col style=\"text-align:right;\" class=\"extended\"/>\n");
635
+ } else if ( strncmp(&table_alignment[table_column],"c",1) == 0) {
636
+ g_string_append_printf(out, "<col style=\"text-align:center;\"/>\n");
637
+ } else if ( strncmp(&table_alignment[table_column],"C",1) == 0) {
638
+ g_string_append_printf(out, "<col style=\"text-align:center;\" class=\"extended\"/>\n");
639
+ } else if ( strncmp(&table_alignment[table_column],"L",1) == 0) {
640
+ g_string_append_printf(out, "<col style=\"text-align:left;\" class=\"extended\"/>\n");
641
+ } else {
642
+ g_string_append_printf(out, "<col style=\"text-align:left;\"/>\n");
643
+ }
644
+ }
645
+ g_string_append_printf(out, "</colgroup>\n");
646
+ cell_type = 'h';
647
+ g_string_append_printf(out, "\n<thead>\n");
648
+ print_html_element_list(out, elt->children, obfuscate);
649
+ g_string_append_printf(out, "</thead>\n");
650
+ cell_type = 'd';
651
+ break;
652
+ case TABLEBODY:
653
+ g_string_append_printf(out, "\n<tbody>\n");
654
+ print_html_element_list(out, elt->children, obfuscate);
655
+ g_string_append_printf(out, "</tbody>\n");
656
+ break;
657
+ case TABLEROW:
658
+ g_string_append_printf(out, "<tr>\n");
659
+ table_column = 0;
660
+ print_html_element_list(out, elt->children, obfuscate);
661
+ g_string_append_printf(out, "</tr>\n");
662
+ break;
663
+ case TABLECELL:
664
+ if ( strncmp(&table_alignment[table_column],"r",1) == 0) {
665
+ g_string_append_printf(out, "\t<t%c style=\"text-align:right;\"", cell_type);
666
+ } else if ( strncmp(&table_alignment[table_column],"R",1) == 0) {
667
+ g_string_append_printf(out, "\t<t%c style=\"text-align:right;\"", cell_type);
668
+ } else if ( strncmp(&table_alignment[table_column],"c",1) == 0) {
669
+ g_string_append_printf(out, "\t<t%c style=\"text-align:center;\"", cell_type);
670
+ } else if ( strncmp(&table_alignment[table_column],"C",1) == 0) {
671
+ g_string_append_printf(out, "\t<t%c style=\"text-align:center;\"", cell_type);
672
+ } else {
673
+ g_string_append_printf(out, "\t<t%c style=\"text-align:left;\"", cell_type);
674
+ }
675
+ if ((elt->children != NULL) && (elt->children->key == CELLSPAN)) {
676
+ g_string_append_printf(out, " colspan=\"%d\"",(int)strlen(elt->children->contents.str)+1);
677
+ }
678
+ g_string_append_printf(out, ">");
679
+ padded = 2;
680
+ print_html_element_list(out, elt->children, obfuscate);
681
+ g_string_append_printf(out, "</t%c>\n", cell_type);
682
+ table_column++;
683
+ break;
684
+ case CELLSPAN:
685
+ break;
686
+ case ATTRKEY:
687
+ if ( (strcmp(elt->contents.str,"height") == 0) ||
688
+ (strcmp(elt->contents.str, "width") == 0)) {
689
+ } else {
690
+ g_string_append_printf(out, " %s=\"%s\"", elt->contents.str,
691
+ elt->children->contents.str);
692
+ }
693
+ break;
694
+ case MATHSPAN:
695
+ if ( elt->contents.str[strlen(elt->contents.str)-1] == ']') {
696
+ elt->contents.str[strlen(elt->contents.str)-3] = '\0';
697
+ g_string_append_printf(out, "<span class=\"math\">%s\\]</span>", elt->contents.str);
698
+ } else {
699
+ elt->contents.str[strlen(elt->contents.str)-3] = '\0';
700
+ g_string_append_printf(out, "<span class=\"math\">%s\\)</span>", elt->contents.str);
701
+ }
702
+ break;
703
+ default:
704
+ fprintf(stderr, "print_html_element encountered unknown element key = %d\n", elt->key);
705
+ exit(EXIT_FAILURE);
706
+ }
707
+ }
708
+
709
+ static void print_html_endnotes(GString *out) {
710
+ int counter = 0;
711
+ GSList *note;
712
+ element *note_elt;
713
+ if (endnotes == NULL)
714
+ return;
715
+ note = g_slist_reverse(endnotes);
716
+ g_string_append_printf(out, "<div class=\"footnotes\">\n<hr />\n<ol>");
717
+ while (note != NULL) {
718
+ note_elt = note->data;
719
+ counter++;
720
+ pad(out, 1);
721
+ if (note_elt->key == CITATION) {
722
+ g_string_append_printf(out, "<li id=\"fn:%s\" class=\"citation\"><span class=\"citekey\" style=\"display:none\">", note_elt->contents.str);
723
+ element *temp = note_elt;
724
+ while ( temp != NULL ) {
725
+ if (temp->key == NOTELABEL)
726
+ print_html_string(out, temp->contents.str, 0);
727
+ temp = temp->next;
728
+ }
729
+ g_string_append_printf(out, "</span>");
730
+ padded = 2;
731
+ print_html_element_list(out, note_elt->children, false);
732
+ pad(out, 1);
733
+ g_string_append_printf(out, "</li>");
734
+ } else {
735
+ g_string_append_printf(out, "<li id=\"fn:%d\">\n", counter);
736
+ padded = 2;
737
+ am_printing_html_footnote = TRUE;
738
+ footnote_counter_to_print = counter;
739
+ print_html_element_list(out, note_elt, false);
740
+ am_printing_html_footnote = FALSE;
741
+ footnote_counter_to_print = 0;
742
+ pad(out, 1);
743
+ g_string_append_printf(out, "</li>");
744
+ }
745
+ note = note->next;
746
+ }
747
+ pad(out, 1);
748
+ g_string_append_printf(out, "</ol>\n</div>\n");
749
+
750
+ g_slist_free(endnotes);
751
+ }
752
+
753
+ /**********************************************************************
754
+
755
+ Functions for printing Elements as LaTeX
756
+
757
+ ***********************************************************************/
758
+
759
+ /* print_latex_string - print string, escaping for LaTeX */
760
+ static void print_latex_string(GString *out, char *str) {
761
+ char *tmp;
762
+ while (*str != '\0') {
763
+ switch (*str) {
764
+ case '{': case '}': case '$': case '%':
765
+ case '&': case '_': case '#':
766
+ g_string_append_printf(out, "\\%c", *str);
767
+ break;
768
+ case '^':
769
+ g_string_append_printf(out, "\\^{}");
770
+ break;
771
+ case '\\':
772
+ g_string_append_printf(out, "\\textbackslash{}");
773
+ break;
774
+ case '~':
775
+ g_string_append_printf(out, "\\ensuremath{\\sim}");
776
+ break;
777
+ case '|':
778
+ g_string_append_printf(out, "\\textbar{}");
779
+ break;
780
+ case '<':
781
+ g_string_append_printf(out, "$<$");
782
+ break;
783
+ case '>':
784
+ g_string_append_printf(out, "$>$");
785
+ break;
786
+ case '/':
787
+ str++;
788
+ while (*str == '/') {
789
+ g_string_append_printf(out, "/");
790
+ str++;
791
+ }
792
+ g_string_append_printf(out, "\\slash ");
793
+ str--;
794
+ break;
795
+ case '\n':
796
+ tmp = str;
797
+ tmp--;
798
+ if (*tmp == ' ') {
799
+ tmp--;
800
+ if (*tmp == ' ') {
801
+ g_string_append_printf(out, "\\\\\n");
802
+ } else {
803
+ g_string_append_printf(out, "\n");
804
+ }
805
+ } else {
806
+ g_string_append_printf(out, "\n");
807
+ }
808
+ break;
809
+ default:
810
+ g_string_append_c(out, *str);
811
+ }
812
+ str++;
813
+ }
814
+ }
815
+
816
+ static void print_latex_endnotes(GString *out) {
817
+ GSList *note;
818
+ element *note_elt;
819
+ if (endnotes == NULL)
820
+ return;
821
+ note = g_slist_reverse(endnotes);
822
+ pad(out,2);
823
+ g_string_append_printf(out, "\\begin{thebibliography}{0}");
824
+ while (note != NULL) {
825
+ note_elt = note->data;
826
+ pad(out, 1);
827
+ g_string_append_printf(out, "\\bibitem{%s}\n", note_elt->contents.str);
828
+ padded=2;
829
+ print_latex_element_list(out, note_elt);
830
+ pad(out, 1);
831
+ note = note->next;
832
+ }
833
+ pad(out, 1);
834
+ g_string_append_printf(out, "\\end{thebibliography}\n");
835
+ padded = 1;
836
+ g_slist_free(endnotes);
837
+ }
838
+
839
+ /* print_latex_element_list - print a list of elements as LaTeX */
840
+ static void print_latex_element_list(GString *out, element *list) {
841
+ while (list != NULL) {
842
+ print_latex_element(out, list);
843
+ list = list->next;
844
+ }
845
+ }
846
+
847
+ /* print_latex_element - print an element as LaTeX */
848
+ static void print_latex_element(GString *out, element *elt) {
849
+ int lev;
850
+ char *label;
851
+ char *height;
852
+ char *width;
853
+ char *upper;
854
+ int i;
855
+ double floatnum;
856
+ switch (elt->key) {
857
+ case SPACE:
858
+ g_string_append_printf(out, "%s", elt->contents.str);
859
+ break;
860
+ case LINEBREAK:
861
+ g_string_append_printf(out, "\\\\\n");
862
+ break;
863
+ case STR:
864
+ print_latex_string(out, elt->contents.str);
865
+ break;
866
+ case ELLIPSIS:
867
+ localize_typography(out, ELLIP, language, LATEXOUT);
868
+ break;
869
+ case EMDASH:
870
+ localize_typography(out, MDASH, language, LATEXOUT);
871
+ break;
872
+ case ENDASH:
873
+ localize_typography(out, NDASH, language, LATEXOUT);
874
+ break;
875
+ case APOSTROPHE:
876
+ localize_typography(out, APOS, language, LATEXOUT);
877
+ break;
878
+ case SINGLEQUOTED:
879
+ localize_typography(out, LSQUOTE, language, LATEXOUT);
880
+ print_latex_element_list(out, elt->children);
881
+ localize_typography(out, RSQUOTE, language, LATEXOUT);
882
+ break;
883
+ case DOUBLEQUOTED:
884
+ localize_typography(out, LDQUOTE, language, LATEXOUT);
885
+ print_latex_element_list(out, elt->children);
886
+ localize_typography(out, RDQUOTE, language, LATEXOUT);
887
+ break;
888
+ case CODE:
889
+ g_string_append_printf(out, "\\texttt{");
890
+ print_latex_string(out, elt->contents.str);
891
+ g_string_append_printf(out, "}");
892
+ break;
893
+ case HTML:
894
+ /* don't print HTML */
895
+ /* but do print HTML comments for raw LaTeX */
896
+ if (strncmp(elt->contents.str,"<!--",4) == 0) {
897
+ /* trim "-->" from end */
898
+ elt->contents.str[strlen(elt->contents.str)-3] = '\0';
899
+ g_string_append_printf(out, "%s", &elt->contents.str[4]);
900
+ }
901
+ break;
902
+ case LINK:
903
+ if (elt->contents.link->url[0] == '#') {
904
+ /* This is a link to anchor within document */
905
+ label = label_from_string(elt->contents.link->url,0);
906
+ if (elt->contents.link->label != NULL) {
907
+ print_latex_element_list(out, elt->contents.link->label);
908
+ g_string_append_printf(out, " (\\autoref{%s})", label);
909
+ } else {
910
+ g_string_append_printf(out, "\\autoref{%s}", label);
911
+ }
912
+ free(label);
913
+ } else if ( (elt->contents.link->label != NULL) &&
914
+ ( elt->contents.link->label->contents.str != NULL) &&
915
+ ( strcmp(elt->contents.link->label->contents.str,
916
+ elt->contents.link->url) == 0 )) {
917
+ /* This is a <link> */
918
+ g_string_append_printf(out, "\\href{%s}{", elt->contents.link->url);
919
+ print_latex_string(out, elt->contents.link->url);
920
+ g_string_append_printf(out, "}");
921
+ } else if ( (elt->contents.link->label != NULL) &&
922
+ ( elt->contents.link->label->contents.str != NULL) &&
923
+ ( strcmp(&elt->contents.link->url[7],
924
+ elt->contents.link->label->contents.str) == 0 )) {
925
+ /* This is a <mailto> */
926
+ g_string_append_printf(out, "\\href{%s}{%s}", elt->contents.link->url, &elt->contents.link->url[7]);
927
+ } else {
928
+ /* This is a [text](link) */
929
+ g_string_append_printf(out, "\\href{%s}{", elt->contents.link->url);
930
+ print_latex_element_list(out, elt->contents.link->label);
931
+ g_string_append_printf(out, "}");
932
+ if ( no_latex_footnote == FALSE ) {
933
+ g_string_append_printf(out, "\\footnote{\\href{%s}{", elt->contents.link->url);
934
+ print_latex_string(out, elt->contents.link->url);
935
+ g_string_append_printf(out, "}}");
936
+ }
937
+ }
938
+ break;
939
+ case IMAGEBLOCK:
940
+ pad(out, 2);
941
+ case IMAGE:
942
+ /* Figure if we have height, width, neither */
943
+ height = dimension_for_attribute("height", elt->contents.link->attr);
944
+ width = dimension_for_attribute("width", elt->contents.link->attr);
945
+ if (elt->key == IMAGEBLOCK) {
946
+ g_string_append_printf(out, "\\begin{figure}[htbp]\n\\centering\n");
947
+ }
948
+ g_string_append_printf(out, "\\includegraphics[");
949
+ if ((height == NULL) && (width == NULL)) {
950
+ /* No dimensions given */
951
+ g_string_append_printf(out,"keepaspectratio,width=\\textwidth,height=0.75\\textheight");
952
+ } else {
953
+ /* at least one dimension given */
954
+ if ((height != NULL) && (width != NULL)) {
955
+
956
+ } else {
957
+ g_string_append_printf(out, "keepaspectratio,");
958
+ }
959
+ if (width != NULL) {
960
+ if (width[strlen(width)-1] == '%') {
961
+ width[strlen(width)-1] = '\0';
962
+ floatnum = strtod(width, NULL);
963
+ floatnum = floatnum/100;
964
+ g_string_append_printf(out,"width=%.4f\\textwidth,", floatnum);
965
+ } else {
966
+ g_string_append_printf(out,"width=%s,", width);
967
+ }
968
+ } else {
969
+ g_string_append_printf(out, "width=\\textwidth,");
970
+ }
971
+ if (height != NULL) {
972
+ if (height[strlen(height)-1] == '%') {
973
+ height[strlen(height)-1] = '\0';
974
+ floatnum = strtod(height, NULL);
975
+ floatnum = floatnum/100;
976
+ g_string_append_printf(out,"height=%.4f\\textheight,", floatnum);
977
+ } else {
978
+ g_string_append_printf(out,"height=%s",height);
979
+ }
980
+ } else {
981
+ g_string_append_printf(out, "height=0.75\\textheight");
982
+ }
983
+ }
984
+
985
+ g_string_append_printf(out, "]{%s}\n", elt->contents.link->url);
986
+ if (elt->key == IMAGEBLOCK) {
987
+ if (elt->contents.link->label != NULL) {
988
+ g_string_append_printf(out, "\\caption{");
989
+ print_latex_element_list(out, elt->contents.link->label);
990
+ g_string_append_printf(out, "}\n");
991
+ }
992
+ g_string_append_printf(out, "\\label{%s}\n", elt->contents.link->identifier);
993
+ g_string_append_printf(out,"\\end{figure}\n");
994
+ }
995
+ free(height);
996
+ free(width);
997
+ break;
998
+ case EMPH:
999
+ g_string_append_printf(out, "\\emph{");
1000
+ print_latex_element_list(out, elt->children);
1001
+ g_string_append_printf(out, "}");
1002
+ break;
1003
+ case STRONG:
1004
+ g_string_append_printf(out, "\\textbf{");
1005
+ print_latex_element_list(out, elt->children);
1006
+ g_string_append_printf(out, "}");
1007
+ break;
1008
+ case LIST:
1009
+ print_latex_element_list(out, elt->children);
1010
+ break;
1011
+ case RAW:
1012
+ /* Shouldn't occur - these are handled by process_raw_blocks() */
1013
+ assert(elt->key != RAW);
1014
+ break;
1015
+ case H1: case H2: case H3: case H4: case H5: case H6:
1016
+ pad(out, 2);
1017
+ lev = elt->key - H1 + base_header_level; /* assumes H1 ... H6 are in order */
1018
+ switch (lev) {
1019
+ case 1:
1020
+ g_string_append_printf(out, "\\part{");
1021
+ break;
1022
+ case 2:
1023
+ g_string_append_printf(out, "\\chapter{");
1024
+ break;
1025
+ case 3:
1026
+ g_string_append_printf(out, "\\section{");
1027
+ break;
1028
+ case 4:
1029
+ g_string_append_printf(out, "\\subsection{");
1030
+ break;
1031
+ case 5:
1032
+ g_string_append_printf(out, "\\subsubsection{");
1033
+ break;
1034
+ case 6:
1035
+ g_string_append_printf(out, "\\paragraph{");
1036
+ break;
1037
+ case 7:
1038
+ g_string_append_printf(out, "\\subparagraph{");
1039
+ break;
1040
+ default:
1041
+ g_string_append_printf(out, "\\noindent\\textbf{");
1042
+ break;
1043
+ }
1044
+ /* generate a label for each header (MMD);
1045
+ don't allow footnotes since invalid here */
1046
+ no_latex_footnote = TRUE;
1047
+ if (elt->children->key == AUTOLABEL) {
1048
+ label = label_from_string(elt->children->contents.str,0);
1049
+ print_latex_element_list(out, elt->children->next);
1050
+ } else {
1051
+ label = label_from_element_list(elt->children,0);
1052
+ print_latex_element_list(out, elt->children);
1053
+ }
1054
+ no_latex_footnote = FALSE;
1055
+ g_string_append_printf(out, "}\n\\label{");
1056
+ g_string_append_printf(out, "%s", label);
1057
+ g_string_append_printf(out, "}\n");
1058
+ free(label);
1059
+ padded = 1;
1060
+ break;
1061
+ case PLAIN:
1062
+ pad(out, 1);
1063
+ print_latex_element_list(out, elt->children);
1064
+ padded = 0;
1065
+ break;
1066
+ case PARA:
1067
+ pad(out, 2);
1068
+ print_latex_element_list(out, elt->children);
1069
+ padded = 0;
1070
+ break;
1071
+ case HRULE:
1072
+ pad(out, 2);
1073
+ g_string_append_printf(out, "\\begin{center}\\rule{3in}{0.4pt}\\end{center}\n");
1074
+ padded = 0;
1075
+ break;
1076
+ case HTMLBLOCK:
1077
+ /* don't print HTML block */
1078
+ /* but do print HTML comments for raw LaTeX */
1079
+ if (strncmp(elt->contents.str,"<!--",4) == 0) {
1080
+ pad(out, 2);
1081
+ /* trim "-->" from end */
1082
+ elt->contents.str[strlen(elt->contents.str)-3] = '\0';
1083
+ g_string_append_printf(out, "%s", &elt->contents.str[4]);
1084
+ padded = 0;
1085
+ }
1086
+ break;
1087
+ case VERBATIM:
1088
+ pad(out, 1);
1089
+ g_string_append_printf(out, "\n\\begin{verbatim}\n");
1090
+ print_raw_element(out, elt);
1091
+ g_string_append_printf(out, "\\end{verbatim}\n");
1092
+ padded = 0;
1093
+ break;
1094
+ case BULLETLIST:
1095
+ pad(out, 1);
1096
+ g_string_append_printf(out, "\n\\begin{itemize}");
1097
+ padded = 0;
1098
+ print_latex_element_list(out, elt->children);
1099
+ g_string_append_printf(out, "\n\\end{itemize}");
1100
+ padded = 0;
1101
+ break;
1102
+ case ORDEREDLIST:
1103
+ pad(out, 2);
1104
+ g_string_append_printf(out, "\\begin{enumerate}");
1105
+ padded = 0;
1106
+ print_latex_element_list(out, elt->children);
1107
+ pad(out, 1);
1108
+ g_string_append_printf(out, "\\end{enumerate}");
1109
+ padded = 0;
1110
+ break;
1111
+ case LISTITEM:
1112
+ pad(out, 1);
1113
+ g_string_append_printf(out, "\\item ");
1114
+ padded = 2;
1115
+ print_latex_element_list(out, elt->children);
1116
+ g_string_append_printf(out, "\n");
1117
+ break;
1118
+ case BLOCKQUOTE:
1119
+ pad(out, 2);
1120
+ g_string_append_printf(out, "\\begin{quote}");
1121
+ padded = 0;
1122
+ print_latex_element_list(out, elt->children);
1123
+ pad(out, 1);
1124
+ g_string_append_printf(out, "\\end{quote}");
1125
+ padded = 0;
1126
+ break;
1127
+ case NOTELABEL:
1128
+ /* Nonprinting */
1129
+ break;
1130
+ case NOTE:
1131
+ /* if contents.str == 0, then print note; else ignore, since this
1132
+ * is a note block that has been incorporated into the notes list */
1133
+ if (elt->contents.str == 0) {
1134
+ if (elt->children->key == GLOSSARYTERM) {
1135
+ g_string_append_printf(out, "\\newglossaryentry{%s}{", elt->children->children->contents.str);
1136
+ padded = 2;
1137
+ if (elt->children->next->key == GLOSSARYSORTKEY) {
1138
+ g_string_append_printf(out, "sort={");
1139
+ print_latex_string(out, elt->children->next->contents.str);
1140
+ g_string_append_printf(out, "},");
1141
+ }
1142
+ print_latex_element_list(out, elt->children);
1143
+ g_string_append_printf(out, "}}\\glsadd{%s}", elt->children->children->contents.str);
1144
+ padded = 0;
1145
+ } else {
1146
+ g_string_append_printf(out, "\\footnote{");
1147
+ padded = 2;
1148
+ print_latex_element_list(out, elt->children);
1149
+ g_string_append_printf(out, "}");
1150
+ padded = 0;
1151
+ }
1152
+ elt->children = NULL;
1153
+ }
1154
+ break;
1155
+ case GLOSSARY:
1156
+ /* This shouldn't do anything */
1157
+ break;
1158
+ case GLOSSARYTERM:
1159
+ g_string_append_printf(out, "name={");
1160
+ print_latex_string(out, elt->children->contents.str);
1161
+ g_string_append_printf(out, "},description={");
1162
+ break;
1163
+ case GLOSSARYSORTKEY:
1164
+ break;
1165
+ case REFERENCE:
1166
+ /* Nonprinting */
1167
+ break;
1168
+ case NOCITATION:
1169
+ case CITATION:
1170
+ if (strncmp(elt->contents.str,"[#",2) == 0) {
1171
+ /* This should be used as a bibtex citation key after trimming */
1172
+ elt->contents.str[strlen(elt->contents.str)-1] = '\0';
1173
+ if (elt->key == NOCITATION ) {
1174
+ g_string_append_printf(out, "~\\nocite{%s}", &elt->contents.str[2]);
1175
+ } else {
1176
+ if ((elt->children != NULL) && (elt->children->key == LOCATOR)) {
1177
+ if (strcmp(&elt->contents.str[strlen(elt->contents.str) - 1],";") == 0) {
1178
+ g_string_append_printf(out, " \\citet[");
1179
+ elt->contents.str[strlen(elt->contents.str) - 1] = '\0';
1180
+ } else {
1181
+ g_string_append_printf(out, "~\\citep[");
1182
+ }
1183
+ print_latex_element(out,elt->children);
1184
+ g_string_append_printf(out, "]{%s}",&elt->contents.str[2]);
1185
+ } else {
1186
+ if (strcmp(&elt->contents.str[strlen(elt->contents.str) - 1],";") == 0) {
1187
+ elt->contents.str[strlen(elt->contents.str) - 1] = '\0';
1188
+ g_string_append_printf(out, " \\citet{%s}", &elt->contents.str[2]);
1189
+ } else {
1190
+ g_string_append_printf(out, "~\\citep{%s}", &elt->contents.str[2]);
1191
+ }
1192
+ }
1193
+ }
1194
+ } else {
1195
+ /* This citation was specified in the document itself */
1196
+ if (elt->key == NOCITATION ) {
1197
+ g_string_append_printf(out, "~\\nocite{%s}", elt->contents.str);
1198
+ element *temp;
1199
+ temp = elt->children;
1200
+ elt->children = temp->next;
1201
+ free_element(temp);
1202
+ } else {
1203
+ if ((elt->children != NULL) && (elt->children->key == LOCATOR)){
1204
+ if (strcmp(&elt->contents.str[strlen(elt->contents.str) - 1],";") == 0) {
1205
+ g_string_append_printf(out, " \\citet[");
1206
+ elt->contents.str[strlen(elt->contents.str) - 1] = '\0';
1207
+ } else {
1208
+ g_string_append_printf(out, "~\\citep[");
1209
+ }
1210
+ print_latex_element(out,elt->children);
1211
+ g_string_append_printf(out, "]{%s}",elt->contents.str);
1212
+ element *temp;
1213
+ temp = elt->children;
1214
+ elt->children = temp->next;
1215
+ free_element(temp);
1216
+ } else {
1217
+ if (strcmp(&elt->contents.str[strlen(elt->contents.str) - 1],";") == 0) {
1218
+ elt->contents.str[strlen(elt->contents.str) - 1] = '\0';
1219
+ g_string_append_printf(out, " \\citet{%s}", elt->contents.str);
1220
+ } else {
1221
+ g_string_append_printf(out, "~\\citep{%s}", elt->contents.str);
1222
+ }
1223
+ }
1224
+ }
1225
+ if ((elt->children != NULL) && (elt->children->contents.str == NULL)) {
1226
+ elt->children->contents.str = strdup(elt->contents.str);
1227
+ add_endnote(elt->children);
1228
+ }
1229
+ elt->children = NULL;
1230
+ }
1231
+ break;
1232
+ case LOCATOR:
1233
+ print_latex_element_list(out, elt->children);
1234
+ break;
1235
+ case DEFLIST:
1236
+ g_string_append_printf(out, "\\begin{description}");
1237
+ padded = 0;
1238
+ print_latex_element_list(out, elt->children);
1239
+ pad(out,1);
1240
+ g_string_append_printf(out, "\\end{description}");
1241
+ padded = 0;
1242
+ break;
1243
+ case TERM:
1244
+ pad(out,2);
1245
+ g_string_append_printf(out, "\\item[");
1246
+ print_latex_element_list(out, elt->children);
1247
+ g_string_append_printf(out, "]");
1248
+ padded = 0;
1249
+ break;
1250
+ case DEFINITION:
1251
+ pad(out,2);
1252
+ padded = 2;
1253
+ print_latex_element_list(out, elt->children);
1254
+ padded = 0;
1255
+ break;
1256
+ case METADATA:
1257
+ /* Metadata is present, so this should be a "complete" document */
1258
+ print_latex_header(out, elt);
1259
+ html_footer = is_html_complete_doc(elt);
1260
+ break;
1261
+ case METAKEY:
1262
+ if (strcmp(elt->contents.str, "title") == 0) {
1263
+ g_string_append_printf(out, "\\def\\mytitle{");
1264
+ print_latex_element_list(out, elt->children);
1265
+ g_string_append_printf(out, "}\n");
1266
+ } else if (strcmp(elt->contents.str, "author") == 0) {
1267
+ g_string_append_printf(out, "\\def\\myauthor{");
1268
+ print_latex_element_list(out, elt->children);
1269
+ g_string_append_printf(out, "}\n");
1270
+ } else if (strcmp(elt->contents.str, "date") == 0) {
1271
+ g_string_append_printf(out, "\\def\\mydate{");
1272
+ print_latex_element_list(out, elt->children);
1273
+ g_string_append_printf(out, "}\n");
1274
+ } else if (strcmp(elt->contents.str, "copyright") == 0) {
1275
+ g_string_append_printf(out, "\\def\\mycopyright{");
1276
+ print_latex_element_list(out, elt->children);
1277
+ g_string_append_printf(out, "}\n");
1278
+ } else if (strcmp(elt->contents.str, "baseheaderlevel") == 0) {
1279
+ base_header_level = atoi(elt->children->contents.str);
1280
+ } else if (strcmp(elt->contents.str, "latexheaderlevel") == 0) {
1281
+ base_header_level = atoi(elt->children->contents.str);
1282
+ } else if (strcmp(elt->contents.str, "latexinput") == 0) {
1283
+ g_string_append_printf(out, "\\input{%s}\n", elt->children->contents.str);
1284
+ } else if (strcmp(elt->contents.str, "latexfooter") == 0) {
1285
+ latex_footer = elt->children->contents.str;
1286
+ } else if (strcmp(elt->contents.str, "bibtex") == 0) {
1287
+ g_string_append_printf(out, "\\def\\bibliocommand{\\bibliography{%s}}\n",elt->children->contents.str);
1288
+ } else if (strcmp(elt->contents.str, "xhtmlheader") == 0) {
1289
+ } else if (strcmp(elt->contents.str, "htmlheader") == 0) {
1290
+ } else if (strcmp(elt->contents.str, "css") == 0) {
1291
+ } else if (strcmp(elt->contents.str, "quoteslanguage") == 0) {
1292
+ label = label_from_element_list(elt->children, 0);
1293
+ if (strcmp(label, "dutch") == 0) { language = DUTCH; } else
1294
+ if (strcmp(label, "german") == 0) { language = GERMAN; } else
1295
+ if (strcmp(label, "germanguillemets") == 0) { language = GERMANGUILL; } else
1296
+ if (strcmp(label, "french") == 0) { language = FRENCH; } else
1297
+ if (strcmp(label, "swedish") == 0) { language = SWEDISH; }
1298
+ free(label);
1299
+ } else {
1300
+ g_string_append_printf(out, "\\def\\");
1301
+ print_latex_string(out, elt->contents.str);
1302
+ g_string_append_printf(out, "{");
1303
+ print_latex_element_list(out, elt->children);
1304
+ g_string_append_printf(out, "}\n");
1305
+ }
1306
+ break;
1307
+ case METAVALUE:
1308
+ print_latex_string(out, elt->contents.str);
1309
+ break;
1310
+ case FOOTER:
1311
+ print_latex_endnotes(out);
1312
+ print_latex_footer(out);
1313
+ break;
1314
+ case HEADINGSECTION:
1315
+ print_latex_element_list(out, elt->children);
1316
+ break;
1317
+ case TABLE:
1318
+ pad(out, 2);
1319
+ g_string_append_printf(out, "\\begin{table}[htbp]\n\\begin{minipage}{\\linewidth}\n\\setlength{\\tymax}{0.5\\linewidth}\n\\centering\n\\small\n");
1320
+ print_latex_element_list(out, elt->children);
1321
+ g_string_append_printf(out, "\n\\end{tabulary}\n\\end{minipage}\n\\end{table}\n");
1322
+ padded = 0;
1323
+ break;
1324
+ case TABLESEPARATOR:
1325
+ upper = strdup(elt->contents.str);
1326
+
1327
+ for(i = 0; upper[ i ]; i++)
1328
+ upper[i] = toupper(upper[ i ]);
1329
+
1330
+ g_string_append_printf(out, "\\begin{tabulary}{\\textwidth}{@{}%s@{}} \\toprule\n", upper);
1331
+ free(upper);
1332
+ break;
1333
+ case TABLECAPTION:
1334
+ if (elt->children->key == TABLELABEL) {
1335
+ label = label_from_element_list(elt->children->children,0);
1336
+ } else {
1337
+ label = label_from_element_list(elt->children,0);
1338
+ }
1339
+ g_string_append_printf(out, "\\caption{");
1340
+ print_latex_element_list(out, elt->children);
1341
+ g_string_append_printf(out, "}\n\\label{%s}\n",label);
1342
+ free(label);
1343
+ break;
1344
+ case TABLELABEL:
1345
+ break;
1346
+ case TABLEHEAD:
1347
+ print_latex_element_list(out, elt->children);
1348
+ g_string_append_printf(out, "\\midrule\n");
1349
+ break;
1350
+ case TABLEBODY:
1351
+ print_latex_element_list(out, elt->children);
1352
+ if ( ( elt->next != NULL ) && (elt->next->key == TABLEBODY) ) {
1353
+ g_string_append_printf(out, "\n\\midrule\n");
1354
+ } else {
1355
+ g_string_append_printf(out, "\n\\bottomrule\n");
1356
+ }
1357
+ break;
1358
+ case TABLEROW:
1359
+ print_latex_element_list(out, elt->children);
1360
+ g_string_append_printf(out, "\\\\\n");
1361
+ break;
1362
+ case TABLECELL:
1363
+ padded = 2;
1364
+ if ((elt->children != NULL) && (elt->children->key == CELLSPAN)) {
1365
+ g_string_append_printf(out, "\\multicolumn{%d}{c}{", (int)strlen(elt->children->contents.str)+1);
1366
+ }
1367
+ print_latex_element_list(out, elt->children);
1368
+ if ((elt->children != NULL) && (elt->children->key == CELLSPAN)) {
1369
+ g_string_append_printf(out, "}");
1370
+ }
1371
+ if (elt->next != NULL) {
1372
+ g_string_append_printf(out, "&");
1373
+ }
1374
+ break;
1375
+ case CELLSPAN:
1376
+ break;
1377
+ case ATTRKEY:
1378
+ g_string_append_printf(out, " %s=\"%s\"", elt->contents.str,
1379
+ elt->children->contents.str);
1380
+ break;
1381
+ case MATHSPAN:
1382
+ if (strncmp(&elt->contents.str[2],"\\begin",5) == 0) {
1383
+ elt->contents.str[strlen(elt->contents.str)-3] = '\0';
1384
+ g_string_append_printf(out, "%s",&elt->contents.str[2]);
1385
+ } else {
1386
+ if ( elt->contents.str[strlen(elt->contents.str)-1] == ']') {
1387
+ elt->contents.str[strlen(elt->contents.str)-3] = '\0';
1388
+ g_string_append_printf(out, "%s\\]", elt->contents.str);
1389
+ } else {
1390
+ elt->contents.str[strlen(elt->contents.str)-3] = '\0';
1391
+ g_string_append_printf(out, "$%s$", &elt->contents.str[2]);
1392
+ }
1393
+ }
1394
+ break;
1395
+ default:
1396
+ fprintf(stderr, "print_latex_element encountered unknown element key = %d\n", elt->key);
1397
+ exit(EXIT_FAILURE);
1398
+ }
1399
+ }
1400
+
1401
+ /**********************************************************************
1402
+
1403
+ Functions for printing Elements as groff (mm macros)
1404
+
1405
+ ***********************************************************************/
1406
+
1407
+ static bool in_list_item = false; /* True if we're parsing contents of a list item. */
1408
+
1409
+ /* print_groff_string - print string, escaping for groff */
1410
+ static void print_groff_string(GString *out, char *str) {
1411
+ while (*str != '\0') {
1412
+ switch (*str) {
1413
+ case '\\':
1414
+ g_string_append_printf(out, "\\e");
1415
+ break;
1416
+ default:
1417
+ g_string_append_c(out, *str);
1418
+ }
1419
+ str++;
1420
+ }
1421
+ }
1422
+
1423
+ /* print_groff_mm_element_list - print a list of elements as groff ms */
1424
+ static void print_groff_mm_element_list(GString *out, element *list) {
1425
+ int count = 1;
1426
+ while (list != NULL) {
1427
+ print_groff_mm_element(out, list, count);
1428
+ list = list->next;
1429
+ count++;
1430
+ }
1431
+ }
1432
+
1433
+ /* print_groff_mm_element - print an element as groff ms */
1434
+ static void print_groff_mm_element(GString *out, element *elt, int count) {
1435
+ int lev;
1436
+ switch (elt->key) {
1437
+ case SPACE:
1438
+ g_string_append_printf(out, "%s", elt->contents.str);
1439
+ padded = 0;
1440
+ break;
1441
+ case LINEBREAK:
1442
+ pad(out, 1);
1443
+ g_string_append_printf(out, ".br\n");
1444
+ padded = 0;
1445
+ break;
1446
+ case STR:
1447
+ print_groff_string(out, elt->contents.str);
1448
+ padded = 0;
1449
+ break;
1450
+ case ELLIPSIS:
1451
+ g_string_append_printf(out, "...");
1452
+ break;
1453
+ case EMDASH:
1454
+ g_string_append_printf(out, "\\[em]");
1455
+ break;
1456
+ case ENDASH:
1457
+ g_string_append_printf(out, "\\[en]");
1458
+ break;
1459
+ case APOSTROPHE:
1460
+ g_string_append_printf(out, "'");
1461
+ break;
1462
+ case SINGLEQUOTED:
1463
+ g_string_append_printf(out, "`");
1464
+ print_groff_mm_element_list(out, elt->children);
1465
+ g_string_append_printf(out, "'");
1466
+ break;
1467
+ case DOUBLEQUOTED:
1468
+ g_string_append_printf(out, "\\[lq]");
1469
+ print_groff_mm_element_list(out, elt->children);
1470
+ g_string_append_printf(out, "\\[rq]");
1471
+ break;
1472
+ case CODE:
1473
+ g_string_append_printf(out, "\\fC");
1474
+ print_groff_string(out, elt->contents.str);
1475
+ g_string_append_printf(out, "\\fR");
1476
+ padded = 0;
1477
+ break;
1478
+ case HTML:
1479
+ /* don't print HTML */
1480
+ break;
1481
+ case LINK:
1482
+ print_groff_mm_element_list(out, elt->contents.link->label);
1483
+ g_string_append_printf(out, " (%s)", elt->contents.link->url);
1484
+ padded = 0;
1485
+ break;
1486
+ case IMAGE:
1487
+ g_string_append_printf(out, "[IMAGE: ");
1488
+ print_groff_mm_element_list(out, elt->contents.link->label);
1489
+ g_string_append_printf(out, "]");
1490
+ padded = 0;
1491
+ /* not supported */
1492
+ break;
1493
+ case EMPH:
1494
+ g_string_append_printf(out, "\\fI");
1495
+ print_groff_mm_element_list(out, elt->children);
1496
+ g_string_append_printf(out, "\\fR");
1497
+ padded = 0;
1498
+ break;
1499
+ case STRONG:
1500
+ g_string_append_printf(out, "\\fB");
1501
+ print_groff_mm_element_list(out, elt->children);
1502
+ g_string_append_printf(out, "\\fR");
1503
+ padded = 0;
1504
+ break;
1505
+ case LIST:
1506
+ print_groff_mm_element_list(out, elt->children);
1507
+ padded = 0;
1508
+ break;
1509
+ case RAW:
1510
+ /* Shouldn't occur - these are handled by process_raw_blocks() */
1511
+ assert(elt->key != RAW);
1512
+ break;
1513
+ case H1: case H2: case H3: case H4: case H5: case H6:
1514
+ lev = elt->key - H1 + 1;
1515
+ pad(out, 1);
1516
+ g_string_append_printf(out, ".H %d \"", lev);
1517
+ print_groff_mm_element_list(out, elt->children);
1518
+ g_string_append_printf(out, "\"");
1519
+ padded = 0;
1520
+ break;
1521
+ case PLAIN:
1522
+ pad(out, 1);
1523
+ print_groff_mm_element_list(out, elt->children);
1524
+ padded = 0;
1525
+ break;
1526
+ case PARA:
1527
+ pad(out, 1);
1528
+ if (!in_list_item || count != 1)
1529
+ g_string_append_printf(out, ".P\n");
1530
+ print_groff_mm_element_list(out, elt->children);
1531
+ padded = 0;
1532
+ break;
1533
+ case HRULE:
1534
+ pad(out, 1);
1535
+ g_string_append_printf(out, "\\l'\\n(.lu*8u/10u'");
1536
+ padded = 0;
1537
+ break;
1538
+ case HTMLBLOCK:
1539
+ /* don't print HTML block */
1540
+ break;
1541
+ case VERBATIM:
1542
+ pad(out, 1);
1543
+ g_string_append_printf(out, ".VERBON 2\n");
1544
+ print_groff_string(out, elt->contents.str);
1545
+ g_string_append_printf(out, ".VERBOFF");
1546
+ padded = 0;
1547
+ break;
1548
+ case BULLETLIST:
1549
+ pad(out, 1);
1550
+ g_string_append_printf(out, ".BL");
1551
+ padded = 0;
1552
+ print_groff_mm_element_list(out, elt->children);
1553
+ pad(out, 1);
1554
+ g_string_append_printf(out, ".LE 1");
1555
+ padded = 0;
1556
+ break;
1557
+ case ORDEREDLIST:
1558
+ pad(out, 1);
1559
+ g_string_append_printf(out, ".AL");
1560
+ padded = 0;
1561
+ print_groff_mm_element_list(out, elt->children);
1562
+ pad(out, 1);
1563
+ g_string_append_printf(out, ".LE 1");
1564
+ padded = 0;
1565
+ break;
1566
+ case LISTITEM:
1567
+ pad(out, 1);
1568
+ g_string_append_printf(out, ".LI\n");
1569
+ in_list_item = true;
1570
+ padded = 2;
1571
+ print_groff_mm_element_list(out, elt->children);
1572
+ in_list_item = false;
1573
+ break;
1574
+ case BLOCKQUOTE:
1575
+ pad(out, 1);
1576
+ g_string_append_printf(out, ".DS I\n");
1577
+ padded = 2;
1578
+ print_groff_mm_element_list(out, elt->children);
1579
+ pad(out, 1);
1580
+ g_string_append_printf(out, ".DE");
1581
+ padded = 0;
1582
+ break;
1583
+ case NOTELABEL:
1584
+ /* Nonprinting */
1585
+ break;
1586
+ case NOTE:
1587
+ /* if contents.str == 0, then print note; else ignore, since this
1588
+ * is a note block that has been incorporated into the notes list */
1589
+ if (elt->contents.str == 0) {
1590
+ g_string_append_printf(out, "\\*F\n");
1591
+ g_string_append_printf(out, ".FS\n");
1592
+ padded = 2;
1593
+ print_groff_mm_element_list(out, elt->children);
1594
+ pad(out, 1);
1595
+ g_string_append_printf(out, ".FE\n");
1596
+ padded = 1;
1597
+ }
1598
+ break;
1599
+ case REFERENCE:
1600
+ /* Nonprinting */
1601
+ break;
1602
+ default:
1603
+ fprintf(stderr, "print_groff_mm_element encountered unknown element key = %d\n", elt->key);
1604
+ exit(EXIT_FAILURE);
1605
+ }
1606
+ }
1607
+
1608
+ /**********************************************************************
1609
+
1610
+ Functions for printing Elements as ODF
1611
+
1612
+ ***********************************************************************/
1613
+
1614
+ /* print_odf_code_string - print string, escaping for HTML and saving newlines
1615
+ */
1616
+ static void print_odf_code_string(GString *out, char *str) {
1617
+ char *tmp;
1618
+ while (*str != '\0') {
1619
+ switch (*str) {
1620
+ case '&':
1621
+ g_string_append_printf(out, "&amp;");
1622
+ break;
1623
+ case '<':
1624
+ g_string_append_printf(out, "&lt;");
1625
+ break;
1626
+ case '>':
1627
+ g_string_append_printf(out, "&gt;");
1628
+ break;
1629
+ case '"':
1630
+ g_string_append_printf(out, "&quot;");
1631
+ break;
1632
+ case '\n':
1633
+ g_string_append_printf(out, "<text:line-break/>");
1634
+ break;
1635
+ case ' ':
1636
+ tmp = str;
1637
+ tmp++;
1638
+ if (*tmp == ' ') {
1639
+ tmp++;
1640
+ if (*tmp == ' ') {
1641
+ tmp++;
1642
+ if (*tmp == ' ') {
1643
+ g_string_append_printf(out, "<text:tab/>");
1644
+ str = tmp;
1645
+ } else {
1646
+ g_string_append_printf(out, " ");
1647
+ }
1648
+ } else {
1649
+ g_string_append_printf(out, " ");
1650
+ }
1651
+ } else {
1652
+ g_string_append_printf(out, " ");
1653
+ }
1654
+ break;
1655
+ default:
1656
+ g_string_append_c(out, *str);
1657
+ }
1658
+ str++;
1659
+ }
1660
+ }
1661
+
1662
+ /* print_odf_string - print string, escaping for HTML and saving newlines */
1663
+ static void print_odf_string(GString *out, char *str) {
1664
+ char *tmp;
1665
+ while (*str != '\0') {
1666
+ switch (*str) {
1667
+ case '&':
1668
+ g_string_append_printf(out, "&amp;");
1669
+ break;
1670
+ case '<':
1671
+ g_string_append_printf(out, "&lt;");
1672
+ break;
1673
+ case '>':
1674
+ g_string_append_printf(out, "&gt;");
1675
+ break;
1676
+ case '"':
1677
+ g_string_append_printf(out, "&quot;");
1678
+ break;
1679
+ case '\n':
1680
+ tmp = str;
1681
+ tmp--;
1682
+ if (*tmp == ' ') {
1683
+ tmp--;
1684
+ if (*tmp == ' ') {
1685
+ g_string_append_printf(out, "<text:line-break/>");
1686
+ } else {
1687
+ g_string_append_printf(out, "\n");
1688
+ }
1689
+ } else {
1690
+ g_string_append_printf(out, "\n");
1691
+ }
1692
+ break;
1693
+ case ' ':
1694
+ tmp = str;
1695
+ tmp++;
1696
+ if (*tmp == ' ') {
1697
+ tmp++;
1698
+ if (*tmp == ' ') {
1699
+ tmp++;
1700
+ if (*tmp == ' ') {
1701
+ g_string_append_printf(out, "<text:tab/>");
1702
+ str = tmp;
1703
+ } else {
1704
+ g_string_append_printf(out, " ");
1705
+ }
1706
+ } else {
1707
+ g_string_append_printf(out, " ");
1708
+ }
1709
+ } else {
1710
+ g_string_append_printf(out, " ");
1711
+ }
1712
+ break;
1713
+ default:
1714
+ g_string_append_c(out, *str);
1715
+ }
1716
+ str++;
1717
+ }
1718
+ }
1719
+
1720
+ /* print_odf_element_list - print an element list as ODF */
1721
+ void print_odf_element_list(GString *out, element *list) {
1722
+ while (list != NULL) {
1723
+ print_odf_element(out, list);
1724
+ list = list->next;
1725
+ }
1726
+ }
1727
+
1728
+ /* print_odf_element - print an element as ODF */
1729
+ void print_odf_element(GString *out, element *elt) {
1730
+ int lev;
1731
+ char *label;
1732
+ char *height;
1733
+ char *width;
1734
+ /* element *locator = NULL; */
1735
+ int old_type = 0;
1736
+ switch (elt->key) {
1737
+ case SPACE:
1738
+ g_string_append_printf(out, "%s", elt->contents.str);
1739
+ break;
1740
+ case LINEBREAK:
1741
+ g_string_append_printf(out, "<text:line-break/>");
1742
+ break;
1743
+ case STR:
1744
+ print_html_string(out, elt->contents.str, 0);
1745
+ break;
1746
+ case ELLIPSIS:
1747
+ localize_typography(out, ELLIP, language, HTMLOUT);
1748
+ break;
1749
+ case EMDASH:
1750
+ localize_typography(out, MDASH, language, HTMLOUT);
1751
+ break;
1752
+ case ENDASH:
1753
+ localize_typography(out, NDASH, language, HTMLOUT);
1754
+ break;
1755
+ case APOSTROPHE:
1756
+ localize_typography(out, APOS, language, HTMLOUT);
1757
+ break;
1758
+ case SINGLEQUOTED:
1759
+ localize_typography(out, LSQUOTE, language, HTMLOUT);
1760
+ print_odf_element_list(out, elt->children);
1761
+ localize_typography(out, RSQUOTE, language, HTMLOUT);
1762
+ break;
1763
+ case DOUBLEQUOTED:
1764
+ localize_typography(out, LDQUOTE, language, HTMLOUT);
1765
+ print_odf_element_list(out, elt->children);
1766
+ localize_typography(out, RDQUOTE, language, HTMLOUT);
1767
+ break;
1768
+ case CODE:
1769
+ g_string_append_printf(out, "<text:span text:style-name=\"Source_20_Text\">");
1770
+ print_html_string(out, elt->contents.str, 0);
1771
+ g_string_append_printf(out, "</text:span>");
1772
+ break;
1773
+ case HTML:
1774
+ /* don't print HTML */
1775
+ /* but do print HTML comments for raw ODF */
1776
+ if (strncmp(elt->contents.str,"<!--",4) == 0) {
1777
+ /* trim "-->" from end */
1778
+ elt->contents.str[strlen(elt->contents.str)-3] = '\0';
1779
+ g_string_append_printf(out, "%s", &elt->contents.str[4]);
1780
+ }
1781
+ break;
1782
+ case LINK:
1783
+ if (elt->contents.link->url[0] == '#') {
1784
+ /* This is a cross-reference */
1785
+ label = label_from_string(elt->contents.link->url,0);
1786
+ if (elt->contents.link->label != NULL) {
1787
+ g_string_append_printf(out, "<text:a xlink:type=\"simple\" xlink:href=\"#%s\">",label);
1788
+ print_latex_element_list(out, elt->contents.link->label);
1789
+ g_string_append_printf(out,"</text:a>");
1790
+ } else {
1791
+
1792
+ }
1793
+ } else {
1794
+ g_string_append_printf(out, "<text:a xlink:type=\"simple\" xlink:href=\"");
1795
+ print_html_string(out, elt->contents.link->url, 0);
1796
+ g_string_append_printf(out, "\"");
1797
+ if (strlen(elt->contents.link->title) > 0) {
1798
+ g_string_append_printf(out, " office:name=\"");
1799
+ print_html_string(out, elt->contents.link->title, 0);
1800
+ g_string_append_printf(out, "\"");
1801
+ }
1802
+ /* print_html_element_list(out, elt->contents.link->attr, obfuscate);*/
1803
+ g_string_append_printf(out, ">");
1804
+ print_odf_element_list(out, elt->contents.link->label);
1805
+ g_string_append_printf(out, "</text:a>");
1806
+ }
1807
+ break;
1808
+ case IMAGEBLOCK:
1809
+ g_string_append_printf(out, "<text:p>\n");
1810
+ case IMAGE:
1811
+ height = dimension_for_attribute("height", elt->contents.link->attr);
1812
+ width = dimension_for_attribute("width", elt->contents.link->attr);
1813
+ g_string_append_printf(out, "<draw:frame text:anchor-type=\"as-char\"\ndraw:z-index=\"0\" draw:style-name=\"fr1\" ");
1814
+ /* need both attributes for image to be visible */
1815
+ if ((width != NULL)) {
1816
+ g_string_append_printf(out, "svg:width=\"%s\"\n", width);
1817
+ } else {
1818
+ g_string_append_printf(out, "svg:width=\"95%%\"\n");
1819
+ }
1820
+ g_string_append_printf(out, ">\n<draw:text-box><text:p><draw:frame text:anchor-type=\"as-char\" draw:z-index=\"1\" ");
1821
+ if ((height != NULL) && (width != NULL)) {
1822
+ g_string_append_printf(out, "svg:height=\"%s\"\n",height);
1823
+ g_string_append_printf(out, "svg:width=\"%s\"\n", width);
1824
+ }
1825
+ g_string_append_printf(out, "><draw:image xlink:href=\"");
1826
+ print_odf_string(out, elt->contents.link->url);
1827
+ g_string_append_printf(out,"\" xlink:type=\"simple\" xlink:show=\"embed\" xlink:actuate=\"onLoad\" draw:filter-name=\"&lt;All formats&gt;\"/>\n</draw:frame></text:p>");
1828
+ if (elt->key == IMAGEBLOCK) {
1829
+ g_string_append_printf(out, "<text:p>");
1830
+ if (elt->contents.link->label != NULL) {
1831
+ g_string_append_printf(out, "Figure <text:sequence text:name=\"Figure\" text:formula=\"ooow:Figure+1\" style:num-format=\"1\"> Update Fields to calculate numbers</text:sequence>: ");
1832
+ print_odf_element_list(out, elt->contents.link->label);
1833
+ }
1834
+ g_string_append_printf(out, "</text:p></draw:text-box></draw:frame>\n</text:p>\n");
1835
+ } else {
1836
+ g_string_append_printf(out, "</draw:text-box></draw:frame>\n");
1837
+ }
1838
+ break;
1839
+ case EMPH:
1840
+ g_string_append_printf(out,
1841
+ "<text:span text:style-name=\"MMD-Italic\">");
1842
+ print_odf_element_list(out, elt->children);
1843
+ g_string_append_printf(out, "</text:span>");
1844
+ break;
1845
+ case STRONG:
1846
+ g_string_append_printf(out,
1847
+ "<text:span text:style-name=\"MMD-Bold\">");
1848
+ print_odf_element_list(out, elt->children);
1849
+ g_string_append_printf(out, "</text:span>");
1850
+ break;
1851
+ case LIST:
1852
+ print_odf_element_list(out, elt->children);
1853
+ break;
1854
+ case RAW:
1855
+ /* Shouldn't occur - these are handled by process_raw_blocks() */
1856
+ assert(elt->key != RAW);
1857
+ break;
1858
+ case H1: case H2: case H3: case H4: case H5: case H6:
1859
+ lev = elt->key - H1 + base_header_level; /* assumes H1 ... H6 are in order */
1860
+ g_string_append_printf(out, "<text:h text:outline-level=\"%d\">", lev);
1861
+ if (elt->children->key == AUTOLABEL) {
1862
+ /* generate a label for each header (MMD)*/
1863
+ g_string_append_printf(out,"<text:bookmark text:name=\"%s\"/>", elt->children->contents.str);
1864
+ print_odf_element_list(out, elt->children->next);
1865
+ g_string_append_printf(out,"<text:bookmark-end text:name=\"%s\"/>", elt->children->contents.str);
1866
+ } else {
1867
+ label = label_from_element_list(elt->children, 0);
1868
+ g_string_append_printf(out,"<text:bookmark text:name=\"%s\"/>", label);
1869
+ print_odf_element_list(out, elt->children);
1870
+ g_string_append_printf(out,"<text:bookmark-end text:name=\"%s\"/>", label);
1871
+ free(label);
1872
+ }
1873
+ g_string_append_printf(out, "</text:h>\n");
1874
+ padded = 0;
1875
+ break;
1876
+ case PLAIN:
1877
+ print_odf_element_list(out, elt->children);
1878
+ padded = 0;
1879
+ break;
1880
+ case PARA:
1881
+ g_string_append_printf(out, "<text:p");
1882
+ switch (odf_type) {
1883
+ case DEFINITION:
1884
+ case BLOCKQUOTE:
1885
+ g_string_append_printf(out," text:style-name=\"Quotations\"");
1886
+ break;
1887
+ case CODE:
1888
+ g_string_append_printf(out," text:style-name=\"Preformatted Text\"");
1889
+ break;
1890
+ case VERBATIM:
1891
+ g_string_append_printf(out," text:style-name=\"Preformatted Text\"");
1892
+ break;
1893
+ case ORDEREDLIST:
1894
+ case BULLETLIST:
1895
+ g_string_append_printf(out," text:style-name=\"P2\"");
1896
+ break;
1897
+ case NOTE:
1898
+ g_string_append_printf(out," text:style-name=\"Footnote\"");
1899
+ break;
1900
+ default:
1901
+ g_string_append_printf(out," text:style-name=\"Standard\"");
1902
+ break;
1903
+ }
1904
+ g_string_append_printf(out, ">");
1905
+ print_odf_element_list(out, elt->children);
1906
+ g_string_append_printf(out, "</text:p>\n");
1907
+ break;
1908
+ case HRULE:
1909
+ g_string_append_printf(out,"<text:p text:style-name=\"Horizontal_20_Line\"/>\n");
1910
+ break;
1911
+ case HTMLBLOCK:
1912
+ /* don't print HTML block */
1913
+ /* but do print HTML comments for raw ODF */
1914
+ if (strncmp(elt->contents.str,"<!--",4) == 0) {
1915
+ /* trim "-->" from end */
1916
+ elt->contents.str[strlen(elt->contents.str)-3] = '\0';
1917
+ g_string_append_printf(out, "<text:p text:style-name=\"Standard\">%s</text:p>", &elt->contents.str[4]);
1918
+ }
1919
+ break;
1920
+ case VERBATIM:
1921
+ old_type = odf_type;
1922
+ odf_type = VERBATIM;
1923
+ g_string_append_printf(out, "<text:p text:style-name=\"Preformatted Text\">");
1924
+ print_odf_code_string(out, elt->contents.str);
1925
+ g_string_append_printf(out, "</text:p>\n");
1926
+ odf_type = old_type;
1927
+ break;
1928
+ case BULLETLIST:
1929
+ if ((odf_type == BULLETLIST) ||
1930
+ (odf_type == ORDEREDLIST)) {
1931
+ /* I think this was made unnecessary by another change.
1932
+ Same for ORDEREDLIST below */
1933
+ /* g_string_append_printf(out, "</text:p>"); */
1934
+ }
1935
+ old_type = odf_type;
1936
+ odf_type = BULLETLIST;
1937
+ if (odf_list_needs_end_p) {
1938
+ g_string_append_printf(out, "%s", "</text:p>");
1939
+ odf_list_needs_end_p = 0;
1940
+ }
1941
+ g_string_append_printf(out, "%s", "<text:list>");
1942
+ print_odf_element_list(out, elt->children);
1943
+ g_string_append_printf(out, "%s", "</text:list>");
1944
+ odf_type = old_type;
1945
+ break;
1946
+ case ORDEREDLIST:
1947
+ if ((odf_type == BULLETLIST) ||
1948
+ (odf_type == ORDEREDLIST)) {
1949
+ /* g_string_append_printf(out, "</text:p>"); */
1950
+ }
1951
+ old_type = odf_type;
1952
+ odf_type = ORDEREDLIST;
1953
+ if (odf_list_needs_end_p) {
1954
+ g_string_append_printf(out, "%s", "</text:p>");
1955
+ odf_list_needs_end_p = 0;
1956
+ }
1957
+ g_string_append_printf(out, "%s", "<text:list>\n");
1958
+ print_odf_element_list(out, elt->children);
1959
+ g_string_append_printf(out, "%s", "</text:list>\n");
1960
+ odf_type = old_type;
1961
+ break;
1962
+ case LISTITEM:
1963
+ g_string_append_printf(out, "<text:list-item>\n");
1964
+ if (elt->children->children->key != PARA) {
1965
+ g_string_append_printf(out, "<text:p text:style-name=\"P2\">");
1966
+ odf_list_needs_end_p = 1;
1967
+ }
1968
+ print_odf_element_list(out, elt->children);
1969
+
1970
+ odf_list_needs_end_p = 0;
1971
+ if ((list_contains_key(elt->children,BULLETLIST) ||
1972
+ (list_contains_key(elt->children,ORDEREDLIST)))) {
1973
+ } else {
1974
+ if (elt->children->children->key != PARA) {
1975
+ g_string_append_printf(out, "</text:p>");
1976
+ }
1977
+ }
1978
+ g_string_append_printf(out, "</text:list-item>\n");
1979
+ break;
1980
+ case BLOCKQUOTE:
1981
+ old_type = odf_type;
1982
+ odf_type = BLOCKQUOTE;
1983
+ print_odf_element_list(out, elt->children);
1984
+ odf_type = old_type;
1985
+ break;
1986
+ case REFERENCE:
1987
+ break;
1988
+ case NOTELABEL:
1989
+ break;
1990
+ case NOTE:
1991
+ old_type = odf_type;
1992
+ odf_type = NOTE;
1993
+ /* if contents.str == 0 then print; else ignore - like above */
1994
+ if (elt->contents.str == 0) {
1995
+ if (elt->children->key == GLOSSARYTERM) {
1996
+ g_string_append_printf(out, "<text:note text:id=\"\" text:note-class=\"glossary\"><text:note-body>\n");
1997
+ print_odf_element_list(out, elt->children);
1998
+ g_string_append_printf(out, "</text:note-body>\n</text:note>\n");
1999
+ } else {
2000
+ g_string_append_printf(out, "<text:note text:id=\"\" text:note-class=\"footnote\"><text:note-body>\n");
2001
+ print_odf_element_list(out, elt->children);
2002
+ g_string_append_printf(out, "</text:note-body>\n</text:note>\n");
2003
+ }
2004
+ }
2005
+ elt->children = NULL;
2006
+ odf_type = old_type;
2007
+ break;
2008
+ case GLOSSARY:
2009
+ break;
2010
+ case GLOSSARYTERM:
2011
+ g_string_append_printf(out, "<text:p text:style-name=\"Glossary\">");
2012
+ print_odf_string(out, elt->children->contents.str);
2013
+ g_string_append_printf(out, ":");
2014
+ g_string_append_printf(out, "</text:p>");
2015
+ break;
2016
+ case GLOSSARYSORTKEY:
2017
+ break;
2018
+ case NOCITATION:
2019
+ case CITATION:
2020
+ /* Get locator, if present */
2021
+ /* locator = locator_for_citation(elt); */
2022
+
2023
+ if (strncmp(elt->contents.str,"[#",2) == 0) {
2024
+ /* reference specified externally, so just display it */
2025
+ g_string_append_printf(out, "%s", elt->contents.str);
2026
+ } else {
2027
+ /* reference specified within the MMD document,
2028
+ so will output as footnote */
2029
+ if (elt->children->contents.str == NULL) {
2030
+ /* First use of this citation */
2031
+ ++notenumber;
2032
+ char buf[5];
2033
+ sprintf(buf, "%d",notenumber);
2034
+ /* Store the number for future reference */
2035
+ elt->children->contents.str = strdup(buf);
2036
+
2037
+ /* Insert the footnote here */
2038
+ old_type = odf_type;
2039
+ odf_type = NOTE;
2040
+ g_string_append_printf(out, "<text:note text:id=\"cite%s\" text:note-class=\"footnote\"><text:note-body>\n", buf);
2041
+ print_odf_element_list(out, elt->children);
2042
+ g_string_append_printf(out, "</text:note-body>\n</text:note>\n");
2043
+ odf_type = old_type;
2044
+
2045
+ elt->children->key = CITATION;
2046
+ } else {
2047
+ /* Additional reference to prior citation,
2048
+ and therefore must link to another footnote */
2049
+ g_string_append_printf(out, "<text:span text:style-name=\"Footnote_20_anchor\"><text:note-ref text:note-class=\"footnote\" text:reference-format=\"text\" text:ref-name=\"cite%s\">%s</text:note-ref></text:span>", elt->children->contents.str, elt->children->contents.str);
2050
+ }
2051
+ elt->children = NULL;
2052
+ }
2053
+ break;
2054
+ case LOCATOR:
2055
+ print_odf_element_list(out, elt->children);
2056
+ break;
2057
+ case DEFLIST:
2058
+ print_odf_element_list(out, elt->children);
2059
+ break;
2060
+ case TERM:
2061
+ g_string_append_printf(out, "<text:p><text:span text:style-name=\"MMD-Bold\">");
2062
+ print_odf_element_list(out, elt->children);
2063
+ g_string_append_printf(out, "</text:span></text:p>");
2064
+ break;
2065
+ case DEFINITION:
2066
+ old_type = odf_type;
2067
+ odf_type = DEFINITION;
2068
+ g_string_append_printf(out, "<text:p text:style-name=\"Quotations\">");
2069
+ print_odf_element_list(out, elt->children);
2070
+ g_string_append_printf(out, "</text:p>");
2071
+ odf_type = old_type;
2072
+ break;
2073
+ case METADATA:
2074
+ g_string_append_printf(out, "<office:meta>\n");
2075
+ print_odf_element_list(out, elt->children);
2076
+ g_string_append_printf(out, "</office:meta>\n");
2077
+ element *header;
2078
+ header = metadata_for_key("odfheader",elt);
2079
+ if (header != NULL) {
2080
+ print_raw_element(out,header->children);
2081
+ }
2082
+ break;
2083
+ case METAKEY:
2084
+ if (strcmp(elt->contents.str, "title") == 0) {
2085
+ g_string_append_printf(out, "<dc:title>");
2086
+ print_odf_element(out, elt->children);
2087
+ g_string_append_printf(out,"</dc:title>\n");
2088
+ } else if (strcmp(elt->contents.str, "css") == 0) {
2089
+ } else if (strcmp(elt->contents.str, "baseheaderlevel") == 0) {
2090
+ base_header_level = atoi(elt->children->contents.str);
2091
+ } else if (strcmp(elt->contents.str, "odfheaderlevel") == 0) {
2092
+ base_header_level = atoi(elt->children->contents.str);
2093
+ } else if (strcmp(elt->contents.str, "xhtmlheader") == 0) {
2094
+ } else if (strcmp(elt->contents.str, "htmlheader") == 0) {
2095
+ } else if (strcmp(elt->contents.str, "odfheader") == 0) {
2096
+ } else if (strcmp(elt->contents.str, "latexfooter") == 0) {
2097
+ } else if (strcmp(elt->contents.str, "latexinput") == 0) {
2098
+ } else if (strcmp(elt->contents.str, "latexmode") == 0) {
2099
+ } else if (strcmp(elt->contents.str, "keywords") == 0) {
2100
+ g_string_append_printf(out, "<meta:keyword>");
2101
+ print_odf_element(out,elt->children);
2102
+ g_string_append_printf(out, "</meta:keyword>\n");
2103
+ } else if (strcmp(elt->contents.str, "quoteslanguage") == 0) {
2104
+ label = label_from_element_list(elt->children, 0);
2105
+ if (strcmp(label, "dutch") == 0) { language = DUTCH; } else
2106
+ if (strcmp(label, "german") == 0) { language = GERMAN; } else
2107
+ if (strcmp(label, "germanguillemets") == 0) { language = GERMANGUILL; } else
2108
+ if (strcmp(label, "french") == 0) { language = FRENCH; } else
2109
+ if (strcmp(label, "swedish") == 0) { language = SWEDISH; }
2110
+ free(label);
2111
+ } else {
2112
+ g_string_append_printf(out, "<meta:user-defined meta:name=\"");
2113
+ print_odf_string(out,elt->contents.str);
2114
+ g_string_append_printf(out, "\">");
2115
+ print_odf_element(out, elt->children);
2116
+ g_string_append_printf(out,"</meta:user-defined>\n");
2117
+ }
2118
+ break;
2119
+ case METAVALUE:
2120
+ print_odf_string(out, elt->contents.str);
2121
+ break;
2122
+ case FOOTER:
2123
+ break;
2124
+ case HEADINGSECTION:
2125
+ print_odf_element_list(out, elt->children);
2126
+ break;
2127
+ case TABLE:
2128
+ g_string_append_printf(out,"\n<table:table>\n");
2129
+ print_odf_element_list(out, elt->children);
2130
+ g_string_append_printf(out, "</table:table>");
2131
+ /* print caption if present */
2132
+ if (elt->children->key == TABLECAPTION) {
2133
+ if (elt->children->children->key == TABLELABEL) {
2134
+ label = label_from_element_list(elt->children->children->children,0);
2135
+ } else {
2136
+ label = label_from_element_list(elt->children->children,0);
2137
+ }
2138
+ g_string_append_printf(out,"<text:p><text:bookmark text:name=\"%s\"/>Table <text:sequence text:name=\"Table\" text:formula=\"ooow:Table+1\" style:num-format=\"1\"> Update Fields to calculate numbers</text:sequence>:", label);
2139
+ print_odf_element_list(out,elt->children->children);
2140
+ g_string_append_printf(out, "<text:bookmark-end text:name=\"%s\"/></text:p>\n",label);
2141
+ free(label);
2142
+ }
2143
+ break;
2144
+ case TABLESEPARATOR:
2145
+ table_alignment = elt->contents.str;
2146
+ break;
2147
+ case TABLECAPTION:
2148
+ break;
2149
+ case TABLELABEL:
2150
+ break;
2151
+ case TABLEHEAD:
2152
+ for (table_column=0;table_column<strlen(table_alignment);table_column++) {
2153
+ g_string_append_printf(out, "<table:table-column/>\n");
2154
+ }
2155
+ cell_type = 'h';
2156
+ print_odf_element_list(out, elt->children);
2157
+ cell_type = 'd';
2158
+ break;
2159
+ case TABLEBODY:
2160
+ print_odf_element_list(out,elt->children);
2161
+ break;
2162
+ case TABLEROW:
2163
+ g_string_append_printf(out, "<table:table-row>\n");
2164
+ table_column = 0;
2165
+ print_odf_element_list(out,elt->children);
2166
+ g_string_append_printf(out,"</table:table-row>\n");
2167
+ break;
2168
+ case TABLECELL:
2169
+ g_string_append_printf(out, "<table:table-cell");
2170
+ if ((elt->children != NULL) && (elt->children->key == CELLSPAN)) {
2171
+ g_string_append_printf(out, " table:number-columns-spanned=\"%d\"",(int)strlen(elt->children->contents.str)+1);
2172
+ }
2173
+ g_string_append_printf(out,">\n<text:p");
2174
+ if (cell_type == 'h') {
2175
+ g_string_append_printf(out, " text:style-name=\"Table_20_Heading\"");
2176
+ } else {
2177
+ if ( strncmp(&table_alignment[table_column],"r",1) == 0) {
2178
+ g_string_append_printf(out, " text:style-name=\"MMD-Table-Right\"");
2179
+ } else if ( strncmp(&table_alignment[table_column],"R",1) == 0) {
2180
+ g_string_append_printf(out, " text:style-name=\"MMD-Table-Right\"");
2181
+ } else if ( strncmp(&table_alignment[table_column],"c",1) == 0) {
2182
+ g_string_append_printf(out, " text:style-name=\"MMD-Table-Center\"");
2183
+ } else if ( strncmp(&table_alignment[table_column],"C",1) == 0) {
2184
+ g_string_append_printf(out, " text:style-name=\"MMD-Table-Center\"");
2185
+ } else {
2186
+ g_string_append_printf(out, " text:style-name=\"MMD-Table\"");
2187
+ }
2188
+ }
2189
+ g_string_append_printf(out, ">");
2190
+ print_odf_element_list(out,elt->children);
2191
+ g_string_append_printf(out, "</text:p>\n</table:table-cell>\n");
2192
+ table_column++;
2193
+ break;
2194
+ case CELLSPAN:
2195
+ break;
2196
+ case MATHSPAN:
2197
+ if ( elt->contents.str[strlen(elt->contents.str)-1] == ']') {
2198
+ elt->contents.str[strlen(elt->contents.str)-3] = '\0';
2199
+ g_string_append_printf(out, "<text:span text:style-name=\"math\">%s\\]</text:span>", elt->contents.str);
2200
+ } else {
2201
+ elt->contents.str[strlen(elt->contents.str)-3] = '\0';
2202
+ g_string_append_printf(out, "<text:span text:style-name=\"math\">%s\\)</text:span>", elt->contents.str);
2203
+ }
2204
+ break; default:
2205
+ fprintf(stderr, "print_html_element encountered unknown element key = %d\n", elt->key);
2206
+ exit(EXIT_FAILURE);
2207
+ }
2208
+ }
2209
+
2210
+ /**********************************************************************
2211
+
2212
+ Parameterized function for printing an Element.
2213
+
2214
+ ***********************************************************************/
2215
+
2216
+ void print_element_list(GString *out, element *elt, int format, int exts) {
2217
+ /* Initialize globals */
2218
+ endnotes = NULL;
2219
+ notenumber = 0;
2220
+
2221
+ /* And MultiMarkdown globals */
2222
+ base_header_level = 1;
2223
+ language = ENGLISH;
2224
+ html_footer = FALSE;
2225
+ no_latex_footnote = FALSE;
2226
+ footnote_counter_to_print = 0;
2227
+ odf_list_needs_end_p = 0;
2228
+ element *title;
2229
+
2230
+ extensions = exts;
2231
+ padded = 2; /* set padding to 2, so no extra blank lines at beginning */
2232
+
2233
+ format = find_latex_mode(format, elt);
2234
+ switch (format) {
2235
+ case HTML_FORMAT:
2236
+ print_html_element_list(out, elt, false);
2237
+ if (endnotes != NULL) {
2238
+ pad(out, 2);
2239
+ print_html_endnotes(out);
2240
+ }
2241
+ if (html_footer == TRUE) print_html_footer(out, false);
2242
+ break;
2243
+ case LATEX_FORMAT:
2244
+ print_latex_element_list(out, elt);
2245
+ break;
2246
+ case MEMOIR_FORMAT:
2247
+ print_memoir_element_list(out, elt);
2248
+ break;
2249
+ case BEAMER_FORMAT:
2250
+ print_beamer_element_list(out, elt);
2251
+ break;
2252
+ case OPML_FORMAT:
2253
+ g_string_append_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<opml version=\"1.0\">\n");
2254
+ if (list_contains_key(elt,METAKEY)) {
2255
+ title = metadata_for_key("title",elt);
2256
+ if (title != NULL) {
2257
+ g_string_append_printf(out,"<head><title>");
2258
+ print_raw_element(out,title->children);
2259
+ g_string_append_printf(out,"</title></head>");
2260
+ }
2261
+ }
2262
+ g_string_append_printf(out, "<body>\n");
2263
+ print_opml_element_list(out, elt);
2264
+ if (html_footer == TRUE) print_opml_metadata(out, elt);
2265
+ g_string_append_printf(out, "</body>\n</opml>");
2266
+ break;
2267
+ case ODF_FORMAT:
2268
+ print_odf_header(out);
2269
+ if (elt->key == METADATA) {
2270
+ /* print metadata */
2271
+ print_odf_element(out,elt);
2272
+ elt = elt->next;
2273
+ }
2274
+ g_string_append_printf(out, "<office:body>\n<office:text>\n");
2275
+ if (elt != NULL) print_odf_element_list(out,elt);
2276
+ print_odf_footer(out);
2277
+ break;
2278
+ case ODF_BODY_FORMAT:
2279
+ if (elt != NULL) print_odf_body_element_list(out, elt);
2280
+ break;
2281
+ case GROFF_MM_FORMAT:
2282
+ print_groff_mm_element_list(out, elt);
2283
+ break;
2284
+ default:
2285
+ fprintf(stderr, "print_element - unknown format = %d\n", format);
2286
+ exit(EXIT_FAILURE);
2287
+ }
2288
+ }
2289
+
2290
+
2291
+ /**********************************************************************
2292
+
2293
+ MultiMarkdown Routines - Used for generating "complete" documents
2294
+
2295
+ ***********************************************************************/
2296
+
2297
+
2298
+ void print_html_header(GString *out, element *elt, bool obfuscate) {
2299
+ g_string_append_printf(out,
2300
+ "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\"/>\n");
2301
+
2302
+ print_html_element_list(out, elt->children, obfuscate);
2303
+ g_string_append_printf(out, "</head>\n<body>\n\n");
2304
+ }
2305
+
2306
+
2307
+ void print_html_footer(GString *out, bool obfuscate) {
2308
+ g_string_append_printf(out, "\n\n</body>\n</html>");
2309
+ }
2310
+
2311
+
2312
+ void print_latex_header(GString *out, element *elt) {
2313
+ print_latex_element_list(out, elt->children);
2314
+ }
2315
+
2316
+
2317
+ void print_latex_footer(GString *out) {
2318
+ if (latex_footer != NULL) {
2319
+ pad(out,2);
2320
+ g_string_append_printf(out, "\\input{%s}\n", latex_footer);
2321
+ }
2322
+ if (html_footer) {
2323
+ g_string_append_printf(out, "\n\\end{document}");
2324
+ }
2325
+ }
2326
+
2327
+
2328
+ /* print_memoir_element_list - print an element as LaTeX for memoir class */
2329
+ void print_memoir_element_list(GString *out, element *list) {
2330
+ while (list != NULL) {
2331
+ print_memoir_element(out, list);
2332
+ list = list->next;
2333
+ }
2334
+ }
2335
+
2336
+
2337
+ /* print_memoir_element - print an element as LaTeX for memoir class */
2338
+ static void print_memoir_element(GString *out, element *elt) {
2339
+ switch (elt->key) {
2340
+ case VERBATIM:
2341
+ pad(out, 1);
2342
+ g_string_append_printf(out, "\n\\begin{adjustwidth}{2.5em}{2.5em}\n\\begin{verbatim}\n\n");
2343
+ print_raw_element(out, elt);
2344
+ g_string_append_printf(out, "\n\\end{verbatim}\n\\end{adjustwidth}");
2345
+ padded = 0;
2346
+ break;
2347
+ case HEADINGSECTION:
2348
+ print_memoir_element_list(out, elt->children);
2349
+ break;
2350
+ case DEFLIST:
2351
+ g_string_append_printf(out, "\\begin{description}");
2352
+ padded = 0;
2353
+ print_memoir_element_list(out, elt->children);
2354
+ pad(out,1);
2355
+ g_string_append_printf(out, "\\end{description}");
2356
+ padded = 0;
2357
+ break;
2358
+ case DEFINITION:
2359
+ pad(out,2);
2360
+ padded = 2;
2361
+ print_memoir_element_list(out, elt->children);
2362
+ padded = 0;
2363
+ break;
2364
+ default:
2365
+ /* most things are not changed for memoir output */
2366
+ print_latex_element(out, elt);
2367
+ }
2368
+ }
2369
+
2370
+
2371
+ /* print_beamer_element_list - print an element as LaTeX for beamer class */
2372
+ void print_beamer_element_list(GString *out, element *list) {
2373
+ while (list != NULL) {
2374
+ print_beamer_element(out, list);
2375
+ list = list->next;
2376
+ }
2377
+ }
2378
+
2379
+ static void print_beamer_endnotes(GString *out) {
2380
+ GSList *note;
2381
+ element *note_elt;
2382
+ if (endnotes == NULL)
2383
+ return;
2384
+ note = g_slist_reverse(endnotes);
2385
+ pad(out,2);
2386
+ g_string_append_printf(out, "\\part{Bibliography}\n\\begin{frame}[allowframebreaks]\n\\frametitle{Bibliography}\n\\def\\newblock{}\n\\begin{thebibliography}{0}\n");
2387
+ while (note != NULL) {
2388
+ note_elt = note->data;
2389
+ pad(out, 1);
2390
+ g_string_append_printf(out, "\\bibitem{%s}\n", note_elt->contents.str);
2391
+ padded=2;
2392
+ print_latex_element_list(out, note_elt);
2393
+ pad(out, 1);
2394
+ note = note->next;
2395
+ }
2396
+ pad(out, 1);
2397
+ g_string_append_printf(out, "\\end{thebibliography}\n\\end{frame}\n\n");
2398
+ padded = 2;
2399
+ g_slist_free(endnotes);
2400
+ }
2401
+
2402
+ /* print_beamer_element - print an element as LaTeX for beamer class */
2403
+ static void print_beamer_element(GString *out, element *elt) {
2404
+ int lev;
2405
+ char *label;
2406
+ switch (elt->key) {
2407
+ case FOOTER:
2408
+ print_beamer_endnotes(out);
2409
+ g_string_append_printf(out, "\\mode<all>\n");
2410
+ print_latex_footer(out);
2411
+ g_string_append_printf(out, "\\mode*\n");
2412
+ break;
2413
+ case LISTITEM:
2414
+ pad(out, 1);
2415
+ g_string_append_printf(out, "\\item<+-> ");
2416
+ padded = 2;
2417
+ print_latex_element_list(out, elt->children);
2418
+ g_string_append_printf(out, "\n");
2419
+ break;
2420
+ case HEADINGSECTION:
2421
+ if (elt->children->key -H1 + base_header_level == 3) {
2422
+ pad(out,2);
2423
+ g_string_append_printf(out, "\\begin{frame}");
2424
+ if (list_contains_key(elt->children,VERBATIM)) {
2425
+ g_string_append_printf(out, "[fragile]");
2426
+ }
2427
+ padded = 0;
2428
+ print_beamer_element_list(out, elt->children);
2429
+ g_string_append_printf(out, "\n\n\\end{frame}\n\n");
2430
+ padded = 2;
2431
+ } else if (elt->children->key -H1 + base_header_level == 4) {
2432
+ pad(out, 1);
2433
+ g_string_append_printf(out, "\\mode<article>{\n");
2434
+ padded = 0;
2435
+ print_beamer_element_list(out, elt->children->next);
2436
+ g_string_append_printf(out, "\n\n}\n\n");
2437
+ padded = 2;
2438
+ } else {
2439
+ print_beamer_element_list(out, elt->children);
2440
+ }
2441
+ break;
2442
+ case H1: case H2: case H3: case H4: case H5: case H6:
2443
+ pad(out, 2);
2444
+ lev = elt->key - H1 + base_header_level; /* assumes H1 ... H6 are in order */
2445
+ switch (lev) {
2446
+ case 1:
2447
+ g_string_append_printf(out, "\\part{");
2448
+ break;
2449
+ case 2:
2450
+ g_string_append_printf(out, "\\section{");
2451
+ break;
2452
+ case 3:
2453
+ g_string_append_printf(out, "\\frametitle{");
2454
+ break;
2455
+ default:
2456
+ g_string_append_printf(out, "\\emph{");
2457
+ break;
2458
+ }
2459
+ /* generate a label for each header (MMD);
2460
+ don't allow footnotes since invalid here */
2461
+ no_latex_footnote = TRUE;
2462
+ if (elt->children->key == AUTOLABEL) {
2463
+ label = label_from_string(elt->children->contents.str,0);
2464
+ print_latex_element_list(out, elt->children->next);
2465
+ } else {
2466
+ label = label_from_element_list(elt->children,0);
2467
+ print_latex_element_list(out, elt->children);
2468
+ }
2469
+ no_latex_footnote = FALSE;
2470
+ g_string_append_printf(out, "}\n\\label{");
2471
+ g_string_append_printf(out, "%s", label);
2472
+ g_string_append_printf(out, "}\n");
2473
+ free(label);
2474
+ padded = 1;
2475
+ break;
2476
+ default:
2477
+ print_latex_element(out, elt);
2478
+ }
2479
+ }
2480
+
2481
+
2482
+ element * print_html_headingsection(GString *out, element *list, bool obfuscate) {
2483
+ element *base = list;
2484
+ print_html_element_list(out, list->children, obfuscate);
2485
+
2486
+ list = list->next;
2487
+ while ( (list != NULL) && (list->key == HEADINGSECTION) && (list->children->key > base->children->key) && (list->children->key <= H6)) {
2488
+ list = print_html_headingsection(out, list, obfuscate);
2489
+ }
2490
+
2491
+ return list;
2492
+ }
2493
+
2494
+ /* look for "LaTeX Mode" metadata and change format to match */
2495
+ static int find_latex_mode(int format, element *list) {
2496
+ element *latex_mode;
2497
+ char *label;
2498
+
2499
+ if (format != LATEX_FORMAT) return format;
2500
+
2501
+ if (list_contains_key(list,METAKEY)) {
2502
+ latex_mode = metadata_for_key("latexmode", list);
2503
+ if ( latex_mode != NULL) {
2504
+ label = label_from_element_list(latex_mode->children, 0);
2505
+ if (strcmp(label, "beamer") == 0) { format = BEAMER_FORMAT; } else
2506
+ if (strcmp(label, "memoir") == 0) { format = MEMOIR_FORMAT; }
2507
+ free(label);
2508
+ }
2509
+ return format;
2510
+ } else {
2511
+ return format;
2512
+ }
2513
+ }
2514
+
2515
+
2516
+ /* find specified metadata key, if present */
2517
+ element * metadata_for_key(char *key, element *list) {
2518
+ element *step = NULL;
2519
+ step = list;
2520
+ char *label;
2521
+
2522
+ label = label_from_string(key,0);
2523
+
2524
+ while (step != NULL) {
2525
+ if (step->key == METADATA) {
2526
+ /* search METAKEY children */
2527
+ step = step->children;
2528
+ while ( step != NULL) {
2529
+ if (strcmp(step->contents.str, label) == 0) {
2530
+ free(label);
2531
+ return step;
2532
+ }
2533
+ step = step->next;
2534
+ }
2535
+ free(label);
2536
+ return NULL;
2537
+ }
2538
+ step = step->next;
2539
+ }
2540
+ free(label);
2541
+ return NULL;
2542
+ }
2543
+
2544
+
2545
+ /* find specified metadata key, if present */
2546
+ char * metavalue_for_key(char *key, element *list) {
2547
+ element *step = NULL;
2548
+ step = list;
2549
+ char *label;
2550
+ char *result;
2551
+
2552
+ label = label_from_string(key,0);
2553
+
2554
+ while (step != NULL) {
2555
+ if (step->key == METADATA) {
2556
+ /* search METAKEY children */
2557
+ step = step->children;
2558
+ while ( step != NULL) {
2559
+ if (strcmp(step->contents.str, label) == 0) {
2560
+ /* Found a match */
2561
+ if ((strcmp(label,"latexmode") == 0) ||
2562
+ (strcmp(label,"quoteslanguage") == 0)) {
2563
+ result = label_from_string(step->children->contents.str,0);
2564
+ } else {
2565
+ result = strdup(step->children->contents.str);
2566
+ }
2567
+ free(label);
2568
+ return result;
2569
+ }
2570
+ step = step->next;
2571
+ }
2572
+ free(label);
2573
+ return NULL;
2574
+ }
2575
+ step = step->next;
2576
+ }
2577
+ free(label);
2578
+ return NULL;
2579
+ }
2580
+
2581
+ /* find attribute, if present */
2582
+ element * element_for_attribute(char *querystring, element *list) {
2583
+ element *step = NULL;
2584
+ step = list;
2585
+ char *query;
2586
+ query = label_from_string(querystring,0);
2587
+
2588
+ while (step != NULL) {
2589
+ if (strcmp(step->contents.str,query) == 0) {
2590
+ free(query);
2591
+ return step;
2592
+ }
2593
+ step = step->next;
2594
+ }
2595
+ free(query);
2596
+ return NULL;
2597
+ }
2598
+
2599
+ /* convert attribute to dimensions suitable for LaTeX or ODF */
2600
+ /* returns c string that needs to be freed */
2601
+
2602
+ char * dimension_for_attribute(char *querystring, element *list) {
2603
+ element *attribute;
2604
+ char *dimension;
2605
+ char *ptr;
2606
+ int i;
2607
+ char *upper;
2608
+ GString *result;
2609
+
2610
+ attribute = element_for_attribute(querystring, list);
2611
+ if (attribute == NULL) return NULL;
2612
+
2613
+ dimension = strdup(attribute->children->contents.str);
2614
+ upper = strdup(attribute->children->contents.str);
2615
+
2616
+ for(i = 0; dimension[ i ]; i++)
2617
+ dimension[i] = tolower(dimension[ i ]);
2618
+
2619
+ for(i = 0; upper[ i ]; i++)
2620
+ upper[i] = toupper(upper[ i ]);
2621
+
2622
+ if (strstr(dimension, "px")) {
2623
+ ptr = strstr(dimension,"px");
2624
+ ptr[0] = '\0';
2625
+ strcat(ptr,"pt");
2626
+ }
2627
+
2628
+ result = g_string_new(dimension);
2629
+
2630
+ if ((strcmp(dimension,upper) == 0) && (dimension[strlen(dimension) -1] != '%')) {
2631
+ /* no units */
2632
+ g_string_append_printf(result, "pt");
2633
+ }
2634
+
2635
+ free(upper);
2636
+ free(dimension);
2637
+
2638
+ dimension = result->str;
2639
+ g_string_free(result, false);
2640
+ return(dimension);
2641
+ }
2642
+
2643
+ /* Check metadata keys and determine if I need a complete document */
2644
+ static bool is_html_complete_doc(element *meta) {
2645
+ element *step;
2646
+ step = meta->children;
2647
+
2648
+ while (step != NULL) {
2649
+ if ((strcmp(step->contents.str, "baseheaderlevel") != 0) &&
2650
+ (strcmp(step->contents.str, "xhtmlheaderlevel") != 0) &&
2651
+ (strcmp(step->contents.str, "htmlheaderlevel") != 0) &&
2652
+ (strcmp(step->contents.str, "latexheaderlevel") != 0) &&
2653
+ (strcmp(step->contents.str, "odfheaderlevel") != 0) &&
2654
+ (strcmp(step->contents.str, "quoteslanguage") != 0))
2655
+ {
2656
+ return TRUE;
2657
+ }
2658
+ step = step->next;
2659
+ }
2660
+
2661
+ return FALSE;
2662
+ }
2663
+
2664
+ /* if citation has a locator, return as element and "prune", else NULL */
2665
+ element * locator_for_citation(element *elt) {
2666
+ element *result;
2667
+
2668
+ if ((elt->children != NULL) && (elt->children->key == LOCATOR)) {
2669
+ /* Locator is present */
2670
+ result = elt->children;
2671
+ elt->children = elt->children->next;
2672
+ return result;
2673
+ } else {
2674
+ /* no locator exists */
2675
+ return NULL;
2676
+ }
2677
+ }
2678
+
2679
+ /* print_opml_element_list - print an element list as OPML */
2680
+ void print_opml_element_list(GString *out, element *list) {
2681
+ int lev;
2682
+ while (list != NULL) {
2683
+ if (list->key == HEADINGSECTION) {
2684
+ lev = list->children->key;
2685
+
2686
+ print_opml_section_and_children(out, list);
2687
+
2688
+ while ((list->next != NULL) && (list->next->key == HEADINGSECTION)
2689
+ && (list->next->children->key > lev)) {
2690
+ list = list->next;
2691
+ }
2692
+ } else {
2693
+ print_opml_element(out, list);
2694
+ }
2695
+ list = list->next;
2696
+ }
2697
+ }
2698
+
2699
+ /* print_opml_section_and_children - print section and "children" */
2700
+ static void print_opml_section_and_children(GString *out, element *list) {
2701
+ int lev = list->children->key;
2702
+ /* Print current section, aka "parent" */
2703
+ print_opml_element(out, list);
2704
+
2705
+ /* check for children */
2706
+ while ((list->next != NULL) && (list->next->key == HEADINGSECTION)
2707
+ && (list->next->children->key > lev)) {
2708
+ /* next item is also HEADINGSECTION and is child */
2709
+ if (list->next->children->key - lev == 1)
2710
+ print_opml_section_and_children(out,list->next);
2711
+ list = list->next;
2712
+ }
2713
+ g_string_append_printf(out, "</outline>\n");
2714
+ }
2715
+
2716
+ /* print_opml_element - print an element as OPML */
2717
+ static void print_opml_element(GString *out, element *elt) {
2718
+ switch (elt->key) {
2719
+ case METADATA:
2720
+ /* Metadata is present, so will need to be appended */
2721
+ html_footer = true;
2722
+ break;
2723
+ case METAKEY:
2724
+ g_string_append_printf(out, "<outline text=\"");
2725
+ print_opml_string(out,elt->contents.str);
2726
+ g_string_append_printf(out, "\" _note=\"");
2727
+ print_opml_string(out, elt->children->contents.str);
2728
+ g_string_append_printf(out, "\"/>");
2729
+ break;
2730
+ case HEADINGSECTION:
2731
+ /* Need to handle "nesting" properly */
2732
+ g_string_append_printf(out, "<outline ");
2733
+
2734
+ /* Print header */
2735
+ print_opml_element(out,elt->children);
2736
+
2737
+ /* print remainder of paragraphs as note */
2738
+ g_string_append_printf(out, " _note=\"");
2739
+ print_opml_element_list(out,elt->children->next);
2740
+ g_string_append_printf(out, "\">");
2741
+ break;
2742
+ case H1: case H2: case H3: case H4: case H5: case H6:
2743
+ g_string_append_printf(out, "text=\"");
2744
+ print_opml_string(out, elt->contents.str);
2745
+ g_string_append_printf(out,"\"");
2746
+ break;
2747
+ case VERBATIM:
2748
+ print_opml_string(out, elt->contents.str);
2749
+ break;
2750
+ case SPACE:
2751
+ print_opml_string(out, elt->contents.str);
2752
+ break;
2753
+ case STR:
2754
+ print_opml_string(out, elt->contents.str);
2755
+ break;
2756
+ case LINEBREAK:
2757
+ g_string_append_printf(out, " &#10;");
2758
+ break;
2759
+ case PLAIN:
2760
+ print_opml_element_list(out,elt->children);
2761
+ if ((elt->next != NULL) && (elt->next->key == PLAIN)) {
2762
+ g_string_append_printf(out, "&#10;");
2763
+ }
2764
+ break;
2765
+ default:
2766
+ fprintf(stderr, "print_opml_element encountered unknown element key = %d\n", elt->key);
2767
+ /*exit(EXIT_FAILURE);*/
2768
+ }
2769
+ }
2770
+
2771
+ /* print_opml_string - print string, escaping for OPML */
2772
+ static void print_opml_string(GString *out, char *str) {
2773
+ while (*str != '\0') {
2774
+ switch (*str) {
2775
+ case '&':
2776
+ g_string_append_printf(out, "&amp;");
2777
+ break;
2778
+ case '<':
2779
+ g_string_append_printf(out, "&lt;");
2780
+ break;
2781
+ case '>':
2782
+ g_string_append_printf(out, "&gt;");
2783
+ break;
2784
+ case '"':
2785
+ g_string_append_printf(out, "&quot;");
2786
+ break;
2787
+ case '\n': case '\r':
2788
+ g_string_append_printf(out, "&#10;");
2789
+ break;
2790
+ default:
2791
+ g_string_append_c(out, *str);
2792
+ }
2793
+ str++;
2794
+ }
2795
+ }
2796
+
2797
+
2798
+ /* print_opml_metadata - add metadata as last outline item */
2799
+ static void print_opml_metadata(GString *out, element *elt) {
2800
+ g_string_append_printf(out, "<outline text=\"Metadata\">\n");
2801
+ print_opml_element_list(out, elt->children);
2802
+ g_string_append_printf(out, "</outline>");
2803
+ }
2804
+
2805
+ /* print_odf_body_element - print an element as ODF */
2806
+ void print_odf_body_element(GString *out, element *elt) {
2807
+ switch (elt->key) {
2808
+ case PARA:
2809
+ print_odf_element_list(out, elt->children);
2810
+ break;
2811
+ default:
2812
+ print_odf_element(out, elt);
2813
+ }
2814
+ }
2815
+
2816
+ /* print_odf_body_element_list - print an element list as ODF for specific
2817
+ places, eg image captions */
2818
+ void print_odf_body_element_list(GString *out, element *list) {
2819
+ while (list != NULL) {
2820
+ print_odf_body_element(out, list);
2821
+ list = list->next;
2822
+ }
2823
+ }
2824
+
2825
+ /* bogus function just references a couple globals defined in utility_functions.c but not used in this source file */
2826
+ static void bogus_function()
2827
+ {
2828
+ static char* bogus;
2829
+ bogus = charbuf;
2830
+ static element* bogus2;
2831
+ bogus2 = parse_result;
2832
+ }