Issue with Formatting Markdown Data in create document from a template Google Docs Module

@Yonatan_Tesfaye I resolved this issue by creating an apps script in the template. This is what I used:

function processNewDocs() {
  var folder = DriveApp.getFolderById("YOUR_FOLDER_ID_HERE"); // Replace with your actual folder ID
  var files = folder.getFiles();
  
  while (files.hasNext()) {
    var file = files.next();
    if (file.getMimeType() === MimeType.GOOGLE_DOCS) {
      var doc = DocumentApp.openById(file.getId());
      processMarkdownInDoc(doc);
    }
  }
}

function processMarkdownInDoc(doc) {
  var body = doc.getBody();
  var textElement = body.editAsText();

  // Process Headers (using regex that allows an optional space and enforces the correct number of '#' characters)
  // H1: Exactly one '#' (not followed by another '#')
  applyHeaderFormatting(textElement, /^#(?!#)\s?(.*)$/gm, 24, true);
  // H2: Exactly two '#' (not followed by a third)
  applyHeaderFormatting(textElement, /^##(?!#)\s?(.*)$/gm, 20, true);
  // H3: Exactly three '#' (not followed by a fourth)
  applyHeaderFormatting(textElement, /^###(?!#)\s?(.*)$/gm, 18, true);
  // H4: Exactly four '#' (not followed by a fifth)
  applyHeaderFormatting(textElement, /^####(?!#)\s?(.*)$/gm, 16, true);
  // H5: Exactly five '#' (not followed by a sixth)
  applyHeaderFormatting(textElement, /^#####(?!#)\s?(.*)$/gm, 14, true);

  // Process bold (**text**)
  applyTextFormatting(textElement, /\*\*(.*?)\*\*/g, "bold");

  // Process italics (*text* and _text_)
  applyTextFormatting(textElement, /(?:\*|_)(.*?)(?:\*|_)/g, "italic");

  // Save the document
  doc.saveAndClose();
}

function applyHeaderFormatting(textElement, regex, fontSize, bold) {
  var text = textElement.getText();
  // Get all matches using the provided regex
  var matches = [...text.matchAll(regex)];

  // Process matches in reverse order to avoid index shifting issues after modifying the text
  for (let i = matches.length - 1; i >= 0; i--) {
    let match = matches[i];
    let start = match.index;
    let headerContent = match[1];
    let contentLength = headerContent.length;

    // Delete the entire matched header (including the '#' symbols and any extra whitespace)
    textElement.deleteText(start, start + match[0].length - 1);
    // Insert the header text without markdown symbols
    textElement.insertText(start, headerContent);
    // Apply the header formatting (font size and bold if requested)
    textElement.setFontSize(start, start + contentLength - 1, fontSize);
    if (bold) {
      textElement.setBold(start, start + contentLength - 1, true);
    }
  }
}

function applyTextFormatting(textElement, regex, formatType) {
  var text = textElement.getText();
  // Get all matches for the markdown (e.g. **text** or *text*/*_text_)
  var matches = [...text.matchAll(regex)];

  // Process matches in reverse order so that modifications don’t affect the positions of earlier matches
  for (let i = matches.length - 1; i >= 0; i--) {
    let match = matches[i];
    let start = match.index;
    let content = match[1];
    let contentLength = content.length;

    // Remove the markdown symbols by deleting the whole matched string
    textElement.deleteText(start, start + match[0].length - 1);
    // Reinsert just the content (without markdown symbols)
    textElement.insertText(start, content);

    // Apply the desired formatting (bold or italic)
    if (formatType === "bold") {
      textElement.setBold(start, start + contentLength - 1, true);
    } else if (formatType === "italic") {
      textElement.setItalic(start, start + contentLength - 1, true);
    }
  }
}
4 Likes