multimarkdown 4.5.0.r1

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