mmd-ruby 5.2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +78 -0
  3. data/MultiMarkdown-5/src/GLibFacade.c +310 -0
  4. data/MultiMarkdown-5/src/GLibFacade.h +100 -0
  5. data/MultiMarkdown-5/src/beamer.c +182 -0
  6. data/MultiMarkdown-5/src/beamer.h +11 -0
  7. data/MultiMarkdown-5/src/critic.c +117 -0
  8. data/MultiMarkdown-5/src/critic.h +15 -0
  9. data/MultiMarkdown-5/src/glib.h +11 -0
  10. data/MultiMarkdown-5/src/html.c +1171 -0
  11. data/MultiMarkdown-5/src/html.h +14 -0
  12. data/MultiMarkdown-5/src/latex.c +1234 -0
  13. data/MultiMarkdown-5/src/latex.h +16 -0
  14. data/MultiMarkdown-5/src/libMultiMarkdown.h +257 -0
  15. data/MultiMarkdown-5/src/lyx.c +2269 -0
  16. data/MultiMarkdown-5/src/lyx.h +37 -0
  17. data/MultiMarkdown-5/src/lyxbeamer.c +265 -0
  18. data/MultiMarkdown-5/src/lyxbeamer.h +11 -0
  19. data/MultiMarkdown-5/src/memoir.c +80 -0
  20. data/MultiMarkdown-5/src/memoir.h +10 -0
  21. data/MultiMarkdown-5/src/multimarkdown.c +559 -0
  22. data/MultiMarkdown-5/src/odf.c +1241 -0
  23. data/MultiMarkdown-5/src/odf.h +18 -0
  24. data/MultiMarkdown-5/src/opml.c +189 -0
  25. data/MultiMarkdown-5/src/opml.h +15 -0
  26. data/MultiMarkdown-5/src/parse_utilities.c +912 -0
  27. data/MultiMarkdown-5/src/parser.c +17341 -0
  28. data/MultiMarkdown-5/src/parser.h +190 -0
  29. data/MultiMarkdown-5/src/rng.c +117 -0
  30. data/MultiMarkdown-5/src/rtf.c +665 -0
  31. data/MultiMarkdown-5/src/rtf.h +17 -0
  32. data/MultiMarkdown-5/src/strtok.c +56 -0
  33. data/MultiMarkdown-5/src/strtok.h +9 -0
  34. data/MultiMarkdown-5/src/text.c +56 -0
  35. data/MultiMarkdown-5/src/text.h +11 -0
  36. data/MultiMarkdown-5/src/toc.c +157 -0
  37. data/MultiMarkdown-5/src/toc.h +15 -0
  38. data/MultiMarkdown-5/src/transclude.c +335 -0
  39. data/MultiMarkdown-5/src/transclude.h +28 -0
  40. data/MultiMarkdown-5/src/version.h +59 -0
  41. data/MultiMarkdown-5/src/writer.c +767 -0
  42. data/MultiMarkdown-5/src/writer.h +38 -0
  43. data/README.md +77 -0
  44. data/Rakefile +88 -0
  45. data/bin/mmd-ruby +123 -0
  46. data/ext/extconf.h +3 -0
  47. data/ext/extconf.rb +10 -0
  48. data/ext/multimarkdown.c +133 -0
  49. data/lib/mmd-jekyll.rb +19 -0
  50. data/lib/mmd-ruby.rb +1 -0
  51. data/lib/mmd.rb +1 -0
  52. data/lib/multimarkdown-ruby.rb +1 -0
  53. data/lib/multimarkdown.bundle +0 -0
  54. data/lib/multimarkdown.rb +69 -0
  55. data/lib/multimarkdown/version.rb +6 -0
  56. data/mmd-ruby.gemspec +37 -0
  57. data/test/extensions_test.rb +174 -0
  58. data/test/multimarkdown_test.rb +77 -0
  59. metadata +120 -0
@@ -0,0 +1,16 @@
1
+ #ifndef LATEX_PARSER_H
2
+ #define LATEX_PARSER_H
3
+
4
+ #include "parser.h"
5
+ #include "writer.h"
6
+
7
+
8
+ void print_latex_node_tree(GString *out, node *list, scratch_pad *scratch);
9
+ void print_latex_node(GString *out, node *n, scratch_pad *scratch);
10
+ void print_latex_localized_typography(GString *out, int character, scratch_pad *scratch);
11
+ void print_latex_string(GString *out, char *str, scratch_pad *scratch);
12
+ void print_latex_url(GString *out, char *str, scratch_pad *scratch);
13
+ void print_latex_endnotes(GString *out, scratch_pad *scratch);
14
+ int find_latex_mode(int format, node *n);
15
+
16
+ #endif
@@ -0,0 +1,257 @@
1
+ /**
2
+
3
+ MultiMarkdown - lightweight markup processor
4
+
5
+ @file libMultiMarkdown.h
6
+
7
+ @brief MultiMarkdown library header
8
+
9
+ libMultiMarkdown.h provides the key commands to convert raw MultiMarkdown
10
+ text into a desired export format.
11
+
12
+ For most simple uses, the main API commands provided here are sufficient.
13
+ For more complex scenarios, however, you may need to handle file
14
+ transclusion which requires knowledge about the location of the source
15
+ file in order to appropriately handle relative links. In this case, you
16
+ may benefit from examining multimarkdown.c.
17
+
18
+ @author Fletcher T. Penney
19
+ @bug No known bugs
20
+
21
+ **/
22
+
23
+ /*
24
+
25
+ Copyright © 2013-2016 Fletcher T. Penney.
26
+
27
+
28
+ The `c-template` project is released under the MIT License.
29
+
30
+
31
+ MMD 5 is released under the MIT License.
32
+
33
+
34
+ CuTest is released under the zlib/libpng license. See CuTest.c for the text
35
+ of the license.
36
+
37
+
38
+ ## The MIT License ##
39
+
40
+ Permission is hereby granted, free of charge, to any person obtaining a copy
41
+ of this software and associated documentation files (the "Software"), to deal
42
+ in the Software without restriction, including without limitation the rights
43
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
44
+ copies of the Software, and to permit persons to whom the Software is
45
+ furnished to do so, subject to the following conditions:
46
+
47
+ The above copyright notice and this permission notice shall be included in
48
+ all copies or substantial portions of the Software.
49
+
50
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
53
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
54
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
56
+ THE SOFTWARE.
57
+
58
+ */
59
+
60
+
61
+ #ifndef LIB_MULTIMARKDOWN_H
62
+ #define LIB_MULTIMARKDOWN_H
63
+
64
+
65
+ /* Main API commands */
66
+
67
+ /// Convert source string to output string, based on provided `parser_extensions`
68
+ /// and requested `export_format`.
69
+ /// The returned `char *` will need to be freed after it is no longer needed.
70
+ char * markdown_to_string(
71
+ const char * source, //!< Pointer to c-string of the source text
72
+ unsigned long extensions, //!< Bit field of parser_extensions
73
+ int format //!< Specify export_format to be used
74
+ );
75
+
76
+ /// Does the source string have metadata, using provided `parser_extensions`?
77
+ ///
78
+ bool has_metadata(
79
+ const char *source, //!< Pointer to c-string of the source text
80
+ unsigned long extensions //!< Bit field of parser_extensions
81
+ );
82
+
83
+ /// List all metadata keys, using provided `parser_extensions`.
84
+ /// The returned `char *` will need to be freed after it is no longer needed.
85
+ char * extract_metadata_keys(
86
+ const char *source, //!< Pointer to c-string of the source text
87
+ unsigned long extensions //!< Bit field of parser_extensions
88
+ );
89
+
90
+ /// Extract the value for the specified metadata key, using provided `parser_extensions`.
91
+ /// The returned `char *` will need to be freed after it is no longer needed.
92
+ char * extract_metadata_value(
93
+ const char *source, //!< Pointer to c-string of the source text
94
+ unsigned long extensions, //!< Bit field of parser_extensions
95
+ char *key //!< C-string of the key we need to find
96
+ );
97
+
98
+ /// Return the version string for this build of libMultiMarkdown
99
+ /// The returned `char *` will need to be freed after it is no longer needed.
100
+ char * mmd_version(void);
101
+
102
+
103
+ /// These are the basic extensions that enable or disable MultiMarkdown features
104
+ enum parser_extensions {
105
+ EXT_COMPATIBILITY = 1 << 0, //!< Markdown compatibility mode
106
+ EXT_COMPLETE = 1 << 1, //!< Create complete document
107
+ EXT_SNIPPET = 1 << 2, //!< Create snippet only
108
+ EXT_HEAD_CLOSED = 1 << 3, //!< for use by parser
109
+ EXT_SMART = 1 << 4, //!< Enable Smart quotes
110
+ EXT_NOTES = 1 << 5, //!< Enable Footnotes
111
+ EXT_NO_LABELS = 1 << 6, //!< Don't add anchors to headers, etc.
112
+ EXT_FILTER_STYLES = 1 << 7, //!< Filter out style blocks
113
+ EXT_FILTER_HTML = 1 << 8, //!< Filter out raw HTML
114
+ EXT_PROCESS_HTML = 1 << 9, //!< Process Markdown inside HTML
115
+ EXT_NO_METADATA = 1 << 10, //!< Don't parse Metadata
116
+ EXT_OBFUSCATE = 1 << 11, //!< Mask email addresses
117
+ EXT_CRITIC = 1 << 12, //!< Critic Markup Support
118
+ EXT_CRITIC_ACCEPT = 1 << 13, //!< Accept all proposed changes
119
+ EXT_CRITIC_REJECT = 1 << 14, //!< Reject all proposed changes
120
+ EXT_RANDOM_FOOT = 1 << 15, //!< Use random numbers for footnote links
121
+ EXT_HEADINGSECTION = 1 << 16, //!< Group blocks under parent heading
122
+ EXT_ESCAPED_LINE_BREAKS = 1 << 17, //!< Escaped line break
123
+ EXT_NO_STRONG = 1 << 18, //!< Don't allow nested \<strong\>'s
124
+ EXT_NO_EMPH = 1 << 19, //!< Don't allow nested \<emph\>'s
125
+ EXT_FAKE = 1 << 31, //!< 31 is highest number allowed
126
+ };
127
+
128
+ /// Define the output formats we support -- not all of these should be used
129
+ enum export_formats {
130
+ ORIGINAL_FORMAT, //!< Transclusion happens, but no parsing
131
+ HTML_FORMAT, //!< Well supported
132
+ TEXT_FORMAT, //!< Not currently used, may exit host process
133
+ LATEX_FORMAT, //!< Well supported
134
+ MEMOIR_FORMAT, //!< Well supported
135
+ BEAMER_FORMAT, //!< Well supported
136
+ OPML_FORMAT, //!< Well supported
137
+ ODF_FORMAT, //!< Well supported
138
+ RTF_FORMAT, //!< Not recommended for production code, may crash
139
+ CRITIC_ACCEPT_FORMAT, //!< Used as a pre-processing step
140
+ CRITIC_REJECT_FORMAT, //!< Used as a pre-processing step
141
+ CRITIC_HTML_HIGHLIGHT_FORMAT, //!< Used as a pre-processing step
142
+ LYX_FORMAT, //!< Developed and maintained by Charles R. Cowan
143
+ TOC_FORMAT, //!< Used as a pre-processing step
144
+ };
145
+
146
+ /// These are the identifiers for node types
147
+ enum keys {
148
+ NO_TYPE,
149
+ LIST,
150
+ STR,
151
+ APOSTROPHE,
152
+ FOOTER,
153
+ PARA,
154
+ PLAIN,
155
+ LINEBREAK,
156
+ SPACE,
157
+ HEADINGSECTION,
158
+ H1, H2, H3, H4, H5, H6, H7, //!< Keep H1 through H7 in order
159
+ METADATA,
160
+ METAKEY,
161
+ METAVALUE,
162
+ MATHSPAN,
163
+ STRONG,
164
+ EMPH,
165
+ LINK,
166
+ SOURCE,
167
+ TITLE,
168
+ REFNAME,
169
+ AUTOLABEL,
170
+ IMAGE,
171
+ IMAGEBLOCK,
172
+ NOTEREFERENCE,
173
+ CODE,
174
+ HTML,
175
+ ELLIPSIS,
176
+ ENDASH,
177
+ EMDASH,
178
+ SINGLEQUOTED,
179
+ DOUBLEQUOTED,
180
+ BLOCKQUOTE,
181
+ BLOCKQUOTEMARKER,
182
+ RAW,
183
+ VERBATIM,
184
+ VERBATIMTYPE,
185
+ VERBATIMFENCE,
186
+ DEFLIST,
187
+ TERM,
188
+ DEFINITION,
189
+ HRULE,
190
+ ORDEREDLIST,
191
+ BULLETLIST,
192
+ LISTITEM,
193
+ HTMLBLOCK,
194
+ TABLE,
195
+ TABLECAPTION,
196
+ TABLELABEL,
197
+ TABLESEPARATOR,
198
+ TABLECELL,
199
+ CELLSPAN,
200
+ TABLEROW,
201
+ TABLEBODY,
202
+ TABLEHEAD,
203
+ LINKREFERENCE,
204
+ NOTESOURCE,
205
+ CITATIONSOURCE,
206
+ SOURCEBRANCH,
207
+ NOTELABEL,
208
+ GLOSSARYLABEL,
209
+ ATTRVALUE,
210
+ ATTRKEY,
211
+ GLOSSARYSOURCE,
212
+ GLOSSARYSORTKEY,
213
+ GLOSSARYTERM,
214
+ CITATION,
215
+ NOCITATION,
216
+ CRITICADDITION,
217
+ CRITICDELETION,
218
+ CRITICSUBSTITUTION,
219
+ CRITICHIGHLIGHT,
220
+ CRITICCOMMENT,
221
+ SUPERSCRIPT,
222
+ SUBSCRIPT,
223
+ VARIABLE,
224
+ ABBREVIATION,
225
+ ABBR,
226
+ ABBRSTART,
227
+ ABBRSTOP,
228
+ TOC,
229
+ KEY_COUNTER //!< This *MUST* be the last item in the list
230
+ };
231
+
232
+
233
+ /// This is the element used in the resulting parse tree
234
+ struct node {
235
+ short key; //!< What type of element is this?
236
+ char *str; //!< Relevant string from source for this element
237
+ struct link_data *link_data; //!< Store link info when relevant to this node
238
+ struct node *children; //!< Pointer to child elements
239
+ struct node *next; //!< Pointer to next element
240
+ };
241
+
242
+ /// This is the element used in the resulting parse tree
243
+ typedef struct node node;
244
+
245
+
246
+ /// Structure to simplify handling of links
247
+ struct link_data {
248
+ char *label; //!< Text of the label, if this is a reference link
249
+ char *source; //!< Source URL string
250
+ char *title; //!< Title string
251
+ node *attr; //!< Pointer to tree of attributes, if any
252
+ };
253
+
254
+ /// Structure to simplify handling of links
255
+ typedef struct link_data link_data;
256
+
257
+ #endif
@@ -0,0 +1,2269 @@
1
+ /*
2
+
3
+ lyx.c -- LyX writer
4
+
5
+ (c) 2013 Charles R. Cowan
6
+ (c) 2013 Fletcher T. Penney (http://fletcherpenney.net/).
7
+
8
+ Derived from MultiMarkdown by Fletcher T. Penney - added code to support the LyX format directly
9
+
10
+ Derived from peg-multimarkdown, which was forked from peg-markdown,
11
+ which is (c) 2008 John MacFarlane (jgm at berkeley dot edu), and
12
+ licensed under GNU GPL or MIT.
13
+
14
+ This program is free software; you can redistribute it and/or modify
15
+ it under the terms of the GNU General Public License or the MIT
16
+ license. See LICENSE for details.
17
+
18
+ This program is distributed in the hope that it will be useful,
19
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
+ GNU General Public License for more details.
22
+
23
+ */
24
+
25
+ #include "lyx.h"
26
+
27
+ /* #define DEBUG_ON */
28
+
29
+ /* #define DUMP_TREES */
30
+
31
+ /* allow the user to change the heading levels */
32
+
33
+ GString *heading_name[7];
34
+ GString *used_abbreviations;
35
+
36
+ #if defined(DEBUG_ON) || defined(DUMP_TREES)
37
+ const char * const node_types[] = {
38
+ "NO_TYPE",
39
+ "LIST",
40
+ "STR",
41
+ "APOSTROPHE",
42
+ "FOOTER",
43
+ "PARA",
44
+ "PLAIN",
45
+ "LINEBREAK",
46
+ "SPACE",
47
+ "HEADINGSECTION",
48
+ "H1",
49
+ "H2",
50
+ "H3",
51
+ "H4",
52
+ "H5",
53
+ "H6",
54
+ "H7",
55
+ "METADATA",
56
+ "METAKEY",
57
+ "METAVALUE",
58
+ "MATHSPAN",
59
+ "STRONG",
60
+ "EMPH",
61
+ "LINK",
62
+ "SOURCE",
63
+ "TITLE",
64
+ "REFNAME",
65
+ "AUTOLABEL",
66
+ "IMAGE",
67
+ "IMAGEBLOCK",
68
+ "NOTEREFERENCE",
69
+ "CODE",
70
+ "HTML",
71
+ "ELLIPSIS",
72
+ "ENDASH",
73
+ "EMDASH",
74
+ "SINGLEQUOTED",
75
+ "DOUBLEQUOTED",
76
+ "BLOCKQUOTE",
77
+ "BLOCKQUOTEMARKER",
78
+ "RAW",
79
+ "VERBATIM",
80
+ "VERBATIMTYPE",
81
+ "DEFLIST",
82
+ "TERM",
83
+ "DEFINITION",
84
+ "HRULE",
85
+ "ORDEREDLIST",
86
+ "BULLETLIST",
87
+ "LISTITEM",
88
+ "HTMLBLOCK",
89
+ "TABLE",
90
+ "TABLECAPTION",
91
+ "TABLELABEL",
92
+ "TABLESEPARATOR",
93
+ "TABLECELL",
94
+ "CELLSPAN",
95
+ "TABLEROW",
96
+ "TABLEBODY",
97
+ "TABLEHEAD",
98
+ "LINKREFERENCE",
99
+ "NOTESOURCE",
100
+ "CITATIONSOURCE",
101
+ "SOURCEBRANCH",
102
+ "NOTELABEL",
103
+ "GLOSSARYLABEL",
104
+ "ATTRVALUE",
105
+ "ATTRKEY",
106
+ "GLOSSARYSOURCE",
107
+ "GLOSSARYSORTKEY",
108
+ "GLOSSARYTERM",
109
+ "CITATION",
110
+ "NOCITATION",
111
+ "CRITICADDITION",
112
+ "CRITICDELETION",
113
+ "CRITICSUBSTITUTION",
114
+ "CRITICHIGHLIGHT",
115
+ "CRITICCOMMENT",
116
+ "SUPERSCRIPT",
117
+ "SUBSCRIPT",
118
+ "VARIABLE",
119
+ "ABBREVIATION",
120
+ "ABBR",
121
+ "ABBRSTART",
122
+ "ABBRSTOP",
123
+ "KEY_COUNTER"
124
+ };
125
+
126
+
127
+ #endif
128
+
129
+
130
+ #ifdef DUMP_TREES
131
+
132
+ void dump_tree(node* n, scratch_pad *scratch)
133
+ {
134
+ int i;
135
+ while(n != NULL){
136
+ scratch->lyx_debug_nest++;
137
+ g_string_append(scratch->lyx_debug_pad," "); /* add a level */
138
+ fprintf(stderr, "\n\n%sNode: %s",scratch->lyx_debug_pad->str,node_types[n->key]);
139
+ fprintf(stderr, "\n%s str: %s",scratch->lyx_debug_pad->str,n->str);
140
+ if (n->link_data != NULL){
141
+ fprintf(stderr, "\n%s label: %s",scratch->lyx_debug_pad->str,n->link_data->label);
142
+ fprintf(stderr, "\n%s source: %s",scratch->lyx_debug_pad->str,n->link_data->source);
143
+ fprintf(stderr, "\n%s title: %s",scratch->lyx_debug_pad->str,n->link_data->title);
144
+ }
145
+ dump_tree(n->children,scratch);
146
+ scratch->lyx_debug_nest--;
147
+ g_string_free(scratch->lyx_debug_pad,TRUE); /* don' see a way to shorten the string */
148
+ scratch->lyx_debug_pad = g_string_new(""); /* so create a new, shorter one */
149
+ for(i=0;i<scratch->lyx_debug_nest;i++){
150
+ g_string_append(scratch->lyx_debug_pad," ");
151
+ }
152
+
153
+ n = n->next;
154
+ }
155
+ }
156
+ #endif
157
+
158
+
159
+ void perform_lyx_output(GString *out, node* list, scratch_pad *scratch)
160
+ {
161
+ node *headings;
162
+ node *base_header_level;
163
+ char *key;
164
+
165
+
166
+ #ifdef DUMP_TREES
167
+ fprintf(stderr, "\n*** Base Tree ***\n");
168
+ dump_tree(list,scratch);
169
+ fprintf (stderr, "\n*** End Base Tree ***\n");
170
+
171
+ fprintf(stderr, "\n*** LINK Tree ***\n");
172
+ dump_tree(scratch->links,scratch);
173
+ fprintf(stderr, "\n*** END LINK Tree ***\n");
174
+
175
+ #endif
176
+
177
+ /* initialize the heading names */
178
+ heading_name[0] = g_string_new("Part");
179
+ heading_name[1] = g_string_new("Chapter");
180
+ heading_name[2] = g_string_new("Section");
181
+ heading_name[3] = g_string_new("Subsection");
182
+ heading_name[4] = g_string_new("Subsubsection");
183
+ heading_name[5] = g_string_new("Paragraph");
184
+ heading_name[6] = g_string_new("Subparagraph");
185
+
186
+ /* get user supplied heading section names and base header level these both
187
+ affect creating the prefixes */
188
+
189
+ GString *lyx_headings = g_string_new("");
190
+ used_abbreviations = g_string_new("");
191
+ int hcount;
192
+ hcount = 0;
193
+ const char s[2] = ",";
194
+ char *token;
195
+ char *cleaned;
196
+ if (tree_contains_key(list, METAKEY)) {
197
+ headings = metadata_for_key("lyxheadings",list);
198
+ if (headings != NULL) {
199
+ key = metavalue_for_key("lyxheadings",list);
200
+ g_string_append(lyx_headings,key);
201
+ token = strtok(lyx_headings->str, s);
202
+ while( token != NULL ) {
203
+ g_string_free(heading_name[hcount],TRUE);
204
+ cleaned = clean_string(token);
205
+ heading_name[hcount] = g_string_new(cleaned);
206
+ free(cleaned);
207
+ token = strtok(NULL, s);
208
+ hcount++;
209
+ if (hcount>6){ /* only 7 allowed */
210
+ break;
211
+ }
212
+ }
213
+ free(key);
214
+ free(token);
215
+ }
216
+ }
217
+ g_string_free(lyx_headings,TRUE);
218
+
219
+ /* get base heading level */
220
+ scratch->baseheaderlevel = 1;
221
+ if (tree_contains_key(list, METAKEY)) {
222
+ base_header_level = metadata_for_key("baseheaderlevel",list);
223
+ if (base_header_level != NULL) {
224
+ key = metavalue_for_key("baseheaderlevel",list);
225
+ scratch->baseheaderlevel = atoi(key);
226
+ free(key);
227
+ };
228
+ };
229
+
230
+
231
+ /* add prefixes for LyX references */
232
+ add_prefixes(list, list, scratch);
233
+
234
+ bool isbeamer;
235
+ isbeamer = begin_lyx_output(out,list,scratch); /* get Metadata controls */
236
+ if (isbeamer){
237
+ g_string_free(heading_name[1],TRUE);
238
+ heading_name[1] = g_string_new("Section");
239
+ g_string_free(heading_name[2],TRUE);
240
+ heading_name[2] = g_string_new("Frame");
241
+ print_lyxbeamer_node_tree(out,list,scratch,FALSE);
242
+ } else {
243
+ print_lyx_node_tree(out,list,scratch,FALSE);
244
+ }
245
+ end_lyx_output(out,list,scratch); /* Close the document */
246
+
247
+ /* clean up the heading names */
248
+ int i;
249
+ for (i=0;i<=6;i++){
250
+ g_string_free(heading_name[i],TRUE);
251
+ }
252
+ g_string_free(used_abbreviations,TRUE);
253
+ }
254
+
255
+ /* begin_lyx_output -- Check metadata and open the document */
256
+ bool begin_lyx_output(GString *out, node* list, scratch_pad *scratch) {
257
+ #ifdef DEBUG_ON
258
+ fprintf(stderr, "begin_lyx_output\n");
259
+ #endif
260
+ node *content;
261
+ node *latex_mode;
262
+ node *number_headings;
263
+ node *clean_pdf;
264
+ node *quote_language;
265
+ node *modules;
266
+ node *packages;
267
+ char short_prefix[6];
268
+ int i,j;
269
+ const char s[2] = ",";
270
+ char *key;
271
+ char *label;
272
+ char *value;
273
+ char *temp;
274
+ char *token;
275
+ char *tmp;
276
+ char *cleaned;
277
+ bool isbeamer; /* beamer has different processing */
278
+
279
+ isbeamer = FALSE; /* only for beamer */
280
+
281
+
282
+ /* check for numbered versus unnumbered headings */
283
+ scratch->lyx_number_headers = TRUE; /* default - numbering */
284
+ if (tree_contains_key(list, METAKEY)) {
285
+ number_headings = metadata_for_key("numberheadings",list);
286
+ if (number_headings != NULL) {
287
+ key = metavalue_for_key("numberheadings",list);
288
+ label = label_from_string(key);
289
+ if (strcmp(label, "yes") == 0) {
290
+ scratch->lyx_number_headers = TRUE;
291
+ } else if (strcmp(label, "no") == 0) {
292
+ scratch->lyx_number_headers = FALSE;
293
+ }
294
+ free(label);
295
+ free(key);
296
+ }
297
+ }
298
+
299
+ /* Get the language for quotes */
300
+ if (tree_contains_key(list, METAKEY)) {
301
+ quote_language = metadata_for_key("quoteslanguage",list);
302
+ if (quote_language != NULL) {
303
+ key = metavalue_for_key("quoteslanguage",list);
304
+ temp = label_from_node_tree(quote_language->children);
305
+ if ((strcmp(temp, "nl") == 0) || (strcmp(temp, "dutch") == 0)) { scratch->language = DUTCH; } else
306
+ if ((strcmp(temp, "de") == 0) || (strcmp(temp, "german") == 0)) { scratch->language = GERMAN; } else
307
+ if (strcmp(temp, "germanguillemets") == 0) { scratch->language = GERMANGUILL; } else
308
+ if ((strcmp(temp, "fr") == 0) || (strcmp(temp, "french") == 0)) { scratch->language = FRENCH; } else
309
+ if ((strcmp(temp, "sv") == 0) || (strcmp(temp, "swedish") == 0)) { scratch->language = SWEDISH; }
310
+ free(temp);
311
+ free(key);
312
+ }
313
+ }
314
+
315
+ g_string_append(out, "#LyX File created by multimarkdown\n");
316
+ g_string_append(out,"\\lyxformat 413\n");
317
+ g_string_append(out, "\\begin_document\n");
318
+ g_string_append(out, "\\begin_header\n");
319
+
320
+ GString *lyx_class = g_string_new("");
321
+ if (tree_contains_key(list, METAKEY)) {
322
+ latex_mode = metadata_for_key("latexmode",list);
323
+ if (latex_mode != NULL) {
324
+ key = metavalue_for_key("latexmode",list);
325
+ label = label_from_string(key);
326
+ g_string_append(lyx_class,label);
327
+ if (strcmp(label,"beamer")==0){
328
+ isbeamer = TRUE;
329
+ }
330
+ free(label);
331
+ free(key);
332
+ } else {
333
+ g_string_append(lyx_class,"memoir");
334
+ }
335
+
336
+ }else{
337
+ g_string_append(lyx_class,"memoir");
338
+ }
339
+ g_string_append(out,"\\textclass ");
340
+ g_string_append_printf(out,"%s",lyx_class->str);
341
+ g_string_append(out,"\n");
342
+
343
+ g_string_append(out,"\\begin_preamble\n");
344
+ g_string_append(out,"\\usepackage{listings}\n");
345
+ g_string_append(out,"\\usepackage{natbib}\n");
346
+ g_string_append(out,"\\usepackage{nomencl}\n");
347
+ g_string_append(out,"\\usepackage{booktabs}\n");
348
+ g_string_append(out,"\\usepackage{refstyle}\n");
349
+ g_string_append(out,"\\usepackage{varioref}\n");
350
+
351
+
352
+ if (tree_contains_key(list, METAKEY)) {
353
+ packages = metadata_for_key("packages",list);
354
+ if (packages != NULL) {
355
+ key = metavalue_for_key("packages",list);
356
+ tmp = strdup(key);
357
+ token = strtok(tmp, s);
358
+ while( token != NULL ) {
359
+ g_string_append_printf(out,"\\usepackage{%s}\n",clean_string(token));
360
+ token = strtok(NULL, s);
361
+ }
362
+ free(key);
363
+ free(tmp);
364
+ }
365
+ }
366
+
367
+ if(isbeamer){
368
+ if (tree_contains_key(list, METAKEY)) {
369
+ content = metadata_for_key("theme", list);
370
+ if (content != NULL) {
371
+ value = metavalue_for_key("theme",list);
372
+ g_string_append_printf(out,"\\usetheme{%s}\n",value);
373
+ free(value);
374
+ } else{
375
+ g_string_append(out,"\\usetheme{warsaw}\n");
376
+ }
377
+ } else {
378
+ g_string_append(out,"\\usetheme{warsaw}\n");
379
+ }
380
+ g_string_append(out,"\\setbeamercovered{transparent}\n");
381
+ }
382
+
383
+ if (tree_contains_key(list, METAKEY)) {
384
+ content = metadata_for_key("latex input", list);
385
+ if (content != NULL) {
386
+ value = metavalue_for_key("latex input",list);
387
+ if (strcmp(value,"mmd-natbib-plain")==0){
388
+ g_string_append(out,"\\bibpunct{[}{]}{;}{n}{}{,}\n");
389
+ }else{
390
+ g_string_append(out,"\\bibpunct{(}{)}{,}{a}{,}{,}\n");
391
+ }
392
+ free(value);
393
+ } else{
394
+ g_string_append(out,"\\bibpunct{(}{)}{,}{a}{,}{,}\n");
395
+ }
396
+ } else {
397
+ g_string_append(out,"\\bibpunct{(}{)}{,}{a}{,}{,}\n");
398
+ }
399
+
400
+ /* set up nice referencing */
401
+
402
+ if (scratch->lyx_number_headers){
403
+ for(i=0;i<7;i++){
404
+ strncpy(short_prefix,heading_name[i]->str,5);
405
+ short_prefix[5]= '\0'; /* no terminator if strncpy ends because of length */
406
+ for(j = 0; short_prefix[j]; j++){
407
+ short_prefix[j] = tolower(short_prefix[j]);
408
+ }
409
+ g_string_append_printf(out,"\\newref{%s}{refcmd={%s \\ref{#1} \\vpageref{#1}}}\n",short_prefix,heading_name[i]->str);
410
+ }
411
+ g_string_append(out,"\\newref{tab}{refcmd={Table \\ref{#1} \\vpageref{#1}}}\n");
412
+ g_string_append(out,"\\newref{fig}{refcmd={Figure \\ref{#1} \\vpageref{#1}}}\n");
413
+ } else {
414
+ for(i=0;i<7;i++){
415
+ strncpy(short_prefix,heading_name[i]->str,5);
416
+ short_prefix[5]= '\0'; /* no terminator if strncpy ends because of length */
417
+ for(j = 0; short_prefix[j]; j++){
418
+ short_prefix[j] = tolower(short_prefix[j]);
419
+ }
420
+ g_string_append_printf(out,"\\newref{%s}{refcmd={``\\nameref{#1}'' \\vpageref{#1}}}\n",short_prefix);
421
+ }
422
+ g_string_append(out,"\\newref{tab}{refcmd={Table \\ref{#1} \\vpageref{#1}}}\n");
423
+ g_string_append(out,"\\newref{fig}{refcmd={Figure \\ref{#1} \\vpageref{#1}}}\n");
424
+
425
+ }
426
+
427
+ g_string_append(out,"\\end_preamble\n");
428
+
429
+ GString *class_options = g_string_new("\\options refpage");
430
+
431
+ if (tree_contains_key(list, METAKEY)) {
432
+ clean_pdf = metadata_for_key("cleanpdf",list);
433
+ if (clean_pdf != NULL) {
434
+ key = metavalue_for_key("cleanpdf",list);
435
+ label = label_from_string(key);
436
+ if (strcmp(label, "yes") == 0) {
437
+ g_string_append(class_options,",hidelinks");
438
+ }
439
+ free(label);
440
+ free(key);
441
+ }
442
+ }
443
+
444
+ if (tree_contains_key(list, METAKEY)) {
445
+ content = metadata_for_key("class options", list);
446
+ if (content != NULL) {
447
+ value = metavalue_for_key("class options",list);
448
+ g_string_append(class_options,",");
449
+ g_string_append(class_options,value);
450
+ free(value);
451
+ }
452
+ }
453
+ g_string_append(class_options,"\n");
454
+ g_string_append(out,class_options->str);
455
+ g_string_free(class_options,TRUE);
456
+
457
+
458
+
459
+ g_string_append(out,"\\begin_modules\n");
460
+ if (tree_contains_key(list, METAKEY)) {
461
+ modules = metadata_for_key("modules",list);
462
+ if (modules != NULL) {
463
+ key = metavalue_for_key("modules",list);
464
+ tmp = strdup(key);
465
+ token = strtok(tmp, s);
466
+ while( token != NULL ) {
467
+ cleaned = clean_string(token);
468
+ g_string_append_printf(out,"%s\n",cleaned);
469
+ free(cleaned);
470
+ token = strtok(NULL, s);
471
+ }
472
+ free(key);
473
+ free(tmp);
474
+ free(token);
475
+ }
476
+ }
477
+ g_string_append(out,"\\end_modules\n");
478
+
479
+ g_string_append(out,"\\bibtex_command default\n");
480
+ g_string_append(out,"\\cite_engine natbib_authoryear\n");
481
+
482
+ g_string_free(lyx_class,TRUE);
483
+
484
+ g_string_append(out,"\\end_header\n");
485
+ g_string_append(out,"\\begin_body\n");
486
+
487
+ if (tree_contains_key(list, METAKEY)) {
488
+ content = metadata_for_key("title", list);
489
+ if (content != NULL) {
490
+ g_string_append(out, "\n\\begin_layout Title\n");
491
+ value = metavalue_for_key("title",list);
492
+ print_lyx_string(out,value,scratch,LYX_NONE);
493
+ free(value);
494
+ g_string_append(out, "\n\\end_layout\n");
495
+ }
496
+ }
497
+
498
+ if ((isbeamer) && (tree_contains_key(list, METAKEY))) {
499
+ content = metadata_for_key("subtitle", list);
500
+ if (content != NULL) {
501
+ g_string_append(out, "\n\\begin_layout Subtitle\n");
502
+ value = metavalue_for_key("subtitle",list);
503
+ print_lyx_string(out,value,scratch,LYX_NONE);
504
+ free(value);
505
+ g_string_append(out, "\n\\end_layout\n");
506
+ }
507
+ }
508
+
509
+ if (tree_contains_key(list, METAKEY)) {
510
+ content = metadata_for_key("author", list);
511
+ if (content != NULL) {
512
+ g_string_append(out, "\n\\begin_layout Author\n");
513
+ value = metavalue_for_key("author",list);
514
+ print_lyx_string(out,value,scratch,LYX_NONE);
515
+ free(value);
516
+ g_string_append(out, "\n\\end_layout\n");
517
+ }
518
+ }
519
+
520
+ if ((isbeamer) && (tree_contains_key(list, METAKEY))){
521
+ content = metadata_for_key("affiliation", list);
522
+ if (content != NULL) {
523
+ g_string_append(out, "\n\\begin_layout Institute\n");
524
+ value = metavalue_for_key("affiliation",list);
525
+ print_lyx_string(out,value,scratch,LYX_NONE);
526
+ free(value);
527
+ g_string_append(out, "\n\\end_layout\n");
528
+ }
529
+ }
530
+
531
+ if (tree_contains_key(list, METAKEY)) {
532
+ content = metadata_for_key("date", list);
533
+ if (content != NULL) {
534
+ g_string_append(out, "\n\\begin_layout Date\n");
535
+ value = metavalue_for_key("date",list);
536
+ print_lyx_string(out,value,scratch,LYX_NONE);
537
+ free(value);
538
+ g_string_append(out, "\n\\end_layout\n");
539
+ }
540
+ }
541
+
542
+ if (tree_contains_key(list, METAKEY)) {
543
+ content = metadata_for_key("abstract", list);
544
+ if (content != NULL) {
545
+ g_string_append(out, "\n\\begin_layout Abstract\n");
546
+ value = metavalue_for_key("abstract",list);
547
+ print_lyx_string(out,value,scratch,LYX_NONE);
548
+ free(value);
549
+ g_string_append(out, "\n\\end_layout\n");
550
+ }
551
+ }
552
+ return isbeamer;
553
+ }
554
+
555
+ /* end_lyx_output -- close the document */
556
+ void end_lyx_output(GString *out, node* list, scratch_pad *scratch) {
557
+ node *content;
558
+ char *value;
559
+ #ifdef DEBUG_ON
560
+ fprintf(stderr, "end_lyx_output\n");
561
+ #endif
562
+
563
+
564
+ /* Handle BibTeX */
565
+
566
+ if (tree_contains_key(list, METAKEY)) {
567
+ content = metadata_for_key("bibtex",list);
568
+ if (content != NULL) {
569
+ g_string_append(out, "\n\\begin_layout Standard\n");
570
+ g_string_append(out,"\n\\begin_inset CommandInset bibtex");
571
+ g_string_append(out,"\nLatexCommand bibtex");
572
+ value = metavalue_for_key("bibtex",list);
573
+ g_string_append_printf(out,"\nbibfiles \"%s\"",value);
574
+ free(value);
575
+ g_string_append(out,"\noptions \"plainnat\"");
576
+ g_string_append(out,"\n\n\\end_inset");
577
+ g_string_append(out, "\n\n\\end_layout\n");
578
+ }
579
+ }
580
+
581
+ g_string_append(out, "\n\\end_body\n");
582
+ g_string_append(out, "\\end_document\n");
583
+ }
584
+
585
+ bool is_lyx_complete_doc(node *meta);
586
+
587
+
588
+ /* print_lyx_node_tree -- convert node tree to Lyx */
589
+ void print_lyx_node_tree(GString *out, node *list, scratch_pad *scratch, bool no_newline) {
590
+ #ifdef DEBUG_ON
591
+ int i;
592
+ scratch->lyx_debug_nest++;
593
+ g_string_append(scratch->lyx_debug_pad," "); /* add a level */
594
+ fprintf(stderr, "\n%sStart_print_Node_Tree: %s\n",scratch->lyx_debug_pad->str,node_types[scratch->lyx_para_type]);
595
+ scratch->lyx_debug_nest++;
596
+ g_string_append(scratch->lyx_debug_pad," "); /* add a level */
597
+ #endif
598
+ while (list != NULL) {
599
+ print_lyx_node(out, list, scratch, no_newline);
600
+ list = list->next;
601
+ }
602
+ #ifdef DEBUG_ON
603
+ scratch->lyx_debug_nest--;
604
+ g_string_free(scratch->lyx_debug_pad,TRUE); /* don' see a way to shorten the string */
605
+ scratch->lyx_debug_pad = g_string_new(""); /* so create a new, shorter one */
606
+ for(i=0;i<scratch->lyx_debug_nest;i++)
607
+ g_string_append(scratch->lyx_debug_pad," ");
608
+ fprintf(stderr, "\n%sEnd_print_Node_Tree: %s\n",scratch->lyx_debug_pad->str,node_types[scratch->lyx_para_type]);
609
+ scratch->lyx_debug_nest--;
610
+ g_string_free(scratch->lyx_debug_pad,TRUE); /* don' see a way to shorten the string */
611
+ scratch->lyx_debug_pad = g_string_new(""); /* so create a new, shorter one */
612
+ for(i=0;i<scratch->lyx_debug_nest;i++)
613
+ g_string_append(scratch->lyx_debug_pad," ");
614
+ #endif
615
+ }
616
+
617
+ /* print_lyx_node -- convert given node to Lyx and append */
618
+ void print_lyx_node(GString *out, node *n, scratch_pad *scratch, bool no_newline) {
619
+ node *temp_node;
620
+ node *tcaption;
621
+ char *temp;
622
+ char *prefixed_label;
623
+ int lev;
624
+ char *width = NULL;
625
+ char *height = NULL;
626
+ GString *temp_str;
627
+ GString *raw_str;
628
+ char char_temp;
629
+ int i;
630
+ int old_type;
631
+ int rows;
632
+ int cols;
633
+ int multicol;
634
+ int colwidth;
635
+
636
+ if (n == NULL)
637
+ return;
638
+
639
+ /* debugging statement */
640
+ #ifdef DEBUG_ON
641
+ fprintf(stderr, "\n%sprint_lyx_node: %s\n",scratch->lyx_debug_pad->str,node_types[n->key]);
642
+ fprintf(stderr,"%scontent: %s\n",scratch->lyx_debug_pad->str,n->str);
643
+ #endif
644
+
645
+ switch (n->key) {
646
+ case NO_TYPE:
647
+ break;
648
+ case LIST:
649
+ print_lyx_node_tree(out,n->children,scratch, no_newline);
650
+ break;
651
+ case STR:
652
+ print_lyx_string(out,n->str, scratch,LYX_NONE);
653
+ break;
654
+ case ABBREVIATION:
655
+ // this work was done in writer.c
656
+ break;
657
+ case ABBRSTART:
658
+ /* Strip out nodes that are being replaced with the abbreviation */
659
+ temp_node = n->next;
660
+ while (temp_node->key != ABBRSTOP) {
661
+ n->next = temp_node->next;
662
+ temp_node->next = NULL;
663
+ free_node(temp_node);
664
+ temp_node = n->next;
665
+ }
666
+ n->next = temp_node->next;
667
+ temp_node->next = NULL;
668
+ free_node(temp_node);
669
+ case ABBR:
670
+ /* In either case, now we call on the abbreviation */
671
+ // width = ascii_label_from_node(n->children->children);
672
+ width = string_from_node_tree(n->children->children);
673
+ // temp = ascii_label_from_string(n->children->str);
674
+ temp_str = g_string_new("");
675
+ g_string_append_printf(temp_str,"[%s]",width);
676
+ if(strstr(used_abbreviations->str,temp_str->str)){
677
+ g_string_append(out,width); // just the abbrev
678
+ }
679
+ else
680
+ {
681
+ g_string_append(used_abbreviations,temp_str->str);
682
+
683
+
684
+ g_string_append(out,n->children->str);
685
+ g_string_append_printf(out," (%s)",width);
686
+
687
+
688
+ g_string_append(out,"\n\\begin_inset CommandInset nomenclature");
689
+ g_string_append(out,"\nLatexCommand nomenclature");
690
+ g_string_append_printf(out,"\nsymbol \"%s\"",width);
691
+ g_string_append(out,"\ndescription \"");
692
+ // g_string_append(out,n->children->str);
693
+ temp = escape_string(n->children->str);
694
+ g_string_append(out,temp);
695
+ g_string_append(out,"\"");
696
+ g_string_append(out, "\n\\end_inset\n");
697
+ free(temp);
698
+ }
699
+ g_string_free(temp_str,TRUE);
700
+ free(width);
701
+ break;
702
+ case ABBRSTOP:
703
+ break;
704
+ case SPACE:
705
+ if (strncmp(n->str,"\n",1)==0){
706
+ if (no_newline){
707
+ g_string_append(out," "); /* just a space */
708
+ } else{
709
+ g_string_append_printf(out,"%s ",n->str); /* lyx needs the space */
710
+ }
711
+ }else{
712
+ g_string_append_printf(out,"%s",n->str);
713
+ }
714
+ break;
715
+ case PLAIN: /* act as if all items are wrapped in a paragraph */
716
+ case PARA:
717
+ #ifdef DEBUG_ON
718
+ fprintf(stderr, "\n%sprint_lyx_paragraph: %s\n",scratch->lyx_debug_pad->str,node_types[scratch->lyx_para_type]);
719
+ fprintf(stderr,"%scontent: %s\n",scratch->lyx_debug_pad->str,n->str);
720
+ #endif
721
+ /* definition list special case, must append first definition to the term */
722
+ if (scratch -> lyx_para_type == DEFINITION){
723
+ if (!scratch->lyx_definition_open){ /* first definition after a term */
724
+ g_string_append(out,"\n ");
725
+ print_lyx_node_tree(out,n->children,scratch, FALSE); /* stick on the end of the term */
726
+ g_string_append(out,"\n\\end_layout\n");
727
+ scratch->lyx_definition_open = TRUE; /* first definition after a term hit */
728
+ } else{
729
+ g_string_append(out,"\n\n\\begin_deeper\n"); // second (or nth definition)
730
+ g_string_append(out, "\n\\begin_layout Standard\n"); /* treat it as a paragraph */
731
+ print_lyx_node_tree(out,n->children,scratch, FALSE);
732
+ g_string_append(out, "\n\\end_layout\n");
733
+ g_string_append(out,"\n\\end_deeper\n");
734
+ }
735
+ break;
736
+ }
737
+ switch (scratch->lyx_para_type) {
738
+ case BLOCKQUOTE:
739
+ g_string_append(out, "\n\\begin_layout Quote\n");
740
+ break;
741
+ case ORDEREDLIST:
742
+ g_string_append(out, "\n\\begin_layout Enumerate\n");
743
+ if (scratch-> lyx_beamerbullet){
744
+ g_string_append(out,"\n\\begin_inset Argument 1");
745
+ g_string_append(out,"\nstatus open\n");
746
+ g_string_append(out,"\n\\begin_layout Plain Layout");
747
+ g_string_append(out,"\n<+->");
748
+ g_string_append(out,"\n\\end_layout\n");
749
+ g_string_append(out,"\n\\end_inset\n");
750
+ scratch -> lyx_beamerbullet = FALSE;
751
+ }
752
+ break;
753
+ case BULLETLIST:
754
+ g_string_append(out, "\n\\begin_layout Itemize\n");
755
+ if (scratch-> lyx_beamerbullet){
756
+ g_string_append(out,"\n\\begin_inset Argument 1");
757
+ g_string_append(out,"\nstatus open\n");
758
+ g_string_append(out,"\n\\begin_layout Plain Layout");
759
+ g_string_append(out,"\n+-");
760
+ g_string_append(out,"\n\\end_layout\n");
761
+ g_string_append(out,"\n\\end_inset\n");
762
+ scratch -> lyx_beamerbullet = FALSE;
763
+ }
764
+ break;
765
+ case NOTEREFERENCE:
766
+ case CITATION:
767
+ case NOCITATION:
768
+ g_string_append(out, "\n\\begin_inset Foot");
769
+ g_string_append(out, "\nstatus collapsed\n");
770
+ g_string_append(out, "\n\\begin_layout Plain Layout");
771
+ break;
772
+ case NOTESOURCE:
773
+ case CITATIONSOURCE:
774
+ break; /* no enclosure by an environment */
775
+ case GLOSSARYSOURCE:
776
+ g_string_append(out,"\ndescription \"");
777
+ break;
778
+ default:
779
+ g_string_append(out, "\n\\begin_layout Standard\n");
780
+ break;
781
+ }
782
+ print_lyx_node_tree(out,n->children,scratch, FALSE);
783
+ if (scratch->lyx_para_type == GLOSSARYSOURCE){
784
+ g_string_append(out,"\"\n");
785
+ } else if ((scratch->lyx_para_type != NOTESOURCE) &&
786
+ (scratch->lyx_para_type != CITATIONSOURCE)){
787
+ g_string_append(out, "\n\\end_layout\n");
788
+ }
789
+ if ((scratch->lyx_para_type == CITATION) ||
790
+ (scratch->lyx_para_type == NOCITATION)) {
791
+ g_string_append(out,"\n\\end_layout\n");
792
+ g_string_append(out,"\n\\end_inset");
793
+ }
794
+ break;
795
+ case HRULE:
796
+ g_string_append(out,"\n\\begin_layout Standard\n");
797
+ g_string_append(out,"\n\\begin_inset CommandInset line\n");
798
+ g_string_append(out,"LatexCommand rule\n");
799
+ g_string_append(out,"offset \"0.5ex\"\n");
800
+ g_string_append(out,"width \"100col%\"\n");
801
+ g_string_append(out,"height \"1pt\"\n");
802
+ g_string_append(out,"\n\\end_inset\n");
803
+ g_string_append(out,"\n\\end_layout\n");
804
+ break;
805
+ case HTMLBLOCK:
806
+ /* don't print HTML block */
807
+ /* but do print HTML comments for raw LaTeX */
808
+ if (strncmp(n->str,"<!--",4) == 0) {
809
+ /* trim "-->" from end */
810
+ n->str[strlen(n->str)-3] = '\0';
811
+ g_string_append(out, "\n\\begin_layout Plain Layout\n\\begin_inset ERT\nstatus collapsed\n\n\\begin_layout Plain Layout\n\n");
812
+ print_latex_string(out,&n->str[4],scratch);
813
+ g_string_append(out,"\n\n\\end_layout\n\n\\end_inset\n\\end_layout\n");
814
+ }
815
+ break;
816
+ case VERBATIM:
817
+ case VERBATIMFENCE:
818
+ old_type = scratch->lyx_para_type;
819
+ scratch->lyx_para_type = VERBATIM;
820
+ scratch->lyx_level++;
821
+ if (scratch->lyx_level > 1){
822
+ g_string_append(out,"\n\\begin_deeper\n");
823
+ }
824
+ g_string_append(out,"\\begin_layout Standard\n");
825
+ g_string_append(out,"\\begin_inset listings\n");
826
+ if ((n->children != NULL) && (n->children->key == VERBATIMTYPE)) {
827
+ trim_trailing_whitespace(n->children->str);
828
+ if (strlen(n->children->str) > 0) {
829
+ // NOTE: the language must match the LyX (LaTex) languages (e.g: Perl, not perl)
830
+ g_string_append_printf(out, "lstparams \"basicstyle={\\footnotesize\\ttfamily},language=%s\"\n", n->children->str,n->str);
831
+ }
832
+ else {
833
+ g_string_append(out,"lstparams \"basicstyle={\\footnotesize\\ttfamily}\"\n");
834
+ }
835
+ } else {
836
+ g_string_append(out,"lstparams \"basicstyle={\\footnotesize\\ttfamily}\"\n");
837
+ }
838
+ g_string_append(out,"inline false\n");
839
+ g_string_append(out,"status collapsed\n");
840
+ print_lyx_string(out, n->str, scratch,LYX_PLAIN); /* it is not children - just \n separated lines */
841
+ g_string_append(out,"\n\\end_inset\n");
842
+ g_string_append(out,"\\end_layout\n");
843
+ scratch->lyx_level--;
844
+ if (scratch->lyx_level > 0){
845
+ g_string_append(out,"\n\\end_deeper\n");
846
+ }
847
+ scratch->lyx_para_type = old_type;
848
+ break;
849
+ case BULLETLIST:
850
+ case ORDEREDLIST:
851
+ case DEFLIST:
852
+ if (n->key == DEFLIST){
853
+ scratch->lyx_definition_hit = TRUE;
854
+ scratch->lyx_definition_open = FALSE;
855
+ }
856
+ old_type = scratch->lyx_para_type;
857
+ scratch->lyx_para_type = n->key;
858
+ scratch->lyx_level++;
859
+ if (scratch->lyx_level > 1){
860
+ g_string_append(out,"\n\\begin_deeper\n");
861
+ }
862
+ print_lyx_node_tree(out, n->children, scratch, FALSE);
863
+ scratch->lyx_level--;
864
+ if (scratch->lyx_level > 0){
865
+ g_string_append(out,"\n\\end_deeper\n");
866
+ }
867
+ scratch->lyx_para_type = old_type;
868
+ scratch->lyx_definition_open = FALSE;
869
+ break;
870
+ case LISTITEM:
871
+ #ifdef DEBUG_ON
872
+ fprintf(stderr, "\nStart List Item\n");
873
+ #endif
874
+ old_type = scratch->lyx_para_type;
875
+ temp_node = n-> children; /* should be a list node */
876
+ if(temp_node->children == NULL) {
877
+ g_string_append(out,"\n\\begin_layout Itemize\n\\end_layout\n"); /* empty list item */
878
+ }
879
+ else {
880
+ i = 0;
881
+ temp_node = temp_node-> children; /* process the list */
882
+ /* the first paragraph is the list item's first paragraph */
883
+ print_lyx_node(out,temp_node,scratch,no_newline);
884
+ /* now process any other content, including additional lists */
885
+ temp_node = temp_node-> next;
886
+ while ((temp_node != NULL) && (temp_node->key != BULLETLIST)
887
+ && (temp_node->key != ORDEREDLIST) && (temp_node->key != DEFLIST)){
888
+ i++;
889
+ if (i == 1){
890
+ g_string_append(out,"\n\\begin_deeper\n");
891
+ old_type = scratch->lyx_para_type;
892
+ scratch->lyx_para_type = PARA; /* and make it a paragraph, not a list item */
893
+ }
894
+ print_lyx_node(out, temp_node, scratch, no_newline);
895
+ temp_node = temp_node->next;
896
+ }
897
+ if (i>0){
898
+ i--;
899
+ scratch->lyx_para_type = old_type; /* reset the paragraph type */
900
+ g_string_append(out,"\n\\end_deeper\n");
901
+ }
902
+ if (temp_node != NULL){ /* have hid an imbedded list */
903
+ print_lyx_node(out,temp_node,scratch,no_newline);
904
+ }
905
+ }
906
+ #ifdef DEBUG_ON
907
+ fprintf(stderr, "\nEnd List Item\n");
908
+ #endif
909
+ break;
910
+ case METADATA:
911
+ /* metadata we care about already handled */
912
+ break;
913
+ case METAKEY:
914
+ /* metadata we care about already handled */
915
+ break;
916
+ case METAVALUE:
917
+ /* metadata we care about already handled */
918
+ break;
919
+ case FOOTER:
920
+ print_lyx_endnotes(out, scratch);
921
+ break;
922
+ case HEADINGSECTION:
923
+ print_lyx_node_tree(out,n->children,scratch , FALSE);
924
+ break;
925
+ case H1: case H2: case H3: case H4: case H5: case H6:
926
+ lev = n->key - H1 + scratch->baseheaderlevel; /* assumes H1 ... H6 are in order */
927
+ if (lev > 7)
928
+ lev = 7; /* Max at level 7 */
929
+ GString *environment = g_string_new("\n\\begin_layout ");
930
+ g_string_append(environment,heading_name[lev-1]->str); /* get the (possibly user modified) section name */
931
+
932
+ if (!scratch->lyx_number_headers){
933
+ g_string_append(environment,"*\n");} /* mark as unnumbered */
934
+ else{
935
+ g_string_append(environment,"\n");
936
+ };
937
+ /* Begin the environment */
938
+ g_string_append_printf(out,"%s",environment->str);
939
+ g_string_free(environment,true);
940
+ /* Don't allow footnotes */
941
+ scratch->no_lyx_footnote = TRUE;
942
+ if (n->children->key == AUTOLABEL) {
943
+ /* use label for header since one was specified (MMD)*/
944
+ temp = label_from_string(n->children->str);
945
+ prefixed_label = prefix_label(heading_name[lev-1]->str,temp,FALSE);
946
+ print_lyx_node_tree(out, n->children->next, scratch , FALSE);
947
+ g_string_append(out,"\n\\begin_inset CommandInset label\n");
948
+ g_string_append(out,"LatexCommand label\n");
949
+ g_string_append_printf(out, "name \"%s\"",prefixed_label);
950
+ g_string_append(out,"\n\\end_inset\n");
951
+ free(prefixed_label);
952
+ free(temp);
953
+ } else {
954
+ /* generate a label by default for MMD */
955
+ temp = label_from_node_tree(n->children);
956
+ prefixed_label = prefix_label(heading_name[lev-1]->str,temp,FALSE);
957
+ print_lyx_node_tree(out, n->children, scratch, FALSE);
958
+ g_string_append(out,"\n\\begin_inset CommandInset label\n");
959
+ g_string_append(out,"LatexCommand label\n");
960
+ g_string_append_printf(out, "name \"%s\"",prefixed_label);
961
+ g_string_append(out,"\n\\end_inset\n");
962
+ free(prefixed_label);
963
+ free(temp);
964
+ }
965
+ scratch->no_lyx_footnote = FALSE;
966
+ g_string_append(out,"\n\\end_layout\n");
967
+ break;
968
+ case APOSTROPHE:
969
+ print_lyx_localized_typography(out, APOS, scratch);
970
+ break;
971
+ case ELLIPSIS:
972
+ print_lyx_localized_typography(out, ELLIP, scratch);
973
+ break;
974
+ case EMDASH:
975
+ print_lyx_localized_typography(out, MDASH, scratch);
976
+ break;
977
+ case ENDASH:
978
+ print_lyx_localized_typography(out, NDASH, scratch);
979
+ break;
980
+ case SINGLEQUOTED:
981
+ print_lyx_localized_typography(out, LSQUOTE, scratch);
982
+ print_lyx_node_tree(out, n->children, scratch, FALSE);
983
+ print_lyx_localized_typography(out, RSQUOTE, scratch);
984
+ break;
985
+ case DOUBLEQUOTED:
986
+ print_lyx_localized_typography(out, LDQUOTE, scratch);
987
+ print_lyx_node_tree(out, n->children, scratch, FALSE);
988
+ print_lyx_localized_typography(out, RDQUOTE, scratch);
989
+ break;
990
+ case LINEBREAK:
991
+ g_string_append(out, "\n\\begin_inset Newline newline\n\\end_inset\n");
992
+ break;
993
+ case MATHSPAN:
994
+ if (n->str[0] == '$') {
995
+ if (n->str[1] == '$') {
996
+ if (strncmp(&n->str[2],"\\begin",5) == 0) {
997
+ n->str[strlen(n->str)-2] = '\0';
998
+ g_string_append_printf(out, "\n\\begin_inset Formula %s\n\\end_inset\n",&n->str[2]);
999
+ } else {
1000
+ g_string_append_printf(out, "\n\\begin_inset Formula %s\n\\end_inset\n",n->str);
1001
+ }
1002
+ } else {
1003
+ if (strncmp(&n->str[1],"\\begin",5) == 0) {
1004
+ n->str[strlen(n->str)-1] = '\0';
1005
+ g_string_append_printf(out, "\n\\begin_inset Formula %s\n\\end_inset\n",&n->str[1]);
1006
+ } else {
1007
+ g_string_append_printf(out, "\n\\begin_inset Formula %s\n\\end_inset\n",n->str);
1008
+ }
1009
+ }
1010
+ } else if (strncmp(&n->str[2],"\\begin",5) == 0) {
1011
+ /* trim */
1012
+ n->str[strlen(n->str)-3] = '\0';
1013
+ g_string_append_printf(out, "\n\\begin_inset Formula %s\n\\end_inset\n", &n->str[2]);
1014
+ } else {
1015
+ if (n->str[strlen(n->str)-1] == ']') {
1016
+ n->str[strlen(n->str)-3] = '\0';
1017
+ g_string_append(out,"\\begin_inset Formula \n\\[");
1018
+ g_string_append_printf(out, "\n%s\n\\]\n\\end_inset\n", &n->str[2]);
1019
+ } else {
1020
+ n->str[strlen(n->str)-3] = '\0';
1021
+ g_string_append_printf(out, "\n\\begin_inset Formula $%s$\n\\end_inset\n", &n->str[2]);
1022
+ }
1023
+ }
1024
+ break;
1025
+ case STRONG:
1026
+ g_string_append(out, "\n\\series bold\n");
1027
+ print_lyx_node_tree(out,n->children,scratch, FALSE);
1028
+ g_string_append(out, "\n\\series default\n");
1029
+ break;
1030
+ case EMPH:
1031
+ g_string_append(out, "\n\\emph on\n");
1032
+ print_lyx_node_tree(out,n->children,scratch, FALSE);
1033
+ g_string_append(out, "\n\\emph default\n");
1034
+ break;
1035
+ case LINKREFERENCE:
1036
+ break;
1037
+ case LINK:
1038
+ #ifdef DEBUG_ON
1039
+ fprintf(stderr, "print LyX link: '%s'\n",n->str);
1040
+ #endif
1041
+
1042
+ /* Do we have proper info? */
1043
+
1044
+ if (n->link_data == NULL) {
1045
+ /* NULL link_data could occur if we parsed this link before and it didn't
1046
+ match anything */
1047
+ n->link_data = mk_link_data(NULL, NULL, NULL, NULL);
1048
+ }
1049
+
1050
+ if ((n->link_data->label == NULL) &&
1051
+ (n->link_data->source == NULL)) {
1052
+ #ifdef DEBUG_ON
1053
+ fprintf(stderr, "print LyX link: '%s'\n",n->str);
1054
+ #endif
1055
+ /* we seem to be a [foo][] style link */
1056
+ /* so load a label */
1057
+ temp_str = g_string_new("");
1058
+ print_raw_node_tree(temp_str, n->children);
1059
+ /* replace new-lines with spaces */
1060
+ temp = temp_str->str;
1061
+ while (*temp != '\0'){
1062
+ if (*temp == '\n'){
1063
+ *temp = ' ';
1064
+ }
1065
+ temp++;
1066
+ }
1067
+ free(n->link_data->label);
1068
+ n->link_data->label = temp_str->str;
1069
+ g_string_free(temp_str, FALSE);
1070
+ }
1071
+ #ifdef DEBUG_ON
1072
+ fprintf(stderr, "look for reference data for LyX link: '%s'\n",n->str);
1073
+ #endif
1074
+ /* Load reference data */
1075
+ if (n->link_data->label != NULL) {
1076
+ #ifdef DEBUG_ON
1077
+ fprintf(stderr, "have label for LyX link: '%s'\n",n->str);
1078
+ #endif
1079
+ temp = strdup(n->link_data->label);
1080
+ free_link_data(n->link_data);
1081
+ n->link_data = extract_link_data(temp, scratch);
1082
+
1083
+ if (n->link_data == NULL) {
1084
+ /* replace original text since no definition found */
1085
+ g_string_append(out, "[");
1086
+ print_lyx_node(out, n->children, scratch, FALSE);
1087
+ g_string_append(out,"]");
1088
+ if (n->children->next != NULL) {
1089
+ g_string_append(out, "[");
1090
+ print_lyx_node_tree(out, n->children->next, scratch, FALSE);
1091
+ g_string_append(out,"]");
1092
+ } else if (n->str != NULL) {
1093
+ /* no title label, so see if we stashed str*/
1094
+ g_string_append_printf(out, "%s", n->str);
1095
+ } else {
1096
+ g_string_append_printf(out, "[%s]",temp);
1097
+ }
1098
+ free(temp);
1099
+ break;
1100
+ }
1101
+ free(temp);
1102
+ }
1103
+ temp_str = g_string_new("");
1104
+ print_lyx_node_tree(temp_str, n->children, scratch, TRUE);
1105
+ raw_str = g_string_new("");
1106
+ print_raw_node_tree(raw_str, n->children);
1107
+ /* replace new-lines with spaces */
1108
+ temp = raw_str->str;
1109
+ while (*temp != '\0'){
1110
+ if (*temp == '\n'){
1111
+ *temp = ' ';
1112
+ }
1113
+ temp++;
1114
+ }
1115
+ if ((n->link_data->source != NULL) && (n->link_data->source[0] == '#' )) {
1116
+
1117
+ /* link to anchor within the document */
1118
+ if (strlen(temp_str->str) > 0) {
1119
+ /* We have text before the link */
1120
+ g_string_append_printf(out, "%s (", temp_str->str);
1121
+ }
1122
+
1123
+ if (n->link_data->label == NULL) {
1124
+ if ((n->link_data->source != NULL) && (n->link_data->source[0] == '#' )) {
1125
+ /* This link was specified as [](#bar) */
1126
+ g_string_append(out,"\n\\begin_inset CommandInset ref");
1127
+ g_string_append_printf(out,"\nLatexCommand formatted");
1128
+ g_string_append_printf(out,"\nreference \"%s\"\n",n->link_data->source + 1);
1129
+ g_string_append(out,"\n\\end_inset\n");
1130
+
1131
+ } else {
1132
+ g_string_append_printf(out, "\n\\begin_inset CommandInset href\nLatexCommand href\ntarget \"%s\"\n", n->link_data->source);
1133
+ g_string_append(out, "\"\n\n\\end_inset\n");
1134
+
1135
+ }
1136
+ } else {
1137
+ g_string_append(out,"\n\\begin_inset CommandInset ref");
1138
+ g_string_append_printf(out,"\nLatexCommand formatted");
1139
+ g_string_append_printf(out,"\nreference \"%s\"\n",n->link_data->source + 1);
1140
+ g_string_append(out,"\n\\end_inset\n");
1141
+ }
1142
+ if (strlen(temp_str->str) > 0) {
1143
+ g_string_append(out, ")");
1144
+ }
1145
+ } else if (strcmp(raw_str->str, n->link_data->source) == 0){
1146
+ /* This is a <link> */
1147
+ g_string_append_printf(out, "\n\\begin_inset CommandInset href\nLatexCommand href\ntarget \"%s\"\n", n->link_data->source);
1148
+ g_string_append_printf(out,"name \"%s\"",temp_str->str);
1149
+ g_string_append(out, "\n\n\\end_inset\n");
1150
+ } else if (strcmp(raw_str->str,&n->link_data->source[7]) == 0) {
1151
+ /*This is a <mailto> */
1152
+ g_string_append_printf(out, "\n\\begin_inset CommandInset href\nLatexCommand href\ntarget \"%s\"\n", n->link_data->source);
1153
+ g_string_append_printf(out,"name \"%s\"",temp_str->str);
1154
+ g_string_append(out,"\ntype \"mailto:\"");
1155
+ g_string_append(out, "\n\n\\end_inset\n");
1156
+ } else {
1157
+ g_string_append_printf(out, "\n\\begin_inset CommandInset href\nLatexCommand href\ntarget \"%s\"\n", n->link_data->source);
1158
+ g_string_append(out,"name \"");
1159
+
1160
+ g_string_free(temp_str,TRUE);
1161
+ temp_str = g_string_new("");
1162
+ print_escaped_node_tree(out,n->children);
1163
+
1164
+ g_string_append(out, "\"\n\n\\end_inset\n");
1165
+ if (scratch->no_lyx_footnote == FALSE) {
1166
+ g_string_append(out, "\n\\begin_inset Foot\nstatus collapsed\n\n\\begin_layout Plain Layout\n");
1167
+ g_string_append(out, "\n\\begin_inset CommandInset href\nLatexCommand href\n");
1168
+ g_string_append_printf(out,"\nname \"%s\"",n->link_data->source);
1169
+ g_string_append_printf(out,"\ntarget \"%s\"",n->link_data->source);
1170
+ g_string_append(out,"\n\n\\end_inset");
1171
+ g_string_append(out, "\n\\end_layout\n\n\\end_inset\n");
1172
+ }
1173
+ }
1174
+ g_string_free(temp_str, TRUE);
1175
+ g_string_free(raw_str, true);
1176
+ n->link_data->attr = NULL;
1177
+ break;
1178
+ case ATTRKEY:
1179
+ g_string_append_printf(out, " %s=\"%s\"", n->str,
1180
+ n->children->str);
1181
+ break;
1182
+ case REFNAME:
1183
+ case SOURCE:
1184
+ case TITLE:
1185
+ break;
1186
+ case IMAGEBLOCK:
1187
+ case IMAGE:
1188
+ #ifdef DEBUG_ON
1189
+ fprintf(stderr, "print image\n");
1190
+ #endif
1191
+ /* Do we have proper info? */
1192
+ if ((n->link_data->label == NULL) &&
1193
+ (n->link_data->source == NULL)) {
1194
+ /* we seem to be a [foo][] style link */
1195
+ /* so load a label */
1196
+ temp_str = g_string_new("");
1197
+ print_raw_node_tree(temp_str, n->children);
1198
+ n->link_data->label = temp_str->str;
1199
+ g_string_free(temp_str, FALSE);
1200
+ }
1201
+ /* Load reference data */
1202
+ if (n->link_data->label != NULL) {
1203
+ temp = strdup(n->link_data->label);
1204
+ free_link_data(n->link_data);
1205
+ n->link_data = extract_link_data(temp, scratch);
1206
+
1207
+ if (n->link_data == NULL) {
1208
+ /* replace original text since no definition found */
1209
+ g_string_append(out, "![");
1210
+ print_lyx_node(out, n->children, scratch, FALSE);
1211
+ g_string_append(out,"]");
1212
+ if (n->children->next != NULL) {
1213
+ g_string_append(out, "[");
1214
+ print_lyx_node_tree(out, n->children->next, scratch, FALSE);
1215
+ g_string_append(out,"]");
1216
+ } else if (n->str != NULL) {
1217
+ /* no title label, so see if we stashed str*/
1218
+ g_string_append_printf(out, "%s", n->str);
1219
+ } else {
1220
+ g_string_append_printf(out, "[%s]",temp);
1221
+ }
1222
+ free(temp);
1223
+ break;
1224
+ }
1225
+ free(temp);
1226
+ }
1227
+
1228
+ if (n->key == IMAGEBLOCK){
1229
+ g_string_append(out,"\n\\begin_layout Standard"); /* needs to be in an environment */
1230
+ g_string_append(out,"\n\\begin_inset Float figure");
1231
+ g_string_append(out,"\nwide false");
1232
+ g_string_append(out,"\nsideways false");
1233
+ g_string_append(out,"\nstatus collapsed");
1234
+ g_string_append(out, "\n\n\\begin_layout Plain Layout");
1235
+ }
1236
+
1237
+ g_string_append(out,"\n\\begin_inset Graphics");
1238
+
1239
+ g_string_append_printf(out, "\n\t filename %s\n",n->link_data->source);
1240
+
1241
+ #ifdef DEBUG_ON
1242
+ fprintf(stderr, "attributes\n");
1243
+ #endif
1244
+
1245
+ if (n->link_data->attr != NULL) {
1246
+ temp_node = node_for_attribute("height",n->link_data->attr);
1247
+ if (temp_node != NULL)
1248
+ height = correct_dimension_units(temp_node->children->str);
1249
+ temp_node = node_for_attribute("width",n->link_data->attr);
1250
+ if (temp_node != NULL)
1251
+ width = correct_dimension_units(temp_node->children->str);
1252
+ }
1253
+
1254
+ if (width != NULL) {
1255
+ if (width[strlen(width)-1] == '%') {
1256
+ width[strlen(width)-1] = '\0';
1257
+ g_string_append_printf(out, "\tlyxscale %s\n", width);
1258
+ g_string_append_printf(out, "\tscale %s\n",width);
1259
+ } else {
1260
+ g_string_append_printf(out, "\twidth %s\n",width);
1261
+ }
1262
+ }
1263
+
1264
+ if (height != NULL) {
1265
+ if (height[strlen(height)-1] == '%') {
1266
+ height[strlen(height)-1] = '\0';
1267
+ g_string_append_printf(out, "\tlyxscale %s\n",height);
1268
+ g_string_append_printf(out, "\tscale %s\n",height);
1269
+ } else {
1270
+ g_string_append_printf(out, "\theight %s\n",height);
1271
+ }
1272
+ }
1273
+ g_string_append(out,"\n\\end_inset\n");
1274
+
1275
+ if (n->key == IMAGEBLOCK) {
1276
+ g_string_append(out,"\n\n\\end_layout\n");
1277
+ if (n->children != NULL) {
1278
+ g_string_append(out,"\n\\begin_layout Plain Layout");
1279
+ g_string_append(out,"\n\\begin_inset Caption");
1280
+ g_string_append(out,"\n\n\\begin_layout Plain Layout\n");
1281
+ print_lyx_node_tree(out, n->children, scratch, FALSE);
1282
+ g_string_append(out,"\n\\end_layout\n");
1283
+ g_string_append(out,"\n\\end_inset");
1284
+ if (n->link_data->label != NULL) {
1285
+ g_string_append(out,"\n\n\\begin_inset CommandInset label");
1286
+ g_string_append(out,"\nLatexCommand label\n");
1287
+ temp = label_from_string(n->link_data->label);
1288
+ g_string_append_printf(out, "\nname \"fig:%s\"",temp);
1289
+ g_string_append(out,"\n\\end_inset");
1290
+ free(temp);
1291
+ }
1292
+ g_string_append(out,"\n\\end_layout\n");
1293
+ g_string_append(out,"\n\\end_inset\n");
1294
+ }
1295
+
1296
+ g_string_append(out, "\n\\end_layout\n");
1297
+ }
1298
+
1299
+ free(height);
1300
+ free(width);
1301
+ n->link_data->attr = NULL; /* We'll delete these elsewhere */
1302
+ break;
1303
+ #ifdef DEBUG_ON
1304
+ fprintf(stderr, "finish image\n");
1305
+ #endif
1306
+ case NOTEREFERENCE:
1307
+ lev = note_number_for_node(n, scratch);
1308
+ temp_node = node_for_count(scratch->used_notes, lev);
1309
+ if (temp_node->key == GLOSSARYSOURCE) {
1310
+ g_string_append(out,"\n\\begin_inset CommandInset nomenclature");
1311
+ g_string_append(out,"\nLatexCommand nomenclature");
1312
+ scratch->lyx_para_type = temp_node->key;
1313
+ print_lyx_node_tree(out, temp_node->children, scratch, FALSE);
1314
+ scratch->lyx_para_type = NO_TYPE;
1315
+ g_string_append(out, "\n\\end_inset\n");
1316
+ } else {
1317
+ g_string_append(out, "\n\\begin_inset Foot");
1318
+ g_string_append(out,"\nstatus collapsed\n\n");
1319
+ old_type = scratch->lyx_para_type;
1320
+ scratch->lyx_para_type = PARA;
1321
+ print_lyx_node_tree(out, temp_node->children, scratch, FALSE);
1322
+ scratch->lyx_para_type = old_type;
1323
+ g_string_append(out, "\n\n\\end_inset\n");
1324
+ }
1325
+ break;
1326
+ case NOCITATION:
1327
+ case CITATION:
1328
+ #ifdef DEBUG_ON
1329
+ fprintf(stderr, "\nprint cite\n");
1330
+ #endif
1331
+ if ((n->link_data != NULL) && (strncmp(n->link_data->label,"[#",2) == 0)) {
1332
+ /* external citation (e.g. BibTeX) */
1333
+ n->link_data->label[strlen(n->link_data->label)-1] = '\0';
1334
+ if (n->key == NOCITATION) {
1335
+ g_string_append(out,"\n\\begin_inset CommandInset citation");
1336
+ g_string_append(out,"\nLatexCommand nocite");
1337
+ g_string_append_printf(out,"\nkey \"%s\"",&n->str[2]);
1338
+ g_string_append(out,"\n\n\\end_inset\n");
1339
+ } else {
1340
+ g_string_append(out, "<FAKE span class=\"externalcitation\">");
1341
+ g_string_append(out, "</span>");
1342
+ }
1343
+ } else {
1344
+ #ifdef DEBUG_ON
1345
+ fprintf(stderr, "internal cite\n");
1346
+ #endif
1347
+ /* MMD citation, so output as footnote */
1348
+ /* TODO: create separate stream from footnotes */
1349
+ lev = note_number_for_label(n->link_data->label, scratch);
1350
+ if (lev != 0) {
1351
+ #ifdef DEBUG_ON
1352
+ fprintf(stderr, "matching cite found\n");
1353
+ #endif
1354
+ temp_node = node_for_count(scratch->used_notes, lev);
1355
+ /* flag that this is used as a citation */
1356
+ temp_node->key = CITATIONSOURCE;
1357
+ if (lev > scratch->max_footnote_num) {
1358
+ scratch->max_footnote_num = lev;
1359
+ }
1360
+ if (n->key == NOCITATION) {
1361
+ g_string_append(out,"\n\\begin_inset CommandInset citation");
1362
+ g_string_append(out,"\nLatexCommand nocite");
1363
+ g_string_append_printf(out,"\nkey \"%s\"",n->link_data->label);
1364
+ g_string_append(out,"\n\n\\end_inset\n");
1365
+ } else {
1366
+ if (n->children != NULL) {
1367
+ g_string_append(out,"\n\\begin_inset CommandInset citation");
1368
+ g_string_append(out,"\nLatexCommand cite");
1369
+ g_string_append(out, "\nafter \"");
1370
+ print_lyx_node(out, n->children, scratch, FALSE);
1371
+ g_string_append_printf(out,"\"\nkey \"%s\"",n->link_data->label);
1372
+ g_string_append(out,"\n\n\\end_inset\n");
1373
+ } else {
1374
+ g_string_append(out,"\n\\begin_inset CommandInset citation");
1375
+ g_string_append(out,"\nLatexCommand cite");
1376
+ g_string_append_printf(out,"\nkey \"%s\"",n->link_data->label);
1377
+ g_string_append(out,"\n\n\\end_inset\n");
1378
+ }
1379
+ }
1380
+ } else {
1381
+ /* not located -- this is external cite */
1382
+ #ifdef DEBUG_ON
1383
+ fprintf(stderr, "no match for cite: '%s'\n",n->link_data->label);
1384
+ #endif
1385
+ temp = n->link_data->label;
1386
+ if (n->key == NOCITATION) {
1387
+ g_string_append(out,"\n\\begin_inset CommandInset citation");
1388
+ g_string_append(out,"\nLatexCommand nocite");
1389
+ g_string_append_printf(out,"\nkey \"%s\"",n->link_data->label);
1390
+ g_string_append(out,"\n\n\\end_inset\n");
1391
+ } else {
1392
+ if (n->children != NULL) {
1393
+ #ifdef DEBUG_ON
1394
+ fprintf(stderr, "cite with children\n");
1395
+ #endif
1396
+ if (strcmp(&temp[strlen(temp) - 1],";") == 0) {
1397
+ g_string_append(out, " \\citet[");
1398
+ temp[strlen(temp) - 1] = '\0';
1399
+ } else {
1400
+ g_string_append(out,"\n\\begin_inset CommandInset citation");
1401
+ g_string_append(out,"\nLatexCommand cite");
1402
+ g_string_append(out, "\nafter \"");
1403
+ }
1404
+ print_lyx_node(out, n->children, scratch, FALSE);
1405
+ g_string_append_printf(out,"\"\nkey \"%s\"",temp);
1406
+ g_string_append(out,"\n\n\\end_inset\n");
1407
+ } else {
1408
+ #ifdef DEBUG_ON
1409
+ fprintf(stderr, "cite without children. locat:'%s'\n",n->str);
1410
+ #endif
1411
+ if (strcmp(&temp[strlen(temp) - 1],";") == 0) {
1412
+ temp[strlen(temp) - 1] = '\0';
1413
+ g_string_append_printf(out, " \\citet{%s}",temp);
1414
+ } else {
1415
+ g_string_append(out,"\n\\begin_inset CommandInset citation");
1416
+ g_string_append(out,"\nLatexCommand cite");
1417
+ g_string_append_printf(out,"\nkey \"%s\"",temp);
1418
+ g_string_append(out,"\n\n\\end_inset\n");
1419
+ }
1420
+ }
1421
+ }
1422
+ }
1423
+ }
1424
+ #ifdef DEBUG_ON
1425
+ fprintf(stderr, "finish cite\n");
1426
+ #endif
1427
+ break;
1428
+ case VARIABLE:
1429
+ temp = metavalue_for_key(n->str,scratch->result_tree);
1430
+ if (temp == NULL) {
1431
+ g_string_append_printf(out, "[%%%s]",n->str);
1432
+ } else {
1433
+ print_lyx_string(out, temp, scratch, LYX_NONE);
1434
+ free(temp);
1435
+ }
1436
+ break;
1437
+ case GLOSSARYTERM:
1438
+ if ((n->next != NULL) && (n->next->key == GLOSSARYSORTKEY) ) {
1439
+ g_string_append(out, "\nprefix \"");
1440
+ print_lyx_string(out, n->next->str, scratch,LYX_NONE);
1441
+ g_string_append(out, "\"");
1442
+ }
1443
+ g_string_append(out,"\nsymbol \"");
1444
+ print_latex_string(out, n->children->str, scratch);
1445
+ g_string_append(out, "\"");
1446
+ break;
1447
+ case GLOSSARYSORTKEY:
1448
+ break;
1449
+ case CODE:
1450
+ g_string_append(out, "\n\\family typewriter\n");
1451
+ print_lyx_string(out, n->str, scratch,LYX_CODE);
1452
+ g_string_append(out, "\n\\family default\n");
1453
+ break;
1454
+ case BLOCKQUOTEMARKER:
1455
+ print_lyx_node_tree(out, n->children, scratch, FALSE);
1456
+ break;
1457
+ case BLOCKQUOTE: /* can be nested - make it work like lists */
1458
+ old_type = scratch->lyx_para_type;
1459
+ scratch->lyx_para_type = n->key;
1460
+ scratch->lyx_level++;
1461
+ if (scratch->lyx_level > 1){
1462
+ g_string_append(out,"\n\\begin_deeper\n");
1463
+ }
1464
+ print_lyx_node_tree(out, n->children, scratch, FALSE);
1465
+ scratch->lyx_level--;
1466
+ if (scratch->lyx_level > 0){
1467
+ g_string_append(out,"\n\\end_deeper\n");
1468
+ }
1469
+ scratch->lyx_para_type = old_type;
1470
+ break;
1471
+ case RAW:
1472
+ /* This shouldn't happen */
1473
+ g_string_append(out, "RAW:");
1474
+ g_string_append_printf(out,"%s",n->str);
1475
+ break;
1476
+ case HTML:
1477
+ /* Handle HTML Reserved Characters */
1478
+ if (strncmp(n->str,"&quot;",6) == 0){
1479
+ g_string_append(out,"\"");
1480
+ break;
1481
+ } else if (strncmp(n->str,"&apos;",6) == 0){
1482
+ g_string_append(out,"'");
1483
+ break;
1484
+ } else if (strncmp(n->str,"&amp;",5) == 0){
1485
+ g_string_append(out,"&");
1486
+ break;
1487
+ } else if (strncmp(n->str,"&lt;",4) == 0){
1488
+ g_string_append(out,"<");
1489
+ break;
1490
+ } else if (strncmp(n->str,"&gt;",4) == 0){
1491
+ g_string_append(out,">");
1492
+ break;
1493
+ };
1494
+
1495
+ /* don't print HTML block */
1496
+ /* but do print HTML comments for raw LaTeX */
1497
+ if (strncmp(n->str,"<!--",4) == 0) {
1498
+ /* trim "-->" from end */
1499
+ n->str[strlen(n->str)-3] = '\0';
1500
+ // g_string_append(out, "\n\\begin_layout Plain Layout\n\\begin_inset ERT\nstatus collapsed\n\n\\begin_layout Plain Layout\n\n");
1501
+ g_string_append(out, "\n\\begin_inset ERT\nstatus collapsed\n\n\\begin_layout Plain Layout\n\n");
1502
+ print_lyx_string(out,&n->str[4],scratch,LYX_NONE);
1503
+ // g_string_append(out,"\n\n\\end_layout\n\\end_inset\n\\end_layout\n");
1504
+ g_string_append(out,"\n\n\\end_layout\n\\end_inset\n");
1505
+ }
1506
+ break;
1507
+ case TERM:
1508
+ scratch->lyx_definition_open = FALSE; /* and it is closed */
1509
+ old_type = scratch->lyx_para_type;
1510
+ scratch->lyx_para_type = n->key;
1511
+ if (scratch->lyx_definition_hit){
1512
+ g_string_append(out,"\n\\begin_layout Labeling");
1513
+ g_string_append(out,"\n\\labelwidthstring 00.00.0000\n");
1514
+ g_string_append(out,"\n\\series bold\n");
1515
+ scratch -> lyx_definition_hit = FALSE; /* waiting for it to start a new set of terms */
1516
+ } else { /* multiple terms, join with commas */
1517
+ g_string_append(out,",");
1518
+ g_string_append(out,"\n\\begin_inset space ~\n\\end_inset\n");
1519
+ }
1520
+ temp_str = g_string_new("");
1521
+ print_lyx_node_tree(temp_str, n->children, scratch, FALSE);
1522
+ /* replace spaces with protected spaces */
1523
+ temp = temp_str->str;
1524
+ while (*temp != '\0'){
1525
+ if (*temp == ' '){
1526
+ g_string_append(out,"\n\\begin_inset space ~\n\\end_inset\n");
1527
+ } else{
1528
+ g_string_append_printf(out,"%c",*temp);
1529
+ }
1530
+ temp++;
1531
+ }
1532
+ g_string_free(temp_str,TRUE);
1533
+ scratch->lyx_para_type = old_type;
1534
+ break;
1535
+ case DEFINITION:
1536
+ if (!scratch -> lyx_definition_hit){
1537
+ g_string_append(out,"\n\\series default\n"); /* close bolding */
1538
+ }
1539
+ scratch -> lyx_definition_hit = TRUE; /* have hit the definiton thus we can start a new one */
1540
+ old_type = scratch->lyx_para_type;
1541
+ scratch->lyx_para_type = n->key;
1542
+ print_lyx_node_tree(out, n->children, scratch, FALSE);
1543
+ scratch->lyx_para_type = old_type;
1544
+ break;
1545
+ case TABLE:
1546
+ scratch->lyx_table_caption = NULL;
1547
+ /* need to check the caption here in order to decide whether to increment the number of rows */
1548
+ tcaption = n->children;
1549
+ if (tcaption->key == TABLECAPTION) {
1550
+ scratch->lyx_table_caption = tcaption;
1551
+ }
1552
+ scratch->table_row = 0;
1553
+ scratch->table_column = 0;
1554
+ lyx_get_table_dimensions(n->children,&rows,&cols,scratch);
1555
+ scratch->lyx_table_total_rows = rows;
1556
+ if (scratch->lyx_table_caption != NULL){
1557
+ rows++; /* caption goes on the first row */
1558
+ }
1559
+ scratch->lyx_table_total_cols = cols;
1560
+ g_string_append(out,"\n\\begin_layout Standard");
1561
+ g_string_append(out,"\n\\begin_inset Tabular");
1562
+ g_string_append_printf(out,"\n<lyxtabular version=\"3\" rows=\"%d\" columns=\"%d\">",rows, cols);
1563
+ g_string_append(out,"\n<features booktabs=\"true\" tabularvalignment=\"middle\" islongtable=\"true\" longtabularalignment=\"center\">");
1564
+
1565
+ print_lyx_node_tree(out, n->children, scratch, FALSE); /* table body */
1566
+ g_string_append(out, "\n</lyxtabular>");
1567
+ g_string_append(out,"\n\\end_inset");
1568
+ g_string_append(out, "\n\\end_layout\n");
1569
+ scratch->lyx_table_caption = NULL;
1570
+ scratch->table_alignment = NULL;
1571
+ break;
1572
+ case TABLESEPARATOR:
1573
+ colwidth = 100/scratch->lyx_table_total_cols;
1574
+ scratch->table_alignment = n->str;
1575
+ for (i=0;i<scratch->lyx_table_total_cols;i++){
1576
+ temp_str = g_string_new("");
1577
+ char_temp = scratch->table_alignment[i];
1578
+ switch(char_temp){
1579
+ case 'c':
1580
+ case 'C':
1581
+ g_string_append(temp_str,"center");
1582
+ break;
1583
+ case 'r':
1584
+ case 'R':
1585
+ g_string_append(temp_str,"right");
1586
+ break;
1587
+ case 'l':
1588
+ case 'L':
1589
+ case 'N':
1590
+ case 'n':
1591
+ g_string_append(temp_str,"left");
1592
+ break;
1593
+ }
1594
+ g_string_append_printf(out,"\n<column alignment=\"%s\" valignment=\"top\" width=\"%dcol%%\">",temp_str->str,colwidth);
1595
+ g_string_free(temp_str,TRUE);
1596
+ }
1597
+ break;
1598
+ case TABLECAPTION:
1599
+ /* handled above */
1600
+ break;
1601
+ case TABLELABEL:
1602
+ break;
1603
+ case TABLEHEAD:
1604
+ if (scratch-> lyx_table_caption != NULL){ /* if there is a caption */
1605
+ g_string_append(out,"\n<row caption=\"true\">");
1606
+ g_string_append(out,"\n<cell multicolumn=\"1\" alignment=\"left\" valignment=\"top\" usebox=\"none\">");
1607
+ g_string_append(out,"\n\\begin_inset Text\n");
1608
+ g_string_append(out,"\n\\begin_layout Plain Layout");
1609
+ g_string_append(out,"\n\\begin_inset Caption\n");
1610
+ g_string_append(out,"\n\\begin_layout Plain Layout\n");
1611
+ print_lyx_node_tree(out, scratch->lyx_table_caption->children, scratch, FALSE);
1612
+ if ((scratch->lyx_table_caption->children != NULL) && (scratch->lyx_table_caption->children->key == TABLELABEL)) {
1613
+ temp = label_from_string(scratch->lyx_table_caption->children->str);
1614
+ } else {
1615
+ temp = label_from_node_tree(scratch->lyx_table_caption->children);
1616
+ }
1617
+ g_string_append(out,"\n\\end_layout\n");
1618
+ g_string_append(out,"\n\\end_inset");
1619
+ g_string_append(out,"\n\n\\begin_inset CommandInset label");
1620
+ g_string_append(out,"\nLatexCommand label\n");
1621
+ g_string_append_printf(out, "\nname \"tab:%s\"",temp);
1622
+ g_string_append(out,"\n\\end_inset");
1623
+ g_string_append(out,"\n\\end_layout\n");
1624
+ g_string_append(out,"\n\\end_inset\n");
1625
+ g_string_append(out,"\n</cell>");
1626
+ for (i=0;i<scratch->lyx_table_total_cols-1;i++){
1627
+ g_string_append(out,"\n<cell multicolumn=\"2\" alignment=\"center\" valignment=\"top\" topline=\"true\" bottomline=\"true\" leftline=\"true\" usebox=\"none\">");
1628
+ g_string_append(out,"\n\\begin_inset Text\n");
1629
+ g_string_append(out,"\n\\begin_layout Plain Layout\n");
1630
+ g_string_append(out,"\n\\end_layout\n");
1631
+ g_string_append(out,"\n\\end_inset");
1632
+ g_string_append(out,"\n</cell>");
1633
+ }
1634
+ g_string_append(out,"\n</row>");
1635
+ free(temp);
1636
+ }
1637
+ scratch->lyx_table_need_line = TRUE;
1638
+ scratch->lyx_in_header = TRUE;
1639
+ print_lyx_node_tree(out, n->children, scratch, FALSE);
1640
+ scratch->lyx_in_header = FALSE;
1641
+ break;
1642
+ case TABLEBODY:
1643
+ scratch->lyx_table_need_line = TRUE;
1644
+ print_lyx_node_tree(out, n->children, scratch, FALSE);
1645
+ break;
1646
+ case TABLEROW:
1647
+ if (scratch->lyx_in_header){
1648
+ g_string_append(out, "\n<row endhead=\"true\" endfirsthead=\"true\">");
1649
+ } else {
1650
+ g_string_append(out, "\n<row>");
1651
+ }
1652
+ scratch->table_column = 0;
1653
+ print_lyx_node_tree(out, n->children, scratch, FALSE);
1654
+ g_string_append(out,"\n</row>");
1655
+ scratch->lyx_table_need_line = FALSE;
1656
+ scratch->table_row++;
1657
+ break;
1658
+ case TABLECELL:
1659
+ temp_str = g_string_new("");
1660
+ char_temp = scratch->table_alignment[scratch->table_column];
1661
+ switch(char_temp){
1662
+ case 'c':
1663
+ case 'C':
1664
+ g_string_append(temp_str,"center");
1665
+ break;
1666
+ case 'r':
1667
+ case 'R':
1668
+ g_string_append(temp_str,"right");
1669
+ break;
1670
+ case 'l':
1671
+ case 'L':
1672
+ case 'N':
1673
+ case 'n':
1674
+ g_string_append(temp_str,"left");
1675
+ break;
1676
+ }
1677
+ multicol = 1;
1678
+ if ((n->children != NULL) && (n->children->key == CELLSPAN)){
1679
+ multicol = (int)strlen(n->children->str)+1;
1680
+ }
1681
+ for(i=1;i<=multicol;i++){
1682
+
1683
+ g_string_append(out,"\n<cell" ) ;
1684
+ if (multicol > 1) {
1685
+ g_string_append_printf(out, " multicolumn=\"%d\"",i);
1686
+ }
1687
+ g_string_append_printf(out, " alignment=\"%s\"",temp_str->str);
1688
+ g_string_append(out, " valignment=\"top\"");
1689
+
1690
+ if (scratch->lyx_table_need_line){
1691
+ g_string_append(out," topline=\"true\"" );
1692
+ }
1693
+ if (scratch->table_row >= scratch->lyx_table_total_rows-1){
1694
+ g_string_append(out," bottomline=\"true\"" );
1695
+ }
1696
+
1697
+ g_string_append(out," usebox=\"none\"");
1698
+
1699
+ g_string_append(out,">");
1700
+
1701
+ g_string_append(out,"\n\\begin_inset Text");
1702
+ g_string_append(out,"\n\n\\begin_layout Plain Layout\n");
1703
+
1704
+ print_lyx_node_tree(out, n->children, scratch, FALSE);
1705
+
1706
+ g_string_append(out,"\n\\end_layout\n");
1707
+ g_string_append(out,"\n\n\\end_inset");
1708
+ g_string_append(out,"\n</cell>");
1709
+ }
1710
+ g_string_free(temp_str,TRUE);
1711
+ scratch->table_column++;
1712
+ break;
1713
+ case CELLSPAN:
1714
+ break;
1715
+ case GLOSSARYSOURCE: /* handled inline */
1716
+ break;
1717
+ case NOTESOURCE: /* handled inline */
1718
+ break;
1719
+ case CITATIONSOURCE:
1720
+ scratch->lyx_para_type = n-> key;
1721
+ print_lyx_node(out, n->children, scratch, FALSE);
1722
+ break;
1723
+ case SOURCEBRANCH:
1724
+ fprintf(stderr,"SOURCEBRANCH\n");
1725
+ break;
1726
+ case NOTELABEL:
1727
+ case GLOSSARYLABEL:
1728
+ break;
1729
+ case SUPERSCRIPT:
1730
+ g_string_append_printf(out, "\n\\begin_inset script superscript\n\n\\begin_layout Plain Layout\n%s\n\\end_layout\n\n\\end_inset\n",n->str);
1731
+ break;
1732
+ case SUBSCRIPT:
1733
+ g_string_append_printf(out, "\n\\begin_inset script subscript\n\n\\begin_layout Plain Layout\n%s\n\\end_layout\n\n\\end_inset\n",n->str);
1734
+ break;
1735
+ case KEY_COUNTER:
1736
+ break;
1737
+ case TOC:
1738
+ print_lyx_node_tree(out,n->children, scratch, false);
1739
+ break;
1740
+ default:
1741
+ fprintf(stderr, "print_lyx_node encountered unknown node key = %d\n",n->key);
1742
+ exit(EXIT_FAILURE);
1743
+ }
1744
+ }
1745
+
1746
+ /* print_lyx_endnotes */
1747
+ void print_lyx_endnotes(GString *out, scratch_pad *scratch) {
1748
+ node *temp_node;
1749
+ bool do_nomenclature;
1750
+ scratch->used_notes = reverse_list(scratch->used_notes);
1751
+ node *note = scratch->used_notes;
1752
+ #ifdef DEBUG_ON
1753
+ fprintf(stderr, "start endnotes\n");
1754
+ #endif
1755
+
1756
+ /* Handle Glossary or abbreviations */
1757
+ do_nomenclature = false;
1758
+ if (strcmp(used_abbreviations->str,"")!=0){ // if any abbreviations have been used, print a glossary
1759
+ do_nomenclature = true;
1760
+ } else
1761
+ {
1762
+ temp_node = note;
1763
+ while (temp_node != NULL){
1764
+ if(temp_node->key == GLOSSARYSOURCE){
1765
+ do_nomenclature = true;
1766
+ break;
1767
+ }
1768
+ temp_node = temp_node->next;
1769
+ }
1770
+ }
1771
+
1772
+ if (do_nomenclature){
1773
+ g_string_append(out,"\n\\begin_layout Standard");
1774
+ g_string_append(out,"\n\\begin_inset CommandInset nomencl_print");
1775
+ g_string_append(out,"\nLatexCommand printnomenclature");
1776
+ g_string_append(out,"\nset_width \"auto\"\n");
1777
+ g_string_append(out,"\n\\end_inset\n");
1778
+ g_string_append(out,"\n\\end_layout\n");
1779
+ }
1780
+
1781
+ if (note == NULL)
1782
+ return;
1783
+
1784
+ note = scratch->used_notes;
1785
+
1786
+ #ifdef DEBUG_ON
1787
+ fprintf(stderr, "there are endnotes to print\n");
1788
+ #endif
1789
+
1790
+ while ( note != NULL) {
1791
+ if (note->key == KEY_COUNTER) {
1792
+ note = note->next;
1793
+ continue;
1794
+ }
1795
+
1796
+ if (note->key == CITATIONSOURCE) {
1797
+ g_string_append(out, "\n\\begin_layout Bibliography\n");
1798
+ g_string_append(out,"\\begin_inset CommandInset bibitem\n");
1799
+ g_string_append(out,"LatexCommand bibitem\n");
1800
+ g_string_append_printf(out, "key \"%s\"\n", note->str);
1801
+ g_string_append_printf(out, "label \"%s\"\n", note->str);
1802
+ g_string_append(out,"\n\\end_inset\n");
1803
+ print_lyx_node(out, note, scratch, FALSE);
1804
+ g_string_append(out,"\n\\end_layout\n");
1805
+ } else {
1806
+ /* footnotes handled elsewhere */
1807
+ }
1808
+
1809
+ note = note->next;
1810
+ }
1811
+
1812
+
1813
+ #ifdef DEBUG_ON
1814
+ fprintf(stderr, "\n\\end_layout\n");
1815
+ #endif
1816
+ }
1817
+
1818
+ /* print_lyx_localized_typography -- convert to "smart" typography */
1819
+ void print_lyx_localized_typography(GString *out, unsigned char character, scratch_pad *scratch) {
1820
+ if (!extension(EXT_SMART, scratch->extensions)) {
1821
+ g_string_append_c(out, character);
1822
+ return;
1823
+ }
1824
+ switch (character) {
1825
+ case LSQUOTE:
1826
+ case 0x91:
1827
+ switch (scratch->language) {
1828
+ case SWEDISH:
1829
+ g_string_append(out, "'");
1830
+ break;
1831
+ case FRENCH:
1832
+ g_string_append(out,"'");
1833
+ break;
1834
+ case GERMAN:
1835
+ g_string_append(out,"‚");
1836
+ break;
1837
+ case GERMANGUILL:
1838
+ g_string_append(out,"›");
1839
+ break;
1840
+ default:
1841
+ g_string_append(out,"\n\\begin_inset Quotes els\n\\end_inset\n");
1842
+ }
1843
+ break;
1844
+ case RSQUOTE:
1845
+ case 0x92:
1846
+ switch (scratch->language) {
1847
+ case GERMAN:
1848
+ g_string_append(out,"`");
1849
+ break;
1850
+ case GERMANGUILL:
1851
+ g_string_append(out,"‹");
1852
+ break;
1853
+ default:
1854
+ g_string_append(out,"\n\\begin_inset Quotes ers\n\\end_inset\n");
1855
+ }
1856
+ break;
1857
+ case APOS:
1858
+ g_string_append(out,"'");
1859
+ break;
1860
+ case LDQUOTE:
1861
+ case 0x93:
1862
+ switch (scratch->language) {
1863
+ case DUTCH:
1864
+ case GERMAN:
1865
+ g_string_append(out,"„");
1866
+ break;
1867
+ case GERMANGUILL:
1868
+ g_string_append(out,"»");
1869
+ break;
1870
+ case FRENCH:
1871
+ g_string_append(out,"«");
1872
+ break;
1873
+ case SWEDISH:
1874
+ g_string_append(out, "''");
1875
+ break;
1876
+ default:
1877
+ g_string_append(out,"\n\\begin_inset Quotes eld\n\\end_inset\n");
1878
+ }
1879
+ break;
1880
+ case RDQUOTE:
1881
+ case 0x94:
1882
+ switch (scratch->language) {
1883
+ case SWEDISH:
1884
+ case DUTCH:
1885
+ g_string_append(out,"''");
1886
+ break;
1887
+ case GERMAN:
1888
+ g_string_append(out,"``");
1889
+ break;
1890
+ case GERMANGUILL:
1891
+ g_string_append(out,"«");
1892
+ break;
1893
+ case FRENCH:
1894
+ g_string_append(out,"»");
1895
+ break;
1896
+ default:
1897
+ g_string_append(out,"\n\\begin_inset Quotes erd\n\\end_inset\n");
1898
+ }
1899
+ break;
1900
+ case NDASH:
1901
+ case 0x96:
1902
+ g_string_append(out,"--");
1903
+ break;
1904
+ case MDASH:
1905
+ case 0x97:
1906
+ g_string_append(out,"---");
1907
+ break;
1908
+ case ELLIP:
1909
+ case 0x85:
1910
+ if(scratch->lyx_para_type != GLOSSARYSOURCE){
1911
+ g_string_append(out,"\n\\SpecialChar \\ldots{}\n");
1912
+ } else{
1913
+ g_string_append(out,"...");
1914
+ }
1915
+ break;
1916
+ default:;
1917
+ }
1918
+ }
1919
+
1920
+ /* print_lyx_string - print string, escaping and formatting for LYX */
1921
+ void print_lyx_string(GString *out, char *str, scratch_pad *scratch, short environment) {
1922
+ char *tmp;
1923
+ char *start;
1924
+ unsigned char extended_character;
1925
+ if (str == NULL)
1926
+ return;
1927
+ start = str; /* Store start of string */
1928
+ if (environment == LYX_PLAIN) {
1929
+ g_string_append(out,"\n\\begin_layout Plain Layout\n\n");
1930
+ }
1931
+ while (*str != '\0') {
1932
+ /* first look for unicode so it doesn't get caught in the "smart quote" processing */
1933
+ /* will use a huristic of looking for a sequence that begins with two bytes of */
1934
+ /* the format 11xxxxxx 10xxxxxxxx to indicate a unicode sting */
1935
+ /* this is Ok if the second byte is the terminator ('\0') because it is all zeros and won't match */
1936
+ if ((((unsigned char)*str & 0xc0) == 0xc0) && ((((unsigned char)*(str+1)) & 0xc0) == 0x80)) { /* hit unicode (huristic */
1937
+ g_string_append_c(out, *str);
1938
+ str++;
1939
+ while ((((unsigned char)*str != '\0')) && (((unsigned char)*str & 0xc0) == 0x80)){
1940
+ g_string_append_c(out,*str); /* send out the other bytes */
1941
+ str++;
1942
+ }
1943
+ } else {
1944
+ switch ((unsigned char)*str) { /* cast to handle the "smart quotes" outside the ASCII range - they are in there */
1945
+ case '\\':
1946
+ g_string_append(out,"\n\\backslash\n\n");
1947
+ break;
1948
+ case '\"':
1949
+ if (environment == LYX_PLAIN){
1950
+ g_string_append(out,"\"");
1951
+ } else {
1952
+ g_string_append(out,"\n\\begin_inset Quotes erd\n\\end_inset\n");
1953
+ }
1954
+ break;
1955
+ case '\n':
1956
+ if(environment == LYX_PLAIN) {
1957
+ if (*(str+1) == '\0'){ /* skip last new line */
1958
+ break;
1959
+ }
1960
+ g_string_append(out,"\n\\end_layout\n\n\\begin_layout Plain Layout\n\n");
1961
+ } else {
1962
+ tmp = str;
1963
+ tmp--;
1964
+ if ((tmp > start) && (*tmp == ' ')) {
1965
+ g_string_append(out,"\n");
1966
+ } else {
1967
+ g_string_append(out, "\n "); /* add a space */
1968
+ }
1969
+ }
1970
+ break;
1971
+ case '<': /* look for HTML comment LaTeX escape */
1972
+ if ( (environment != LYX_CODE) && (environment != LYX_PLAIN) && (strncmp(str,"<!--",4) == 0)){
1973
+ str+=4; /* move past delimeter */
1974
+ g_string_append(out, "\n\\begin_layoutPlain Layout\n\\begin_inset ERT\nstatus collapsed\n\n\\begin_layout Plain Layout\n\n");
1975
+ while(strncmp(str,"-->",3) !=0){
1976
+ switch (*str){
1977
+ case '\\':
1978
+ g_string_append(out,"\n\\backslash\n\n");
1979
+ break;
1980
+ case '\"':
1981
+ g_string_append(out,"\n\\begin_inset Quotes erd\n\\end_inset\n\\end_layout\n");
1982
+ break;
1983
+ default:
1984
+ g_string_append_c(out,*str);
1985
+ }
1986
+ str++;
1987
+ }
1988
+ str+=2; /* and past the end delimeter */
1989
+ g_string_append(out,"\n\n\\end_layout\n\\end_inset\n");
1990
+ }
1991
+ else {
1992
+ g_string_append_c(out, *str);
1993
+ }
1994
+ break;
1995
+ /* handle "smart Quotes" and other "non ASCII" characters */
1996
+ case 0x91:
1997
+ case 0x92:
1998
+ case 0x93:
1999
+ case 0x94:
2000
+ case 0x96:
2001
+ case 0x97:
2002
+ case 0x85:
2003
+ extended_character = str[0];
2004
+ print_lyx_localized_typography(out,extended_character,scratch);
2005
+ break;
2006
+ default:
2007
+ g_string_append_c(out, *str);
2008
+ }
2009
+ str++;
2010
+ }
2011
+ }
2012
+ if (environment == LYX_PLAIN) {
2013
+ g_string_append(out,"\n\\end_layout\n");
2014
+ }
2015
+ }
2016
+
2017
+ /* print_lyx_url - print url, escaping for LYX */
2018
+ void print_lyx_url(GString *out, char *str, scratch_pad *scratch) {
2019
+ if (str == NULL)
2020
+ return;
2021
+ while (*str != '\0') {
2022
+ switch (*str) {
2023
+ case '$': case '%': case '!':
2024
+ case '&': case '_': case '#':
2025
+ g_string_append_printf(out, "\\%c", *str);
2026
+ break;
2027
+ case '^':
2028
+ g_string_append(out, "\\^{}");
2029
+ break;
2030
+ default:
2031
+ g_string_append_c(out, *str);
2032
+ }
2033
+ str++;
2034
+ }
2035
+ }
2036
+
2037
+ /* lyx_get_table_dimensions - find the dimensions of a table (rows and columns) */
2038
+ void lyx_get_table_dimensions(node* list, int *rows, int *cols, scratch_pad *scratch){
2039
+ int tmp_rows;
2040
+ int tmp_cols;
2041
+ *rows = 0;
2042
+ *cols = 0;
2043
+ tmp_rows = 0;
2044
+ tmp_cols = 0;
2045
+ while (list != NULL) {
2046
+ switch (list->key){
2047
+ case TABLEHEAD:
2048
+ case TABLEBODY:
2049
+ lyx_get_table_dimensions(list->children, &tmp_rows, &tmp_cols, scratch);
2050
+ *rows += tmp_rows;
2051
+ if (tmp_cols > *cols) {*cols = tmp_cols;};
2052
+ break;
2053
+ case TABLEROW:
2054
+ (*rows)++;
2055
+ lyx_get_table_dimensions(list->children, &tmp_rows, &tmp_cols,scratch);
2056
+ if (tmp_cols>*cols) {*cols = tmp_cols;};
2057
+ break;
2058
+ case TABLECELL:
2059
+ (*cols)++;
2060
+ break;
2061
+ }
2062
+ list = list->next;
2063
+ }
2064
+ }
2065
+ /* add_prefixes -- go through node tree and find elements created from headers, figures, and tables
2066
+ add the prefix so LyX can create proper references */
2067
+ void add_prefixes(node *list, node *root, scratch_pad *scratch) {
2068
+ char *label;
2069
+ GString *pound_label;
2070
+ int lev;
2071
+
2072
+
2073
+ while (list != NULL) {
2074
+ switch (list->key) {
2075
+ case H1: case H2: case H3: case H4: case H5: case H6:
2076
+ lev = list->key - H1 + scratch->baseheaderlevel;
2077
+ if (lev > 7)
2078
+ lev = 7; /* Max at level 7 */
2079
+ if (list->children->key != AUTOLABEL) {
2080
+ label = label_from_node_tree(list->children);
2081
+ } else{
2082
+ label = label_from_string(list->children->str);
2083
+ }
2084
+
2085
+ /* update any links in the tree */
2086
+
2087
+ pound_label = g_string_new("#");
2088
+ g_string_append(pound_label,label);
2089
+ update_link_source(pound_label->str,heading_name[lev-1]->str,root);
2090
+
2091
+
2092
+ /* and any in the "links" list */
2093
+
2094
+ update_links(pound_label->str,heading_name[lev-1]->str,scratch);
2095
+
2096
+ g_string_free(pound_label,TRUE);
2097
+ free(label);
2098
+ break;
2099
+ case TABLE:
2100
+ if (list->children->key == TABLECAPTION) {
2101
+ if (list->children->children->key == TABLELABEL){
2102
+ label = label_from_string(list->children->children->str);
2103
+ } else {
2104
+ label = label_from_node_tree(list->children->children);
2105
+ }
2106
+ pound_label = g_string_new("#");
2107
+ g_string_append(pound_label,label);
2108
+ update_links(pound_label->str,"tab",scratch);
2109
+ g_string_free(pound_label,TRUE);
2110
+ free(label);
2111
+
2112
+ }
2113
+ break;
2114
+ case IMAGE:
2115
+ case IMAGEBLOCK:
2116
+ if ((list->link_data != NULL) && (list->link_data->label != NULL)) {
2117
+ label = label_from_string(list->link_data->label);
2118
+ pound_label = g_string_new("#");
2119
+ g_string_append(pound_label,label);
2120
+ update_link_source(pound_label->str,"fig",root);
2121
+ g_string_free(pound_label,TRUE);
2122
+ free(label);
2123
+ }
2124
+ break;
2125
+ case HEADINGSECTION:
2126
+ add_prefixes(list->children, root, scratch);
2127
+ break;
2128
+ default:
2129
+ break;
2130
+ }
2131
+ list = list->next;
2132
+ }
2133
+ }
2134
+ void update_links(char *source,char *prefix, scratch_pad *scratch) {
2135
+ node* n = scratch->links;
2136
+ link_data *l;
2137
+ char* new_source;
2138
+ while (n != NULL) {
2139
+ l = n->link_data;
2140
+ if ((l != NULL) && (l->source != NULL)) {
2141
+ if (strcmp (l->source,source) == 0){
2142
+ new_source = prefix_label(prefix,l->source,TRUE);
2143
+ free(l->source);
2144
+ l->source = strdup(new_source);
2145
+ free(new_source);
2146
+ }
2147
+ }
2148
+ n = n->next;
2149
+ }
2150
+ }
2151
+
2152
+ /* update_link_source - walk the tree and add prefixes */
2153
+ void update_link_source(char *source, char *prefix,node *n){
2154
+ link_data *l;
2155
+ char* new_source;
2156
+ while(n != NULL){
2157
+ if (n->key == LINK){
2158
+ l = n->link_data;
2159
+ if ((l != NULL) && (l->source != NULL)) {
2160
+ if (strcmp (l->source,source) == 0){
2161
+ new_source = prefix_label(prefix,l->source,TRUE);
2162
+ free(l->source);
2163
+ l->source = strdup(new_source);
2164
+ free(new_source);
2165
+ }
2166
+ }
2167
+ }
2168
+ if(n->children != NULL) {
2169
+ update_link_source(source,prefix,n->children);
2170
+ }
2171
+ n = n-> next;
2172
+ }
2173
+
2174
+ }
2175
+
2176
+ /* prefix_label - Builds a label with a prefix - Returns a null-terminated string,
2177
+ which must be freed after use. */
2178
+ char *prefix_label(char *prefix, char *label, bool pound) {
2179
+ char* function_result;
2180
+ char short_prefix[6];
2181
+ int i;
2182
+ strncpy(short_prefix,prefix,5);
2183
+ short_prefix[5]= '\0'; /* no terminator if strncpy ends because of length */
2184
+ for(i = 0; short_prefix[i]; i++){
2185
+ short_prefix[i] = tolower(short_prefix[i]);
2186
+ }
2187
+ GString *result = g_string_new("");
2188
+ if (label[0]== '#'){
2189
+ g_string_append(result,label+1); /* drop the pound */
2190
+ } else{
2191
+ g_string_append(result,label);
2192
+ }
2193
+ g_string_prepend(result,":"); /* prefix colon */
2194
+ g_string_prepend(result,short_prefix); /* add the prefix */
2195
+ if (pound){
2196
+ g_string_prepend(result,"#"); /* add back in the pound if needed */
2197
+ }
2198
+ function_result = result->str;
2199
+ g_string_free(result,FALSE); /* sending back the string */
2200
+ return function_result;
2201
+ }
2202
+
2203
+ /* print_escaped_node_tree - print a list of elements as original text */
2204
+ void print_escaped_node_tree(GString *out, node *n) {
2205
+ #ifdef DEBUG_ON
2206
+ if (n != NULL)
2207
+ fprintf(stderr, "start print_escaped_node_tree: '%d'\n",n->key);
2208
+ #endif
2209
+ while (n != NULL) {
2210
+ print_escaped_node(out, n);
2211
+ n = n->next;
2212
+ }
2213
+ #ifdef DEBUG_ON
2214
+ if (n != NULL)
2215
+ fprintf(stderr, "finish print_escaped_node_tree: '%d'\n",n->key);
2216
+ #endif
2217
+ }
2218
+
2219
+ /* print_escaped_node - print an element as original text with LyX escaping*/
2220
+ void print_escaped_node(GString *out, node *n) {
2221
+ switch (n->key) {
2222
+ case STR:
2223
+ g_string_append(out,n->str);
2224
+ break;
2225
+ case SPACE:
2226
+ g_string_append(out," ");
2227
+ break;
2228
+ case APOSTROPHE:
2229
+ g_string_append(out,"'");
2230
+ break;
2231
+ case SINGLEQUOTED:
2232
+ g_string_append(out,"'");
2233
+ print_escaped_node_tree(out,n->children);
2234
+ g_string_append(out,"'");
2235
+ return;
2236
+ case DOUBLEQUOTED:
2237
+ g_string_append(out,"\"");
2238
+ print_escaped_node_tree(out,n->children);
2239
+ g_string_append(out,"\"");
2240
+ return;
2241
+ case ELLIPSIS:
2242
+ g_string_append(out,"...");
2243
+ break;
2244
+ case ENDASH:
2245
+ g_string_append(out,"--");
2246
+ break;
2247
+ case EMDASH:
2248
+ g_string_append(out,"---");
2249
+ default:
2250
+ break;
2251
+ }
2252
+ print_escaped_node_tree(out, n->children);
2253
+ }
2254
+ /* escape string - replace double quotes with escaped version */
2255
+ char * escape_string(char *str) {
2256
+ GString *out = g_string_new("");
2257
+ char *clean;
2258
+ while (*str != '\0') {
2259
+ if (*str == '"') {
2260
+ g_string_append(out, "\\\"");
2261
+ } else {
2262
+ g_string_append_c(out, *str);
2263
+ }
2264
+ str++;
2265
+ }
2266
+ clean = out->str;
2267
+ g_string_free(out, false);
2268
+ return clean;
2269
+ }