rpeg-multimarkdown 0.1.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
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
+ }