Ejemplo n.º 1
0
/* find_latex_mode -- check for metadata to switch to beamer/memoir */
int find_latex_mode(int format, node *n) {
	node *latex_mode;
	char *key;
	char *label;
	
	if (format != LATEX_FORMAT)
		return format;
	
	if (tree_contains_key(n, METAKEY)) {
		latex_mode = metadata_for_key("latexmode",n);
		if (latex_mode != NULL) {
			key = metavalue_for_key("latexmode",n);
			label = label_from_string(key);
			if (strcmp(label, "beamer") == 0) {
				format = BEAMER_FORMAT;
			} else if (strcmp(label, "memoir") == 0) {
				format = MEMOIR_FORMAT;
			}
			free(label);
			free(key);
		}
	}
	
	return format;
}
/* extract_metadata_value - parse document and return value of specified
   metadata key (e.g. "LateX Mode")/
   Returns a null-terminated string, which must be freed after use. */
char * extract_metadata_value(char *text, int extensions, char *key) {
    char *value;
    element *result;
    GString *formatted_text;

    formatted_text = preformat_text(text);
    
    result = parse_metadata_only(formatted_text->str, extensions);
    
    value = metavalue_for_key(key, result->children);
    free_element_list(result);
    return value;
}
Ejemplo n.º 3
0
/* extract_metadata_value - parse document and return value of specified
   metadata key (e.g. "LateX Mode")/
   Returns a null-terminated string, which must be freed after use. */
char * extract_metadata_value(char *text, int extensions, char *key) {
    char *value;
    element *result;
    element *references;
    element *notes;
    element *labels;
    GString *formatted_text;

    formatted_text = preformat_text(text);

    references = parse_references(formatted_text->str, extensions);
    notes = parse_notes(formatted_text->str, extensions, references);
    labels = parse_labels(formatted_text->str, extensions, references, notes);

    result = parse_metadata_only(formatted_text->str, extensions);

    value = metavalue_for_key(key, result);
    free_element_list(result);
    free_element_list(references);
    free_element_list(labels);

    return value;
}
Ejemplo n.º 4
0
/* print_html_node -- convert given node to HTML and append */
void print_html_node(GString *out, node *n, scratch_pad *scratch) {
	node *temp_node;
	link_data *temp_link_data = NULL;
	char *temp;
	int lev;
	int random;
	char temp_type;
	char *width = NULL;
	char *height = NULL;
	GString *temp_str;

	if (n == NULL)
		return;
	
	/* debugging statement */
#ifdef DEBUG_ON
	fprintf(stderr, "print_html_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))) {
			g_string_append_printf(out, "</head>\n<body>\n");
			scratch->extensions = scratch->extensions | EXT_HEAD_CLOSED;
		}
	switch (n->key) {
		case NO_TYPE:
			break;
		case LIST:
			print_html_node_tree(out,n->children,scratch);
			break;
		case STR:
			/* fprintf(stderr, "str: '%s'\n", n->str); */
			print_html_string(out,n->str, scratch);
			break;
		case ABBR:
			if (strlen(n->children->str) == 0) {
				g_string_append_printf(out, "<abbr>");
			} else {
				g_string_append_printf(out, "<abbr title=\"");
				print_html_string(out, n->children->str, scratch);
				g_string_append_printf(out, "\">");
			}
			print_html_string(out,n->str, scratch);
			g_string_append_printf(out, "</abbr>");
			break;
		case ABBRSTART:
			if (strlen(n->children->str) == 0) {
				g_string_append_printf(out, "<abbr>");
			} else {
				g_string_append_printf(out, "<abbr title=\"");
				print_html_string(out, n->children->str, scratch);
				g_string_append_printf(out, "\">");
			}
			print_html_string(out,n->str, scratch);
			break;
		case ABBRSTOP:
			print_html_string(out,n->str, scratch);
			g_string_append_printf(out, "</abbr>");
			break;		
		case SPACE:
			g_string_append_printf(out,"%s",n->str);
			break;
		case PLAIN:
			pad(out,1, scratch);
			print_html_node_tree(out,n->children, scratch);
			scratch->padded = 0;
			break;
		case PARA:
			pad(out, 2, scratch);
			g_string_append_printf(out, "<p>");
			print_html_node_tree(out,n->children,scratch);
			if (scratch->footnote_to_print != 0){
				scratch->footnote_para_counter --;
				if (scratch->footnote_para_counter == 0) {
					if (scratch->extensions & EXT_RANDOM_FOOT) {
						srand(scratch->random_seed_base + scratch->footnote_to_print);
						random = rand() % 99999 + 1;
					} else {
						random = scratch->footnote_to_print;
					}
				
					g_string_append_printf(out, " <a href=\"#fnref:%d\" title=\"return to article\" class=\"reversefootnote\">&#160;&#8617;</a>", random);
					scratch->footnote_to_print = 0;
				}
			}
			g_string_append_printf(out, "</p>");
			scratch->padded = 0;
			break;
		case HRULE:
			pad(out, 2, scratch);
			g_string_append_printf(out, "<hr />");
			scratch->padded = 0;
			break;
		case HTMLBLOCK:
			pad(out, 2, scratch);
			g_string_append_printf(out, "%s", n->str);
			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, "<pre><code class=\"%s\">", n->children->str);
				else
					g_string_append_printf(out, "%s", "<pre><code>");
			} else {
				g_string_append_printf(out, "%s", "<pre><code>");
			}
			print_html_string(out, n->str, scratch);
			g_string_append_printf(out, "%s", "</code></pre>");
			scratch->padded = 0;
			break;
		case BULLETLIST:
			pad(out, 2, scratch);
			g_string_append_printf(out, "%s", "<ul>");
			scratch->padded = 0;
			print_html_node_tree(out, n->children, scratch);
			pad(out, 1, scratch);
			g_string_append_printf(out, "%s", "</ul>");
			scratch->padded = 0;
			break;
		case ORDEREDLIST:
			pad(out, 2, scratch);
			g_string_append_printf(out, "%s", "<ol>");
			scratch->padded = 0;
			print_html_node_tree(out, n->children, scratch);
			pad(out, 1, scratch);
			g_string_append_printf(out, "</ol>");
			scratch->padded = 0;
			break;
		case LISTITEM:
			pad(out, 1, scratch);
			g_string_append_printf(out, "<li>");
			scratch->padded = 2;
			print_html_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</li>");
			scratch->padded = 0;
			break;
		case METADATA:
			/* Not if snippet only */
			if (scratch->extensions & EXT_SNIPPET) {
				is_html_complete_doc(n);
				print_html_node_tree(out,n->children, scratch);
				break;
			}
			
			if (!(scratch->extensions & EXT_COMPLETE) && (is_html_complete_doc(n))) {
				/* We have metadata to include, and didn't already force complete */
				g_string_append_printf(out,
				"<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\"/>\n");
				/* either way, now we need to be a complete doc */
				scratch->extensions = scratch->extensions | EXT_COMPLETE;
			} else {
				/* Ensure we lowercase metadata */
				is_html_complete_doc(n);
			}
			/* print the metadata */
			scratch->extensions = scratch->extensions | EXT_HEAD_CLOSED;
			print_html_node_tree(out,n->children, scratch);
			if (scratch->extensions & EXT_COMPLETE) {
				/* need to close head and open body */
				g_string_append_printf(out, "</head>\n<body>\n\n");
			}
			break;
		case METAKEY:
			if (strcmp(n->str, "baseheaderlevel") == 0) {
				scratch->baseheaderlevel = atoi(n->children->str);
				break;
			} else if (strcmp(n->str, "xhtmlheaderlevel") == 0) {
				scratch->baseheaderlevel = atoi(n->children->str);
				break;
			} else if (strcmp(n->str, "htmlheaderlevel") == 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;
			}
			
			/* Don't handle other metadata if we're snippet only */
			if (scratch->extensions & EXT_SNIPPET)
				break;
			
			if (strcmp(n->str, "title") == 0) {
				g_string_append_printf(out, "\t<title>");
				print_html_node(out, n->children, scratch);
				g_string_append_printf(out, "</title>\n");
			} else if (strcmp(n->str, "css") == 0) {
				g_string_append_printf(out, "\t<link type=\"text/css\" rel=\"stylesheet\" href=\"");
				print_html_node(out, n->children, scratch);
				g_string_append_printf(out, "\"/>\n");
			} else if (strcmp(n->str, "xhtmlheader") == 0) {
				trim_trailing_whitespace(n->children->str);
				print_raw_node(out, n->children);
				g_string_append_printf(out, "\n");
			} else if (strcmp(n->str, "htmlheader") == 0) {
				trim_trailing_whitespace(n->children->str);
				print_raw_node(out, n->children);
				g_string_append_printf(out, "\n");
			} else if (strcmp(n->str, "mmdfooter") == 0) {
			} else {
				g_string_append_printf(out,"\t<meta name=\"%s\" content=\"",n->str);
				print_html_node(out,n->children,scratch);
				g_string_append_printf(out,"\"/>\n");
			}
			break;
		case METAVALUE:
			trim_trailing_whitespace(n->str);
			print_html_string(out,n->str, scratch);
			break;
		case FOOTER:
			break;
		case HEADINGSECTION:
			print_html_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 > 6)
				lev = 6;	/* Max at level 6 */
			pad(out, 2, scratch);
			if ( scratch->extensions & EXT_COMPATIBILITY ) {
				/* Use regular Markdown header format */
				g_string_append_printf(out, "<h%1d>", lev);
				print_html_node_tree(out, n->children, scratch);
			} else if (n->children->key == AUTOLABEL) {
				temp = label_from_string(n->children->str);
				/* use label for header since one was specified (MMD)*/
				g_string_append_printf(out, "<h%d id=\"%s\">", lev,temp);
				print_html_node_tree(out, n->children->next, scratch);
				free(temp);
			} else if ( scratch->extensions & EXT_NO_LABELS ) {
				/* Don't generate a label */
				g_string_append_printf(out, "<h%1d>", lev);
				print_html_node_tree(out, n->children, scratch);
			} else {
				/* generate a label by default for MMD */
				temp = label_from_node_tree(n->children);
				g_string_append_printf(out, "<h%d id=\"%s\">", lev, temp);
				print_html_node_tree(out, n->children, scratch);
				free(temp);
			}
			g_string_append_printf(out, "</h%1d>", lev);
			scratch->padded = 0;
			break;
		case APOSTROPHE:
			print_html_localized_typography(out, APOS, scratch);
			break;
		case ELLIPSIS:
			print_html_localized_typography(out, ELLIP, scratch);
			break;
		case EMDASH:
			print_html_localized_typography(out, MDASH, scratch);
			break;
		case ENDASH:
			print_html_localized_typography(out, NDASH, scratch);
			break;
		case SINGLEQUOTED:
			print_html_localized_typography(out, LSQUOTE, scratch);
			print_html_node_tree(out, n->children, scratch);
			print_html_localized_typography(out, RSQUOTE, scratch);
			break;
		case DOUBLEQUOTED:
			print_html_localized_typography(out, LDQUOTE, scratch);
			print_html_node_tree(out, n->children, scratch);
			print_html_localized_typography(out, RDQUOTE, scratch);
			break;
		case LINEBREAK:
			g_string_append_printf(out, "<br/>\n");
			break;
		case MATHSPAN:
			if (n->str[0] == '$') {
				n->str[strlen(n->str)-1] = '\0';
				if (n->str[1] == '$') {
					n->str[strlen(n->str)-1] = '\0';
					g_string_append_printf(out, "<span class=\"math\">\\[%s\\]</span>",&n->str[2]);
				} else {
					g_string_append_printf(out, "<span class=\"math\">\\(%s\\)</span>",&n->str[1]);
				}
			} else if (n->str[strlen(n->str) - 1] == ']') {
				n->str[strlen(n->str) - 3] = '\0';
				g_string_append_printf(out, "<span class=\"math\">%s\\]</span>",n->str);
			} else {
				n->str[strlen(n->str) - 3] = '\0';
				g_string_append_printf(out, "<span class=\"math\">%s\\)</span>",n->str);
			}
			break;
		case STRONG:
			g_string_append_printf(out, "<strong>");
			print_html_node_tree(out,n->children,scratch);
			g_string_append_printf(out, "</strong>");
		break;
		case EMPH:
			g_string_append_printf(out, "<em>");
			print_html_node_tree(out,n->children,scratch);
			g_string_append_printf(out, "</em>");
		break;
		case LINKREFERENCE:
			break;
		case LINK:
#ifdef DEBUG_ON
	fprintf(stderr, "print html link: '%s'\n",n->str);
#endif
			/* Stash a copy of the link data */
			if (n->link_data != NULL)
				temp_link_data = mk_link_data(n->link_data->label, n->link_data->source, n->link_data->title, n->link_data->attr);

			/* 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);

				n->link_data->attr = NULL;
				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_html_node(out, n->children, scratch);
					g_string_append_printf(out,"]");
					if (n->children->next != NULL) {
						g_string_append_printf(out, "[");
						print_html_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);

					/* Restore stashed copy */
					n->link_data = temp_link_data;

					break;
				}
				free(temp);
			}
			g_string_append_printf(out, "<a");
			if (n->link_data->source != NULL) {
				g_string_append_printf(out, " href=\"");
				if (strncmp(n->link_data->source,"mailto:", 6) == 0) {
					scratch->obfuscate = 1;		/* flag obfuscated */
				}
				print_html_string(out,n->link_data->source, scratch);
				g_string_append_printf(out, "\"");
			}
			if ((n->link_data->title != NULL) && (strlen(n->link_data->title) > 0)) {
				g_string_append_printf(out, " title=\"");
				print_html_string(out, n->link_data->title, scratch);
				g_string_append_printf(out, "\"");
			}
			print_html_node_tree(out, n->link_data->attr, scratch);
			g_string_append_printf(out, ">");
			if (n->children != NULL)
				print_html_node_tree(out,n->children,scratch);
			g_string_append_printf(out, "</a>");
			scratch->obfuscate = 0;

			/* Restore stashed copy */
			n->link_data->attr = NULL;
			free_link_data(n->link_data);
			n->link_data = temp_link_data;

			break;
		case ATTRKEY:
			if ( (strcmp(n->str,"height") == 0) || (strcmp(n->str, "width") == 0)) {
			} else {
				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
			/* Stash a copy of the link data */
			if (n->link_data != NULL)
				temp_link_data = mk_link_data(n->link_data->label, n->link_data->source, n->link_data->title, n->link_data->attr);

			if (n->key == IMAGEBLOCK)
				g_string_append_printf(out, "<figure>\n");
			/* 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);
			}
#ifdef DEBUG_ON
	fprintf(stderr, "load reference data\n");
#endif
			/* Load reference data */
			if (n->link_data->label != NULL) {
				temp = strdup(n->link_data->label);

				n->link_data->attr = NULL;
				free_link_data(n->link_data);

				n->link_data = extract_link_data(temp, scratch);
				
				if (n->link_data == NULL) {
					g_string_append_printf(out, "![");
					print_html_node_tree(out, n->children, scratch);
					g_string_append_printf(out,"][%s]",temp);

					/* Restore stashed copy */
					n->link_data = temp_link_data;

					free(temp);

					break;
				}
				free(temp);
			}
#ifdef DEBUG_ON
	fprintf(stderr, "create img\n");
#endif
			g_string_append_printf(out, "<img");
			if (n->link_data->source != NULL)
				g_string_append_printf(out, " src=\"%s\"",n->link_data->source);
			if (n->children != NULL) {
				g_string_append_printf(out, " alt=\"");
				temp_str = g_string_new("");
				print_raw_node_tree(temp_str, n->children);
				print_html_string(out, temp_str->str, scratch);
				g_string_free(temp_str, true);
				g_string_append_printf(out, "\"");
			} else {
				g_string_append_printf(out, " alt=\"%s\"",n->link_data->title);
			}
			if (!(scratch->extensions & EXT_COMPATIBILITY)) {
				if (n->link_data->label != NULL) {
					temp = label_from_string(n->link_data->label);
					g_string_append_printf(out, " id=\"%s\"",temp);
					free(temp);
				}
			}
			if ((n->link_data->title != NULL) && (strlen(n->link_data->title) > 0)) {
				g_string_append_printf(out, " title=\"");
				print_html_string(out, n->link_data->title, scratch);
				g_string_append_printf(out, "\"");
			}
#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 = strdup(temp_node->children->str);
				temp_node = node_for_attribute("width",n->link_data->attr);
				if (temp_node != NULL)
					width = strdup(temp_node->children->str);
				if ((height != NULL) || (width != NULL)) {
	#ifdef DEBUG_ON
		fprintf(stderr, "width/height\n");
	#endif
				g_string_append_printf(out, " style=\"");
				if (height != NULL)
					g_string_append_printf(out, "height:%s;", height);
				if (width != NULL)
					g_string_append_printf(out, "width:%s;", width);
				g_string_append_printf(out, "\"");
			}
	#ifdef DEBUG_ON
		fprintf(stderr, "other attributes\n");
	#endif
				print_html_node_tree(out, n->link_data->attr, scratch);
				free(height);
				free(width);
			}
			g_string_append_printf(out, " />");
			if (n->key == IMAGEBLOCK) {
				if ((n->children != NULL) && (n->children->children != NULL) && (n->children->children->str != NULL)) {
					g_string_append_printf(out, "\n<figcaption>");
					print_html_node(out,n->children,scratch);
					g_string_append_printf(out, "</figcaption>");
				}
				g_string_append_printf(out,"\n</figure>");
				scratch->padded = 0;
			}

			/* Restore stashed copy */
			n->link_data->attr = NULL;
			free_link_data(n->link_data);
			n->link_data = temp_link_data;

			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);
			
			if (scratch->extensions & EXT_RANDOM_FOOT) {
				srand(scratch->random_seed_base + lev);
				random = rand() % 99999 + 1;
			} else {
				random = lev;
			}
			
			if (temp_node->key == GLOSSARYSOURCE) {
				if (lev > scratch->max_footnote_num) {
					g_string_append_printf(out, "<a href=\"#fn:%d\" id=\"fnref:%d\" title=\"see footnote\" class=\"footnote glossary\">[%d]</a>",
						random, random, lev);
						scratch->max_footnote_num = lev;
				} else {
					g_string_append_printf(out, "<a href=\"#fn:%d\" title=\"see footnote\" class=\"footnote glossary\">[%d]</a>",
						random, lev);
				}
			} else {
				if (lev > scratch->max_footnote_num) {
					g_string_append_printf(out, "<a href=\"#fn:%d\" id=\"fnref:%d\" title=\"see footnote\" class=\"footnote\">[%d]</a>",
						random, random, lev);
						scratch->max_footnote_num = lev;
				} else {
					g_string_append_printf(out, "<a href=\"#fn:%d\" title=\"see footnote\" class=\"footnote\">[%d]</a>",
						random, lev);
				}
			}
			break;
		case NOCITATION:
		case CITATION:
#ifdef DEBUG_ON
	fprintf(stderr, "print cite\n");
#endif
			if ((n->link_data != NULL) && (strncmp(n->link_data->label,"[#",2) == 0)) {
				fprintf(stderr, "external cite\n");
				/* external citation (e.g. BibTeX) */
				if (n->key == NOCITATION) {
					g_string_append_printf(out, "<span class=\"notcited\" id=\"%s\"/>",n->str);
				} else {
					g_string_append_printf(out, "<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 = 0;
				if (n->link_data != NULL)
					lev = note_number_for_label(n->link_data->label, scratch);
				if (lev != 0) {
#ifdef DEBUG_ON
					fprintf(stderr, "matching cite found - %d\n",lev);
#endif
					if (scratch->extensions & EXT_RANDOM_FOOT) {
						srand(scratch->random_seed_base + lev);
						random = rand() % 99999 + 1;
					} else {
						random = lev;
					}
					
					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, "<span class=\"notcited\" id=\"%d\">",random);
					} else {
						g_string_append_printf(out, "<a class=\"citation\" href=\"#fn:%d\" title=\"Jump to citation\">[",
							random);
							if (n->children != NULL) {
								g_string_append_printf(out, "<span class=\"locator\">");
								print_html_node(out, n->children, scratch);
								g_string_append_printf(out, "</span>, %d]", lev);
							} else {
								g_string_append_printf(out, "%d]", lev);
							}
					}
					g_string_append_printf(out, "<span class=\"citekey\" style=\"display:none\">%s</span>", n->link_data->label);
					if (n->key == NOCITATION) {
						g_string_append_printf(out, "</span>");
					} else {
						g_string_append_printf(out, "</a>");
					}
				} else {
					/* not located -- this is external cite */
#ifdef DEBUG_ON
				fprintf(stderr, "no match for cite: '%s'\n",n->link_data->label);
#endif
					if ((n->link_data != NULL) && (n->key == NOCITATION)) {
						g_string_append_printf(out, "<span class=\"notcited\" id=\"%s\"/>",n->link_data->label);
					} else if (n->link_data != NULL) {
						g_string_append_printf(out, "<span class=\"externalcitation\">[");
						if (n->children != NULL) {
							print_html_node(out, n->children, scratch);
							g_string_append_printf(out, "][");
						}
						g_string_append_printf(out, "#%s]</span>",n->link_data->label);
					}
				}
			}
#ifdef DEBUG_ON
		fprintf(stderr, "finish cite\n");
#endif
			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;
		case GLOSSARYTERM:
			g_string_append_printf(out,"<span class=\"glossary name\">");
			print_html_string(out, n->children->str, scratch);
			g_string_append_printf(out, "</span>");
			if ((n->next != NULL) && (n->next->key == GLOSSARYSORTKEY) ) {
				g_string_append_printf(out, "<span class=\"glossary sort\" style=\"display:none\">");
				print_html_string(out, n->next->str, scratch);
				g_string_append_printf(out, "</span>");
			}
			g_string_append_printf(out, ": ");
			break;
		case GLOSSARYSORTKEY:
			break;
		case CODE:
			g_string_append_printf(out, "<code>");
			print_html_string(out, n->str, scratch);
			g_string_append_printf(out, "</code>");
			break;
		case BLOCKQUOTEMARKER:
			print_html_node_tree(out, n->children, scratch);
			break;
		case BLOCKQUOTE:
			pad(out,2, scratch);
			g_string_append_printf(out, "<blockquote>\n");
			scratch->padded = 2;
			print_html_node_tree(out, n->children, scratch);
			pad(out,1, scratch);
			g_string_append_printf(out, "</blockquote>");
			scratch->padded = 0;
			break;
		case RAW:
			g_string_append_printf(out, "RAW:");
			g_string_append_printf(out,"%s",n->str);
			break;
		case HTML:
			g_string_append_printf(out, "%s", n->str);
			break;
		case DEFLIST:
			pad(out,2, scratch);
			scratch->padded = 1;
			g_string_append_printf(out, "<dl>\n");
			print_html_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</dl>");
			scratch->padded = 0;
			break;
		case TERM:
			pad(out,1, scratch);
			g_string_append_printf(out, "<dt>");
			print_html_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</dt>\n");
			scratch->padded = 1;
			break;
		case DEFINITION:
			pad(out,1, scratch);
			scratch->padded = 1;
			g_string_append_printf(out, "<dd>");
			print_html_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</dd>\n");
			scratch->padded = 0;
			break;
		case TABLE:
			pad(out,2, scratch);
			g_string_append_printf(out, "<table>\n");
			print_html_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</table>\n");
			scratch->cell_type = 0;
			scratch->padded = 1;
			break;
		case TABLESEPARATOR:
			scratch->table_alignment = n->str;
			if (scratch->cell_type == 0)
				print_col_group(out, scratch);
			scratch->cell_type = 'd';
			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 id=\"%s\">", temp);
			print_html_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</caption>\n");
			free(temp);
			break;
		case TABLELABEL:
			break;
		case TABLEHEAD:
			/* print column alignment for XSLT processing if needed */
			if (scratch->cell_type == 0)
				print_col_group(out, scratch);
			scratch->cell_type = 'h';
			g_string_append_printf(out, "\n<thead>\n");
			print_html_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</thead>\n");
			scratch->cell_type = 'd';
			break;
		case TABLEBODY:
			g_string_append_printf(out, "\n<tbody>\n");
			print_html_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</tbody>\n");
			break;
		case TABLEROW:
			g_string_append_printf(out, "<tr>\n");
			scratch->table_column = 0;
			print_html_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</tr>\n");
			break;
		case TABLECELL:
			temp = scratch->table_alignment;
			if (strncmp(&temp[scratch->table_column],"h",1) == 0) {
				temp_type = 'h';
				scratch->table_column++;
			} else {
				temp_type = scratch->cell_type;
			}
			lev = scratch->table_column;
			if ( strncmp(&temp[lev],"r",1) == 0) {
				g_string_append_printf(out, "\t<t%c style=\"text-align:right;\"", temp_type);
			} else if ( strncmp(&temp[lev],"R",1) == 0) {
				g_string_append_printf(out, "\t<t%c style=\"text-align:right;\"", temp_type);
			} else if ( strncmp(&temp[lev],"c",1) == 0) {
				g_string_append_printf(out, "\t<t%c style=\"text-align:center;\"", temp_type);
			} else if ( strncmp(&temp[lev],"C",1) == 0) {
				g_string_append_printf(out, "\t<t%c style=\"text-align:center;\"", temp_type);
			} else {
				g_string_append_printf(out, "\t<t%c style=\"text-align:left;\"", temp_type);
			}
			if ((n->children != NULL) && (n->children->key == CELLSPAN)) {
				g_string_append_printf(out, " colspan=\"%d\"",(int)strlen(n->children->str)+1);
				scratch->table_column += (int)strlen(n->children->str);
			}
			g_string_append_printf(out, ">");
			scratch->padded = 2;
			print_html_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</t%c>\n", temp_type);
			scratch->table_column++;
			break;
		case CELLSPAN:
			break;
		case GLOSSARYSOURCE:
			if (scratch->printing_notes)
				print_html_node_tree(out, n->children, scratch);
			break;
		case CITATIONSOURCE:
		case NOTESOURCE:
			if (scratch->printing_notes)
				print_html_node_tree(out, n->children, scratch);
			break;
		case SOURCEBRANCH:
			fprintf(stderr,"SOURCEBRANCH\n");
			break;
		case NOTELABEL:
			break;
		case SUPERSCRIPT:
			g_string_append_printf(out, "<sup>%s</sup>",n->str);
			break;
		case SUBSCRIPT:
			g_string_append_printf(out, "<sub>%s</sub>",n->str);
			break;
		case ABBREVIATION:
		case KEY_COUNTER:
			break;
		default:
			fprintf(stderr, "print_html_node encountered unknown node key = %d\n",n->key);
			exit(EXIT_FAILURE);
	}
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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;
	}
}
Ejemplo n.º 7
0
/* print_odf_node -- convert given node to odf and append */
void print_odf_node(GString *out, node *n, scratch_pad *scratch) {
	node *temp_node;
	char *temp;
	int lev;
	int old_type;
	char *width = NULL;
	char *height = NULL;
	GString *temp_str;
	int i;

	if (n == NULL)
		return;
	
	/* debugging statement */
#ifdef DEBUG_ON
	fprintf(stderr, "print_odf_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_HEAD_CLOSED) && 
		!((n->key == FOOTER) || (n->key == METADATA))) {
			g_string_append_printf(out, "<office:body>\n<office:text>\n");
			scratch->extensions = scratch->extensions | EXT_HEAD_CLOSED;
		}
	
	switch (n->key) {
		case NO_TYPE:
			break;
		case LIST:
			print_odf_node_tree(out,n->children,scratch);
			break;
		case STR:
			print_html_string(out,n->str, scratch);
			break;
		case SPACE:
			g_string_append_printf(out,"%s",n->str);
			break;
		case PLAIN:
			pad(out,1, scratch);
			print_odf_node_tree(out,n->children, scratch);
			scratch->padded = 0;
			break;
		case PARA:
			pad(out, 2, scratch);
			g_string_append_printf(out, "<text:p");
			switch (scratch->odf_para_type) {
				case DEFINITION:
				case BLOCKQUOTE:
					g_string_append_printf(out, " text:style-name=\"Quotations\"");
					break;
				case CODE:
				case VERBATIM:
					g_string_append_printf(out, " text:style-name=\"Preformatted Text\"");
					break;
				case ORDEREDLIST:
					g_string_append_printf(out, " text:style-name=\"P2\"");
					break;
				case BULLETLIST:
					g_string_append_printf(out, " text:style-name=\"P1\"");
					break;
				case NOTEREFERENCE:
				case NOTESOURCE:
				case CITATION:
				case NOCITATION:
					g_string_append_printf(out, " text:style-name=\"Footnote\"");
					break;
				default:
					g_string_append_printf(out, " text:style-name=\"Standard\"");
					break;
			}
			g_string_append_printf(out, ">");
			print_odf_node_tree(out,n->children,scratch);
			g_string_append_printf(out, "</text:p>\n");
			scratch->padded = 1;
			break;
		case HRULE:
			pad(out, 2, scratch);
			g_string_append_printf(out,"<text:p text:style-name=\"Horizontal_20_Line\"/>");
			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, "<text:p text:style-name=\"Standard\">%s</text:p>", &n->str[4]);
				scratch->padded = 0;
			}
			break;
		case VERBATIM:
			old_type = scratch->odf_para_type;
			scratch->odf_para_type = VERBATIM;
			pad(out, 2, scratch);
			g_string_append_printf(out, "<text:p text:style-name=\"Preformatted Text\">");
			print_odf_code_string(out, n->str);
			g_string_append_printf(out, "</text:p>\n");
 			scratch->padded = 0;
			scratch->odf_para_type = old_type;
			break;
		case BULLETLIST:
		case ORDEREDLIST:
			old_type = scratch->odf_para_type;
			scratch->odf_para_type = n->key;
			if (scratch->odf_list_needs_end_p) {
				g_string_append_printf(out, "</text:p>");
				scratch->odf_list_needs_end_p = false;
			}
			pad(out, 2, scratch);
			switch (n->key) {
				case BULLETLIST:
					g_string_append_printf(out, "<text:list text:style-name=\"L1\">");
					break;
				case ORDEREDLIST:
					g_string_append_printf(out, "<text:list text:style-name=\"L2\">");
					break;
			}
			scratch->padded = 1;
			print_odf_node_tree(out, n->children, scratch);
			pad(out, 1, scratch);
			g_string_append_printf(out, "</text:list>");
			scratch->padded = 0;
			scratch->odf_para_type = old_type;
			break;
		case LISTITEM:
#ifdef DEBUG_ON
	fprintf(stderr, "print list item\n");
#endif
			pad(out, 1, scratch);
			g_string_append_printf(out, "<text:list-item>\n");
			if ((n->children != NULL) && (n->children->children != NULL) && (n->children->children->key != PARA)) {
				switch (scratch->odf_para_type) {
					case BULLETLIST:
						g_string_append_printf(out, "<text:p text:style-name=\"P1\">");
						break;
					case ORDEREDLIST:
						g_string_append_printf(out, "<text:p text:style-name=\"P2\">");
						break;
				}
				scratch->odf_list_needs_end_p = true;
			}
			scratch->padded = 2;
			print_odf_node_tree(out, n->children, scratch);
			scratch->odf_list_needs_end_p = false;
#ifdef DEBUG_ON
	fprintf(stderr, "print list tree\n");
#endif
			if (!(tree_contains_key(n->children, BULLETLIST)) && 
				!(tree_contains_key(n->children, ORDEREDLIST))) {
				if ((n->children != NULL) && (n->children->children != NULL) && (n->children->children->key != PARA))
					g_string_append_printf(out, "</text:p>");
			}
			g_string_append_printf(out, "</text:list-item>\n");
			scratch->padded = 1;
#ifdef DEBUG_ON
	fprintf(stderr, "finish print list item\n");
#endif
			break;
		case METADATA:
			g_string_append_printf(out, "<office:meta>\n");
			scratch->extensions = scratch->extensions | EXT_HEAD_CLOSED;
			print_odf_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</office:meta>\n");
			temp_node = metadata_for_key("odfheader", n);
			if (temp_node != NULL) {
				print_raw_node(out, temp_node->children);
			}
			g_string_append_printf(out, "<office:body>\n<office:text>\n");
			break;
		case METAKEY:
			temp = label_from_string(n->str);
			if (strcmp(temp, "title") == 0) {
				g_string_append_printf(out, "<dc:title>");
				print_odf_node(out, n->children, scratch);
				g_string_append_printf(out, "</dc:title>\n");
			} else if (strcmp(temp, "css") == 0) {
			} else if (strcmp(temp, "xhtmlheader") == 0) {
			} else if (strcmp(temp, "htmlheader") == 0) {
			} else if (strcmp(temp, "baseheaderlevel") == 0) {
				scratch->baseheaderlevel = atoi(n->children->str);
			} else if (strcmp(temp, "odfheaderlevel") == 0) {
				scratch->baseheaderlevel = atoi(n->children->str);
			} else if (strcmp(temp, "htmlheaderlevel") == 0) {
			} else if (strcmp(temp, "latexinput") == 0) {
			} else if (strcmp(temp, "latexfooter") == 0) {
			} else if (strcmp(temp, "latexmode") == 0) {
			} else if (strcmp(temp, "keywords") == 0) {
				g_string_append_printf(out, "<meta:keyword>");
				print_odf_node(out, n->children, scratch);
				g_string_append_printf(out, "</meta:keyword>\n");
			} else if (strcmp(temp, "quoteslanguage") == 0) {
				free(temp);
				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,"<meta:user-defined meta:name=\"");
				print_odf_string(out, n->str);
				g_string_append_printf(out, "\">");
				print_odf_node(out,n->children,scratch);
				g_string_append_printf(out,"</meta:user-defined>\n");
			}
			free(temp);
			break;
		case METAVALUE:
			trim_trailing_whitespace(n->str);
			print_odf_string(out,n->str);
			break;
		case FOOTER:
			break;
		case HEADINGSECTION:
			print_odf_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 */
			pad(out, 2, scratch);
			g_string_append_printf(out, "<text:h text:outline-level=\"%d\">", lev);
			if (n->children->key == AUTOLABEL) {
				/* use label for header since one was specified (MMD)*/
				temp = label_from_string(n->children->str);
				g_string_append_printf(out, "<text:bookmark text:name=\"%s\"/>", temp);
				print_odf_node_tree(out, n->children->next, scratch);
				g_string_append_printf(out, "<text:bookmark-end text:name=\"%s\"/>", temp);
				free(temp);
			} else {
				/* generate a label by default for MMD */
				temp = label_from_node_tree(n->children);
				g_string_append_printf(out, "<text:bookmark text:name=\"%s\"/>", temp);
				print_odf_node_tree(out, n->children, scratch);
				g_string_append_printf(out, "<text:bookmark-end text:name=\"%s\"/>", temp);
				free(temp);
			}
			g_string_append_printf(out, "</text:h>");
			scratch->padded = 0;
			break;
		case APOSTROPHE:
			print_html_localized_typography(out, APOS, scratch);
			break;
		case ELLIPSIS:
			print_html_localized_typography(out, ELLIP, scratch);
			break;
		case EMDASH:
			print_html_localized_typography(out, MDASH, scratch);
			break;
		case ENDASH:
			print_html_localized_typography(out, NDASH, scratch);
			break;
		case SINGLEQUOTED:
			print_html_localized_typography(out, LSQUOTE, scratch);
			print_odf_node_tree(out, n->children, scratch);
			print_html_localized_typography(out, RSQUOTE, scratch);
			break;
		case DOUBLEQUOTED:
			print_html_localized_typography(out, LDQUOTE, scratch);
			print_odf_node_tree(out, n->children, scratch);
			print_html_localized_typography(out, RDQUOTE, scratch);
			break;
		case LINEBREAK:
			g_string_append_printf(out, "<text:line-break/>");
			break;
		case MATHSPAN:
			if (n->str[0] == '$') {
				g_string_append_printf(out, "<text:span text:style-name=\"math\">%s</text:span>",n->str);
			} else if (n->str[strlen(n->str) - 1] == ']') {
				n->str[strlen(n->str) - 3] = '\0';
				g_string_append_printf(out, "<text:span text:style-name=\"math\">%s\\]</text:span>",n->str);
			} else {
				n->str[strlen(n->str) - 3] = '\0';
				g_string_append_printf(out, "<text:span text:style-name=\"math\">%s\\)</text:span>",n->str);
			}
			break;
		case STRONG:
			g_string_append_printf(out, "<text:span text:style-name=\"MMD-Bold\">");
			print_odf_node_tree(out,n->children,scratch);
			g_string_append_printf(out, "</text:span>");
		break;
		case EMPH:
			g_string_append_printf(out, "<text:span text:style-name=\"MMD-Italic\">");
			print_odf_node_tree(out,n->children,scratch);
			g_string_append_printf(out, "</text:span>");
		break;
		case LINKREFERENCE:
			break;
		case LINK:
#ifdef DEBUG_ON
	fprintf(stderr, "print odf 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 odf 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 odf link: '%s'\n",n->str);
#endif
			/* Load reference data */
			if (n->link_data->label != NULL) {
#ifdef DEBUG_ON
	fprintf(stderr, "have label for odf 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_odf_node(out, n->children, scratch);
					g_string_append_printf(out,"]");
					if (n->children->next != NULL) {
						g_string_append_printf(out, "[");
						print_odf_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);
			}
#ifdef DEBUG_ON
	fprintf(stderr, "got link data for odf link: '%s'\n",n->str);
#endif
			g_string_append_printf(out, "<text:a xlink:type=\"simple\"");
			if (n->link_data->source != NULL) {
				g_string_append_printf(out, " xlink:href=\"");
				print_html_string(out,n->link_data->source, scratch);
				g_string_append_printf(out, "\"");
			}
			if ((n->link_data->title != NULL) && (strlen(n->link_data->title) > 0)) {
				g_string_append_printf(out, " office:name=\"");
				print_html_string(out, n->link_data->title, scratch);
				g_string_append_printf(out, "\"");
			}
			print_odf_node_tree(out, n->link_data->attr, scratch);
			g_string_append_printf(out, ">");
			if (n->children != NULL)
				print_odf_node_tree(out,n->children,scratch);
			g_string_append_printf(out, "</text:a>");
			n->link_data->attr = NULL;	/* We'll delete these elsewhere */
			break;
		case ATTRKEY:
			if ( (strcmp(n->str,"height") == 0) || (strcmp(n->str, "width") == 0)) {
			}
			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
			if (n->key == IMAGEBLOCK)
				g_string_append_printf(out, "<text:p>\n");
			/* 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);
			}
#ifdef DEBUG_ON
	fprintf(stderr, "load reference data\n");
#endif
			/* 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) {
					g_string_append_printf(out, "![");
					print_html_node_tree(out, n->children, scratch);
					g_string_append_printf(out,"][%s]",temp);
					free(temp);
					break;
				}
				free(temp);
			}
#ifdef DEBUG_ON
	fprintf(stderr, "create img\n");
#endif
			g_string_append_printf(out, "<draw:frame text:anchor-type=\"as-char\"\ndraw:z-index=\"0\" draw:style-name=\"fr1\" ");

			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 (width != NULL) {
				g_string_append_printf(out, "svg:width=\"%s\"\n", width);
			} else {
				g_string_append_printf(out, "svg:width=\"95%%\"\n");
			}
			
			g_string_append_printf(out, ">\n<draw:text-box><text:p><draw:frame text:anchor-type=\"as-char\" draw:z-index=\"1\" ");
			if ((height != NULL) && (width != NULL)) {
				g_string_append_printf(out, "svg:height=\"%s\"\n",height);
				g_string_append_printf(out, "svg:width=\"%s\"\n", width);
			}
			
			if (n->link_data->source != NULL)
				g_string_append_printf(out, "><draw:image xlink:href=\"%s\"",n->link_data->source);

			g_string_append_printf(out," xlink:type=\"simple\" xlink:show=\"embed\" xlink:actuate=\"onLoad\" draw:filter-name=\"&lt;All formats&gt;\"/>\n</draw:frame></text:p>");

			if (n->key == IMAGEBLOCK) {
				g_string_append_printf(out,"<text:p>");
				if (n->children != NULL) {
					g_string_append_printf(out, "Figure <text:sequence text:name=\"Figure\" text:formula=\"ooow:Figure+1\" style:num-format=\"1\"> Update Fields to calculate numbers</text:sequence>: ");
					print_odf_node_tree(out, n->children, scratch);
				}
				g_string_append_printf(out, "</text:p></draw:text-box></draw:frame>\n</text:p>\n");
			} else {
				g_string_append_printf(out, "</draw:text-box></draw:frame>\n");
			}
			scratch->padded = 1;
			n->link_data->attr = NULL;	/* We'll delete these elsewhere */
			
			free(height);
			free(width);
			break;
#ifdef DEBUG_ON
	fprintf(stderr, "finish image\n");
#endif
		case NOTEREFERENCE:
			old_type = scratch->odf_para_type;
			scratch->odf_para_type = 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, "<text:note text:id=\"\" text:note-class=\"glossary\"><text:note-body>\n");
				print_odf_node_tree(out, temp_node->children, scratch);
				g_string_append_printf(out, "</text:note-body>\n</text:note>\n");
			} else {
				g_string_append_printf(out, "<text:note text:id=\"\" text:note-class=\"footnote\"><text:note-body>\n");
				print_odf_node_tree(out, temp_node->children, scratch);
				g_string_append_printf(out, "</text:note-body>\n</text:note>\n");
			}
			scratch->padded = 1;
			scratch->odf_para_type = old_type;
			break;
		case NOCITATION:
		case CITATION:
#ifdef DEBUG_ON
	fprintf(stderr, "print cite\n");
#endif
			if ((n->link_data != NULL) && (strncmp(n->link_data->label,"[#",2) == 0)) {
				/* external citation */
#ifdef DEBUG_ON
					fprintf(stderr, "external first??");
#endif
				g_string_append_printf(out, "%s", n->link_data->label);
			} else {
#ifdef DEBUG_ON
				fprintf(stderr, "internal cite\n");
#endif
				/* MMD citation, so output as footnote */
				/* TODO: create separate stream from footnotes */
				lev = 0;
				if (n->link_data != NULL)
					lev = note_number_for_label(n->link_data->label, scratch);
				if (lev != 0) {
#ifdef DEBUG_ON
					fprintf(stderr, "matching cite found - %d\n", lev);
#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) {
						/* 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, "<text:note text:id=\"cite%d\" text:note-class=\"endnote\"><text:note-body>\n", lev);
						scratch->padded = 2;
						if (temp_node->children != NULL) {
							print_odf_node(out, temp_node->children, scratch);
						}
						pad(out, 1, scratch);
						g_string_append_printf(out, "</text:note-body>\n</text:note>\n");
						scratch->odf_para_type = old_type;
					} else {
						/* We are reusing a previous citation */
#ifdef DEBUG_ON
					fprintf(stderr, "link to existing cite %d\n", lev);
#endif
						/* Change lev to represent cite count only */
						lev = cite_count_node_from_end(temp_node);
#ifdef DEBUG_ON
					fprintf(stderr, "renumbered to %d\n", lev);
#endif
					
						g_string_append_printf(out, "<text:span text:style-name=\"Footnote_20_anchor\"><text:note-ref text:note-class=\"endnote\" text:reference-format=\"text\" text:ref-name=\"cite%d\">%d</text:note-ref></text:span>", lev, lev);
					}
				} else {
					/* not located -- this is external cite */
#ifdef DEBUG_ON
				fprintf(stderr, "no match for cite: '%s'\n",n->link_data->label);
#endif
					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_odf_node(out, n->children, scratch);
							g_string_append_printf(out, "][");
						}
						g_string_append_printf(out, "#%s]",n->link_data->label);
					}
				}
			}
			if ((n->next != NULL) && (n->next->key == CITATION)) {
				g_string_append_printf(out, " ");
			}
#ifdef DEBUG_ON
		fprintf(stderr, "finish cite\n");
#endif
			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;
		case GLOSSARYTERM:
			g_string_append_printf(out,"<text:p text:style-name=\"Glossary\">");
			print_odf_string(out, n->children->str);
			g_string_append_printf(out, ":</text:p>\n");
			break;
		case GLOSSARYSORTKEY:
			break;
		case CODE:
			g_string_append_printf(out, "<text:span text:style-name=\"Source_20_Text\">");
			print_html_string(out, n->str, scratch);
			g_string_append_printf(out, "</text:span>");
			break;
		case BLOCKQUOTEMARKER:
			print_odf_node_tree(out, n->children, scratch);
			break;
		case BLOCKQUOTE:
			pad(out,2, scratch);
			scratch->padded = 2;
			old_type = scratch->odf_para_type;
			scratch->odf_para_type = BLOCKQUOTE;
			print_odf_node_tree(out, n->children, scratch);
			scratch->odf_para_type = old_type;
			break;
		case RAW:
		/* shouldn't happen */
			assert(n->key != RAW);
			break;
		case HTML:
			/* don't print HTML */
			/* but do print HTML comments for raw ODF */
			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]);
			}
			break;
		case DEFLIST:
			print_odf_node_tree(out, n->children, scratch);
			break;
		case TERM:
			pad(out,1, scratch);
			g_string_append_printf(out, "<text:p><text:span text:style-name=\"MMD-Bold\">");
			print_odf_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</text:span></text:p>\n");
			scratch->padded = 1;
			break;
		case DEFINITION:
			old_type = scratch->odf_para_type;
			scratch->odf_para_type = DEFINITION;
			pad(out,1, scratch);
			scratch->padded = 1;
			g_string_append_printf(out, "<text:p text:style-name=\"Quotations\">");
			print_odf_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</text:p>\n");
			scratch->padded = 0;
			scratch->odf_para_type = old_type;
			break;
		case TABLE:
			pad(out,2, scratch);
			g_string_append_printf(out, "<table:table>\n");
			print_odf_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</table:table>\n");
			/* caption if present */
			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,"<text:p><text:bookmark text:name=\"%s\"/>Table <text:sequence text:name=\"Table\" text:formula=\"ooow:Table+1\" style:num-format=\"1\"> Update Fields to calculate numbers</text:sequence>:", temp);
				print_odf_node_tree(out,n->children->children, scratch);
				g_string_append_printf(out, "<text:bookmark-end text:name=\"%s\"/></text:p>\n",temp);
				free(temp);
			}
			scratch->padded = 1;
			break;
		case TABLESEPARATOR:
			scratch->table_alignment = n->str;
			break;
		case TABLECAPTION:
			break;
		case TABLELABEL:
			break;
		case TABLEHEAD:
			for (i=0; i < strlen(scratch->table_alignment); i++) {
				g_string_append_printf(out, "<table:table-column/>\n");
			}
			scratch->cell_type = 'h';
			print_odf_node_tree(out, n->children, scratch);
			scratch->cell_type = 'd';
			break;
		case TABLEBODY:
			print_odf_node_tree(out, n->children, scratch);
			break;
		case TABLEROW:
			g_string_append_printf(out, "<table:table-row>\n");
			scratch->table_column = 0;
			print_odf_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</table:table-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, "<table:table-cell");
			if ((n->children != NULL) && (n->children->key == CELLSPAN)) {
				g_string_append_printf(out, " table:number-columns-spanned=\"%d\"", strlen(n->children->str)+1);
			}
			g_string_append_printf(out, ">\n<text:p");
			if (scratch->cell_type == 'h') {
				g_string_append_printf(out, " text:style-name=\"Table_20_Heading\"");
			} else {
				if ( strncmp(&temp[lev],"r",1) == 0) {
					g_string_append_printf(out, " text:style-name=\"MMD-Table-Right\"");
				} else if ( strncmp(&temp[lev],"R",1) == 0) {
					g_string_append_printf(out, " text:style-name=\"MMD-Table-Right\"");
				} else if ( strncmp(&temp[lev],"c",1) == 0) {
					g_string_append_printf(out, " text:style-name=\"MMD-Table-Center\"");
				} else if ( strncmp(&temp[lev],"C",1) == 0) {
					g_string_append_printf(out, " text:style-name=\"MMD-Table-Center\"");
				} else {
					g_string_append_printf(out, " text:style-name=\"MMD-Table\"");
				}
			}

			g_string_append_printf(out, ">");
			scratch->padded = 2;
			print_odf_node_tree(out, n->children, scratch);
			g_string_append_printf(out, "</text:p>\n</table:table-cell>\n", scratch->cell_type);
			scratch->table_column++;
			break;
		case CELLSPAN:
			break;
		case GLOSSARYSOURCE:
			print_odf_node_tree(out, n->children, scratch);
			break;
		case CITATIONSOURCE:
		case NOTESOURCE:
			print_odf_node(out, n->children, scratch);
			break;
		case SOURCEBRANCH:
			fprintf(stderr,"SOURCEBRANCH\n");
			break;
		case NOTELABEL:
			break;
		case SUPERSCRIPT:
			g_string_append_printf(out, "<text:span text:style-name=\"MMD-Superscript\">");
			print_html_string(out,n->str, scratch);
			g_string_append_printf(out, "</text:span>");
			break;
		case SUBSCRIPT:
			g_string_append_printf(out, "<text:span text:style-name=\"MMD-Subscript\">");
			print_html_string(out,n->str, scratch);
			g_string_append_printf(out, "</text:span>");
			break;
		case KEY_COUNTER:
			break;
		default:
			fprintf(stderr, "print_odf_node encountered unknown node key = %d\n",n->key);
			exit(EXIT_FAILURE);
	}
	
#ifdef DEBUG_ON
	fprintf(stderr, "finish print_odf_node: %d\n",n->key);
#endif

}