1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Desktop: Significantly reduces size of exported HTML files in most cases

This commit is contained in:
Laurent Cozic 2024-06-03 23:49:09 +01:00
parent 32e16f6e51
commit 32710e44c3
5 changed files with 55 additions and 10 deletions

View File

@ -207,7 +207,7 @@
for (const [assetId, asset] of Object.entries(pluginAssetsAdded_)) {
if (!processedAssetIds.includes(assetId)) {
try {
asset.element.remove();
if (asset?.element) asset.element.remove();
} catch (error) {
// We don't throw an exception but we log it since
// it shouldn't happen

View File

@ -16,7 +16,7 @@ interface RendererRule {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
install(context: any, ruleOptions: any): any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
assets?(theme: any): any;
assets?(theme: any): PluginAsset[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
plugin?: any;
assetPath?: string;
@ -103,6 +103,7 @@ export interface Options {
}
interface PluginAsset {
source?: string;
mime?: string;
inline?: boolean;
name?: string;
@ -134,6 +135,15 @@ interface PluginContext {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
userData: any;
currentLinks: Link[];
// This must be set by the plugin to indicate whether the document contains markup that was
// processed by the plugin or not. Currently this information is then used to remove unnecessary
// plugin assets from the rendered document. This is particularly useful when exporting as HTML
// since it can reduce the size from several MB to a few KB.
pluginWasUsed: {
mermaid: boolean;
katex: boolean;
};
}
export interface RuleOptions {
@ -330,10 +340,14 @@ export default class MdToHtml implements MarkupRenderer {
const name = `${pluginName}/${asset.name}`;
const assetPath = rule?.assetPath ? `${rule.assetPath}/${asset.name}` : `pluginAssets/${name}`;
files.push({ ...asset, name: name,
files.push({
...asset,
source: asset.source,
name: name,
path: assetPath,
pathIsAbsolute: !!rule && !!rule.assetPathIsAbsolute,
mime: mime });
mime: mime,
});
}
}
}
@ -354,7 +368,7 @@ export default class MdToHtml implements MarkupRenderer {
if (this.allProcessedAssets_[cacheKey]) return this.allProcessedAssets_[cacheKey];
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const assets: any = {};
const assets: PluginAssets = {};
for (const key in rules) {
if (!this.pluginEnabled(key)) continue;
const rule = rules[key];
@ -494,6 +508,10 @@ export default class MdToHtml implements MarkupRenderer {
cache: this.contextCache_,
userData: {},
currentLinks: [],
pluginWasUsed: {
mermaid: false,
katex: false,
},
};
const markdownIt: MarkdownIt = new MarkdownIt({
@ -622,7 +640,14 @@ export default class MdToHtml implements MarkupRenderer {
contentMaxWidth: options.contentMaxWidth,
});
let output = { ...this.allProcessedAssets(allRules, options.theme, options.codeTheme) };
let output: RenderResult = { ...this.allProcessedAssets(allRules, options.theme, options.codeTheme) };
output.pluginAssets = output.pluginAssets.filter(pa => {
if (!context.pluginWasUsed.mermaid && pa.source === 'mermaid') return false;
if (!context.pluginWasUsed.katex && pa.source === 'katex') return false;
return true;
});
cssStrings = cssStrings.concat(output.cssStrings);
if (this.customCss_) cssStrings.push(this.customCss_);

View File

@ -98,7 +98,12 @@ function katexStyle() {
{ name: 'fonts/KaTeX_Size3-Regular.woff2' },
{ name: 'fonts/KaTeX_Size4-Regular.woff2' },
{ name: 'fonts/KaTeX_Typewriter-Regular.woff2' },
];
].map(e => {
return {
source: 'katex',
...e,
};
});
}
// Test if potential opening or closing delimiter
@ -338,6 +343,7 @@ export default {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const inlineRenderer = function(tokens: any[], idx: number) {
options.context.pluginWasUsed.katex = true;
return katexInline(tokens[idx].content);
};
@ -355,6 +361,7 @@ export default {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const blockRenderer = function(tokens: any[], idx: number) {
options.context.pluginWasUsed.katex = true;
return `${katexBlock(tokens[idx].content)}\n`;
};

View File

@ -5,8 +5,12 @@ export default {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
assets: function(theme: any) {
return [
{ name: 'mermaid.min.js' },
{ name: 'mermaid_render.js' },
{
name: 'mermaid.min.js',
},
{
name: 'mermaid_render.js',
},
{
inline: true,
// Note: Mermaid is buggy when rendering below a certain width (500px?)
@ -43,7 +47,12 @@ export default {
`.trim(),
mime: 'text/css',
},
];
].map(e => {
return {
source: 'mermaid',
...e,
};
});
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
@ -59,6 +68,9 @@ export default {
markdownIt.renderer.rules.fence = function(tokens: any[], idx: number, options: any, env: any, self: any) {
const token = tokens[idx];
if (token.info !== 'mermaid') return defaultRender(tokens, idx, options, env, self);
ruleOptions.context.pluginWasUsed.mermaid = true;
const contentHtml = markdownIt.utils.escapeHtml(token.content);
const cssClasses = ['mermaid'];

View File

@ -56,6 +56,7 @@ export interface RenderOptions {
}
export interface RenderResultPluginAsset {
source: string;
name: string;
mime: string;
path: string;