feat: init

This commit is contained in:
Morten Olsen
2022-12-06 09:12:53 +01:00
commit 3f5e941446
115 changed files with 13148 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
/node_modules/
/*.logs
/.yarn/
/dist/

View File

@@ -0,0 +1,20 @@
{
"name": "@morten-olsen/goodwrites-webpack-loader",
"main": "./dist/index.js",
"devDependencies": {
"@types/fs-extra": "^9.0.13",
"@types/marked": "^4.0.7",
"@types/webpack": "^5.28.0",
"loader-utils": "^3.2.1",
"yaml": "^2.1.3"
},
"dependencies": {
"@morten-olsen/goodwrites": "workspace:^",
"@morten-olsen/goodwrites-latex": "workspace:^",
"fs-extra": "^11.1.0",
"marked": "^4.0.12",
"node-latex": "^3.1.0",
"slugify": "^1.6.5",
"stream": "^0.0.2"
}
}

View File

@@ -0,0 +1,3 @@
import { webpackLoader } from './loader';
export default webpackLoader;

View File

@@ -0,0 +1,88 @@
import * as webpack from 'webpack';
import * as loaderUtils from 'loader-utils';
import {
replaceImages,
Document,
parseDocument,
} from '@morten-olsen/goodwrites';
import { join, dirname, basename } from 'path';
import yaml from 'yaml';
import { readFileSync } from 'fs-extra';
import { toPdf } from '@morten-olsen/goodwrites-latex';
import slugify from 'slugify';
type LoaderOptions = {
publicPath?: string;
outputPath?: string;
};
function webpackLoader(
this: webpack.LoaderContext<LoaderOptions>,
contents: string = ''
) {
const options: LoaderOptions = this.getOptions();
const publicPath =
options.publicPath ?? '';
const outputPath =
options.outputPath ?? this._compilation?.outputOptions.path ?? '';
const callback = this.async();
const source = this.resourcePath;
const run = async () => {
const document: Document = yaml.parse(contents);
const slug = slugify(document.title, { lower: true });
const addFile = (fileLocation: string) => {
const content = readFileSync(fileLocation);
const filename = basename(fileLocation);
const targetName = loaderUtils.interpolateName(
this as any,
`/goodwrite/${slug}/[hash]-${filename}`,
{
content,
}
);
const targetLocation = targetName;
this.emitFile(join(outputPath, targetLocation), content);
this.addDependency(fileLocation);
return join(publicPath, targetName);
};
const location = dirname(source);
const parsed = await parseDocument({
document,
location,
});
const markdown = await replaceImages(parsed, {
replaceImage: (image) => {
return addFile(image);
}
});
if (markdown.cover) {
markdown.cover = await addFile(join(location, markdown.cover));
}
const pdf = await toPdf(parsed);
const pdfName = loaderUtils.interpolateName(
this as any,
`/goodwrite/[hash]/${slug}.pdf`,
{
content: pdf,
}
);
this.emitFile(join(outputPath, pdfName), pdf);
return {
...markdown,
pdf: join(publicPath, pdfName),
};
};
run()
.then((content) => {
content.files.forEach((file) => (file ? this.addDependency(file) : null));
callback(null, `module.exports=${JSON.stringify(content)}`);
})
.catch((error) => {
callback(error);
});
}
export { webpackLoader };

View File

@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist"
},
"include": [
"./src"
]
}