):
- openCodeBlock: '\n\n',
- openCodeBlockStart: '\n\n',
- openCodeBlockLangNone: '\n\n',
- closeCodeBlock: '
\n\n',
+ openCodeBlock: '\n\n',
+ openCodeBlockStart: '\n\n',
+ openCodeBlockLangNone: "\n\n",
+ closeCodeBlock: "
\n\n",
// non-semantic underline, since Docs supports it.
underlineStart: '',
- underlineEnd: '',
-
+ underlineEnd: "",
- // I think we need to track these independently because the previous/next sibling won't always be a list item,
- // thus not giving reliable nesting level.
+ // I think we need to track these independently because the previous/next sibling won't always be a list item,
+ // thus not giving reliable nesting level.
listNestingLevel: 0,
- // This will also help us know if a list item needs to be closed before opening a new one.
- inListItem: false
+ // This will also help us know if a list item needs to be closed before opening a new one.
+ inListItem: false,
};
-html.tablePrefix = ' ';
+html.tablePrefix = " ";
-html.doHtml = function(config) {
+html.doHtml = function (config) {
// Basically, we can use the same code as doMarkdown, just change the markup.
gdc.useHtml();
-
+
gdc.config(config);
// Get the body elements.
var elements = gdc.getElements();
@@ -69,30 +68,51 @@ html.doHtml = function(config) {
izip.createImagesZip();
}
}
-
+
if (gdc.hasImages) {
- gdc.info += '\n* This document has images: check for ' + gdc.alertPrefix;
- gdc.info += ' inline image link in generated source and store images to your server.';
- gdc.info += ' NOTE: Images in exported zip file from Google Docs may not appear in ';
- gdc.info += ' the same order as they do in your doc. Please check the images!\n';
+ gdc.info += "\n* This document has images: check for " + gdc.alertPrefix;
+ gdc.info +=
+ " inline image link in generated source and store images to your server.";
+ gdc.info +=
+ " NOTE: Images in exported zip file from Google Docs may not appear in ";
+ gdc.info +=
+ " the same order as they do in your doc. Please check the images!\n";
}
-
+
if (gdc.hasFootnotes) {
- gdc.info += '\n* Footnote support in HTML is alpha: please check your footnotes.';
+ gdc.info +=
+ "\n* Footnote support in HTML is alpha: please check your footnotes.";
+ }
+
+ // Add comment support (if enabled)
+ const comments = getDocumentComments();
+ if (comments && comments.length > 0) {
+ if (gdc.docType === gdc.docTypes.md) {
+ gdc.out = insertMarkdownCommentReferences(gdc.out, comments);
+ gdc.out += createMarkdownCommentSection(comments);
+ } else {
+ gdc.out = insertHtmlCommentReferences(gdc.out, comments);
+ gdc.out =
+ addCommentStyles() + gdc.out + createHtmlCommentSection(comments);
+ }
}
-
+
// Record elapsed time.
- var eTime = (new Date().getTime() - gdc.startTime)/1000;
- gdc.info = '\n\nConversion time: ' + eTime + ' seconds.\n' + gdc.info;
+ var eTime = (new Date().getTime() - gdc.startTime) / 1000;
+ gdc.info = "\n\nConversion time: " + eTime + " seconds.\n" + gdc.info;
// Note ERRORs or WARNINGs or ALERTs at the top if there are any.
- gdc.errorSummary = '';
- if ( gdc.errorCount || gdc.warningCount || gdc.alertCount ) {
- gdc.errorSummary = 'You have some errors, warnings, or alerts. '
- + 'If you are using reckless mode, turn it off to see inline alerts.'
- + '\n* ERRORs: ' + gdc.errorCount
- + '\n* WARNINGs: ' + gdc.warningCount
- + '\n* ALERTS: ' + gdc.alertCount;
+ gdc.errorSummary = "";
+ if (gdc.errorCount || gdc.warningCount || gdc.alertCount) {
+ gdc.errorSummary =
+ "You have some errors, warnings, or alerts. " +
+ "If you are using reckless mode, turn it off to see inline alerts." +
+ "\n* ERRORs: " +
+ gdc.errorCount +
+ "\n* WARNINGs: " +
+ gdc.warningCount +
+ "\n* ALERTS: " +
+ gdc.alertCount;
}
gdc.info = gdc.errorSummary + gdc.info;
@@ -101,7 +121,7 @@ html.doHtml = function(config) {
// Warn at the top if DEBUG is true.
if (DEBUG) {
- gdc.info = '\n\n' + gdc.info;
+ gdc.info = "\n\n" + gdc.info;
}
// Add info and alert message to top of output.
@@ -109,23 +129,22 @@ html.doHtml = function(config) {
gdc.out = gdc.alertMessage + gdc.out;
// Add info comment if desired.
if (!gdc.suppressInfo) {
- gdc.out = gdc.info + '\n----->\n\n' + gdc.out;
- } else if (gdc.suppressInfo && gdc.errorSummary !== '') {
+ gdc.out = gdc.info + "\n----->\n\n" + gdc.out;
+ } else if (gdc.suppressInfo && gdc.errorSummary !== "") {
// But notify if there are errors.
- gdc.out = '\n' + gdc.out;
+ gdc.out = "\n" + gdc.out;
}
// Always include the banner.
gdc.out = gdc.banner + gdc.out;
-
// Output content.
gdc.flushBuffer();
gdc.flushFootnoteBuffer();
// Close footnotes list if necessary.
if (gdc.hasFootnotes) {
- gdc.writeStringToBuffer('\n');
+ gdc.writeStringToBuffer("\n");
gdc.flushBuffer();
}
@@ -134,16 +153,16 @@ html.doHtml = function(config) {
// Switch for handling different child elements for HTML conversion.
// Use for all element types, unless they have no children.
-html.handleChildElement = function(child) {
+html.handleChildElement = function (child) {
gdc.useHtml();
var childType = child.getType();
-
+
// Get indent if possible for this element.
// For HTML, we can also count blank paragraphs: Note difference in md.handleChildElement.
if (child.getIndentStart) {
gdc.indent = child.getIndentStart();
}
-
+
html.checkList();
// Most common element types first.
@@ -155,8 +174,13 @@ html.handleChildElement = function(child) {
case TEXT:
try {
gdc.handleText(child);
- } catch(e) {
- gdc.log('ERROR handling text element:\n\n' + e + '\n\nText: ' + child.getText());
+ } catch (e) {
+ gdc.log(
+ "ERROR handling text element:\n\n" +
+ e +
+ "\n\nText: " +
+ child.getText()
+ );
}
break;
case LIST_ITEM:
@@ -199,21 +223,21 @@ html.handleChildElement = function(child) {
case EQUATION:
break;
case UNSUPPORTED:
- gdc.log('child element: UNSUPPORTED');
+ gdc.log("child element: UNSUPPORTED");
break;
default:
- gdc.log('child element: unknown');
- };
+ gdc.log("child element: unknown");
+ }
gdc.lastChildType = childType;
};
-html.handleTable = function(tableElement) {
+html.handleTable = function (tableElement) {
// Note that we're converting all tables to HTML.
if (!gdc.hasTables) {
- gdc.info += '\n* Tables are currently converted to HTML tables.';
+ gdc.info += "\n* Tables are currently converted to HTML tables.";
gdc.hasTables = true;
}
-
+
// init counters.
gdc.nCols = 0;
gdc.nRows = 0;
@@ -228,7 +252,6 @@ html.handleTable = function(tableElement) {
// Handle single-cell table here.
if (gdc.nCols === 1 && gdc.nRows === 1) {
-
// Examine text length and text font to see if it's a suspicious single-cell table.
var text = tableElement.getChild(0).getText();
var textElement = tableElement.getChild(0).editAsText();
@@ -236,43 +259,46 @@ html.handleTable = function(tableElement) {
// But if it's in code font (first and last lines), we'll let it go.
// How long is suspiciously long?
var singleCellMaxChars = 5120;
- if (text.length > singleCellMaxChars && !gdc.textIsCode(textElement) ) {
+ if (text.length > singleCellMaxChars && !gdc.textIsCode(textElement)) {
gdc.warningCount++;
- gdc.info += '\nWARNING:\nFound a long single-cell table ';
- gdc.info += '(' + text.length + ' characters) starting with:\n';
- gdc.info += '**start sample:**\n';
- gdc.info += text.substring(0, 32) + '\n**end sample**\n';
- gdc.info += 'Check to make sure this is supposed to be a code block.\n';
- gdc.alert('Long single-cell table. Check to make sure this is meant to be a code block.');
+ gdc.info += "\nWARNING:\nFound a long single-cell table ";
+ gdc.info += "(" + text.length + " characters) starting with:\n";
+ gdc.info += "**start sample:**\n";
+ gdc.info += text.substring(0, 32) + "\n**end sample**\n";
+ gdc.info += "Check to make sure this is supposed to be a code block.\n";
+ gdc.alert(
+ "Long single-cell table. Check to make sure this is meant to be a code block."
+ );
}
-
+
// Markdown or HTML table for single-cell table.
// Also handling lang for single-cell table.
if (gdc.docType === gdc.docTypes.md && !gdc.isHTML) {
gdc.inCodeBlock = gdc.isSingleCellTable = true;
var text = tableElement.getText();
- var lang = gdc.getLang(text.split('\n')[0]);
- if (lang !== '') {
+ var lang = gdc.getLang(text.split("\n")[0]);
+ if (lang !== "") {
// Skip first line, since it just specified lang.
// XXX: note difference between HTML and Markdown. Why?
- text = text.substring(text.indexOf('\n') + 1);
- }
-
+ text = text.substring(text.indexOf("\n") + 1);
+ }
+
// Write the code block.
gdc.startCodeBlock(lang);
gdc.writeStringToBuffer(text);
- gdc.writeStringToBuffer('' + md.closeCodeBlock);
+ gdc.writeStringToBuffer("" + md.closeCodeBlock);
gdc.inCodeBlock = gdc.isSingleCellTable = false;
- } else { // HTML code block.
+ } else {
+ // HTML code block.
gdc.inCodeBlock = gdc.isSingleCellTable = true;
var text = tableElement.getText();
- var lang = gdc.getLang(text.split('\n')[0]);
- if (lang !== '') {
+ var lang = gdc.getLang(text.split("\n")[0]);
+ if (lang !== "") {
// Skip first line, since it just specified lang.
// Note difference between HTML and Markdown. Why?
- text = text.substring(text.indexOf('\n'));
+ text = text.substring(text.indexOf("\n"));
}
-
+
// Write the code block.
gdc.startCodeBlock(lang);
text = html.escapeOpenTag(text);
@@ -280,43 +306,42 @@ html.handleTable = function(tableElement) {
text = util.markSpecial(text);
text = util.markNewlines(text);
gdc.writeStringToBuffer(text);
- gdc.writeStringToBuffer(html.closeCodeBlock);
+ gdc.writeStringToBuffer(html.closeCodeBlock);
gdc.inCodeBlock = gdc.isSingleCellTable = false;
}
-
+
return;
}
-
+
// Regular table processing.
gdc.isTable = true;
-
+
gdc.useHtml();
-
+
// Go through children of this table.
- gdc.writeStringToBuffer('\n\n');
+ gdc.writeStringToBuffer("\n\n");
md.childLoop(tableElement);
- gdc.writeStringToBuffer('\n
\n\n');
+ gdc.writeStringToBuffer("\n
\n\n");
// Turn off guard for table cell.
gdc.startingTableCell = false;
-
+
gdc.isTable = false;
gdc.useMarkdown();
};
-html.handleTableRow = function(tableRowElement) {
-
+html.handleTableRow = function (tableRowElement) {
if (gdc.isSingleCellTable === true) {
md.childLoop(tableRowElement);
return;
}
-
+
// Go through children of this row.
- gdc.writeStringToBuffer('\n ');
+ gdc.writeStringToBuffer("\n
");
md.childLoop(tableRowElement);
- gdc.writeStringToBuffer('\n
');
+ gdc.writeStringToBuffer("\n ");
};
-html.handleTableCell = function(tableCellElement) {
+html.handleTableCell = function (tableCellElement) {
if (gdc.isSingleCellTable === true) {
md.childLoop(tableCellElement);
return;
@@ -325,11 +350,13 @@ html.handleTableCell = function(tableCellElement) {
gdc.startingTableCell = true;
// Set attribute for colspan or rowspan, if necessary (>1).
- var tdAttr = '';
-
+ var tdAttr = "";
+
// Rowspan handling.
var rowspan = tableCellElement.getRowSpan();
- if (rowspan === 0) { return; }
+ if (rowspan === 0) {
+ return;
+ }
if (rowspan > 1) {
tdAttr += ' rowspan="' + rowspan + '"';
@@ -338,66 +365,67 @@ html.handleTableCell = function(tableCellElement) {
// Colspan handling.
var colspan = tableCellElement.getColSpan();
- // Skip cells that have been merged over.
- if (colspan === 0) { return; }
-
+ // Skip cells that have been merged over.
+ if (colspan === 0) {
+ return;
+ }
+
if (colspan > 1) {
tdAttr += ' colspan="' + colspan + '"';
}
// End colspan code.
-
+
// Add attribute only if non-empty.
if (tdAttr) {
- gdc.writeStringToBuffer('\n | ');
+ gdc.writeStringToBuffer("\n | ");
} else {
- gdc.writeStringToBuffer('\n | ');
+ gdc.writeStringToBuffer("\n | ");
}
-
+
// Go through children of this cell.
md.childLoop(tableCellElement);
md.maybeEndCodeBlock();
html.closeAllLists();
- gdc.writeStringToBuffer('\n | ');
+ gdc.writeStringToBuffer("\n ");
};
// Handle the heading type of the paragraph.
// Need to close heading for HTML too, so need to save heading state.
// Fall through for NORMAL.
-html.handleHeading = function(heading, para) {
-
+html.handleHeading = function (heading, para) {
// We're doing a little dance here for heading demotion. Also for closing tags.
var htitle = 0;
if (gdc.demoteHeadings) {
htitle = 1;
}
switch (heading) {
- case DocumentApp.ParagraphHeading.HEADING6:
- // Warn about level 6 headings if demoting (and do not demote h6).
- var warning = 'H6 not demoted to H7.';
+ case DocumentApp.ParagraphHeading.HEADING6:
+ // Warn about level 6 headings if demoting (and do not demote h6).
+ var warning = "H6 not demoted to H7.";
if (gdc.demoteHeadings) {
if (!gdc.warnedAboutH7) {
gdc.warn(warning + ' Look for "' + warning + '" inline.');
gdc.warnedAboutH7 = true;
}
- gdc.writeStringToBuffer('\n\n');
+ gdc.writeStringToBuffer("\n\n");
}
- gdc.writeStringToBuffer('\n');
+ gdc.writeStringToBuffer(">");
};
// Close heading if necessary. (Blank line after to keep Markdown parser happy.)
-html.closeHeading = function() {
-
+html.closeHeading = function () {
// We're doing a little dance here for heading demotion.
var htitle = 0;
if (gdc.demoteHeadings) {
htitle = 1;
}
- if (html.h1) { html.h1 = false; gdc.writeStringToBuffer('\n\n'); }
- else if (html.h2) { html.h2 = false; gdc.writeStringToBuffer('\n\n'); }
- else if (html.h3) { html.h3 = false; gdc.writeStringToBuffer('\n\n'); }
- else if (html.h4) { html.h4 = false; gdc.writeStringToBuffer('\n\n'); }
- else if (html.h5) { html.h5 = false; gdc.writeStringToBuffer('\n\n'); }
- else if (html.h6) { html.h6 = false; gdc.writeStringToBuffer('\n\n'); }
+ if (html.h1) {
+ html.h1 = false;
+ gdc.writeStringToBuffer("\n\n");
+ } else if (html.h2) {
+ html.h2 = false;
+ gdc.writeStringToBuffer("\n\n");
+ } else if (html.h3) {
+ html.h3 = false;
+ gdc.writeStringToBuffer("\n\n");
+ } else if (html.h4) {
+ html.h4 = false;
+ gdc.writeStringToBuffer("\n\n");
+ } else if (html.h5) {
+ html.h5 = false;
+ gdc.writeStringToBuffer("\n\n");
+ } else if (html.h6) {
+ html.h6 = false;
+ gdc.writeStringToBuffer("\n\n");
+ }
html.isHeading = false;
};
// Formats footnotes for HTML. For HTML, we'll print out the actual
// footnotes at the end.
-html.handleFootnote = function(footnote) {
-
+html.handleFootnote = function (footnote) {
gdc.hasFootnotes = true;
-
+
gdc.footnoteNumber++;
var fSection = footnote.getFootnoteContents();
if (!fSection) {
@@ -471,26 +516,39 @@ html.handleFootnote = function(footnote) {
var findex = gdc.footnoteNumber - 1;
fSection = gdc.footnotes[findex].getFootnoteContents();
}
-
+
// Write the footnote ref link in the text.
- gdc.writeStringToBuffer('');
+ gdc.writeStringToBuffer(
+ '"
+ );
// Now, write the footnotes themselves.
gdc.isFootnote = true;
// Open list for first footnote.
if (gdc.footnoteNumber === 1) {
- gdc.writeStringToBuffer('\n\n'
- + '\n\nNotes
'
- + '\n
${comment.author} (${new Date( + comment.created + ).toLocaleString()}): ${comment.content}
\n`; + + if (comment.replies && comment.replies.length > 0) { + comment.replies.forEach((reply) => { + output += ` \n`; + }); + } + + output += `