From ec6a3cee5818d8f6d9f11dbb1702a37df4c6d5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20NICOLAS=20=28ccjmne=29?= Date: Tue, 15 Oct 2024 00:59:46 +0200 Subject: [PATCH] --- src/utils/easy-htmlelement.ts | 12 ++++++++++-- webpack.config.ts | 8 +++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/utils/easy-htmlelement.ts b/src/utils/easy-htmlelement.ts index 10344f8a..fd0d3d13 100644 --- a/src/utils/easy-htmlelement.ts +++ b/src/utils/easy-htmlelement.ts @@ -4,6 +4,7 @@ import externalLink from 'src/assets/external-link.svg?template' import { type RegExpGroups } from 'src/types' const SVGNS = 'http://www.w3.org/2000/svg' +const HYPHENATE = /^y/i.test(process.env.HYPHENATE ?? 'no') export default class EasyHTMLElement { @@ -49,20 +50,27 @@ export default class EasyHTMLElement { /** * Parses contents and: * - discard empty strings - * - automatically mark for hyphenation (for `en-gb`) with `\u00AD` (soft hyphen), * - replace linefeeds (literal `\n`) with `
` elements * - replace markdown-style hyperlinks with `...` elements * - replace ` ` with `\u00A0` (non-breaking space) + * - replace `­` with `\u00AD` (soft hyphen) + * + * Additionally, while in `development` mode, automatically mark for + * hyphenation (for `en-gb`) with `\u00AD` (soft hyphen). + * + * This isn't done in `production` builds so as to avoid needlessly confusing + * crawlers and possible ATSs (Applicant Tracking System). */ private static prepare(elements: ReadonlyArray): ReadonlyArray { return elements .filter(content => content !== '') .flatMap(content => (typeof content !== 'string' ? content.elem : content .replace(/ /g, '\u00A0') + .replace(/­/g, '\u00AD') .split(/(?<=\[[^\]]+\]\([^)]+\))|(?=\[[^\]]+\]\([^)]+\))/) // split around markdown-style hyperlinks .map(fragment => fragment.match(/^\[(?[^\]]+)\]\((?[^)]+)\)$/)?.groups as RegExpGroups<'text' | 'href'> | undefined ?? fragment) .flatMap(fragment => (typeof fragment === 'string' - ? fragment.split(/\n/g).flatMap(t => [new EasyHTMLElement('br').elem, hyphenate(t)]).slice(1) + ? fragment.split(/\n/g).flatMap(t => [new EasyHTMLElement('br').elem, HYPHENATE ? hyphenate(t) : t]).slice(1) : EasyHTMLElement.anchor(fragment).elem)) )) } diff --git a/webpack.config.ts b/webpack.config.ts index 93de9eff..c1c1056a 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -10,6 +10,7 @@ import { Compiler } from 'webpack' import 'webpack-dev-server' // Augment "Configuration" type import { author, description, homepage, keywords, name, repository, title } from './package.json' import { PDFPrinter } from './tooling/pdf-printer-plugin' +import { DefinePlugin } from 'webpack' const src = resolve(__dirname, 'src') const dist = resolve(__dirname, 'dist') @@ -32,7 +33,7 @@ const pages = readdirSync(src, { withFileTypes: true }) .reduce((acc, { name, path }) => ({ ...acc, [name]: path }), {}) export default ( - _env: string, + env: NodeJS.ProcessEnv, { mode = 'production', port = '8042' }: { mode?: 'production' | 'development', port?: string } = {}, ): Configuration => ({ entry: pages, @@ -89,9 +90,10 @@ export default ( path: dist, }, plugins: [ + new DefinePlugin({ 'process.env': JSON.stringify(env) }), ...mode === 'production' ? [new CleanWebpackPlugin()] : [], new TypedScssModulesPlugin({ watch: mode === 'development' }), - ...Object.entries(pages).map(([name, path]) => new HtmlWebpackPlugin({ + ...Object.keys(pages).map(name => new HtmlWebpackPlugin({ title: `Page ${name}`, meta: { author, description, repository, keywords: keywords.join(', ') }, chunks: [name], @@ -102,7 +104,7 @@ export default ( ...mode === 'production' ? { scheme: 'file', paths: Object.keys(pages).map(name => resolve(dist, `${name}.html`)) } : { port, paths: Object.keys(pages).map(name => `${name}.html`) }, - output: resolve(dist, `${out}.pdf`), + output: resolve(dist, env.OUTPUT ?? `${out}.pdf`), properties: { title, author, subject: description, keywords: keywords.join(', '), creator: `${name} (${homepage})` }, blocking: mode === 'production', }),