예제 #1
0
/* 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;
}
예제 #2
0
/* print_rtf_node -- convert given node to RTF and append */
void print_rtf_node(GString *out, node *n, scratch_pad *scratch) {
	int i;
	int lev;
	int old_type;
	char *temp;
	link_data *temp_link_data;
	node *temp_node;

	switch (n->key) {
		case SPACE:
		case STR:
		/* TODO: Some of the following need improvements */
		case MATHSPAN:
			print_rtf_string(out, n->str, scratch);
			break;
		case METADATA:
			if (scratch->extensions & EXT_SNIPPET)
				break; 			
			g_string_append_printf(out, "{\\info\n");
			print_rtf_node_tree(out,n->children,scratch);
		 	g_string_append_printf(out, "}\n");
			scratch->padded = 0;
			break;
		case METAKEY:
			/* Convert key */
			temp = label_from_string(n->str);
			free(n->str);
			n->str = temp;
			if (strcmp(n->str, "baseheaderlevel") == 0) {
				scratch->baseheaderlevel = atoi(n->children->str);
				break;
			} else if (strcmp(n->str, "rtfheaderlevel") == 0) {
				scratch->baseheaderlevel = atoi(n->children->str);
				break;
			} 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; }
				free(temp);
				break;
			}
	
			if (strcmp(n->str, "title") == 0) {
				g_string_append_printf(out, "{\\title ");
				print_rtf_node(out, n->children, scratch);
				g_string_append_printf(out, "}\n");
			} else if (strcmp(n->str, "author") == 0) {
				g_string_append_printf(out, "{\\author ");
				print_rtf_node(out, n->children, scratch);
				g_string_append_printf(out, "}\n");
			} else if (strcmp(n->str, "affiliation") == 0) {
				g_string_append_printf(out, "{\\company ");
				print_rtf_node(out, n->children, scratch);
				g_string_append_printf(out, "}\n");
			} else if (strcmp(n->str, "company") == 0) {
				g_string_append_printf(out, "{\\company ");
				print_rtf_node(out, n->children, scratch);
				g_string_append_printf(out, "}\n");
			} else if (strcmp(n->str, "keywords") == 0) {
				g_string_append_printf(out, "{\\keywords ");
				print_rtf_node(out, n->children, scratch);
				g_string_append_printf(out, "}\n");
			} else if (strcmp(n->str, "copyright") == 0) {
				g_string_append_printf(out, "{\\*\\copyright ");
				print_rtf_node(out, n->children, scratch);
				g_string_append_printf(out, "}\n");
			} else if (strcmp(n->str, "comment") == 0) {
				g_string_append_printf(out, "{\\doccomm ");
				print_rtf_node(out, n->children, scratch);
				g_string_append_printf(out, "}\n");
			} else if (strcmp(n->str, "subject") == 0) {
				g_string_append_printf(out, "{\\subject ");
				print_rtf_node(out, n->children, scratch);
				g_string_append_printf(out, "}\n");
			}
			break;
		case METAVALUE:
			trim_trailing_whitespace(n->str);
			print_rtf_string(out, n->str, scratch);
			break;
		case BLOCKQUOTEMARKER:
			print_rtf_node_tree(out, n->children, scratch);
			break;
		case BLOCKQUOTE:
			old_type = scratch->odf_para_type;
			scratch->odf_para_type = BLOCKQUOTE;
			pad_rtf(out, 2, scratch);
			print_rtf_node_tree(out,n->children,scratch);
			scratch->padded = 1;
			scratch->odf_para_type = old_type;
			break;
		case VERBATIM:
			pad_rtf(out, 2, scratch);
			g_string_append_printf(out, "{\\pard " kCodeStyle);
			print_rtf_code_string(out,n->str,scratch);
			g_string_append_printf(out, "\n\\par}\n");
			scratch->padded = 0;
			break;
		case CODE:
			print_rtf_node_tree(out,n->children,scratch);
//			print_rtf_string(out, n->str, scratch);
			break;
		case PARA:
			pad_rtf(out, 2, scratch);
			switch (scratch->odf_para_type) {
				case BLOCKQUOTE:
					g_string_append_printf(out, "{\\pard " kQuoteStyle);
					break;
				case NOTEREFERENCE:
				case CITATION:
					g_string_append_printf(out, "{\\pard " kNoteStyle);
					break;
				case CODE:
				case VERBATIM:
					g_string_append_printf(out, "{\\pard " kCodeStyle);
					break;
				default:
					g_string_append_printf(out, "{\\pard " kNormalStyle);
					break;
			}
			print_rtf_node_tree(out,n->children,scratch);
			g_string_append_printf(out, "\n\\par}\n");
			scratch->padded = 1;
			break;
		case H1: case H2: case H3: case H4: case H5: case H6:
			lev = n->key - H1 + scratch->baseheaderlevel;
			if (lev > 6)
				lev = 6;
			pad_rtf(out, 2, scratch);
			switch (lev) {
				case 1:
					g_string_append_printf(out, "{\\pard " kH1);
					break;
				case 2:
					g_string_append_printf(out, "{\\pard " kH2);
					break;
				case 3:
					g_string_append_printf(out, "{\\pard " kH3);
					break;
				case 4:
					g_string_append_printf(out, "{\\pard " kH4);
					break;
				case 5:
					g_string_append_printf(out, "{\\pard " kH5);
					break;
				case 6:
					g_string_append_printf(out, "{\\pard " kH6);
					break;
			}
			if (n->children->key == AUTOLABEL) {
				temp = label_from_string(n->children->str);
				g_string_append_printf(out, "{\\*\\bkmkstart %s}{\\*\\bkmkend %s}",temp, temp);
				print_rtf_node_tree(out, n->children->next, scratch);
			} else {
				temp = label_from_node_tree(n->children);
				g_string_append_printf(out, "{\\*\\bkmkstart %s}{\\*\\bkmkend %s}",temp,temp);
				print_rtf_node_tree(out, n->children, scratch);
			}
			free(temp);
			g_string_append_printf(out, "\\par}\n");
			scratch->padded = 1;
			break;
		case TABLE:
			if ((n->children != NULL) && (n->children->key == TABLECAPTION)) {
				if (n->children->children->key == TABLELABEL) {
					temp = label_from_string(n->children->children->str);
				} else {
					temp = label_from_node_tree(n->children->children);
				}
				g_string_append_printf(out, "{\\*\\bkmkstart %s}{\\*\\bkmkend %s}",temp,temp);
				free(temp);
			}
			pad_rtf(out, 2, scratch);
			print_rtf_node_tree(out, n->children, scratch);
			if ((n->children != NULL) && (n->children->key == TABLECAPTION)) {
				g_string_append_printf(out, "{\\pard " kNormalStyle "\\qc ");
				print_rtf_node_tree(out, n->children->children, scratch);
				g_string_append_printf(out, "\\par}\n");
			}
			g_string_append_printf(out, "\\pard\\par\n");
			scratch->padded = 1;
			break;
		case TABLELABEL:
		case TABLECAPTION:
			break;
		case TABLESEPARATOR:
			scratch->table_alignment = n->str;
			break;
		case TABLEHEAD:
			scratch->cell_type = 'h';
			print_rtf_node_tree(out, n->children, scratch);
			scratch->cell_type = 'd';
			break;
		case TABLEROW:
			scratch->table_column = 0;
			g_string_append_printf(out, "\\trowd\\trautofit1\n");
			for (i=0; i < strlen(scratch->table_alignment); i++) {
				g_string_append_printf(out, "\\cellx%d\n",i+1);
			}
			print_rtf_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "\\row\n");
			break;
		case TABLECELL:
			temp = scratch->table_alignment;
			if (strncmp(&temp[scratch->table_column],"h",1) == 0) {
				scratch->table_column++;
			}
			lev = scratch->table_column;
	
			g_string_append_printf(out, "\\intbl");

			if (scratch->cell_type == 'h') {
				g_string_append_printf(out, "\\qc{\\b ");
			} else {
				if ( strncmp(&temp[lev],"r",1) == 0) {
					g_string_append_printf(out, "\\qr");
				} else if ( strncmp(&temp[lev],"R",1) == 0) {
					g_string_append_printf(out, "\\qr");
				} else if ( strncmp(&temp[lev],"c",1) == 0) {
					g_string_append_printf(out, "\\qc");
				} else if ( strncmp(&temp[lev],"C",1) == 0) {
					g_string_append_printf(out, "\\qc");
				} else {
					g_string_append_printf(out, "\\ql");
				}
			}
			g_string_append_printf(out, " {");
			print_rtf_node_tree(out, n->children, scratch);

			if (scratch->cell_type == 'h')
				g_string_append_printf(out, "}");

			g_string_append_printf(out, "}\\cell\n");
			scratch->table_column++;
			break;
		case STRONG:
			g_string_append_printf(out, "{\\b ");
			print_rtf_node_tree(out,n->children,scratch);
			g_string_append_printf(out, "}");
			break;
		case EMPH:
			g_string_append_printf(out, "{\\i ");
			print_rtf_node_tree(out,n->children,scratch);
			g_string_append_printf(out, "}");
			break;
		case LINEBREAK:
			g_string_append_printf(out, "\\line ");
			break;
		case LINK:
			temp_link_data = load_link_data(n, scratch);

			if (temp_link_data == NULL) {
				/* replace original text since no definition found */
				g_string_append_printf(out, "[");
				print_rtf_node(out, n->children, scratch);
				g_string_append_printf(out,"]");
				if (n->children->next != NULL) {
					g_string_append_printf(out, "[");
					print_rtf_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]",n->link_data->label);
				}

				free_link_data(temp_link_data);
				break;
			}

			/* Insert link */
			g_string_append_printf(out, "{\\field{\\*\\fldinst{HYPERLINK \"");
			print_rtf_string(out, temp_link_data->source, scratch);
			g_string_append_printf(out, "\"}}{\\fldrslt ");
			if (n->children != NULL)
				print_rtf_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "}}");

			free(temp_link_data);
			break;
		case BULLETLIST:
			pad(out, 2, scratch);
			g_string_append_printf(out, "\\ls1\\ilvl0 ");
			scratch->padded = 0;
			print_rtf_node_tree(out, n->children, scratch);
			break;
		case ORDEREDLIST:
			pad(out, 2, scratch);
			scratch->padded = 0;
			print_rtf_node_tree(out, n->children, scratch);
			break;
		case LISTITEM:
			g_string_append_printf(out, "{\\listtext \\'95 }");
			print_rtf_node_tree(out, n->children, scratch);
			break;
		case NOTEREFERENCE:
			lev = note_number_for_node(n, scratch);
			temp_node = node_for_count(scratch->used_notes, lev);
			scratch->padded = 2;

			g_string_append_printf(out, "{\\super\\chftn}{\\footnote\\pard\\plain\\chtfn ");
			print_rtf_node_tree(out, temp_node->children, scratch);
			g_string_append_printf(out, "}");
			scratch->padded = 0;
			break;
		case GLOSSARYTERM:
			print_rtf_string(out, n->children->str, scratch);
			g_string_append_printf(out, ": ");
			break;
		case GLOSSARYSORTKEY:
			break;
		case NOCITATION:
		case CITATION:
			if ((n->link_data != NULL) && (strncmp(n->link_data->label,"[#",2) == 0)) {
				/* external citation */
				g_string_append_printf(out, "%s", n->link_data->label);
			} else {
				/* MMD citation, so output as endnote */
				scratch->printing_notes = 1;
				lev = 0;
				if (n->link_data != NULL)
					lev = note_number_for_label(n->link_data->label, scratch);
				if (lev != 0) {
					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) {
						/* first use of this citation */
						scratch->max_footnote_num = lev;
						
						old_type = scratch->odf_para_type;
						scratch->odf_para_type = CITATION;
						
						/* change to represent cite count only */
						lev = cite_count_node_from_end(temp_node);
						g_string_append_printf(out, "{\\super\\chftn}{\\footnote\\ftnalt\\pard\\plain\\chtfn ");
						scratch->padded = 2;
						if (temp_node->children != NULL) {
							print_rtf_node(out, temp_node->children, scratch);
						}
						pad(out, 1, scratch);
						g_string_append_printf(out, "}");
						scratch->odf_para_type = old_type;
					} else {
						/* We are reusing a previous citation */

						/* Change lev to represent cite count only */
						lev = cite_count_node_from_end(temp_node);
					
						g_string_append_printf(out, "REUSE CITATION");
					}
				} else {
					/* not located -- this is external cite */

					if ((n->link_data != NULL) && (n->key == NOCITATION)) {
						g_string_append_printf(out, "%s", n->link_data->label);
					} else if (n->link_data != NULL) {
						g_string_append_printf(out, "[");
						if (n->children != NULL) {
							print_rtf_node(out, n->children, scratch);
							g_string_append_printf(out, "][");
						}
						g_string_append_printf(out, "#%s]",n->link_data->label);
					}
				}
			}
			scratch->printing_notes = 0;
			if ((n->next != NULL) && (n->next->key == CITATION)) {
				g_string_append_printf(out, " ");
			}
			break;
		case APOSTROPHE:
			print_rtf_localized_typography(out, APOS, scratch);
			break;
		case ELLIPSIS:
			print_rtf_localized_typography(out, ELLIP, scratch);
			break;
		case EMDASH:
			print_rtf_localized_typography(out, MDASH, scratch);
			break;
		case ENDASH:
			print_rtf_localized_typography(out, NDASH, scratch);
			break;
		case SINGLEQUOTED:
			print_rtf_localized_typography(out, LSQUOTE, scratch);
			print_rtf_node_tree(out, n->children, scratch);
			print_rtf_localized_typography(out, RSQUOTE, scratch);
			break;
		case DOUBLEQUOTED:
			print_rtf_localized_typography(out, LDQUOTE, scratch);
			print_rtf_node_tree(out, n->children, scratch);
			print_rtf_localized_typography(out, RDQUOTE, scratch);
			break;
		case LIST:
		case HEADINGSECTION:
			print_rtf_node_tree(out,n->children,scratch);
			break;
		/* TODO: Some of the following need improvements */
		case TABLEBODY:
		case PLAIN:
			print_rtf_node_tree(out,n->children,scratch);
			g_string_append_printf(out, "\\\n");
			break;
		case NOTELABEL:
		case FOOTER:
		case LINKREFERENCE:
			break;
		case GLOSSARYSOURCE:
		case CITATIONSOURCE:
		case NOTESOURCE:
			if (scratch->printing_notes)
				print_html_node_tree(out, n->children, scratch);
			break;
		case IMAGEBLOCK:
		case IMAGE:
			g_string_append_printf(out, "IMAGES CANNOT BE INSERTED INTO AN RTF DOCUMENT FROM MULTIMARKDOWN \\\n");
			break;
		case VARIABLE:
			temp = metavalue_for_key(n->str,scratch->result_tree);
			if (temp == NULL) {
				g_string_append_printf(out, "[%%%s]",n->str);
			} else {
				g_string_append_printf(out, temp);
				free(temp);
			}
			break;
		default:
			fprintf(stderr, "print_rtf_node encountered unknown node key = %d\n",n->key);
			g_string_append_printf(out, "%s",n->str);
			/* Will use in place of real output during development */
			/* exit(EXIT_FAILURE); */
			break;
	}
}