rpeg-multimarkdown 0.1.1 → 0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. checksums.yaml +7 -0
  2. data/README.markdown +7 -4
  3. data/Rakefile +3 -3
  4. data/bin/rpeg-multimarkdown +7 -7
  5. data/ext/extconf.rb +2 -2
  6. data/ext/markdown.c +14 -0
  7. data/ext/markdown_lib.c +72 -18
  8. data/ext/markdown_lib.h +18 -8
  9. data/ext/markdown_output.c +187 -58
  10. data/ext/markdown_parser.c +8315 -6224
  11. data/ext/markdown_peg.h +5 -4
  12. data/ext/odf.c +7 -1
  13. data/ext/odf.h +8 -0
  14. data/ext/parsing_functions.c +42 -2
  15. data/ext/parsing_functions.h +17 -0
  16. data/ext/utility_functions.c +60 -56
  17. data/ext/utility_functions.h +93 -0
  18. data/lib/peg_multimarkdown.rb +16 -16
  19. data/test/MultiMarkdownTest/BeamerTests/Beamer-Tables.tex +2 -2
  20. data/test/MultiMarkdownTest/CompatibilityTests/Automatic Labels.html +35 -0
  21. data/test/MultiMarkdownTest/CompatibilityTests/Automatic Labels.text +45 -0
  22. data/test/MultiMarkdownTest/CompatibilityTests/Base Header Level.html +14 -0
  23. data/test/MultiMarkdownTest/CompatibilityTests/Base Header Level.text +16 -0
  24. data/test/MultiMarkdownTest/CompatibilityTests/BibTeX.html +9 -0
  25. data/test/MultiMarkdownTest/CompatibilityTests/BibTeX.text +10 -0
  26. data/test/MultiMarkdownTest/CompatibilityTests/Citations.html +40 -0
  27. data/test/MultiMarkdownTest/CompatibilityTests/Citations.text +42 -0
  28. data/test/MultiMarkdownTest/CompatibilityTests/Definition Lists.html +40 -0
  29. data/test/MultiMarkdownTest/CompatibilityTests/Definition Lists.text +39 -0
  30. data/test/MultiMarkdownTest/CompatibilityTests/Dutch.html +17 -0
  31. data/test/MultiMarkdownTest/CompatibilityTests/Dutch.text +17 -0
  32. data/test/MultiMarkdownTest/CompatibilityTests/Email.html +40 -0
  33. data/test/MultiMarkdownTest/CompatibilityTests/Email.text +31 -0
  34. data/test/MultiMarkdownTest/CompatibilityTests/English.html +17 -0
  35. data/test/MultiMarkdownTest/CompatibilityTests/English.text +17 -0
  36. data/test/MultiMarkdownTest/CompatibilityTests/Errors.html +9 -0
  37. data/test/MultiMarkdownTest/CompatibilityTests/Errors.text +11 -0
  38. data/test/MultiMarkdownTest/CompatibilityTests/Footnotes.html +23 -0
  39. data/test/MultiMarkdownTest/CompatibilityTests/Footnotes.text +25 -0
  40. data/test/MultiMarkdownTest/CompatibilityTests/French.html +17 -0
  41. data/test/MultiMarkdownTest/CompatibilityTests/French.text +17 -0
  42. data/test/MultiMarkdownTest/CompatibilityTests/German.html +17 -0
  43. data/test/MultiMarkdownTest/CompatibilityTests/German.text +17 -0
  44. data/test/MultiMarkdownTest/CompatibilityTests/GermanGuillemets.html +17 -0
  45. data/test/MultiMarkdownTest/CompatibilityTests/GermanGuillemets.text +17 -0
  46. data/test/MultiMarkdownTest/CompatibilityTests/Glossary.html +29 -0
  47. data/test/MultiMarkdownTest/CompatibilityTests/Glossary.text +28 -0
  48. data/test/MultiMarkdownTest/CompatibilityTests/Headers.html +42 -0
  49. data/test/MultiMarkdownTest/CompatibilityTests/Headers.text +51 -0
  50. data/test/MultiMarkdownTest/CompatibilityTests/Line Breaks.html +13 -0
  51. data/test/MultiMarkdownTest/CompatibilityTests/Line Breaks.text +15 -0
  52. data/test/MultiMarkdownTest/CompatibilityTests/Link Attributes.html +35 -0
  53. data/test/MultiMarkdownTest/CompatibilityTests/Link Attributes.text +51 -0
  54. data/test/MultiMarkdownTest/CompatibilityTests/List Parsing.html +13 -0
  55. data/test/MultiMarkdownTest/CompatibilityTests/List Parsing.text +11 -0
  56. data/test/MultiMarkdownTest/CompatibilityTests/MarkdownInHTML.html +13 -0
  57. data/test/MultiMarkdownTest/CompatibilityTests/MarkdownInHTML.text +19 -0
  58. data/test/MultiMarkdownTest/CompatibilityTests/Math.html +14 -0
  59. data/test/MultiMarkdownTest/CompatibilityTests/Math.text +15 -0
  60. data/test/MultiMarkdownTest/CompatibilityTests/MetaData.html +14 -0
  61. data/test/MultiMarkdownTest/CompatibilityTests/MetaData.text +14 -0
  62. data/test/MultiMarkdownTest/CompatibilityTests/NotMetaData.html +3 -0
  63. data/test/MultiMarkdownTest/CompatibilityTests/NotMetaData.text +4 -0
  64. data/test/MultiMarkdownTest/CompatibilityTests/Sanity.html +77 -0
  65. data/test/MultiMarkdownTest/CompatibilityTests/Sanity.text +77 -0
  66. data/test/MultiMarkdownTest/CompatibilityTests/SmartQuotes.html +22 -0
  67. data/test/MultiMarkdownTest/CompatibilityTests/SmartQuotes.text +22 -0
  68. data/test/MultiMarkdownTest/CompatibilityTests/Swedish.html +17 -0
  69. data/test/MultiMarkdownTest/CompatibilityTests/Swedish.text +17 -0
  70. data/test/MultiMarkdownTest/CompatibilityTests/Tables.html +65 -0
  71. data/test/MultiMarkdownTest/CompatibilityTests/Tables.text +71 -0
  72. data/test/MultiMarkdownTest/MemoirTests/Definition Lists.tex +5 -10
  73. data/test/MultiMarkdownTest/MemoirTests/Sanity.tex +2 -2
  74. data/test/MultiMarkdownTest/MemoirTests/Tables.tex +10 -10
  75. data/test/MultiMarkdownTest/MultiMarkdownTests/Automatic Labels.html +4 -2
  76. data/test/MultiMarkdownTest/MultiMarkdownTests/Base Header Level.html +4 -2
  77. data/test/MultiMarkdownTest/MultiMarkdownTests/BibTeX.html +4 -2
  78. data/test/MultiMarkdownTest/MultiMarkdownTests/Citations.html +6 -4
  79. data/test/MultiMarkdownTest/MultiMarkdownTests/Definition Lists.html +9 -12
  80. data/test/MultiMarkdownTest/MultiMarkdownTests/Definition Lists.tex +5 -10
  81. data/test/MultiMarkdownTest/MultiMarkdownTests/Dutch.html +4 -2
  82. data/test/MultiMarkdownTest/MultiMarkdownTests/Email.html +4 -2
  83. data/test/MultiMarkdownTest/MultiMarkdownTests/English.html +4 -2
  84. data/test/MultiMarkdownTest/MultiMarkdownTests/Errors.html +4 -2
  85. data/test/MultiMarkdownTest/MultiMarkdownTests/Footnotes.html +7 -5
  86. data/test/MultiMarkdownTest/MultiMarkdownTests/French.html +4 -2
  87. data/test/MultiMarkdownTest/MultiMarkdownTests/German.html +4 -2
  88. data/test/MultiMarkdownTest/MultiMarkdownTests/GermanGuillemets.html +4 -2
  89. data/test/MultiMarkdownTest/MultiMarkdownTests/Glossary.html +6 -4
  90. data/test/MultiMarkdownTest/MultiMarkdownTests/Headers.html +6 -2
  91. data/test/MultiMarkdownTest/MultiMarkdownTests/Headers.tex +2 -0
  92. data/test/MultiMarkdownTest/MultiMarkdownTests/Headers.text +2 -0
  93. data/test/MultiMarkdownTest/MultiMarkdownTests/Line Breaks.html +4 -2
  94. data/test/MultiMarkdownTest/MultiMarkdownTests/Link Attributes.html +4 -2
  95. data/test/MultiMarkdownTest/MultiMarkdownTests/List Parsing.html +4 -2
  96. data/test/MultiMarkdownTest/MultiMarkdownTests/MarkdownInHTML.html +4 -2
  97. data/test/MultiMarkdownTest/MultiMarkdownTests/Math.html +4 -2
  98. data/test/MultiMarkdownTest/MultiMarkdownTests/MetaData.html +4 -2
  99. data/test/MultiMarkdownTest/MultiMarkdownTests/NotMetaData.html +3 -0
  100. data/test/MultiMarkdownTest/MultiMarkdownTests/NotMetaData.tex +3 -0
  101. data/test/MultiMarkdownTest/MultiMarkdownTests/NotMetaData.text +4 -0
  102. data/test/MultiMarkdownTest/MultiMarkdownTests/Sanity.html +4 -2
  103. data/test/MultiMarkdownTest/MultiMarkdownTests/Sanity.tex +2 -2
  104. data/test/MultiMarkdownTest/MultiMarkdownTests/SmartQuotes.html +4 -2
  105. data/test/MultiMarkdownTest/MultiMarkdownTests/Swedish.html +4 -2
  106. data/test/MultiMarkdownTest/MultiMarkdownTests/Tables.html +45 -2
  107. data/test/MultiMarkdownTest/MultiMarkdownTests/Tables.tex +32 -10
  108. data/test/MultiMarkdownTest/MultiMarkdownTests/Tables.text +8 -0
  109. data/test/multimarkdown_test.rb +5 -5
  110. metadata +92 -50
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2ad16113d208ab57ccf7948e4fc1619d9e1b38c0
4
+ data.tar.gz: 67c7e3e4ce2760a7f795c07b63928585a07d2473
5
+ SHA512:
6
+ metadata.gz: 9af9add990883aea35b0153b466fbc5e4f61618004cac29922c5910fc4ca680cc1c0c0208f267c2b88d72ac744012154f2f0fa7723f384ec5626810f9705876b
7
+ data.tar.gz: 35ec043a14a36b40484946fcf577d977263451e88feae0be3dffda11ce54d1d7084e513dcc6c779cbd07f2bbc0ba2bbb914cb41360afc1b7a0d817a8cbb4fcc9
data/README.markdown CHANGED
@@ -14,17 +14,18 @@ Synopsis
14
14
  --------
15
15
 
16
16
  >> require 'multimarkdown'
17
+
17
18
  >> puts MultiMarkdown.new('Hello, world.').to_html
18
- <p>Hello, world.</p>
19
+ # <p>Hello, world.</p>
19
20
 
20
21
  >> puts MultiMarkdown.new('_Hello World!_', :smart, :filter_html).to_html
21
- <p><em>Hello World!</em></p>
22
+ # <p><em>Hello World!</em></p>
22
23
 
23
24
  >> puts MultiMarkdown.new('_Hello World!_').to_latex
24
- \emph{Hello World!}
25
+ # \emph{Hello World!}
25
26
 
26
27
  >> puts MultiMarkdown.new("Title: Some document\n\nSome text in the document").extract_metadata("title")
27
- Some document
28
+ # Some document
28
29
 
29
30
  >> PEGMultiMarkdown.new('Hello! World!')
30
31
 
@@ -42,6 +43,8 @@ Hacking:
42
43
 
43
44
  $ git clone git://github.com/djungelvral/rpeg-multimarkdown.git
44
45
  $ cd rpeg-multimarkdown
46
+ $ git submodule init
47
+ $ git submodule update
45
48
  $ rake test
46
49
 
47
50
  Changes
data/Rakefile CHANGED
@@ -7,8 +7,8 @@ require 'rubygems/package_task'
7
7
 
8
8
  task :default => :test
9
9
 
10
- DLEXT = Config::CONFIG['DLEXT']
11
- VERS = '0.1.1'
10
+ DLEXT = RbConfig::CONFIG['DLEXT']
11
+ VERS = '0.2'
12
12
 
13
13
  spec = Gem::Specification.new do |s|
14
14
  s.name = "rpeg-multimarkdown"
@@ -74,7 +74,7 @@ task :gather => 'submodule:exist' do |t|
74
74
  files =
75
75
  FileList[
76
76
  'peg-multimarkdown/markdown_{peg.h,parser.c,output.c,lib.c,lib.h}',
77
- 'peg-multimarkdown/{utility,parsing}_functions.c',
77
+ 'peg-multimarkdown/{utility,parsing}_functions.{c,h}',
78
78
  'peg-multimarkdown/odf.{c,h}'
79
79
  ]
80
80
  cp files, 'ext/',
@@ -55,11 +55,11 @@ class Parser
55
55
  @used_short << short = o[2][:short] || short_from(o[0])
56
56
  @result[o[0]] = o[2][:default] || false # set default
57
57
  klass = o[2][:default].class == Fixnum ? Integer : o[2][:default].class
58
-
58
+ desk = o[1] + (o[2][:nodefault] ? "" : " (default is #{@result[o[0]]})")
59
59
  if [TrueClass, FalseClass, NilClass].include?(klass) # boolean switch
60
- p.on("-" << short, "--[no-]" << o[0].to_s.gsub("_", "-"), o[1]) {|x| @result[o[0]] = x}
60
+ p.on("-" << short, "--[no-]" << o[0].to_s.gsub("_", "-"), desk) {|x| @result[o[0]] = x}
61
61
  else # argument with parameter
62
- p.on("-" << short, "--" << o[0].to_s.gsub("_", "-") << " " << o[2][:default].to_s, klass, o[1]) {|x| @result[o[0]] = x}
62
+ p.on("-" << short, "--" << o[0].to_s.gsub("_", "-") << " " << (o[2][:name] ? "[#{o[2][:name].to_s}]" : ""), klass, desk) {|x| @result[o[0]] = x}
63
63
  end
64
64
  end
65
65
 
@@ -86,14 +86,14 @@ options = Parser.new do |p|
86
86
  p.banner = "Ruby interface to MultiMarkdown"
87
87
  p.version = "rpeg-multimarkdown 0.1.0"
88
88
  p.option :compatibility, "markdown compatibility mode", :default => false
89
- p.option :filter_html, "filter out raw HTML (except styles)", :default => false
89
+ p.option :filter_html, "filter out raw HTML except styles", :default => false
90
90
  p.option :process_html, "process MultiMarkdown inside of raw HTML", :default => false
91
91
  p.option :filter_styles, "filter out HTML styles", :default => false
92
92
  p.option :smart, "use smart typography extension", :default => true
93
93
  p.option :notes, "use notes extension", :default => true
94
- p.option :output, "send output to FILE (default is stdout)", :default => ""
95
- p.option :to, "convert to FORMAT (default is html)", :default => "html", :value_in_set => ["html","latex","memoir","beamer","odf","opml"]
96
- p.option :extract, "extract and display specified metadata", :default => ""
94
+ p.option :output, "send output to FILE (default is stdout)", :name => "FILE", :default => "", :nodefault => true
95
+ p.option :to, "convert to FORMAT", :name => "FORMAT", :default => "html", :value_in_set => ["html","latex","memoir","beamer","odf","opml"]
96
+ p.option :extract, "extract and display metadata specified by KEY", :name => "KEY", :default => "", :nodefault => true
97
97
  end.process!
98
98
 
99
99
  # Convert options to MultiMarkdown module's options
data/ext/extconf.rb CHANGED
@@ -2,10 +2,10 @@ require 'mkmf'
2
2
 
3
3
  dir_config('peg_multimarkdown')
4
4
 
5
- $objs = %w[markdown.o markdown_lib.o markdown_output.o markdown_parser.o]
5
+ $objs = %w[markdown.o markdown_lib.o markdown_output.o markdown_parser.o parsing_functions.o utility_functions.o]
6
6
 
7
7
  if pkg_config = find_executable('pkg-config')
8
- $CFLAGS = "-fcommon "+`#{pkg_config} --cflags glib-2.0`
8
+ $CFLAGS = "-fcommon -std=gnu89 "+`#{pkg_config} --cflags glib-2.0`
9
9
  $LDFLAGS = `#{pkg_config} --libs glib-2.0`
10
10
  else
11
11
  fail "glib2 not found"
data/ext/markdown.c CHANGED
@@ -80,8 +80,22 @@ rb_multimarkdown_extract_metadata(VALUE self, VALUE key)
80
80
  void Init_peg_multimarkdown()
81
81
  {
82
82
  rb_cMultiMarkdown = rb_define_class("PEGMultiMarkdown", rb_cObject);
83
+ /*
84
+ * Document-method: PEGMultiMarkdown#to_html
85
+ * Return string containing HTML generated from `text`
86
+ */
83
87
  rb_define_method(rb_cMultiMarkdown, "to_html", rb_multimarkdown_to_html, -1);
88
+ /*
89
+ * Document-method: PEGMultiMarkdown#to_latex
90
+ * Return string containing latex generated from `text`
91
+ */
84
92
  rb_define_method(rb_cMultiMarkdown, "to_latex", rb_multimarkdown_to_latex, -1);
93
+ /*
94
+ * Document-method: PEGMultiMarkdown#extract_metadata
95
+ * call-seq:
96
+ * extract_metadata(key)
97
+ * Extract metadata specified by `key` from `text`
98
+ */
85
99
  rb_define_method(rb_cMultiMarkdown, "extract_metadata", rb_multimarkdown_extract_metadata, 1);
86
100
  }
87
101
 
data/ext/markdown_lib.c CHANGED
@@ -1,9 +1,10 @@
1
+
1
2
  /**********************************************************************
2
3
 
3
4
  markdown_lib.c - markdown in C using a PEG grammar.
4
5
  (c) 2008 John MacFarlane (jgm at berkeley dot edu).
5
6
 
6
- portions Copyright (c) 2010-2011 Fletcher T. Penney
7
+ portions Copyright (c) 2010-2013 Fletcher T. Penney
7
8
 
8
9
  This program is free software; you can redistribute it and/or modify
9
10
  it under the terms of the GNU General Public License or the MIT
@@ -22,6 +23,7 @@
22
23
  #include "markdown_peg.h"
23
24
 
24
25
  #define TABSTOP 4
26
+ #define VERSION "3.7"
25
27
 
26
28
  /* preformat_text - allocate and copy text buffer while
27
29
  * performing tab expansion. */
@@ -99,9 +101,9 @@ static void print_tree(element * elt, int indent) {
99
101
  default: key = "?";
100
102
  }
101
103
  if ( elt->key == STR ) {
102
- fprintf(stderr, "0x%x: %s '%s'\n", (int)elt, key, elt->contents.str);
104
+ fprintf(stderr, "0x%p: %s '%s'\n", (void *)elt, key, elt->contents.str);
103
105
  } else {
104
- fprintf(stderr, "0x%x: %s\n", (int)elt, key);
106
+ fprintf(stderr, "0x%p: %s\n", (void *)elt, key);
105
107
  }
106
108
  if (elt->children)
107
109
  print_tree(elt->children, indent + 4);
@@ -155,27 +157,30 @@ GString * markdown_to_g_string(char *text, int extensions, int output_format) {
155
157
 
156
158
  formatted_text = preformat_text(text);
157
159
 
160
+ references = parse_references(formatted_text->str, extensions);
161
+ notes = parse_notes(formatted_text->str, extensions, references);
162
+ labels = parse_labels(formatted_text->str, extensions, references, notes);
163
+
158
164
  if (output_format == OPML_FORMAT) {
159
165
  result = parse_markdown_for_opml(formatted_text->str, extensions);
160
166
  } else {
161
- references = parse_references(formatted_text->str, extensions);
162
- notes = parse_notes(formatted_text->str, extensions, references);
163
- labels = parse_labels(formatted_text->str, extensions, references, notes);
164
167
  result = parse_markdown_with_metadata(formatted_text->str, extensions, references, notes, labels);
165
-
166
168
  result = process_raw_blocks(result, extensions, references, notes, labels);
167
169
  }
168
170
 
169
171
  g_string_free(formatted_text, TRUE);
170
172
 
171
- print_element_list(out, result, output_format, extensions);
172
-
173
+ if (result == NULL) {
174
+ /* The parsing was aborted */
175
+ g_string_append(out,"MultiMarkdown was unable to parse this file.");
176
+ } else {
177
+ print_element_list(out, result, output_format, extensions);
178
+ }
173
179
  free_element_list(result);
174
180
 
175
- if (output_format != OPML_FORMAT) {
176
- free_element_list(references);
177
- free_element_list(labels);
178
- }
181
+ free_element_list(references);
182
+ free_element_list(labels);
183
+
179
184
  return out;
180
185
  }
181
186
 
@@ -198,14 +203,63 @@ char * markdown_to_string(char *text, int extensions, int output_format) {
198
203
  char * extract_metadata_value(char *text, int extensions, char *key) {
199
204
  char *value;
200
205
  element *result;
201
- char *meta;
206
+ element *references;
207
+ element *notes;
208
+ element *labels;
202
209
  GString *formatted_text;
203
210
 
204
211
  formatted_text = preformat_text(text);
205
-
212
+
213
+ references = parse_references(formatted_text->str, extensions);
214
+ notes = parse_notes(formatted_text->str, extensions, references);
215
+ labels = parse_labels(formatted_text->str, extensions, references, notes);
216
+
206
217
  result = parse_metadata_only(formatted_text->str, extensions);
207
-
208
- value = metavalue_for_key(key, result->children);
218
+
219
+ value = metavalue_for_key(key, result);
209
220
  free_element_list(result);
221
+ free_element_list(references);
222
+ free_element_list(labels);
223
+
210
224
  return value;
211
- }
225
+ }
226
+
227
+ /* has_metadata - parse document and report whether metadata is present */
228
+ gboolean has_metadata(char *text, int extensions) {
229
+ gboolean hasMeta;
230
+ element *result;
231
+ element *references;
232
+ element *notes;
233
+ element *labels;
234
+ GString *formatted_text;
235
+
236
+ formatted_text = preformat_text(text);
237
+
238
+ references = parse_references(formatted_text->str, extensions);
239
+ notes = parse_notes(formatted_text->str, extensions, references);
240
+ labels = parse_labels(formatted_text->str, extensions, references, notes);
241
+
242
+ result = parse_metadata_only(formatted_text->str, extensions);
243
+
244
+ hasMeta = FALSE;
245
+
246
+ if (result != NULL) {
247
+ if (result->children != NULL) {
248
+ hasMeta = TRUE;
249
+ free_element_list(result);
250
+ } else {
251
+ free_element(result);
252
+ }
253
+ }
254
+
255
+ free_element_list(references);
256
+ free_element_list(labels);
257
+ return hasMeta;
258
+ }
259
+
260
+ /* version - return the MultiMarkdown library version */
261
+ char * mmd_version() {
262
+ char* result = (char*)malloc(8);
263
+ sprintf(result, "%s",VERSION);
264
+ return result;
265
+ }
data/ext/markdown_lib.h CHANGED
@@ -1,14 +1,18 @@
1
+ #ifndef MARKDOWN_LIB_H
2
+ #define MARKDOWN_LIB_H
3
+
1
4
  #include <stdlib.h>
2
5
  #include <stdio.h>
3
- #include <glib.h>
6
+ #include "glib.h"
4
7
 
5
8
  enum markdown_extensions {
6
- EXT_SMART = 0x01,
7
- EXT_NOTES = 0x02,
8
- EXT_FILTER_HTML = 0x04,
9
- EXT_FILTER_STYLES = 0x08,
10
- EXT_COMPATIBILITY = 0x10,
11
- EXT_PROCESS_HTML = 0x20,
9
+ EXT_SMART = 1 << 0,
10
+ EXT_NOTES = 1 << 1,
11
+ EXT_FILTER_HTML = 1 << 2,
12
+ EXT_FILTER_STYLES = 1 << 3,
13
+ EXT_COMPATIBILITY = 1 << 4,
14
+ EXT_PROCESS_HTML = 1 << 5,
15
+ EXT_NO_LABELS = 1 << 6,
12
16
  };
13
17
 
14
18
  enum markdown_formats {
@@ -19,10 +23,16 @@ enum markdown_formats {
19
23
  OPML_FORMAT,
20
24
  GROFF_MM_FORMAT,
21
25
  ODF_FORMAT,
22
- ODF_BODY_FORMAT
26
+ ODF_BODY_FORMAT,
27
+ ORIGINAL_FORMAT
23
28
  };
24
29
 
25
30
  GString * markdown_to_g_string(char *text, int extensions, int output_format);
26
31
  char * markdown_to_string(char *text, int extensions, int output_format);
32
+ char * extract_metadata_value(char *text, int extensions, char *key);
33
+ gboolean has_metadata(char *text, int extensions);
34
+ char * mmd_version();
27
35
 
28
36
  /* vim: set ts=4 sw=4 : */
37
+ #endif
38
+
@@ -4,7 +4,7 @@
4
4
  markdown_peg.
5
5
  (c) 2008 John MacFarlane (jgm at berkeley dot edu).
6
6
 
7
- portions Copyright (c) 2010-2011 Fletcher T. Penney
7
+ portions Copyright (c) 2010-2013 Fletcher T. Penney
8
8
 
9
9
  This program is free software; you can redistribute it and/or modify
10
10
  it under the terms of the GNU General Public License or the MIT
@@ -22,10 +22,11 @@
22
22
  #include <stdlib.h>
23
23
  #include <string.h>
24
24
  #include <assert.h>
25
- #include <glib.h>
25
+ #include "glib.h"
26
26
  #include "markdown_peg.h"
27
- #include "utility_functions.c"
28
- #include "odf.c"
27
+ #include "odf.h"
28
+
29
+ #include "utility_functions.h"
29
30
 
30
31
  static int extensions;
31
32
  static int base_header_level = 1;
@@ -36,8 +37,10 @@ static char cell_type = 'd';
36
37
  static int language = ENGLISH;
37
38
  static bool html_footer = FALSE;
38
39
  static int odf_type = 0;
39
- static bool in_list = FALSE;
40
40
  static bool no_latex_footnote = FALSE;
41
+ static bool am_printing_html_footnote = FALSE;
42
+ static int footnote_counter_to_print = 0;
43
+ static int odf_list_needs_end_p = 0;
41
44
 
42
45
  static void print_html_string(GString *out, char *str, bool obfuscate);
43
46
  static void print_html_element_list(GString *out, element *list, bool obfuscate);
@@ -85,6 +88,7 @@ char * metavalue_for_key(char *key, element *list);
85
88
  element * element_for_attribute(char *querystring, element *list);
86
89
  char * dimension_for_attribute(char *querystring, element *list);
87
90
 
91
+ element * locator_for_citation(element *elt);
88
92
 
89
93
  /**********************************************************************
90
94
 
@@ -107,7 +111,7 @@ static void pad(GString *out, int num) {
107
111
  }
108
112
 
109
113
  /* determine whether a certain element is contained within a given list */
110
- bool list_contains_key(element *list, int key) {
114
+ static bool list_contains_key(element *list, int key) {
111
115
  element *step = NULL;
112
116
 
113
117
  step = list;
@@ -149,7 +153,7 @@ static void print_html_string(GString *out, char *str, bool obfuscate) {
149
153
  g_string_append_printf(out, "&quot;");
150
154
  break;
151
155
  default:
152
- if (obfuscate) {
156
+ if (obfuscate && ((int) *str < 128) && ((int) *str >= 0)){
153
157
  if (rand() % 2 == 0)
154
158
  g_string_append_printf(out, "&#%d;", (int) *str);
155
159
  else
@@ -184,6 +188,7 @@ static void print_html_element(GString *out, element *elt, bool obfuscate) {
184
188
  int lev;
185
189
  char *label;
186
190
  element *attribute;
191
+ element *locator = NULL;
187
192
  char *height;
188
193
  char *width;
189
194
  switch (elt->key) {
@@ -252,10 +257,13 @@ static void print_html_element(GString *out, element *elt, bool obfuscate) {
252
257
  print_html_string(out, elt->contents.link->url, obfuscate);
253
258
  g_string_append_printf(out, "\" alt=\"");
254
259
  print_raw_element_list(out,elt->contents.link->label);
255
- if ( extension(EXT_COMPATIBILITY) ) {
260
+ if ( (extension(EXT_COMPATIBILITY)) ||
261
+ (strcmp(elt->contents.link->identifier, "") == 0) ) {
256
262
  g_string_append_printf(out, "\"");
257
263
  } else {
258
- g_string_append_printf(out, "\" id=\"%s\"",elt->contents.link->identifier);
264
+ if (!(extension(EXT_COMPATIBILITY))) {
265
+ g_string_append_printf(out, "\" id=\"%s\"",elt->contents.link->identifier);
266
+ }
259
267
  }
260
268
  if (strlen(elt->contents.link->title) > 0) {
261
269
  g_string_append_printf(out, " title=\"");
@@ -315,15 +323,20 @@ static void print_html_element(GString *out, element *elt, bool obfuscate) {
315
323
  if (lev > 6)
316
324
  lev = 6;
317
325
  pad(out, 2);
318
- if ( extension(EXT_COMPATIBILITY) ) {
326
+ if ( extension(EXT_COMPATIBILITY)) {
319
327
  /* Use regular Markdown header format */
320
328
  g_string_append_printf(out, "<h%1d>", lev);
321
329
  print_html_element_list(out, elt->children, obfuscate);
322
330
  } else if (elt->children->key == AUTOLABEL) {
323
- /* generate a label for each header (MMD)*/
331
+ /* use label for header since one was specified (MMD)*/
324
332
  g_string_append_printf(out, "<h%d id=\"%s\">", lev,elt->children->contents.str);
325
333
  print_html_element_list(out, elt->children->next, obfuscate);
334
+ } else if ( extension(EXT_NO_LABELS)) {
335
+ /* Don't generate a label */
336
+ g_string_append_printf(out, "<h%1d>", lev);
337
+ print_html_element_list(out, elt->children, obfuscate);
326
338
  } else {
339
+ /* generate a label by default for MMD */
327
340
  label = label_from_element_list(elt->children, obfuscate);
328
341
  g_string_append_printf(out, "<h%d id=\"%s\">", lev, label);
329
342
  print_html_element_list(out, elt->children, obfuscate);
@@ -341,6 +354,12 @@ static void print_html_element(GString *out, element *elt, bool obfuscate) {
341
354
  pad(out, 2);
342
355
  g_string_append_printf(out, "<p>");
343
356
  print_html_element_list(out, elt->children, obfuscate);
357
+ if (am_printing_html_footnote && ( elt->next == NULL)) {
358
+ g_string_append_printf(out, " <a href=\"#fnref:%d\" title=\"return to article\" class=\"reversefootnote\">&#160;&#8617;</a>", footnote_counter_to_print);
359
+ /* Only print once. For now, it's the first paragraph, until
360
+ I can figure out to make it the last paragraph */
361
+ am_printing_html_footnote = FALSE;
362
+ }
344
363
  g_string_append_printf(out, "</p>");
345
364
  padded = 0;
346
365
  break;
@@ -406,7 +425,7 @@ static void print_html_element(GString *out, element *elt, bool obfuscate) {
406
425
  /* if contents.str == 0, then print note; else ignore, since this
407
426
  * is a note block that has been incorporated into the notes list */
408
427
  if (elt->contents.str == 0) {
409
- if ( (elt->children->contents.str == 0) ){
428
+ if (elt->children->contents.str == 0) {
410
429
  /* The referenced note has not been used before */
411
430
  add_endnote(elt->children);
412
431
  ++notenumber;
@@ -447,62 +466,63 @@ static void print_html_element(GString *out, element *elt, bool obfuscate) {
447
466
  break;
448
467
  case NOCITATION:
449
468
  case CITATION:
450
- if ((elt->children != NULL) && (elt->children->key == LOCATOR)) {
451
- GString *temp = g_string_new("");
452
- print_html_element(temp,elt->children,obfuscate);
453
- label = strdup(temp->str);
454
- g_string_free(temp,true);
455
- elt->children = elt->children->next;
456
- } else {
457
- label = NULL;
458
- }
469
+ /* Get locator, if present */
470
+ locator = locator_for_citation(elt);
471
+
459
472
  if (strncmp(elt->contents.str,"[#",2) == 0) {
460
473
  /* reference specified externally */
461
474
  if ( elt->key == NOCITATION ) {
475
+ /* work not cited, but used in bibliography for LaTeX */
462
476
  g_string_append_printf(out, "<span class=\"notcited\" id=\"%s\"/>", elt->contents.str);
463
477
  } else {
478
+ /* work was cited, so output normally */
464
479
  g_string_append_printf(out, "<span class=\"externalcitation\">");
465
- if (label != NULL) g_string_append_printf(out, "[%s]", label);
480
+ if (locator != NULL) {
481
+ g_string_append_printf(out, "[");
482
+ print_html_element(out,locator,obfuscate);
483
+ g_string_append_printf(out, "]");
484
+ }
466
485
  g_string_append_printf(out, "%s",elt->contents.str);
467
486
  g_string_append_printf(out, "</span>");
468
487
  }
469
488
  } else {
470
- /* reference specified within the MMD document */
489
+ /* reference specified within the MMD document,
490
+ so will output as footnote */
471
491
  if (elt->children->contents.str == NULL) {
492
+ /* Work not previously cited in this document,
493
+ so create "endnote" */
472
494
  elt->children->key = CITATION;
473
495
  add_endnote(elt->children);
474
496
  ++notenumber;
475
497
  char buf[5];
476
498
  sprintf(buf,"%d",notenumber);
477
-
499
+ /* Store the number for future reference */
478
500
  elt->children->contents.str = strdup(buf);
479
501
  }
480
- if (label != NULL) {
502
+ if (locator != NULL) {
481
503
  if ( elt->key == NOCITATION ) {
482
504
  g_string_append_printf(out, "<span class=\"notcited\" id=\"%s\">",
483
505
  elt->children->contents.str);
484
506
  } else {
485
- g_string_append_printf(out, "<a class=\"citation\" href=\"#fn:%s\" title=\"Jump to citation\">[<span class=\"locator\">%s</span>, %s]",
486
- elt->children->contents.str, label, elt->children->contents.str);
507
+ g_string_append_printf(out, "<a class=\"citation\" href=\"#fn:%s\" title=\"Jump to citation\">[<span class=\"locator\">", elt->children->contents.str);
508
+ print_html_element(out,locator,obfuscate);
509
+ g_string_append_printf(out,"</span>, %s]",
510
+ elt->children->contents.str);
487
511
  }
488
- elt->children = NULL;
489
512
  } else {
490
513
  g_string_append_printf(out, "<a class=\"citation\" href=\"#fn:%s\" title=\"Jump to citation\">[%s]",
491
514
  elt->children->contents.str, elt->children->contents.str);
492
- elt->children = NULL;
493
515
  }
516
+ /* Now prune children since will likely be shared elsewhere */
517
+ elt->children = NULL;
518
+
494
519
  g_string_append_printf(out, "<span class=\"citekey\" style=\"display:none\">%s</span>", elt->contents.str);
495
- if (label != NULL) {
496
- if ( elt->key == NOCITATION ) {
520
+ if ((locator != NULL) && (elt->key == NOCITATION)) {
497
521
  g_string_append_printf(out,"</span>");
498
- } else {
499
- g_string_append_printf(out,"</a>");
500
- }
501
522
  } else {
502
523
  g_string_append_printf(out,"</a>");
503
524
  }
504
525
  }
505
- free(label);
506
526
  break;
507
527
  case LOCATOR:
508
528
  print_html_element_list(out, elt->children, obfuscate);
@@ -518,7 +538,7 @@ static void print_html_element(GString *out, element *elt, bool obfuscate) {
518
538
  case TERM:
519
539
  pad(out,1);
520
540
  g_string_append_printf(out, "<dt>");
521
- print_html_string(out, elt->contents.str, obfuscate);
541
+ print_html_element_list(out, elt->children, obfuscate);
522
542
  g_string_append_printf(out, "</dt>\n");
523
543
  padded = 1;
524
544
  break;
@@ -611,8 +631,14 @@ static void print_html_element(GString *out, element *elt, bool obfuscate) {
611
631
  for (table_column=0;table_column<strlen(table_alignment);table_column++) {
612
632
  if ( strncmp(&table_alignment[table_column],"r",1) == 0) {
613
633
  g_string_append_printf(out, "<col style=\"text-align:right;\"/>\n");
634
+ } else if ( strncmp(&table_alignment[table_column],"R",1) == 0) {
635
+ g_string_append_printf(out, "<col style=\"text-align:right;\" class=\"extended\"/>\n");
614
636
  } else if ( strncmp(&table_alignment[table_column],"c",1) == 0) {
615
637
  g_string_append_printf(out, "<col style=\"text-align:center;\"/>\n");
638
+ } else if ( strncmp(&table_alignment[table_column],"C",1) == 0) {
639
+ g_string_append_printf(out, "<col style=\"text-align:center;\" class=\"extended\"/>\n");
640
+ } else if ( strncmp(&table_alignment[table_column],"L",1) == 0) {
641
+ g_string_append_printf(out, "<col style=\"text-align:left;\" class=\"extended\"/>\n");
616
642
  } else {
617
643
  g_string_append_printf(out, "<col style=\"text-align:left;\"/>\n");
618
644
  }
@@ -638,8 +664,12 @@ static void print_html_element(GString *out, element *elt, bool obfuscate) {
638
664
  case TABLECELL:
639
665
  if ( strncmp(&table_alignment[table_column],"r",1) == 0) {
640
666
  g_string_append_printf(out, "\t<t%c style=\"text-align:right;\"", cell_type);
667
+ } else if ( strncmp(&table_alignment[table_column],"R",1) == 0) {
668
+ g_string_append_printf(out, "\t<t%c style=\"text-align:right;\"", cell_type);
641
669
  } else if ( strncmp(&table_alignment[table_column],"c",1) == 0) {
642
670
  g_string_append_printf(out, "\t<t%c style=\"text-align:center;\"", cell_type);
671
+ } else if ( strncmp(&table_alignment[table_column],"C",1) == 0) {
672
+ g_string_append_printf(out, "\t<t%c style=\"text-align:center;\"", cell_type);
643
673
  } else {
644
674
  g_string_append_printf(out, "\t<t%c style=\"text-align:left;\"", cell_type);
645
675
  }
@@ -705,8 +735,11 @@ static void print_html_endnotes(GString *out) {
705
735
  } else {
706
736
  g_string_append_printf(out, "<li id=\"fn:%d\">\n", counter);
707
737
  padded = 2;
738
+ am_printing_html_footnote = TRUE;
739
+ footnote_counter_to_print = counter;
708
740
  print_html_element_list(out, note_elt, false);
709
- g_string_append_printf(out, " <a href=\"#fnref:%d\" title=\"return to article\" class=\"reversefootnote\">&#160;&#8617;</a>", counter);
741
+ am_printing_html_footnote = FALSE;
742
+ footnote_counter_to_print = 0;
710
743
  pad(out, 1);
711
744
  g_string_append_printf(out, "</li>");
712
745
  }
@@ -737,7 +770,7 @@ static void print_latex_string(GString *out, char *str) {
737
770
  g_string_append_printf(out, "\\^{}");
738
771
  break;
739
772
  case '\\':
740
- g_string_append_printf(out, "$\\backslash$");
773
+ g_string_append_printf(out, "\\textbackslash{}");
741
774
  break;
742
775
  case '~':
743
776
  g_string_append_printf(out, "\\ensuremath{\\sim}");
@@ -818,6 +851,8 @@ static void print_latex_element(GString *out, element *elt) {
818
851
  char *label;
819
852
  char *height;
820
853
  char *width;
854
+ char *upper;
855
+ int i;
821
856
  double floatnum;
822
857
  switch (elt->key) {
823
858
  case SPACE:
@@ -871,9 +906,9 @@ static void print_latex_element(GString *out, element *elt) {
871
906
  label = label_from_string(elt->contents.link->url,0);
872
907
  if (elt->contents.link->label != NULL) {
873
908
  print_latex_element_list(out, elt->contents.link->label);
874
- g_string_append_printf(out, " (\\autoref\{%s})", label);
909
+ g_string_append_printf(out, " (\\autoref{%s})", label);
875
910
  } else {
876
- g_string_append_printf(out, "\\autoref\{%s}", label);
911
+ g_string_append_printf(out, "\\autoref{%s}", label);
877
912
  }
878
913
  free(label);
879
914
  } else if ( (elt->contents.link->label != NULL) &&
@@ -1188,7 +1223,7 @@ static void print_latex_element(GString *out, element *elt) {
1188
1223
  }
1189
1224
  }
1190
1225
  }
1191
- if (elt->children->contents.str == NULL) {
1226
+ if ((elt->children != NULL) && (elt->children->contents.str == NULL)) {
1192
1227
  elt->children->contents.str = strdup(elt->contents.str);
1193
1228
  add_endnote(elt->children);
1194
1229
  }
@@ -1208,7 +1243,9 @@ static void print_latex_element(GString *out, element *elt) {
1208
1243
  break;
1209
1244
  case TERM:
1210
1245
  pad(out,2);
1211
- g_string_append_printf(out, "\\item[%s]", elt->contents.str);
1246
+ g_string_append_printf(out, "\\item[");
1247
+ print_latex_element_list(out, elt->children);
1248
+ g_string_append_printf(out, "]");
1212
1249
  padded = 0;
1213
1250
  break;
1214
1251
  case DEFINITION:
@@ -1220,6 +1257,7 @@ static void print_latex_element(GString *out, element *elt) {
1220
1257
  case METADATA:
1221
1258
  /* Metadata is present, so this should be a "complete" document */
1222
1259
  print_latex_header(out, elt);
1260
+ html_footer = is_html_complete_doc(elt);
1223
1261
  break;
1224
1262
  case METAKEY:
1225
1263
  if (strcmp(elt->contents.str, "title") == 0) {
@@ -1281,11 +1319,17 @@ static void print_latex_element(GString *out, element *elt) {
1281
1319
  pad(out, 2);
1282
1320
  g_string_append_printf(out, "\\begin{table}[htbp]\n\\begin{minipage}{\\linewidth}\n\\setlength{\\tymax}{0.5\\linewidth}\n\\centering\n\\small\n");
1283
1321
  print_latex_element_list(out, elt->children);
1284
- g_string_append_printf(out, "\n\\end{tabular}\n\\end{minipage}\n\\end{table}\n");
1322
+ g_string_append_printf(out, "\n\\end{tabulary}\n\\end{minipage}\n\\end{table}\n");
1285
1323
  padded = 0;
1286
1324
  break;
1287
1325
  case TABLESEPARATOR:
1288
- g_string_append_printf(out, "\\begin{tabular}{@{}%s@{}} \\toprule\n", elt->contents.str);
1326
+ upper = strdup(elt->contents.str);
1327
+
1328
+ for(i = 0; upper[ i ]; i++)
1329
+ upper[i] = toupper(upper[ i ]);
1330
+
1331
+ g_string_append_printf(out, "\\begin{tabulary}{\\textwidth}{@{}%s@{}} \\toprule\n", upper);
1332
+ free(upper);
1289
1333
  break;
1290
1334
  case TABLECAPTION:
1291
1335
  if (elt->children->key == TABLELABEL) {
@@ -1675,7 +1719,7 @@ static void print_odf_string(GString *out, char *str) {
1675
1719
  }
1676
1720
 
1677
1721
  /* print_odf_element_list - print an element list as ODF */
1678
- void print_odf_element_list(GString *out, element *list) {
1722
+ static void print_odf_element_list(GString *out, element *list) {
1679
1723
  while (list != NULL) {
1680
1724
  print_odf_element(out, list);
1681
1725
  list = list->next;
@@ -1683,11 +1727,12 @@ void print_odf_element_list(GString *out, element *list) {
1683
1727
  }
1684
1728
 
1685
1729
  /* print_odf_element - print an element as ODF */
1686
- void print_odf_element(GString *out, element *elt) {
1730
+ static void print_odf_element(GString *out, element *elt) {
1687
1731
  int lev;
1688
1732
  char *label;
1689
1733
  char *height;
1690
1734
  char *width;
1735
+ /* element *locator = NULL; */
1691
1736
  int old_type = 0;
1692
1737
  switch (elt->key) {
1693
1738
  case SPACE:
@@ -1727,6 +1772,13 @@ void print_odf_element(GString *out, element *elt) {
1727
1772
  g_string_append_printf(out, "</text:span>");
1728
1773
  break;
1729
1774
  case HTML:
1775
+ /* don't print HTML */
1776
+ /* but do print HTML comments for raw ODF */
1777
+ if (strncmp(elt->contents.str,"<!--",4) == 0) {
1778
+ /* trim "-->" from end */
1779
+ elt->contents.str[strlen(elt->contents.str)-3] = '\0';
1780
+ g_string_append_printf(out, "%s", &elt->contents.str[4]);
1781
+ }
1730
1782
  break;
1731
1783
  case LINK:
1732
1784
  if (elt->contents.link->url[0] == '#') {
@@ -1863,7 +1915,7 @@ void print_odf_element(GString *out, element *elt) {
1863
1915
  if (strncmp(elt->contents.str,"<!--",4) == 0) {
1864
1916
  /* trim "-->" from end */
1865
1917
  elt->contents.str[strlen(elt->contents.str)-3] = '\0';
1866
- g_string_append_printf(out, "%s", &elt->contents.str[4]);
1918
+ g_string_append_printf(out, "<text:p text:style-name=\"Standard\">%s</text:p>", &elt->contents.str[4]);
1867
1919
  }
1868
1920
  break;
1869
1921
  case VERBATIM:
@@ -1883,6 +1935,10 @@ void print_odf_element(GString *out, element *elt) {
1883
1935
  }
1884
1936
  old_type = odf_type;
1885
1937
  odf_type = BULLETLIST;
1938
+ if (odf_list_needs_end_p) {
1939
+ g_string_append_printf(out, "%s", "</text:p>");
1940
+ odf_list_needs_end_p = 0;
1941
+ }
1886
1942
  g_string_append_printf(out, "%s", "<text:list>");
1887
1943
  print_odf_element_list(out, elt->children);
1888
1944
  g_string_append_printf(out, "%s", "</text:list>");
@@ -1895,6 +1951,10 @@ void print_odf_element(GString *out, element *elt) {
1895
1951
  }
1896
1952
  old_type = odf_type;
1897
1953
  odf_type = ORDEREDLIST;
1954
+ if (odf_list_needs_end_p) {
1955
+ g_string_append_printf(out, "%s", "</text:p>");
1956
+ odf_list_needs_end_p = 0;
1957
+ }
1898
1958
  g_string_append_printf(out, "%s", "<text:list>\n");
1899
1959
  print_odf_element_list(out, elt->children);
1900
1960
  g_string_append_printf(out, "%s", "</text:list>\n");
@@ -1904,10 +1964,12 @@ void print_odf_element(GString *out, element *elt) {
1904
1964
  g_string_append_printf(out, "<text:list-item>\n");
1905
1965
  if (elt->children->children->key != PARA) {
1906
1966
  g_string_append_printf(out, "<text:p text:style-name=\"P2\">");
1967
+ odf_list_needs_end_p = 1;
1907
1968
  }
1908
1969
  print_odf_element_list(out, elt->children);
1909
1970
 
1910
- if ((list_contains_key(elt->children,BULLETLIST) ||
1971
+ odf_list_needs_end_p = 0;
1972
+ if ((list_contains_key(elt->children,BULLETLIST) ||
1911
1973
  (list_contains_key(elt->children,ORDEREDLIST)))) {
1912
1974
  } else {
1913
1975
  if (elt->children->children->key != PARA) {
@@ -1956,20 +2018,49 @@ void print_odf_element(GString *out, element *elt) {
1956
2018
  break;
1957
2019
  case NOCITATION:
1958
2020
  case CITATION:
2021
+ /* Get locator, if present */
2022
+ /* locator = locator_for_citation(elt); */
2023
+
1959
2024
  if (strncmp(elt->contents.str,"[#",2) == 0) {
1960
- /* bibtex citation key */
2025
+ /* reference specified externally, so just display it */
1961
2026
  g_string_append_printf(out, "%s", elt->contents.str);
1962
2027
  } else {
1963
- g_string_append_printf(out, "[#%s]", elt->contents.str);
2028
+ /* reference specified within the MMD document,
2029
+ so will output as footnote */
2030
+ if (elt->children->contents.str == NULL) {
2031
+ /* First use of this citation */
2032
+ ++notenumber;
2033
+ char buf[5];
2034
+ sprintf(buf, "%d",notenumber);
2035
+ /* Store the number for future reference */
2036
+ elt->children->contents.str = strdup(buf);
2037
+
2038
+ /* Insert the footnote here */
2039
+ old_type = odf_type;
2040
+ odf_type = NOTE;
2041
+ g_string_append_printf(out, "<text:note text:id=\"cite%s\" text:note-class=\"footnote\"><text:note-body>\n", buf);
2042
+ print_odf_element_list(out, elt->children);
2043
+ g_string_append_printf(out, "</text:note-body>\n</text:note>\n");
2044
+ odf_type = old_type;
2045
+
2046
+ elt->children->key = CITATION;
2047
+ } else {
2048
+ /* Additional reference to prior citation,
2049
+ and therefore must link to another footnote */
2050
+ 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);
2051
+ }
2052
+ elt->children = NULL;
1964
2053
  }
1965
- elt->children = NULL;
2054
+ break;
2055
+ case LOCATOR:
2056
+ print_odf_element_list(out, elt->children);
1966
2057
  break;
1967
2058
  case DEFLIST:
1968
2059
  print_odf_element_list(out, elt->children);
1969
2060
  break;
1970
2061
  case TERM:
1971
2062
  g_string_append_printf(out, "<text:p><text:span text:style-name=\"MMD-Bold\">");
1972
- print_odf_string(out, elt->contents.str);
2063
+ print_odf_element_list(out, elt->children);
1973
2064
  g_string_append_printf(out, "</text:span></text:p>");
1974
2065
  break;
1975
2066
  case DEFINITION:
@@ -2086,8 +2177,12 @@ void print_odf_element(GString *out, element *elt) {
2086
2177
  } else {
2087
2178
  if ( strncmp(&table_alignment[table_column],"r",1) == 0) {
2088
2179
  g_string_append_printf(out, " text:style-name=\"MMD-Table-Right\"");
2180
+ } else if ( strncmp(&table_alignment[table_column],"R",1) == 0) {
2181
+ g_string_append_printf(out, " text:style-name=\"MMD-Table-Right\"");
2089
2182
  } else if ( strncmp(&table_alignment[table_column],"c",1) == 0) {
2090
2183
  g_string_append_printf(out, " text:style-name=\"MMD-Table-Center\"");
2184
+ } else if ( strncmp(&table_alignment[table_column],"C",1) == 0) {
2185
+ g_string_append_printf(out, " text:style-name=\"MMD-Table-Center\"");
2091
2186
  } else {
2092
2187
  g_string_append_printf(out, " text:style-name=\"MMD-Table\"");
2093
2188
  }
@@ -2129,6 +2224,9 @@ void print_element_list(GString *out, element *elt, int format, int exts) {
2129
2224
  language = ENGLISH;
2130
2225
  html_footer = FALSE;
2131
2226
  no_latex_footnote = FALSE;
2227
+ footnote_counter_to_print = 0;
2228
+ odf_list_needs_end_p = 0;
2229
+ element *title;
2132
2230
 
2133
2231
  extensions = exts;
2134
2232
  padded = 2; /* set padding to 2, so no extra blank lines at beginning */
@@ -2154,6 +2252,14 @@ void print_element_list(GString *out, element *elt, int format, int exts) {
2154
2252
  break;
2155
2253
  case OPML_FORMAT:
2156
2254
  g_string_append_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<opml version=\"1.0\">\n");
2255
+ if (list_contains_key(elt,METAKEY)) {
2256
+ title = metadata_for_key("title",elt);
2257
+ if (title != NULL) {
2258
+ g_string_append_printf(out,"<head><title>");
2259
+ print_raw_element(out,title->children);
2260
+ g_string_append_printf(out,"</title></head>");
2261
+ }
2262
+ }
2157
2263
  g_string_append_printf(out, "<body>\n");
2158
2264
  print_opml_element_list(out, elt);
2159
2265
  if (html_footer == TRUE) print_opml_metadata(out, elt);
@@ -2192,15 +2298,15 @@ void print_element_list(GString *out, element *elt, int format, int exts) {
2192
2298
 
2193
2299
  void print_html_header(GString *out, element *elt, bool obfuscate) {
2194
2300
  g_string_append_printf(out,
2195
- "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n");
2301
+ "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\"/>\n");
2196
2302
 
2197
2303
  print_html_element_list(out, elt->children, obfuscate);
2198
- g_string_append_printf(out, "</head>\n<body>\n");
2304
+ g_string_append_printf(out, "</head>\n<body>\n\n");
2199
2305
  }
2200
2306
 
2201
2307
 
2202
2308
  void print_html_footer(GString *out, bool obfuscate) {
2203
- g_string_append_printf(out, "\n</body>\n</html>");
2309
+ g_string_append_printf(out, "\n\n</body>\n</html>");
2204
2310
  }
2205
2311
 
2206
2312
 
@@ -2214,7 +2320,9 @@ void print_latex_footer(GString *out) {
2214
2320
  pad(out,2);
2215
2321
  g_string_append_printf(out, "\\input{%s}\n", latex_footer);
2216
2322
  }
2217
- g_string_append_printf(out, "\n\\end{document}");
2323
+ if (html_footer) {
2324
+ g_string_append_printf(out, "\n\\end{document}");
2325
+ }
2218
2326
  }
2219
2327
 
2220
2328
 
@@ -2229,8 +2337,6 @@ void print_memoir_element_list(GString *out, element *list) {
2229
2337
 
2230
2338
  /* print_memoir_element - print an element as LaTeX for memoir class */
2231
2339
  static void print_memoir_element(GString *out, element *elt) {
2232
- int lev;
2233
- char *label;
2234
2340
  switch (elt->key) {
2235
2341
  case VERBATIM:
2236
2342
  pad(out, 1);
@@ -2556,6 +2662,20 @@ static bool is_html_complete_doc(element *meta) {
2556
2662
  return FALSE;
2557
2663
  }
2558
2664
 
2665
+ /* if citation has a locator, return as element and "prune", else NULL */
2666
+ element * locator_for_citation(element *elt) {
2667
+ element *result;
2668
+
2669
+ if ((elt->children != NULL) && (elt->children->key == LOCATOR)) {
2670
+ /* Locator is present */
2671
+ result = elt->children;
2672
+ elt->children = elt->children->next;
2673
+ return result;
2674
+ } else {
2675
+ /* no locator exists */
2676
+ return NULL;
2677
+ }
2678
+ }
2559
2679
 
2560
2680
  /* print_opml_element_list - print an element list as OPML */
2561
2681
  void print_opml_element_list(GString *out, element *list) {
@@ -2702,3 +2822,12 @@ void print_odf_body_element_list(GString *out, element *list) {
2702
2822
  list = list->next;
2703
2823
  }
2704
2824
  }
2825
+
2826
+ /* bogus function just references a couple globals defined in utility_functions.c but not used in this source file */
2827
+ static void bogus_function()
2828
+ {
2829
+ static char* bogus;
2830
+ bogus = charbuf;
2831
+ static element* bogus2;
2832
+ bogus2 = parse_result;
2833
+ }