@kirigami/php-prepros 3.2.0 → 3.2.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/README.md +2071 -2064
- package/package.json +59 -59
- package/src/libraries/html.class.php +56 -4
package/package.json
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@kirigami/php-prepros",
|
|
3
|
-
"version": "3.2.
|
|
4
|
-
"description": "PHP preprocessor for the Kirigami static site generator. Compile PHP page templates to clean, deployable HTML — with zero server dependency.",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"kirigami",
|
|
7
|
-
"php",
|
|
8
|
-
"preprocessor",
|
|
9
|
-
"static-site-generator",
|
|
10
|
-
"ssg",
|
|
11
|
-
"wasm",
|
|
12
|
-
"php-wasm",
|
|
13
|
-
"markdown",
|
|
14
|
-
"yaml",
|
|
15
|
-
"github-pages",
|
|
16
|
-
"pages"
|
|
17
|
-
],
|
|
18
|
-
"license": "GPL-3.0-or-later",
|
|
19
|
-
"author": "Maxime Larrivée-Roy",
|
|
20
|
-
"type": "module",
|
|
21
|
-
"main": "index.js",
|
|
22
|
-
"types": "index.d.ts",
|
|
23
|
-
"files": [
|
|
24
|
-
"index.js",
|
|
25
|
-
"index.d.ts",
|
|
26
|
-
"src/",
|
|
27
|
-
"LICENSE",
|
|
28
|
-
"README.md"
|
|
29
|
-
],
|
|
30
|
-
"engines": {
|
|
31
|
-
"node": ">=24.0.0",
|
|
32
|
-
"npm": ">=10.2.3"
|
|
33
|
-
},
|
|
34
|
-
"exports": {
|
|
35
|
-
".": {
|
|
36
|
-
"import": "./index.js"
|
|
37
|
-
},
|
|
38
|
-
"./package.json": "./package.json"
|
|
39
|
-
},
|
|
40
|
-
"publishConfig": {
|
|
41
|
-
"access": "public"
|
|
42
|
-
},
|
|
43
|
-
"scripts": {
|
|
44
|
-
"test": "node --test --test-concurrency=1 \"test/*.test.js\""
|
|
45
|
-
},
|
|
46
|
-
"dependencies": {
|
|
47
|
-
"@kirigami/php-wasm": "8.5.11-1",
|
|
48
|
-
"@kirigami/struct-walker": "1.0.6",
|
|
49
|
-
"picomatch": "^4.0.7"
|
|
50
|
-
},
|
|
51
|
-
"repository": {
|
|
52
|
-
"type": "git",
|
|
53
|
-
"url": "git+https://github.com/php-kirigami/kirigami.git"
|
|
54
|
-
},
|
|
55
|
-
"homepage": "https://php-kirigami.github.io",
|
|
56
|
-
"bugs": {
|
|
57
|
-
"url": "https://github.com/php-kirigami/kirigami/issues"
|
|
58
|
-
}
|
|
59
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@kirigami/php-prepros",
|
|
3
|
+
"version": "3.2.1",
|
|
4
|
+
"description": "PHP preprocessor for the Kirigami static site generator. Compile PHP page templates to clean, deployable HTML — with zero server dependency.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"kirigami",
|
|
7
|
+
"php",
|
|
8
|
+
"preprocessor",
|
|
9
|
+
"static-site-generator",
|
|
10
|
+
"ssg",
|
|
11
|
+
"wasm",
|
|
12
|
+
"php-wasm",
|
|
13
|
+
"markdown",
|
|
14
|
+
"yaml",
|
|
15
|
+
"github-pages",
|
|
16
|
+
"pages"
|
|
17
|
+
],
|
|
18
|
+
"license": "GPL-3.0-or-later",
|
|
19
|
+
"author": "Maxime Larrivée-Roy",
|
|
20
|
+
"type": "module",
|
|
21
|
+
"main": "index.js",
|
|
22
|
+
"types": "index.d.ts",
|
|
23
|
+
"files": [
|
|
24
|
+
"index.js",
|
|
25
|
+
"index.d.ts",
|
|
26
|
+
"src/",
|
|
27
|
+
"LICENSE",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=24.0.0",
|
|
32
|
+
"npm": ">=10.2.3"
|
|
33
|
+
},
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"import": "./index.js"
|
|
37
|
+
},
|
|
38
|
+
"./package.json": "./package.json"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"test": "node --test --test-concurrency=1 \"test/*.test.js\""
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@kirigami/php-wasm": "8.5.11-1",
|
|
48
|
+
"@kirigami/struct-walker": "1.0.6",
|
|
49
|
+
"picomatch": "^4.0.7"
|
|
50
|
+
},
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "git+https://github.com/php-kirigami/kirigami.git"
|
|
54
|
+
},
|
|
55
|
+
"homepage": "https://php-kirigami.github.io",
|
|
56
|
+
"bugs": {
|
|
57
|
+
"url": "https://github.com/php-kirigami/kirigami/issues"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -25,6 +25,7 @@ class HTML
|
|
|
25
25
|
'code', 'dfn', 'em', 'i', 'img', 'input', 'kbd', 'label', 'map',
|
|
26
26
|
'mark', 'object', 'output', 'q', 's', 'samp', 'select', 'small',
|
|
27
27
|
'span', 'strong', 'sub', 'sup', 'textarea', 'time', 'tt', 'u', 'var',
|
|
28
|
+
'bdi', 'data', 'del', 'font', 'ins', 'rp', 'rt', 'ruby', 'strike', 'wbr',
|
|
28
29
|
];
|
|
29
30
|
|
|
30
31
|
// The HTML namespace URI Lexbor assigns to plain HTML elements (foreign
|
|
@@ -188,20 +189,63 @@ class HTML
|
|
|
188
189
|
}
|
|
189
190
|
|
|
190
191
|
$inner = '';
|
|
191
|
-
foreach ($children as $
|
|
192
|
-
|
|
192
|
+
foreach (static::groupInlineRuns($children) as $group) {
|
|
193
|
+
if (is_array($group)) {
|
|
194
|
+
// Text and inline elements that follow each other: one line, so
|
|
195
|
+
// the spaces between them survive ("<b>bold</b>, next").
|
|
196
|
+
$inner .= str_repeat(' ', ($depth + 1) * self::INDENT) . trim(static::renderInlineNodes($group)) . "\n";
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
$inner .= static::renderNode($group, $depth + 1);
|
|
193
200
|
}
|
|
194
201
|
|
|
195
202
|
return "{$pad}<{$tag}{$attrs}>\n{$inner}{$pad}</{$tag}>\n";
|
|
196
203
|
}
|
|
197
204
|
|
|
205
|
+
// Splits a block's children into single nodes and runs (arrays) of
|
|
206
|
+
// consecutive text/inline nodes that contain real text. A run without text
|
|
207
|
+
// (a row of <a><img></a>, say) stays as separate nodes, one per line.
|
|
208
|
+
private static function groupInlineRuns(array $children): array
|
|
209
|
+
{
|
|
210
|
+
$groups = [];
|
|
211
|
+
$run = [];
|
|
212
|
+
$flush = static function () use (&$groups, &$run) {
|
|
213
|
+
$hasText = false;
|
|
214
|
+
foreach ($run as $node) {
|
|
215
|
+
if ($node->nodeType === XML_TEXT_NODE && trim($node->nodeValue) !== '') $hasText = true;
|
|
216
|
+
}
|
|
217
|
+
if ($hasText) $groups[] = $run;
|
|
218
|
+
else foreach ($run as $node) $groups[] = $node;
|
|
219
|
+
$run = [];
|
|
220
|
+
};
|
|
221
|
+
foreach ($children as $child) {
|
|
222
|
+
$isInline = $child->nodeType === XML_TEXT_NODE
|
|
223
|
+
|| ($child->nodeType === XML_ELEMENT_NODE
|
|
224
|
+
&& static::isInline($child)
|
|
225
|
+
&& static::hasOnlyInlineChildren($child));
|
|
226
|
+
if ($isInline) {
|
|
227
|
+
$run[] = $child;
|
|
228
|
+
} else {
|
|
229
|
+
$flush();
|
|
230
|
+
$groups[] = $child;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
$flush();
|
|
234
|
+
return $groups;
|
|
235
|
+
}
|
|
236
|
+
|
|
198
237
|
// Serializes a node's inline content on a single line, collapsing any run
|
|
199
238
|
// of spaces/tabs/newlines in the source text to a single space (equivalent
|
|
200
239
|
// to HTML's whitespace-collapsing behavior).
|
|
201
240
|
private static function renderInline(Dom\Node $node): string
|
|
241
|
+
{
|
|
242
|
+
return static::renderInlineNodes($node->childNodes);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
private static function renderInlineNodes(iterable $nodes): string
|
|
202
246
|
{
|
|
203
247
|
$out = '';
|
|
204
|
-
foreach ($
|
|
248
|
+
foreach ($nodes as $child) {
|
|
205
249
|
if ($child->nodeType === XML_TEXT_NODE) {
|
|
206
250
|
$text = preg_replace('/\s+/', ' ', $child->nodeValue);
|
|
207
251
|
$out .= htmlspecialchars($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
|
@@ -244,6 +288,14 @@ class HTML
|
|
|
244
288
|
return $elementCount <= 1;
|
|
245
289
|
}
|
|
246
290
|
|
|
291
|
+
// A known inline element, or a custom element (its name always has a
|
|
292
|
+
// hyphen), which browsers lay out inline unless a stylesheet says otherwise.
|
|
293
|
+
private static function isInline(Dom\Node $node): bool
|
|
294
|
+
{
|
|
295
|
+
$name = strtolower($node->nodeName);
|
|
296
|
+
return in_array($name, self::INLINE, true) || str_contains($name, '-');
|
|
297
|
+
}
|
|
298
|
+
|
|
247
299
|
// Checks that every direct descendant is inline (text, inline void, inline elements)
|
|
248
300
|
// The inline elements themselves must not contain block elements
|
|
249
301
|
private static function hasOnlyInlineChildren(Dom\Node $node): bool
|
|
@@ -255,7 +307,7 @@ class HTML
|
|
|
255
307
|
if ($child->nodeType !== XML_ELEMENT_NODE) {
|
|
256
308
|
return false;
|
|
257
309
|
}
|
|
258
|
-
if (!
|
|
310
|
+
if (!static::isInline($child)) {
|
|
259
311
|
return false;
|
|
260
312
|
}
|
|
261
313
|
// Recursive: the inline element must not contain block elements
|