import path from 'path';
// import { globSync } from 'glob';
import fs from 'fs';
import { config } from '../config.mjs';
import markdownIt from 'markdown-it';
import markdownItAttrs from 'markdown-it-attrs';
import momentJs from 'moment-timezone';
import { inspect } from 'util';
import matter from 'gray-matter';
const moment = momentJs.tz.setDefault("UTC");
const md = markdownIt({
html: true,
linkify: true,
typographer: true,
}).use(
markdownItAttrs, {
// optional, these are default options
leftDelimiter: '{',
rightDelimiter: '}',
allowedAttributes: [] // empty array = all attributes are allowed
}
);
const getSiteName = () => config.siteName;
const trimSlashes = (dirPath: string) => {
return dirPath.replace(/^[\/\\]|[\/\\]$/g, '');
};
const getLeftMostDirectory = (directory: string) => {
if (directory.indexOf(path.sep)) {
return directory.substring(0, directory.indexOf(path.sep));
}
return directory;
}
const leftTrimFirstDirectory = (directory: string) => {
if (directory.indexOf(path.sep)) {
return directory.substring(directory.indexOf(path.sep));
}
return directory;
}
const getDirectoryName = (directory: string) => {
directory = trimSlashes(directory);
const leftMostDirectory = getLeftMostDirectory(directory);
let title = trimSlashes(leftTrimFirstDirectory(directory)).replaceAll(path.sep, path.posix.sep);
return (trimSlashes(directory)==leftMostDirectory) ? getSiteName() : title;
};
const getDirectoryTitle = (directory: string) => {
const leftMostDirectory = getLeftMostDirectory(directory);
let title = trimSlashes(leftTrimFirstDirectory(directory))
.replaceAll(path.sep, path.posix.sep)
.replaceAll('_', ' ')
.split('/')
.reverse()
.join(' - ');
return (trimSlashes(directory)==leftMostDirectory) ? getSiteName() : `${title} - ${getSiteName()}`;
};
const getSiteWelcomeMessage = () => config.siteWelcomeMessage;
const shouldShowDirectorySeparator = (index: number) => (index > 0);
const shouldShowSiteWelcomeMessage = (paths: string[]) => (paths.length == 1);
const shouldOmitLinkOnLastBreadcrumb = (paths: string[], index: number) => (index == paths.length-1);
const resolveReadmeFile: (directory: string) => string|undefined = (directory) => {
const resolveFile = (file: string) => {
const pathToFile = path.join(config.publicPath, trimSlashes(leftTrimFirstDirectory(directory)), file);
return fs.existsSync(pathToFile) ? pathToFile : "";
};
return (
resolveFile("README.md") ||
resolveFile("README.txt") ||
resolveFile("README") ||
resolveFile("README.html") ||
undefined
);
};
const directoryContainsReadme = (directory: string) => resolveReadmeFile(directory);
// const printMarkdownFile = (file) => {
// };
const readmeFm = (directory: string) => {
const readmeFile = resolveReadmeFile(directory);
if (readmeFile) {
return matter.read(readmeFile).data;
}
};
const printReadme = (directory: string) => {
const readmeFile = resolveReadmeFile(directory);
if (readmeFile) {
const fm = matter.read(readmeFile);
const fmData = { fm: fm.data, excerpt: fm.excerpt };
const content = md.render(fm.content, fmData );
return content;
}
};
const stripWebVTT = (webvttText: string) => {
const searchHeader = "WEBVTT\nKind: captions\nLanguage: en\n\n";
if (webvttText.startsWith(searchHeader)) {
webvttText = webvttText.substring(searchHeader.length-1); // remove WEBVTT header
webvttText = webvttText.replaceAll(' align:start position:0%', ''); // remove this align and position junk
webvttText = webvttText
.split('\n')
.map((line) => { return line.replaceAll(/.*<\d{2}:\d{2}:\d{2}.\d{3}>.*/g, '').trim() }) // remove all the animated subtitles and trim the whitespace on each line
.join('\n');
while (webvttText.indexOf('\n\n\n') > -1) {
webvttText = webvttText.replace('\n\n\n', '\n\n'); // remove every instance of triple vertical white space, while allowing double vertical white space
}
webvttText = webvttText.replaceAll(/(\d{2}:\d{2}:\d{2}.\d{3}) --> (\d{2}:\d{2}:\d{2}.\d{3})\n(.*)\n\n(\2) --> (\d{2}:\d{2}:\d{2}.\d{3})\n\3\n/g, '$1 --> $5\n$3\n'); // remove every duplicate entry detected
webvttText = webvttText.replaceAll('\n', '
'); // convert \n to
}
return webvttText;
};
const renderArchive = (html: string, paths: string[]) => {
// Header and Footer content
const headHeaderContent = ``;
const headFooterContent = `
`;
const bodyHeaderContent = `
This is an archived version of the original website. Online features will not be functional. Do not submit any personal information to this archive.
This is an archived version of the original website. Online features will not be functional. Do not submit any personal information to this archive.