@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);
}
}
}