@heroiclands/package-build 23.13.0 → 24.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/README.md +2 -1
- package/assets/preview/gitea.ini +12 -7
- package/assets/styles/content-base.css +150 -1
- package/bin/content-commands.mjs +356 -210
- package/bin/package-build.mjs +3 -2
- package/ci/check-banners.mjs +7 -7
- package/config.mjs +21 -6
- package/content-config.mjs +199 -80
- package/docs/api.md +93 -72
- package/docs/authoring/links-and-markup.md +316 -78
- package/docs/commands.md +248 -80
- package/docs/configuration.md +210 -102
- package/docs/content-format.md +2 -2
- package/docs/diagnostics.md +2 -2
- package/docs/getting-started.md +1 -1
- package/docs/guides/icons.md +1 -1
- package/docs/guides/module-project.md +5 -8
- package/docs/guides/release-and-deploy.md +2 -2
- package/docs/guides/site.md +155 -23
- package/docs/guides/system-project.md +1 -1
- package/docs/guides/writing-in-invented-scripts.md +1247 -0
- package/docs/index.md +1 -0
- package/docs/project-setup.md +28 -30
- package/docs/reference/format-details.md +589 -308
- package/docs/reference/note-types.md +40 -10
- package/docs/reference/theme-pages.md +127 -108
- package/docs/source-preview.md +15 -1
- package/engine/asset-shipping.mjs +22 -10
- package/engine/base-compiler.mjs +62 -104
- package/engine/changelog-lint.mjs +1 -1
- package/engine/content-address.mjs +1 -1
- package/engine/content-alerts.mjs +8 -4
- package/engine/content-blocks.mjs +26 -11
- package/engine/content-embeds.mjs +1 -1
- package/engine/content-expand.mjs +376 -0
- package/engine/content-figures.mjs +13 -6
- package/engine/content-format.yaml +8 -0
- package/engine/content-glyphs.mjs +213 -0
- package/engine/content-images.mjs +6 -7
- package/engine/content-links.mjs +3 -3
- package/engine/content-lint.mjs +1 -1
- package/engine/content-render.mjs +453 -0
- package/engine/content-scripts.mjs +326 -27
- package/engine/content-spans.mjs +4 -1
- package/engine/content-styles.mjs +91 -0
- package/engine/content-symbols.mjs +186 -0
- package/engine/content-verse.mjs +6 -18
- package/engine/core-report.mjs +169 -0
- package/engine/core-vocabulary.mjs +208 -0
- package/engine/dictionary-html.mjs +119 -0
- package/engine/field-reference.mjs +1 -1
- package/engine/frontmatter-lint.mjs +1 -1
- package/engine/heading-attributes.mjs +89 -0
- package/engine/helpers.mjs +61 -101
- package/engine/homepage.mjs +17 -29
- package/engine/html-minify.mjs +70 -0
- package/engine/index.mjs +8 -5
- package/engine/language-rows.mjs +8 -2
- package/engine/language-terms.mjs +115 -14
- package/engine/language-words.mjs +12 -0
- package/engine/logographic.mjs +255 -0
- package/engine/map-lexicon.mjs +221 -25
- package/engine/map-places.mjs +5 -4
- package/engine/markdown-expressions.mjs +0 -2
- package/engine/markdownlint-run.mjs +9 -3
- package/engine/markup-validation.mjs +21 -0
- package/engine/metre-declaration.mjs +134 -0
- package/engine/note-matter.mjs +2 -2
- package/engine/note-vocabulary.mjs +187 -3
- package/engine/pdf-build.mjs +68 -133
- package/engine/pdf-render.mjs +102 -44
- package/engine/post-fields.mjs +157 -0
- package/engine/preview-index.mjs +130 -0
- package/engine/preview-source.mjs +450 -0
- package/engine/project-init.mjs +5 -12
- package/engine/prose-config.mjs +3 -3
- package/engine/run-words.mjs +3 -2
- package/engine/script-emphasis-terms.mjs +38 -0
- package/engine/script-emphasis.mjs +295 -0
- package/engine/script-font-delivery.mjs +4 -4
- package/engine/site-build.mjs +265 -313
- package/engine/site-config.mjs +26 -238
- package/engine/site-files.mjs +175 -0
- package/engine/site-index.mjs +9 -4
- package/engine/site-preview.mjs +50 -523
- package/engine/site-reach.mjs +213 -0
- package/engine/site-render.mjs +668 -0
- package/engine/site-root.mjs +90 -39
- package/engine/site-search.mjs +161 -0
- package/engine/site-serve.mjs +274 -0
- package/engine/site-theme-banner.mjs +154 -0
- package/engine/site-theme-urls.mjs +125 -0
- package/engine/site-theme.mjs +939 -0
- package/engine/sql-tables.mjs +9 -6
- package/engine/text-maps.mjs +57 -10
- package/engine/typographer.mjs +248 -0
- package/engine/verse-metre.mjs +357 -0
- package/engine/wikilink-syntax.mjs +29 -47
- package/engine/wikilinks.mjs +758 -279
- package/engine/word-forms.mjs +39 -24
- package/engine/word-rows.mjs +12 -2
- package/engine/word-terms.mjs +29 -4
- package/manifest.mjs +3 -4
- package/package.json +10 -7
- package/{hugo-theme → site-theme}/data/banners.yaml +6 -10
- package/site-theme/layouts/base.hbs +31 -0
- package/site-theme/layouts/blog-list.hbs +30 -0
- package/site-theme/layouts/blog-post.hbs +40 -0
- package/site-theme/layouts/home.hbs +35 -0
- package/site-theme/layouts/list.hbs +20 -0
- package/site-theme/layouts/not-found.hbs +31 -0
- package/site-theme/layouts/page.hbs +7 -0
- package/site-theme/partials/copy-buttons.hbs +37 -0
- package/site-theme/partials/draft-notice.hbs +5 -0
- package/site-theme/partials/exturl.hbs +2 -0
- package/{hugo-theme/layouts/partials/footer.html → site-theme/partials/footer.hbs} +10 -7
- package/site-theme/partials/header.hbs +44 -0
- package/site-theme/partials/hero-banner.hbs +11 -0
- package/site-theme/partials/infobox-entry.hbs +2 -0
- package/site-theme/partials/infobox-section.hbs +31 -0
- package/site-theme/partials/infobox-value.hbs +2 -0
- package/site-theme/partials/infobox.hbs +18 -0
- package/site-theme/partials/list-members.hbs +9 -0
- package/site-theme/partials/nav-links.hbs +5 -0
- package/site-theme/partials/page-body.hbs +48 -0
- package/site-theme/partials/page-list.hbs +14 -0
- package/site-theme/partials/related.hbs +24 -0
- package/site-theme/partials/search-meta.hbs +6 -0
- package/site-theme/partials/search-names.hbs +2 -0
- package/site-theme/partials/search.hbs +52 -0
- package/site-theme/partials/tags.hbs +4 -0
- package/site-theme/partials/toc.hbs +7 -0
- package/{hugo-theme → site-theme}/static/css/style.css +14 -0
- package/stage.mjs +1 -2
- package/types/config.d.mts +8 -4
- package/types/content-config.d.mts +15 -15
- package/types/engine/asset-shipping.d.mts +5 -2
- package/types/engine/base-compiler.d.mts +20 -2
- package/types/engine/content-address.d.mts +1 -1
- package/types/engine/content-alerts.d.mts +8 -2
- package/types/engine/content-blocks.d.mts +11 -4
- package/types/engine/content-expand.d.mts +288 -0
- package/types/engine/content-figures.d.mts +11 -3
- package/types/engine/content-glyphs.d.mts +85 -0
- package/types/engine/content-images.d.mts +6 -7
- package/types/engine/content-links.d.mts +1 -1
- package/types/engine/content-render.d.mts +199 -0
- package/types/engine/content-scripts.d.mts +62 -0
- package/types/engine/content-spans.d.mts +1 -1
- package/types/engine/content-styles.d.mts +33 -0
- package/types/engine/content-symbols.d.mts +35 -0
- package/types/engine/core-report.d.mts +45 -0
- package/types/engine/core-vocabulary.d.mts +53 -0
- package/types/engine/dictionary-html.d.mts +8 -0
- package/types/engine/field-reference.d.mts +1 -1
- package/types/engine/heading-attributes.d.mts +20 -0
- package/types/engine/helpers.d.mts +3 -10
- package/types/engine/homepage.d.mts +11 -24
- package/types/engine/html-minify.d.mts +9 -0
- package/types/engine/index.d.mts +2 -1
- package/types/engine/language-terms.d.mts +24 -2
- package/types/engine/logographic.d.mts +45 -0
- package/types/engine/map-lexicon.d.mts +48 -8
- package/types/engine/map-places.d.mts +8 -0
- package/types/engine/markdown-expressions.d.mts +0 -2
- package/types/engine/metre-declaration.d.mts +39 -0
- package/types/engine/pdf-render.d.mts +6 -2
- package/types/engine/post-fields.d.mts +44 -0
- package/types/engine/preview-index.d.mts +72 -0
- package/types/engine/preview-source.d.mts +51 -0
- package/types/engine/script-emphasis-terms.d.mts +21 -0
- package/types/engine/script-emphasis.d.mts +84 -0
- package/types/engine/script-font-delivery.d.mts +4 -4
- package/types/engine/site-build.d.mts +71 -113
- package/types/engine/site-config.d.mts +14 -134
- package/types/engine/site-files.d.mts +73 -0
- package/types/engine/site-index.d.mts +11 -3
- package/types/engine/site-preview.d.mts +15 -19
- package/types/engine/site-reach.d.mts +76 -0
- package/types/engine/site-render.d.mts +173 -0
- package/types/engine/site-root.d.mts +14 -4
- package/types/engine/site-search.d.mts +54 -0
- package/types/engine/site-serve.d.mts +44 -0
- package/types/engine/site-theme-banner.d.mts +51 -0
- package/types/engine/site-theme-urls.d.mts +60 -0
- package/types/engine/site-theme.d.mts +127 -0
- package/types/engine/text-maps.d.mts +17 -3
- package/types/engine/typographer.d.mts +11 -0
- package/types/engine/verse-metre.d.mts +131 -0
- package/types/engine/wikilink-syntax.d.mts +30 -48
- package/types/engine/wikilinks.d.mts +330 -14
- package/types/engine/word-forms.d.mts +3 -2
- package/types/manifest.d.mts +3 -4
- package/types/stage.d.mts +1 -2
- package/types/vendor/markdownlint.d.mts +8 -0
- package/vendor/markdownlint.mjs +20388 -0
- package/engine/web-wikilinks.mjs +0 -594
- package/hugo-theme/layouts/404.html +0 -85
- package/hugo-theme/layouts/_default/baseof.html +0 -67
- package/hugo-theme/layouts/_default/list.html +0 -139
- package/hugo-theme/layouts/_default/single.html +0 -4
- package/hugo-theme/layouts/blog/list.html +0 -54
- package/hugo-theme/layouts/blog-post/single.html +0 -36
- package/hugo-theme/layouts/index.html +0 -75
- package/hugo-theme/layouts/partials/banner-url.html +0 -141
- package/hugo-theme/layouts/partials/cdn-url.html +0 -36
- package/hugo-theme/layouts/partials/dictionary-lists.html +0 -58
- package/hugo-theme/layouts/partials/draft-notice.html +0 -41
- package/hugo-theme/layouts/partials/draft-state.html +0 -26
- package/hugo-theme/layouts/partials/header.html +0 -35
- package/hugo-theme/layouts/partials/hero-banner.html +0 -85
- package/hugo-theme/layouts/partials/infobox/entry.html +0 -18
- package/hugo-theme/layouts/partials/infobox/items.html +0 -26
- package/hugo-theme/layouts/partials/infobox/section.html +0 -56
- package/hugo-theme/layouts/partials/infobox/value.html +0 -43
- package/hugo-theme/layouts/partials/infobox.html +0 -57
- package/hugo-theme/layouts/partials/page-body.html +0 -152
- package/hugo-theme/layouts/partials/related.html +0 -138
- package/hugo-theme/layouts/partials/search.html +0 -84
- package/hugo-theme/layouts/partials/site-url.html +0 -32
- package/hugo-theme/layouts/partials/tags.html +0 -30
- package/hugo-theme/layouts/partials/toc.html +0 -28
- package/hugo-theme/layouts/partials/warn-missing-banner.html +0 -3
- package/hugo-theme/layouts/shortcodes/cartouche.html +0 -64
- package/hugo-theme/layouts/shortcodes/exturl.html +0 -12
- package/hugo-theme/layouts/shortcodes/glyph.html +0 -43
- package/hugo-theme/layouts/shortcodes/pagelist.html +0 -63
- package/hugo-theme/theme.toml +0 -11
- package/types/engine/web-wikilinks.d.mts +0 -107
- /package/{hugo-theme → site-theme}/data/banner-kinds.yaml +0 -0
- /package/{hugo-theme → site-theme}/static/css/sohl-icons.css +0 -0
- /package/{hugo-theme → site-theme}/static/fonts/game-icons-kb.woff2 +0 -0
- /package/{hugo-theme → site-theme}/static/img/banners/takheperu-hieroglyphs.svg +0 -0
- /package/{hugo-theme → site-theme}/static/img/cartouches/takheperu.svg +0 -0
- /package/{hugo-theme → site-theme}/static/js/inline-spoilers.js +0 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the Song of Heroic Lands (SoHL) system for Foundry VTT.
|
|
3
|
+
* Copyright (c) 2024-2026 Tom Rodriguez ("Toasty") — <toasty@heroiclands.org>
|
|
4
|
+
*
|
|
5
|
+
* This work is licensed under the GNU General Public License v3.0 (GPLv3).
|
|
6
|
+
* You may copy, modify, and distribute it under the terms of that license.
|
|
7
|
+
*
|
|
8
|
+
* For full terms, see the LICENSE.md file in the project root or visit:
|
|
9
|
+
* https://www.gnu.org/licenses/gpl-3.0.html
|
|
10
|
+
*
|
|
11
|
+
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* **The pages a reader can reach.** Every note is written as a page, but what
|
|
16
|
+
* a reader finds is what the homepage leads to: the sitemap and the search
|
|
17
|
+
* index cover the pages reachable from the homepage by the links the rendered
|
|
18
|
+
* HTML carries, and no others. An unlinked page is still served at its
|
|
19
|
+
* address, so an author reads a page in place before linking it to publish it.
|
|
20
|
+
*
|
|
21
|
+
* Reachability is read from the rendered pages, never from the source notes:
|
|
22
|
+
* the `<a>` and `<link>` targets that lie inside the site's base path, the
|
|
23
|
+
* menu and the chrome included. A link that lands on a feed makes the pages
|
|
24
|
+
* the feed lists reachable too, because a feed is a list of links.
|
|
25
|
+
*
|
|
26
|
+
* @module
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/** A URL with a scheme, or a protocol-relative one: not a path inside the site. */
|
|
30
|
+
const EXTERNAL = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
|
|
31
|
+
|
|
32
|
+
/** An `<a>` or `<link>` and its `href`, quoted either way or bare. */
|
|
33
|
+
const LINK = /<(?:a|link)\b[^>]*?\shref=(?:"([^"]*)"|'([^']*)'|([^\s>]+))/gi;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The internal targets a page links.
|
|
37
|
+
*
|
|
38
|
+
* @param {string} html - A rendered page.
|
|
39
|
+
* @param {string} from - The page's own address, beginning with `/`.
|
|
40
|
+
* @param {string} base - The site's base path, beginning and ending with `/`.
|
|
41
|
+
* @returns {string[]} Absolute paths inside the base, without fragment or query.
|
|
42
|
+
*/
|
|
43
|
+
export function internalLinks(html, from, base) {
|
|
44
|
+
const found = [];
|
|
45
|
+
for (const match of html.matchAll(LINK)) {
|
|
46
|
+
const href = (match[1] ?? match[2] ?? match[3] ?? "").trim().replace(/&/g, "&");
|
|
47
|
+
if (!href || href.startsWith("#") || EXTERNAL.test(href)) continue;
|
|
48
|
+
let pathname;
|
|
49
|
+
try {
|
|
50
|
+
pathname = new URL(href, `http://site.invalid${from}`).pathname;
|
|
51
|
+
} catch {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (pathname.startsWith(base)) found.push(decodeURI(pathname));
|
|
55
|
+
}
|
|
56
|
+
return found;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The address a link to a file names a page by: `…/index.html` is its
|
|
61
|
+
* directory, and a bare directory ends in a slash.
|
|
62
|
+
*
|
|
63
|
+
* @param {string} pathname - An absolute path.
|
|
64
|
+
* @returns {string} The page address it would be keyed by.
|
|
65
|
+
*/
|
|
66
|
+
export function pageAddress(pathname) {
|
|
67
|
+
if (pathname.endsWith("/index.html")) return pathname.slice(0, -"index.html".length);
|
|
68
|
+
return pathname.endsWith("/") || /\.[a-z0-9]+$/i.test(pathname) ? pathname : `${pathname}/`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The pages reachable from the homepage.
|
|
73
|
+
*
|
|
74
|
+
* @param {object} options - The inputs.
|
|
75
|
+
* @param {string} options.base - The site's base path, beginning and ending
|
|
76
|
+
* with `/`; the homepage is at the base.
|
|
77
|
+
* @param {(url: string) => string|undefined} options.html - A page's rendered
|
|
78
|
+
* HTML by its address, or `undefined` where the site has no such page.
|
|
79
|
+
* @param {(pathname: string) => readonly string[]} [options.expand] - The page
|
|
80
|
+
* addresses a linked non-page file, such as a feed, lists.
|
|
81
|
+
* @returns {Set<string>} The address of every reachable page, the homepage
|
|
82
|
+
* included.
|
|
83
|
+
*/
|
|
84
|
+
export function reachablePages({ base, html, expand = () => [] }) {
|
|
85
|
+
/** @type {Set<string>} */
|
|
86
|
+
const reached = new Set();
|
|
87
|
+
const queue = [base];
|
|
88
|
+
const seenFiles = new Set();
|
|
89
|
+
while (queue.length) {
|
|
90
|
+
const url = queue.pop();
|
|
91
|
+
if (reached.has(url)) continue;
|
|
92
|
+
const body = html(url);
|
|
93
|
+
if (body === undefined) continue;
|
|
94
|
+
reached.add(url);
|
|
95
|
+
for (const target of internalLinks(body, url, base)) {
|
|
96
|
+
const address = pageAddress(target);
|
|
97
|
+
if (html(address) !== undefined) {
|
|
98
|
+
queue.push(address);
|
|
99
|
+
} else if (!seenFiles.has(target)) {
|
|
100
|
+
seenFiles.add(target);
|
|
101
|
+
for (const listed of expand(target)) queue.push(pageAddress(listed));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return reached;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* The page addresses an Atom feed lists, as paths.
|
|
110
|
+
*
|
|
111
|
+
* @param {string} xml - The feed.
|
|
112
|
+
* @returns {string[]} The `href` of every `<link>` that is an absolute URL,
|
|
113
|
+
* as its path.
|
|
114
|
+
*/
|
|
115
|
+
export function feedPaths(xml) {
|
|
116
|
+
const paths = [];
|
|
117
|
+
for (const match of xml.matchAll(/<link\b[^>]*?\shref="([^"]*)"/g)) {
|
|
118
|
+
try {
|
|
119
|
+
paths.push(new URL(match[1].replace(/&/g, "&")).pathname);
|
|
120
|
+
} catch {
|
|
121
|
+
// A relative or malformed link names no page.
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return paths;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The comment that separates a page's authored text from the sections the
|
|
129
|
+
* build generated after it, in the HTML the renderer writes.
|
|
130
|
+
*
|
|
131
|
+
* @type {string}
|
|
132
|
+
*/
|
|
133
|
+
export const GENERATED_MARK = "<!--generated-sections-->";
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* A page body split at {@link GENERATED_MARK}.
|
|
137
|
+
*
|
|
138
|
+
* @param {string} html - A page body.
|
|
139
|
+
* @returns {{authored: string, generated: string}} The author's text, and the
|
|
140
|
+
* generated sections after it, `""` where there are none.
|
|
141
|
+
*/
|
|
142
|
+
export function splitContent(html) {
|
|
143
|
+
const text = String(html ?? "");
|
|
144
|
+
const at = text.indexOf(GENERATED_MARK);
|
|
145
|
+
if (at < 0) return { authored: text, generated: "" };
|
|
146
|
+
return { authored: text.slice(0, at), generated: text.slice(at + GENERATED_MARK.length) };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** An `<a>` element with an `href`, whole. */
|
|
150
|
+
const ANCHOR = /<a\b[^>]*?\shref=(?:"([^"]*)"|'([^']*)'|([^\s>]+))[^>]*>[\s\S]*?<\/a>/gi;
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Generated sections with the entries that lead outside a set of pages taken
|
|
154
|
+
* out.
|
|
155
|
+
*
|
|
156
|
+
* An entry is a list item, a table row, or a link in a paragraph's comma
|
|
157
|
+
* separated run; a paragraph, list or table left with no entry goes, and so
|
|
158
|
+
* does a section left with nothing under its heading. A link to anything that
|
|
159
|
+
* is not a page of the site is kept, and so is text that was never a link.
|
|
160
|
+
*
|
|
161
|
+
* @param {string} html - The generated sections, rendered.
|
|
162
|
+
* @param {(href: string) => boolean} outside - Whether an `href` names a page
|
|
163
|
+
* of the site that is not reachable.
|
|
164
|
+
* @returns {string} The sections, or `""` when nothing is left.
|
|
165
|
+
*/
|
|
166
|
+
export function pruneGenerated(html, outside) {
|
|
167
|
+
const dead = (anchor) => {
|
|
168
|
+
const href = new RegExp(ANCHOR.source, "i").exec(anchor);
|
|
169
|
+
const value = href ? (href[1] ?? href[2] ?? href[3] ?? "").replace(/&/g, "&") : "";
|
|
170
|
+
return value !== "" && outside(value);
|
|
171
|
+
};
|
|
172
|
+
const holdsDead = (fragment) => [...fragment.matchAll(ANCHOR)].some((match) => dead(match[0]));
|
|
173
|
+
|
|
174
|
+
// Each section runs from its heading to the next one.
|
|
175
|
+
const parts = String(html ?? "").split(/(?=<h1\b)/);
|
|
176
|
+
const kept = parts.map((part) => {
|
|
177
|
+
if (!holdsDead(part)) return part;
|
|
178
|
+
let out = part
|
|
179
|
+
.replace(/<li\b[^>]*>(?:(?!<\/li>)[\s\S])*<\/li>\s*/g, (item) =>
|
|
180
|
+
holdsDead(item) ? "" : item,
|
|
181
|
+
)
|
|
182
|
+
.replace(/<tr\b[^>]*>(?:(?!<\/tr>)[\s\S])*<\/tr>\s*/g, (row) =>
|
|
183
|
+
holdsDead(row) ? "" : row,
|
|
184
|
+
)
|
|
185
|
+
.replace(/<p\b[^>]*>(?:(?!<\/p>)[\s\S])*<\/p>\s*/g, (paragraph) => {
|
|
186
|
+
if (!holdsDead(paragraph)) return paragraph;
|
|
187
|
+
const trimmed = paragraph.replace(ANCHOR, (anchor) =>
|
|
188
|
+
dead(anchor) ? "\u0000" : anchor,
|
|
189
|
+
);
|
|
190
|
+
const entries = trimmed
|
|
191
|
+
.replace(/<\/?p\b[^>]*>/g, "")
|
|
192
|
+
.replace(/^\s*<strong>[^<]*<\/strong>/, "")
|
|
193
|
+
.replace(/\u0000/g, "")
|
|
194
|
+
.replace(/[\s,]+/g, " ")
|
|
195
|
+
.replace(/<[^>]*>/g, "")
|
|
196
|
+
.trim();
|
|
197
|
+
if (!entries) return "";
|
|
198
|
+
return trimmed
|
|
199
|
+
.replace(/\u0000,\s*/g, "")
|
|
200
|
+
.replace(/,\s*\u0000/g, "")
|
|
201
|
+
.replace(/\u0000/g, "");
|
|
202
|
+
});
|
|
203
|
+
out = out
|
|
204
|
+
.replace(/<(ul|ol)\b[^>]*>\s*<\/\1>\s*/g, "")
|
|
205
|
+
.replace(/<tbody\b[^>]*>\s*<\/tbody>\s*/g, "")
|
|
206
|
+
.replace(/<table\b[^>]*>(?:(?!<tr\b)[\s\S])*<\/table>\s*/g, (table) =>
|
|
207
|
+
/<tr\b/.test(table) ? table : "",
|
|
208
|
+
);
|
|
209
|
+
const rest = out.replace(/^<h1\b[^>]*>[\s\S]*?<\/h1>/, "").replace(/<!--[\s\S]*?-->/g, "");
|
|
210
|
+
return rest.trim() === "" ? "" : out;
|
|
211
|
+
});
|
|
212
|
+
return kept.join("");
|
|
213
|
+
}
|