XeNote/lib/transformer.js
Triston Armstrong f56e07b94e convert transformer to a class
NOTE - all of these methods can be static i believe. no need to use this and instantiate new instances every time.. i dont think atm anyway
2023-12-25 20:48:51 -06:00

202 lines
6.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import matter from 'gray-matter'
import { unified } from "unified";
import markdown from "remark-parse";
import { wikiLinkPlugin } from "remark-wiki-link";
import html from "remark-html";
//import frontmatter from "remark-frontmatter";
import externalLinks from "remark-external-links";
import highlight from "remark-highlight.js";
import { Node } from "./node";
import rehypePrism from 'rehype-prism-plus'
import remarkRehype from 'remark-rehype'
import rehypeStringify from 'rehype-stringify'
import obsidianImage from './obsidian-image.js'
import { getAllMarkdownFiles, toFilePath, toSlug } from "./utils";
export class Transformer {
constructor() { }
haveFrontMatter = (content) => {
//console.log("\t Front matter data content", content)
if (!content) return false
const indexOfFirst = content.indexOf("---");
//console.log("\t Front matter data firstIndex ", indexOfFirst)
//console.log("index first", indexOfFirst)
if (indexOfFirst === -1) {
return false
}
let indexOfSecond = content.indexOf("---", (indexOfFirst + 1));
return indexOfSecond !== -1;
}
getFrontMatterData = (filecontent) => {
if (this.haveFrontMatter(filecontent)) {
return matter(filecontent).data
}
return {}
}
pageResolver = (pageName) => {
const allFileNames = getAllMarkdownFiles()
const result = allFileNames.find(aFile => {
let parseFileNameFromPath = this.parseFileNameFromPath(aFile);
return this.normalizeFileName(parseFileNameFromPath) === this.normalizeFileName(pageName)
}
)
// permalink = permalink.replace("ç", "c").replace("ı", "i").replace("ş", "s")
// console.log(`/note/${toSlug(result)}`)
if (result === undefined || result.length === 0) {
// console.log("Cannot resolve file path " + pageName)
}
// console.log("Internal Link resolved: [" + pageName + "] ==> [" + temp[0] +"]")
return (result !== undefined && result.length > 0) ? [toSlug(result)] : ["/"]
}
hrefTemplate = (permalink) => {
// permalink = this.normalizeFileName(permalink)
permalink = permalink.replace("ç", "c").replace("ı", "i").replace("ş", "s")
return `/note/${permalink}`
}
getHtmlContent = (content) => {
let htmlContent = []
const sanitizedContent = this.preprocessThreeDashes(content)
unified()
.use(markdown, { gfm: true })
.use(obsidianImage)
.use(highlight)
.use(externalLinks, { target: "_blank", rel: ['noopener'] })
// .use(frontmatter, ['yaml', 'toml'])
.use(wikiLinkPlugin, {
permalinks: null,
pageResolver: (pageName) => {
return this.pageResolver(pageName)
},
hrefTemplate: (permalink) => {
return this.hrefTemplate(permalink);
},
aliasDivider: "|"
})
.use(remarkRehype)
.use(rehypePrism)
.use(rehypeStringify)
.process(sanitizedContent,
function(err, file) {
htmlContent.push(String(file).replace("\n", ""))
if (err) {
console.log("ERRROR:" + err)
}
}
)
htmlContent = htmlContent.join("")
htmlContent = htmlContent.split("---")
return [htmlContent]
}
/* SANITIZE MARKDOWN FOR --- */
preprocessThreeDashes = (content) => {
const indexOfFirst = content.indexOf("---");
if (indexOfFirst === -1) {
return content
}
const indexOfSecond = content.indexOf("---", (indexOfFirst + 1));
content.slice(0, indexOfSecond);
const contentPart = content.slice(indexOfSecond);
return contentPart.split("---").join("")
}
/* Normalize File Names */
normalizeFileName = (filename) => {
let processedFileName = filename.replace(".md", "");
processedFileName = processedFileName.replace('(', '').replace(')', '')
processedFileName = processedFileName.split(" ").join("-")
processedFileName = processedFileName.toLowerCase()
const conversionLetters = [
["ç", "c"], ["ş", "s"], ["ı", "i"], ["ü", "u"], ["ö", "o"], ["ğ", "g"],
["Ç", "C"], ["Ş", "S"], ["İ", "I"], ["Ü", "U"], ["Ö", "O"], ["Ğ", "G"]
];
conversionLetters.forEach(letterPair => {
processedFileName = processedFileName.split(letterPair[0]).join(letterPair[1])
//processedFileName = processedFileName.replace(letterPair[0], letterPair[1])
}
)
//console.log("filename", processedFileName)
return processedFileName
}
/* Parse file name from path then sanitize it */
parseFileNameFromPath = (filepath) => {
if (typeof filepath === 'string' && filepath.includes("/")) {
const parsedFileFromPath = filepath.split("/")[filepath.split("/").length - 1]
return parsedFileFromPath.replace(".md", "")
} else {
console.log("Failed: CANNOT Parse" + filepath)
return null
}
}
/* Pair provided and existing Filenames*/
getInternalLinks = (aFilePath) => {
const fileContent = Node.readFileSync(aFilePath);
const internalLinks = []
const sanitizedContent = this.preprocessThreeDashes(fileContent)
const outer_this = this
unified()
.use(markdown, { gfm: true })
.use(wikiLinkPlugin, {
pageResolver: function(pageName) {
// let name = [this.parseFileNameFromPath(pageName)];
let canonicalSlug;
if (pageName.includes('#')) {
// console.log(pageName)
const tempSlug = pageName.split('#')[0]
if (tempSlug.length === 0) {
// Meaning it in form of #Heading1 --> slug will be this file slug
canonicalSlug = toSlug(aFilePath)
} else {
canonicalSlug = outer_this.pageResolver(tempSlug)[0].split('#')[0]
}
} else {
canonicalSlug = outer_this.pageResolver(pageName)[0].split('#')[0]
}
const backLink = {
title: outer_this.parseFileNameFromPath(toFilePath(canonicalSlug)),
slug: canonicalSlug,
shortSummary: canonicalSlug
}
if (canonicalSlug != null && internalLinks.indexOf(canonicalSlug) < 0) {
internalLinks.push(backLink);
}
return [canonicalSlug]
}
,
hrefTemplate: (permalink) => {
return this.hrefTemplate(permalink)
},
aliasDivider: "|"
})
.use(html)
.processSync(sanitizedContent)
// console.log("Internal Links of: " + aFilePath)
// internalLinks.forEach(aLink => {
// console.log(aLink.title + " --> " + aLink.slug)
// })
// console.log("===============Internal Links")
return internalLinks;
}
}