multimarkdown 4.5.0.r1

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