/* export_node_tree -- given a tree, export as specified format */ char * export_node_tree(node *list, int format, unsigned long extensions) { char *output; char *temp; GString *out = g_string_new(""); scratch_pad *scratch = mk_scratch_pad(extensions); scratch->result_tree = list; /* Pointer to result tree to use later */ #ifdef DEBUG_ON fprintf(stderr, "export_node_tree\n"); #endif #ifdef DEBUG_ON fprintf(stderr, "extract_references\n"); #endif if ((format != OPML_FORMAT) && (format != CRITIC_ACCEPT_FORMAT) && (format != CRITIC_REJECT_FORMAT) && (format != CRITIC_HTML_HIGHLIGHT_FORMAT)) { /* Find defined abbreviations */ extract_abbreviations(list, scratch); /* Apply those abbreviations to source text */ find_abbreviations(list, scratch); /* Parse for link, images, etc reference definitions */ extract_references(list, scratch); } /* Change our desired format based on metadata */ if (format == LATEX_FORMAT) format = find_latex_mode(format, list); switch (format) { case TEXT_FORMAT: print_text_node_tree(out, list, scratch); break; case HTML_FORMAT: if (scratch->extensions & EXT_COMPLETE) { temp = metavalue_for_key("lang", scratch->result_tree); if (temp != NULL) { g_string_append_printf(out, "<!DOCTYPE html>\n<html lang=\"%s\">\n<head>\n\t<meta charset=\"utf-8\"/>\n",temp); free(temp); } else { g_string_append_printf(out, "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\"/>\n"); } } #ifdef DEBUG_ON fprintf(stderr, "print_html output\n"); #endif print_html_node_tree(out, list, scratch); #ifdef DEBUG_ON fprintf(stderr, "print html endnotes\n"); #endif print_html_endnotes(out, scratch); #ifdef DEBUG_ON fprintf(stderr, "finished printing html endnotes\n"); #endif if (scratch->extensions & EXT_COMPLETE) { pad(out,2, scratch); g_string_append_printf(out, "</body>\n</html>"); } #ifdef DEBUG_ON fprintf(stderr, "closed HTML document\n"); #endif break; case LATEX_FORMAT: if ((list != NULL) && (list->key != METADATA)) { print_latex_node_tree(out, scratch->abbreviations, scratch); } print_latex_node_tree(out, list, scratch); break; case MEMOIR_FORMAT: if ((list != NULL) && (list->key != METADATA)) { print_memoir_node_tree(out, scratch->abbreviations, scratch); } print_memoir_node_tree(out, list, scratch); break; case BEAMER_FORMAT: if ((list != NULL) && (list->key != METADATA)) { print_beamer_node_tree(out, scratch->abbreviations, scratch); } print_beamer_node_tree(out, list, scratch); break; case LYX_FORMAT: perform_lyx_output(out,list,scratch); break; case OPML_FORMAT: #ifdef DEBUG_ON fprintf(stderr, "export OPML\n"); #endif begin_opml_output(out, list, scratch); print_opml_node_tree(out, list, scratch); end_opml_output(out, list, scratch); break; case ODF_FORMAT: #ifdef DEBUG_ON fprintf(stderr, "export ODF\n"); #endif begin_odf_output(out, list, scratch); print_odf_node_tree(out, list, scratch); end_odf_output(out, list, scratch); break; case RTF_FORMAT: #ifdef DEBUG_ON fprintf(stderr, "export RTF\n"); #endif if (!(scratch->extensions & EXT_SNIPPET)) begin_rtf_output(out, list, scratch); print_rtf_node_tree(out, list, scratch); if (!(scratch->extensions & EXT_SNIPPET)) end_rtf_output(out, list, scratch); break; case CRITIC_ACCEPT_FORMAT: print_critic_accept_node_tree(out, list, scratch); break; case CRITIC_REJECT_FORMAT: print_critic_reject_node_tree(out, list, scratch); break; case CRITIC_HTML_HIGHLIGHT_FORMAT: print_critic_html_highlight_node_tree(out, list, scratch); break; case TOC_FORMAT: scratch->toc_level = 0; print_toc_node_tree(out,list,scratch); break; default: fprintf(stderr, "Unknown export format = %d\n",format); exit(EXIT_FAILURE); } output = out->str; g_string_free(out, false); free_scratch_pad(scratch); #ifdef DEBUG_ON fprintf(stderr, "finish export_node_tree\n"); #endif return output; }
/* export_node_tree -- given a tree, export as specified format */ char * export_node_tree(node *list, int format, int extensions) { char *output; GString *out = g_string_new(""); scratch_pad *scratch = mk_scratch_pad(extensions); #ifdef DEBUG_ON fprintf(stderr, "export_node_tree\n"); #endif #ifdef DEBUG_ON fprintf(stderr, "extract_references\n"); #endif /* Parse for link, images, etc reference definitions */ if ((format != OPML_FORMAT) && (format != CRITIC_ACCEPT_FORMAT) && (format != CRITIC_REJECT_FORMAT) && (format != CRITIC_HTML_HIGHLIGHT_FORMAT)) extract_references(list, scratch); /* Change our desired format based on metadata */ if (format == LATEX_FORMAT) format = find_latex_mode(format, list); switch (format) { case TEXT_FORMAT: print_text_node_tree(out, list, scratch); break; case HTML_FORMAT: if (scratch->extensions & EXT_COMPLETE) { g_string_append_printf(out, "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\"/>\n"); } #ifdef DEBUG_ON fprintf(stderr, "print_html output\n"); #endif print_html_node_tree(out, list, scratch); #ifdef DEBUG_ON fprintf(stderr, "print html endnotes\n"); #endif print_html_endnotes(out, scratch); #ifdef DEBUG_ON fprintf(stderr, "finished printing html endnotes\n"); #endif if (scratch->extensions & EXT_COMPLETE) { pad(out,2, scratch); g_string_append_printf(out, "</body>\n</html>"); } #ifdef DEBUG_ON fprintf(stderr, "closed HTML document\n"); #endif break; case LATEX_FORMAT: print_latex_node_tree(out, list, scratch); break; case MEMOIR_FORMAT: print_memoir_node_tree(out, list, scratch); break; case BEAMER_FORMAT: print_beamer_node_tree(out, list, scratch); break; case OPML_FORMAT: #ifdef DEBUG_ON fprintf(stderr, "export OPML\n"); #endif begin_opml_output(out, list, scratch); print_opml_node_tree(out, list, scratch); end_opml_output(out, list, scratch); break; case ODF_FORMAT: #ifdef DEBUG_ON fprintf(stderr, "export ODF\n"); #endif begin_odf_output(out, list, scratch); print_odf_node_tree(out, list, scratch); end_odf_output(out, list, scratch); break; case CRITIC_ACCEPT_FORMAT: print_critic_accept_node_tree(out, list, scratch); break; case CRITIC_REJECT_FORMAT: print_critic_reject_node_tree(out, list, scratch); break; case CRITIC_HTML_HIGHLIGHT_FORMAT: print_critic_html_highlight_node_tree(out, list, scratch); break; default: fprintf(stderr, "Unknown export format = %d\n",format); exit(EXIT_FAILURE); } output = out->str; g_string_free(out, false); free_scratch_pad(scratch); #ifdef DEBUG_ON fprintf(stderr, "finish export_node_tree\n"); #endif return output; }
/* print_beamer_node -- convert given node to LaTeX and append */ void print_beamer_node(GString *out, node *n, scratch_pad *scratch) { int lev; char *temp; /* If we are forcing a complete document, and METADATA isn't the first thing, we need to close <head> */ if ((scratch->extensions & EXT_COMPLETE) && !(scratch->extensions & EXT_HEAD_CLOSED) && !((n->key == FOOTER) || (n->key == METADATA))) { pad(out, 2, scratch); scratch->extensions = scratch->extensions | EXT_HEAD_CLOSED; } switch (n->key) { case FOOTER: print_beamer_endnotes(out, scratch); g_string_append_printf(out, "\\mode<all>\n"); if (scratch->latex_footer != NULL) { pad(out, 2, scratch); g_string_append_printf(out,"\\input{%s}\n", scratch->latex_footer); } if (scratch->extensions & EXT_COMPLETE) { g_string_append_printf(out, "\n\\end{document}"); } g_string_append_printf(out, "\\mode*\n"); break; case LISTITEM: pad(out, 1, scratch); g_string_append_printf(out, "\\item<+-> "); scratch->padded = 2; print_latex_node_tree(out, n->children, scratch); g_string_append_printf(out, "\n"); break; case HEADINGSECTION: if (n->children->key -H1 + scratch->baseheaderlevel == 3) { pad(out, 2, scratch); g_string_append_printf(out, "\\begin{frame}"); /* TODO: Fix this */ if (tree_contains_key(n->children,VERBATIM)) { g_string_append_printf(out, "[fragile]"); } scratch->padded = 0; print_beamer_node_tree(out, n->children, scratch); g_string_append_printf(out, "\n\n\\end{frame}\n\n"); scratch->padded = 2; } else if (n->children->key -H1 + scratch->baseheaderlevel == 4) { pad(out, 1, scratch); g_string_append_printf(out, "\\mode<article>{\n"); scratch->padded = 0; print_beamer_node_tree(out, n->children->next, scratch); g_string_append_printf(out, "\n\n}\n\n"); scratch->padded = 2; } else { print_beamer_node_tree(out, n->children, scratch); } break; case H1: case H2: case H3: case H4: case H5: case H6: pad(out, 2, scratch); lev = n->key - H1 + scratch->baseheaderlevel; /* assumes H1 ... H6 are in order */ switch (lev) { case 1: g_string_append_printf(out, "\\part{"); break; case 2: g_string_append_printf(out, "\\section{"); break; case 3: g_string_append_printf(out, "\\frametitle{"); break; default: g_string_append_printf(out, "\\emph{"); break; } /* generate a label for each header (MMD); don't allow footnotes since invalid here */ scratch->no_latex_footnote = TRUE; if (n->children->key == AUTOLABEL) { print_latex_node_tree(out, n->children->next, scratch); g_string_append_printf(out, "}\n\\label{%s}", n->children->str); } else { print_latex_node_tree(out, n->children, scratch); temp = label_from_node_tree(n->children); g_string_append_printf(out, "}\n\\label{%s}", temp); free(temp); } scratch->no_latex_footnote = FALSE; scratch->padded = 0; break; default: /* most things are not changed for memoir output */ print_latex_node(out, n, scratch); } }
/* print_latex_node -- convert given node to LaTeX and append */ void print_latex_node(GString *out, node *n, scratch_pad *scratch) { node *temp_node; char *temp; int lev; char *width = NULL; char *height = NULL; GString *temp_str; GString *raw_str; int i; double temp_float; if (n == NULL) return; /* debugging statement */ #ifdef DEBUG_ON fprintf(stderr, "print_latex_node: %d\n",n->key); #endif /* If we are forcing a complete document, and METADATA isn't the first thing, we need to close <head> */ if ((scratch->extensions & EXT_COMPLETE) && !(scratch->extensions & EXT_HEAD_CLOSED) && !((n->key == FOOTER) || (n->key == METADATA))) { pad(out, 2, scratch); scratch->extensions = scratch->extensions | EXT_HEAD_CLOSED; } switch (n->key) { case NO_TYPE: break; case LIST: print_latex_node_tree(out,n->children,scratch); break; case STR: print_latex_string(out,n->str, scratch); break; case SPACE: g_string_append_printf(out,"%s",n->str); break; case PLAIN: pad(out,1, scratch); print_latex_node_tree(out,n->children, scratch); scratch->padded = 0; break; case PARA: pad(out, 2, scratch); print_latex_node_tree(out,n->children,scratch); scratch->padded = 0; break; case HRULE: pad(out, 2, scratch); g_string_append_printf(out, "\\begin{center}\\rule{3in}{0.4pt}\\end{center}\n"); scratch->padded = 0; break; case HTMLBLOCK: /* don't print HTML block */ /* but do print HTML comments for raw LaTeX */ if (strncmp(n->str,"<!--",4) == 0) { pad(out, 2, scratch); /* trim "-->" from end */ n->str[strlen(n->str)-3] = '\0'; g_string_append_printf(out, "%s", &n->str[4]); scratch->padded = 0; } break; case VERBATIM: pad(out, 2, scratch); if ((n->children != NULL) && (n->children->key == VERBATIMTYPE)) { trim_trailing_whitespace(n->children->str); if (strlen(n->children->str) > 0) { g_string_append_printf(out, "\\begin{lstlisting}[language=%s]\n%s\\end{lstlisting}", n->children->str,n->str); scratch->padded = 0; break; } } g_string_append_printf(out, "\\begin{verbatim}\n%s\\end{verbatim}",n->str); scratch->padded = 0; break; case BULLETLIST: pad(out, 2, scratch); g_string_append_printf(out, "\\begin{itemize}"); scratch->padded = 0; print_latex_node_tree(out, n->children, scratch); pad(out, 1, scratch); g_string_append_printf(out, "\\end{itemize}"); scratch->padded = 0; break; case ORDEREDLIST: pad(out, 2, scratch); g_string_append_printf(out, "\\begin{enumerate}"); scratch->padded = 0; print_latex_node_tree(out, n->children, scratch); pad(out, 1, scratch); g_string_append_printf(out, "\\end{enumerate}"); scratch->padded = 0; break; case LISTITEM: pad(out, 1, scratch); g_string_append_printf(out, "\\item "); scratch->padded = 2; print_latex_node_tree(out, n->children, scratch); g_string_append_printf(out, "\n"); scratch->padded = 0; break; case METADATA: /* print the metadata */ print_latex_node_tree(out,n->children, scratch); if (is_latex_complete_doc(n)) { scratch->extensions = scratch->extensions | EXT_COMPLETE; } break; case METAKEY: /* reformat the key */ temp = n->str; n->str = label_from_string(temp); free(temp); if (strcmp(n->str, "title") == 0) { g_string_append_printf(out, "\\def\\mytitle{"); print_latex_node(out, n->children, scratch); g_string_append_printf(out, "}\n"); } else if (strcmp(n->str, "author") == 0) { g_string_append_printf(out, "\\def\\myauthor{"); print_latex_node(out, n->children, scratch); g_string_append_printf(out, "}\n"); } else if (strcmp(n->str, "date") == 0) { g_string_append_printf(out, "\\def\\mydate{"); print_latex_node(out, n->children, scratch); g_string_append_printf(out, "}\n"); } else if (strcmp(n->str, "copyright") == 0) { g_string_append_printf(out, "\\def\\mycopyright{"); print_latex_node(out, n->children, scratch); g_string_append_printf(out, "}\n"); } else if (strcmp(n->str, "css") == 0) { } else if (strcmp(n->str, "xhtmlheader") == 0) { } else if (strcmp(n->str, "htmlheader") == 0) { } else if (strcmp(n->str, "baseheaderlevel") == 0) { scratch->baseheaderlevel = atoi(n->children->str); } else if (strcmp(n->str, "latexheaderlevel") == 0) { scratch->baseheaderlevel = atoi(n->children->str); } else if (strcmp(n->str, "latexinput") == 0) { trim_trailing_whitespace(n->children->str); g_string_append_printf(out, "\\input{%s}\n", n->children->str); } else if (strcmp(n->str, "latexfooter") == 0) { trim_trailing_whitespace(n->children->str); scratch->latex_footer = strdup(n->children->str); } else if (strcmp(n->str, "bibtex") == 0) { trim_trailing_whitespace(n->children->str); g_string_append_printf(out, "\\def\\bibliocommand{\\bibliography{%s}}\n",n->children->str); } else if (strcmp(n->str, "quoteslanguage") == 0) { temp = label_from_node_tree(n->children); if ((strcmp(temp, "nl") == 0) || (strcmp(temp, "dutch") == 0)) { scratch->language = DUTCH; } else if ((strcmp(temp, "de") == 0) || (strcmp(temp, "german") == 0)) { scratch->language = GERMAN; } else if (strcmp(temp, "germanguillemets") == 0) { scratch->language = GERMANGUILL; } else if ((strcmp(temp, "fr") == 0) || (strcmp(temp, "french") == 0)) { scratch->language = FRENCH; } else if ((strcmp(temp, "sv") == 0) || (strcmp(temp, "swedish") == 0)) { scratch->language = SWEDISH; } } else { g_string_append_printf(out, "\\def\\"); print_latex_string(out, n->str, scratch); g_string_append_printf(out, "{"); print_latex_node_tree(out, n->children, scratch); g_string_append_printf(out, "}\n"); } break; case METAVALUE: trim_trailing_whitespace(n->str); print_latex_string(out,n->str, scratch); break; case FOOTER: print_latex_endnotes(out, scratch); if (scratch->latex_footer != NULL) { pad(out, 2, scratch); g_string_append_printf(out,"\\input{%s}\n", scratch->latex_footer); } if (scratch->extensions & EXT_COMPLETE) { g_string_append_printf(out, "\n\\end{document}"); } break; case HEADINGSECTION: print_latex_node_tree(out,n->children,scratch); break; case H1: case H2: case H3: case H4: case H5: case H6: lev = n->key - H1 + scratch->baseheaderlevel; /* assumes H1 ... H6 are in order */ if (lev > 7) lev = 7; /* Max at level 7 */ pad(out, 2, scratch); switch (lev) { case 1: g_string_append_printf(out, "\\part{"); break; case 2: g_string_append_printf(out, "\\chapter{"); break; case 3: g_string_append_printf(out, "\\section{"); break; case 4: g_string_append_printf(out, "\\subsection{"); break; case 5: g_string_append_printf(out, "\\subsubsection{"); break; case 6: g_string_append_printf(out, "\\paragraph{"); break; case 7: g_string_append_printf(out, "\\subparagraph{"); break; } /* Don't allow footnotes */ scratch->no_latex_footnote = TRUE; if (n->children->key == AUTOLABEL) { /* use label for header since one was specified (MMD)*/ temp = label_from_string(n->children->str); print_latex_node_tree(out, n->children->next, scratch); g_string_append_printf(out, "}\n\\label{%s}",temp); free(temp); } else { /* generate a label by default for MMD */ print_latex_node_tree(out, n->children, scratch); temp = label_from_node_tree(n->children); g_string_append_printf(out, "}\n\\label{%s}",temp); free(temp); } scratch->no_latex_footnote = FALSE; scratch->padded = 0; break; case APOSTROPHE: print_latex_localized_typography(out, APOS, scratch); break; case ELLIPSIS: print_latex_localized_typography(out, ELLIP, scratch); break; case EMDASH: print_latex_localized_typography(out, MDASH, scratch); break; case ENDASH: print_latex_localized_typography(out, NDASH, scratch); break; case SINGLEQUOTED: print_latex_localized_typography(out, LSQUOTE, scratch); print_latex_node_tree(out, n->children, scratch); print_latex_localized_typography(out, RSQUOTE, scratch); break; case DOUBLEQUOTED: print_latex_localized_typography(out, LDQUOTE, scratch); print_latex_node_tree(out, n->children, scratch); print_latex_localized_typography(out, RDQUOTE, scratch); break; case LINEBREAK: g_string_append_printf(out, "\\\\\n"); break; case MATHSPAN: if (n->str[0] == '$') { if (n->str[1] == '$') { if (strncmp(&n->str[2],"\\begin",5) == 0) { n->str[strlen(n->str)-2] = '\0'; g_string_append_printf(out, "%s",&n->str[1]); } else { g_string_append_printf(out, "%s",n->str); } } else { if (strncmp(&n->str[1],"\\begin",5) == 0) { n->str[strlen(n->str)-1] = '\0'; g_string_append_printf(out, "%s",&n->str[1]); } else { g_string_append_printf(out, "%s",n->str); } } } else if (strncmp(&n->str[2],"\\begin",5) == 0) { /* trim */ n->str[strlen(n->str)-3] = '\0'; g_string_append_printf(out, "%s", &n->str[2]); } else { if (n->str[strlen(n->str)-1] == ']') { n->str[strlen(n->str)-3] = '\0'; g_string_append_printf(out, "%s\\]", n->str); } else { n->str[strlen(n->str)-3] = '\0'; g_string_append_printf(out, "$%s$", &n->str[2]); } } break; case STRONG: g_string_append_printf(out, "\\textbf{"); print_latex_node_tree(out,n->children,scratch); g_string_append_printf(out, "}"); break; case EMPH: g_string_append_printf(out, "\\emph{"); print_latex_node_tree(out,n->children,scratch); g_string_append_printf(out, "}"); break; case LINKREFERENCE: break; case LINK: #ifdef DEBUG_ON fprintf(stderr, "print LaTeX link: '%s'\n",n->str); #endif /* Do we have proper info? */ if (n->link_data == NULL) { /* NULL link_data could occur if we parsed this link before and it didn't match anything */ n->link_data = mk_link_data(NULL, NULL, NULL, NULL); } if ((n->link_data->label == NULL) && (n->link_data->source == NULL)) { #ifdef DEBUG_ON fprintf(stderr, "print latex link: '%s'\n",n->str); #endif /* we seem to be a [foo][] style link */ /* so load a label */ temp_str = g_string_new(""); print_raw_node_tree(temp_str, n->children); free(n->link_data->label); n->link_data->label = temp_str->str; g_string_free(temp_str, FALSE); } #ifdef DEBUG_ON fprintf(stderr, "look for reference data for latex link: '%s'\n",n->str); #endif /* Load reference data */ if (n->link_data->label != NULL) { #ifdef DEBUG_ON fprintf(stderr, "have label for latex link: '%s'\n",n->str); #endif temp = strdup(n->link_data->label); free_link_data(n->link_data); n->link_data = extract_link_data(temp, scratch); if (n->link_data == NULL) { /* replace original text since no definition found */ g_string_append_printf(out, "["); print_latex_node(out, n->children, scratch); g_string_append_printf(out,"]"); if (n->children->next != NULL) { g_string_append_printf(out, "["); print_latex_node_tree(out, n->children->next, scratch); g_string_append_printf(out,"]"); } else if (n->str != NULL) { /* no title label, so see if we stashed str*/ g_string_append_printf(out, "%s", n->str); } else { g_string_append_printf(out, "[%s]",temp); } free(temp); break; } free(temp); } temp_str = g_string_new(""); print_latex_node_tree(temp_str, n->children, scratch); raw_str = g_string_new(""); print_raw_node_tree(raw_str, n->children); if ((n->link_data->source != NULL) && (n->link_data->source[0] == '#' )) { /* link to anchor within the document */ if (strlen(temp_str->str) > 0) { /* We have text before the link */ g_string_append_printf(out, "%s (", temp_str->str); } if (n->link_data->label == NULL) { if ((n->link_data->source != NULL) && (strncmp(n->link_data->source,"#",1) == 0)) { /* This link was specified as [](#bar) */ g_string_append_printf(out, "\\autoref{%s}", n->link_data->source + 1); } else { g_string_append_printf(out, "\\href{%s}{}", n->link_data->source); } } else { g_string_append_printf(out, "\\autoref{%s}", n->link_data->label); } if (strlen(temp_str->str) > 0) { g_string_append_printf(out, ")", temp_str->str); } } else if (strcmp(raw_str->str, n->link_data->source) == 0){ /* This is a <link> */ g_string_append_printf(out, "\\href{%s}{%s}", n->link_data->source, temp_str->str); } else if (strcmp(raw_str->str,&n->link_data->source[7]) == 0) { /*This is a <mailto> */ g_string_append_printf(out, "\\href{%s}{%s}", n->link_data->source, temp_str->str); } else { /* this is a [text](link) */ g_string_append_printf(out, "\\href{%s}{", n->link_data->source); print_latex_node_tree(out, n->children, scratch); g_string_append_printf(out, "}"); if (scratch->no_latex_footnote == FALSE) { g_string_append_printf(out, "\\footnote{\\href{"); print_latex_url(out, n->link_data->source, scratch); g_string_append_printf(out, "}{", n->link_data->source); print_latex_string(out, n->link_data->source, scratch); g_string_append_printf(out, "}}"); } } g_string_free(temp_str, true); g_string_free(raw_str, true); n->link_data->attr = NULL; break; case ATTRKEY: g_string_append_printf(out, " %s=\"%s\"", n->str, n->children->str); break; case REFNAME: case SOURCE: case TITLE: break; case IMAGEBLOCK: pad(out,2, scratch); case IMAGE: #ifdef DEBUG_ON fprintf(stderr, "print image\n"); #endif /* Do we have proper info? */ if ((n->link_data->label == NULL) && (n->link_data->source == NULL)) { /* we seem to be a [foo][] style link */ /* so load a label */ temp_str = g_string_new(""); print_raw_node_tree(temp_str, n->children); n->link_data->label = temp_str->str; g_string_free(temp_str, FALSE); } /* Load reference data */ if (n->link_data->label != NULL) { temp = strdup(n->link_data->label); free_link_data(n->link_data); n->link_data = extract_link_data(temp, scratch); if (n->link_data == NULL) { /* replace original text since no definition found */ g_string_append_printf(out, "!["); print_latex_node(out, n->children, scratch); g_string_append_printf(out,"]"); if (n->children->next != NULL) { g_string_append_printf(out, "["); print_latex_node_tree(out, n->children->next, scratch); g_string_append_printf(out,"]"); } else if (n->str != NULL) { /* no title label, so see if we stashed str*/ g_string_append_printf(out, "%s", n->str); } else { g_string_append_printf(out, "[%s]",temp); } free(temp); break; } free(temp); } if (n->key == IMAGEBLOCK) g_string_append_printf(out, "\\begin{figure}[htbp]\n\\centering\n"); g_string_append_printf(out, "\\includegraphics["); #ifdef DEBUG_ON fprintf(stderr, "attributes\n"); #endif if (n->link_data->attr != NULL) { temp_node = node_for_attribute("height",n->link_data->attr); if (temp_node != NULL) height = correct_dimension_units(temp_node->children->str); temp_node = node_for_attribute("width",n->link_data->attr); if (temp_node != NULL) width = correct_dimension_units(temp_node->children->str); } if ((height == NULL) && (width == NULL)) { /* No dimensions used */ g_string_append_printf(out, "keepaspectratio,width=\\textwidth,height=0.75\\textheight"); } else { /* At least one dimension given */ if (!((height != NULL) && (width != NULL))) { /* we only have one */ g_string_append_printf(out, "keepaspectratio,"); } if (width != NULL) { if (width[strlen(width)-1] == '%') { width[strlen(width)-1] = '\0'; temp_float = strtod(width, NULL); temp_float = temp_float/100; g_string_append_printf(out, "width=%.4f\\textwidth,", temp_float); } else { g_string_append_printf(out, "width=%s,",width); } } else { g_string_append_printf(out, "width=\\textwidth,"); } if (height != NULL) { if (height[strlen(height)-1] == '%') { height[strlen(height)-1] = '\0'; temp_float = strtod(height, NULL); temp_float = temp_float/100; g_string_append_printf(out, "height=%.4f\\textheight", temp_float); } else { g_string_append_printf(out, "height=%s",height); } } else { g_string_append_printf(out, "height=0.75\\textheight"); } } g_string_append_printf(out, "]{%s}",n->link_data->source); if (n->key == IMAGEBLOCK) { if (n->children != NULL) { g_string_append_printf(out, "\n\\caption{"); print_latex_node_tree(out, n->children, scratch); g_string_append_printf(out, "}"); } if (n->link_data->label != NULL) { temp = label_from_string(n->link_data->label); g_string_append_printf(out, "\n\\label{%s}",temp); free(temp); } g_string_append_printf(out, "\n\\end{figure}"); scratch->padded = 0; } free(height); free(width); n->link_data->attr = NULL; /* We'll delete these elsewhere */ break; #ifdef DEBUG_ON fprintf(stderr, "finish image\n"); #endif case NOTEREFERENCE: lev = note_number_for_node(n, scratch); temp_node = node_for_count(scratch->used_notes, lev); scratch->padded = 2; if (temp_node->key == GLOSSARYSOURCE) { g_string_append_printf(out, "\\newglossaryentry{%s}{",temp_node->children->children->str); print_latex_node_tree(out, temp_node->children, scratch); g_string_append_printf(out, "}}\\glsadd{%s}",temp_node->children->children->str); } else { g_string_append_printf(out, "\\footnote{"); print_latex_node_tree(out, temp_node->children, scratch); g_string_append_printf(out, "}"); } scratch->padded = 0; break; case NOCITATION: case CITATION: #ifdef DEBUG_ON fprintf(stderr, "\nprint cite\n"); #endif if ((n->link_data != NULL) && (strncmp(n->link_data->label,"[#",2) == 0)) { /* external citation (e.g. BibTeX) */ n->link_data->label[strlen(n->link_data->label)-1] = '\0'; if (n->key == NOCITATION) { g_string_append_printf(out, "~\\nocite{%s}",&n->str[2]); } else { g_string_append_printf(out, "<FAKE span class=\"externalcitation\">"); g_string_append_printf(out, "</span>"); } } else { #ifdef DEBUG_ON fprintf(stderr, "internal cite\n"); #endif /* MMD citation, so output as footnote */ /* TODO: create separate stream from footnotes */ lev = note_number_for_label(n->link_data->label, scratch); if (lev != 0) { #ifdef DEBUG_ON fprintf(stderr, "matching cite found\n"); #endif temp_node = node_for_count(scratch->used_notes, lev); /* flag that this is used as a citation */ temp_node->key = CITATIONSOURCE; if (lev > scratch->max_footnote_num) { scratch->max_footnote_num = lev; } if (n->key == NOCITATION) { g_string_append_printf(out, "~\\nocite{%s}", n->link_data->label); } else { if (n->children != NULL) { g_string_append_printf(out, "~\\citep["); print_latex_node(out, n->children, scratch); g_string_append_printf(out,"]{%s}",n->link_data->label); } else { g_string_append_printf(out, "~\\citep{%s}", n->link_data->label); } } } else { /* not located -- this is external cite */ #ifdef DEBUG_ON fprintf(stderr, "no match for cite: '%s'\n",n->link_data->label); #endif temp = n->link_data->label; if (n->key == NOCITATION) { g_string_append_printf(out, "~\\nocite{%s}",n->link_data->label); } else { if (n->children != NULL) { #ifdef DEBUG_ON fprintf(stderr, "cite with children\n"); #endif if (strcmp(&temp[strlen(temp) - 1],";") == 0) { g_string_append_printf(out, " \\citet["); temp[strlen(temp) - 1] = '\0'; } else { g_string_append_printf(out, "~\\citep["); } print_latex_node(out, n->children, scratch); g_string_append_printf(out, "]{%s}",temp); } else { #ifdef DEBUG_ON fprintf(stderr, "cite without children. locat:'%s'\n",n->str); #endif if (strcmp(&temp[strlen(temp) - 1],";") == 0) { temp[strlen(temp) - 1] = '\0'; g_string_append_printf(out, " \\citet{%s}",temp); } else { g_string_append_printf(out, "~\\citep{%s}",temp); } } } } } #ifdef DEBUG_ON fprintf(stderr, "finish cite\n"); #endif break; case GLOSSARYTERM: if ((n->next != NULL) && (n->next->key == GLOSSARYSORTKEY) ) { g_string_append_printf(out, "sort={"); print_latex_string(out, n->next->str, scratch); g_string_append_printf(out, "},"); } g_string_append_printf(out,"name={"); print_latex_string(out, n->children->str, scratch); g_string_append_printf(out, "},description={"); break; case GLOSSARYSORTKEY: break; case CODE: g_string_append_printf(out, "\\texttt{"); print_latex_string(out, n->str, scratch); g_string_append_printf(out, "}"); break; case BLOCKQUOTEMARKER: print_latex_node_tree(out, n->children, scratch); break; case BLOCKQUOTE: pad(out,2, scratch); g_string_append_printf(out, "\\begin{quote}"); scratch->padded = 0; print_latex_node_tree(out, n->children, scratch); pad(out,1, scratch); g_string_append_printf(out, "\\end{quote}"); scratch->padded = 0; break; case RAW: /* This shouldn't happen */ g_string_append_printf(out, "RAW:"); g_string_append_printf(out,"%s",n->str); break; case HTML: /* don't print HTML block */ /* but do print HTML comments for raw LaTeX */ if (strncmp(n->str,"<!--",4) == 0) { /* trim "-->" from end */ n->str[strlen(n->str)-3] = '\0'; g_string_append_printf(out, "%s", &n->str[4]); scratch->padded = 0; } break; case DEFLIST: pad(out,2, scratch); g_string_append_printf(out, "\\begin{description}"); scratch->padded = 0; print_latex_node_tree(out, n->children, scratch); pad(out, 1, scratch); g_string_append_printf(out, "\\end{description}"); scratch->padded = 0; break; case TERM: pad(out,2, scratch); g_string_append_printf(out, "\\item["); print_latex_node_tree(out, n->children, scratch); g_string_append_printf(out, "]"); scratch->padded = 0; break; case DEFINITION: pad(out, 2, scratch); scratch->padded = 2; print_latex_node_tree(out, n->children, scratch); scratch->padded = 0; break; case TABLE: pad(out, 2, scratch); g_string_append_printf(out, "\\begin{table}[htbp]\n\\begin{minipage}{\\linewidth}\n\\setlength{\\tymax}{0.5\\linewidth}\n\\centering\n\\small\n"); print_latex_node_tree(out, n->children, scratch); g_string_append_printf(out, "\n\\end{tabulary}\n\\end{minipage}\n\\end{table}"); scratch->padded = 0; break; case TABLESEPARATOR: temp_str = g_string_new(""); for (i = 0; n->str[i]; i++) { if (n->str[i] != 'h') g_string_append_printf(temp_str,"%c",toupper(n->str[i])); } g_string_append_printf(out, "\\begin{tabulary}{\\textwidth}{@{}%s@{}} \\toprule\n", temp_str->str); g_string_free(temp_str, true); break; case TABLECAPTION: if ((n->children != NULL) && (n->children->key == TABLELABEL)) { temp = label_from_string(n->children->str); } else { temp = label_from_node_tree(n->children); } g_string_append_printf(out, "\\caption{"); print_latex_node_tree(out, n->children, scratch); g_string_append_printf(out, "}\n\\label{%s}\n", temp); free(temp); break; case TABLELABEL: break; case TABLEHEAD: print_latex_node_tree(out, n->children, scratch); g_string_append_printf(out, "\\midrule\n"); break; case TABLEBODY: print_latex_node_tree(out, n->children, scratch); if ((n->next != NULL) && (n->next->key == TABLEBODY)) { g_string_append_printf(out, "\n\\midrule\n"); } else { g_string_append_printf(out, "\n\\bottomrule\n"); } break; case TABLEROW: print_latex_node_tree(out, n->children, scratch); g_string_append_printf(out, "\\\\\n"); break; case TABLECELL: scratch->padded = 2; if ((n->children != NULL) && (n->children->key == CELLSPAN)) { g_string_append_printf(out, "\\multicolumn{%d}{c}{",(int)strlen(n->children->str)+1); } print_latex_node_tree(out, n->children, scratch); if ((n->children != NULL) && (n->children->key == CELLSPAN)) { g_string_append_printf(out, "}"); } if (n->next != NULL) g_string_append_printf(out, "&"); break; case CELLSPAN: break; case GLOSSARYSOURCE: print_latex_node_tree(out, n->children, scratch); break; case CITATIONSOURCE: case NOTESOURCE: print_latex_node(out, n->children, scratch); break; case SOURCEBRANCH: fprintf(stderr,"SOURCEBRANCH\n"); break; case NOTELABEL: break; case SUPERSCRIPT: g_string_append_printf(out, "\\textsuperscript{%s}",n->str); break; case SUBSCRIPT: g_string_append_printf(out, "\\textsubscript{%s}",n->str); break; case KEY_COUNTER: break; default: fprintf(stderr, "print_latex_node encountered unknown node key = %d\n",n->key); exit(EXIT_FAILURE); } }