@ideasonpurpose/build-tools-wordpress 2.1.7 → 2.1.8

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 CHANGED
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### v2.1.7
8
+
9
+ > 28 May 2025
10
+
11
+ - bump deps
12
+ - enable sourcemaps on all CSS loaders
13
+
7
14
  #### v2.1.6
8
15
 
9
16
  > 1 May 2025
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @ideasonpurpose/build-tools-wordpress
2
2
 
3
- #### Version 2.1.7
3
+ #### Version 2.1.8
4
4
 
5
5
  [![NPM Version](https://img.shields.io/npm/v/%40ideasonpurpose%2Fbuild-tools-wordpress?logo=npm)](https://www.npmjs.com/package/@ideasonpurpose/build-tools-wordpress)
6
6
  [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/ideasonpurpose/build-tools-wordpress/npm-publish.yml?logo=github&logoColor=white)](https://github.com/ideasonpurpose/build-tools-wordpress#readme)
@@ -31,7 +31,7 @@ Each project may optionally include an **ideasonpurpose.config.js** file in the
31
31
 
32
32
  ## Local Development
33
33
 
34
- Because this project makes use of bin scripts, conventional `npm link` workflows won't work correctly. To work on this code to work on a development project, change the project's package.json to install from a local file path, probably something like this:
34
+ Because this project makes use of bin scripts, conventional `npm link` workflows won't work correctly. To work on this code in a development project, change the project's package.json to install from a local file path, probably something like this:
35
35
 
36
36
  ```json
37
37
  "devDependencies": {
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ //@ts-check
4
+
3
5
  /**
4
6
  * This is an experimental proof-of-concept for formatting mixed HTML & PHP
5
7
  * files from a single function.
@@ -109,8 +111,15 @@ export function tokenizeHTML(htmlContent) {
109
111
  export function unTokenizeHTML(tokenizedHTML, phpCodeBlocks) {
110
112
  let phpContent = tokenizedHTML;
111
113
  for (const token in phpCodeBlocks) {
114
+ /**
115
+ * Create a pattern from token that matches whitespace breaks resulting
116
+ * from Prettier's HTML formatting, usually on very long lines.
117
+ * eg. the token `<php_4___ />` formats to `<php_4___ \n />`
118
+ * This changes the token to `/<php_4___\s+\/>/g`
119
+ */
120
+ const regexToken = new RegExp(token.replace("_ />", "_\\s+\\/>"), "g");
112
121
  phpContent = phpContent.replace(
113
- new RegExp(token, "g"),
122
+ regexToken,
114
123
  phpCodeBlocks[token].replace(/\$/g, "$$$$"),
115
124
  );
116
125
  }
@@ -128,6 +137,7 @@ async function formatHTMLThenPHP(filepath) {
128
137
  ...prettierConfig,
129
138
  ...htmlOptions,
130
139
  parser: "html",
140
+ embeddedLanguageFormatting: "auto",
131
141
  });
132
142
 
133
143
  const phpUnTokenized = unTokenizeHTML(htmlFormatted, phpCodeBlocks);
@@ -136,6 +146,7 @@ async function formatHTMLThenPHP(filepath) {
136
146
  ...prettierConfig,
137
147
  ...phpOptions,
138
148
  parser: "php",
149
+ embeddedLanguageFormatting: "auto",
139
150
  });
140
151
 
141
152
  await writeFile(filepath, phpFormatted, "utf8");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ideasonpurpose/build-tools-wordpress",
3
- "version": "2.1.7",
3
+ "version": "2.1.8",
4
4
  "description": "Build scripts and dependencies for IOP's WordPress development environments.",
5
5
  "homepage": "https://github.com/ideasonpurpose/build-tools-wordpress#readme",
6
6
  "bugs": {
@@ -6,6 +6,16 @@ import { readFile } from "node:fs/promises";
6
6
 
7
7
  import { tokenizeHTML, unTokenizeHTML } from "../bin/format-php-prettier.js";
8
8
 
9
+ import prettier from "prettier";
10
+ import prettierConfig from "@ideasonpurpose/prettier-config" with { type: "json" };
11
+
12
+ /**
13
+ * Prettier API doesn't recognize overrides, so we extract them
14
+ */
15
+ const htmlOptions = prettierConfig.overrides.find(
16
+ (o) => o.files === "*.html",
17
+ )?.options;
18
+
9
19
  describe("HTML-PHP Prettier", () => {
10
20
  test("All tokens exist", async () => {
11
21
  const input = (
@@ -55,7 +65,7 @@ describe("HTML-PHP Prettier", () => {
55
65
  )
56
66
  ).toString();
57
67
 
58
- const { tokenizedHTML, phpCodeBlocks } = tokenizeHTML(input);
68
+ const { tokenizedHTML, phpCodeBlocks } = tokenizeHTML(input);
59
69
 
60
70
  // console.log({input, tokenizedHTML})
61
71
 
@@ -129,10 +139,59 @@ describe("HTML-PHP Prettier", () => {
129
139
 
130
140
  // console.log({input, tokenizedHTML, phpCodeBlocks});
131
141
 
132
-
133
142
  expect(tokenizedHTML).toContain("<php_0____ />");
134
143
  expect(tokenizedHTML).toContain("<php_1____ />");
135
144
  expect(phpCodeBlocks).toHaveProperty("<php_0____ />");
136
145
  expect(phpCodeBlocks).toHaveProperty("<php_1____ />");
137
146
  });
147
+
148
+ /**
149
+ *
150
+ * Tag-style tokens towards the end of long lines may be line-wrapped by Prettier's HTML
151
+ * formatting, where the token `<php_4___ />` ends up as `<php_4___ \n />`
152
+ *
153
+ * That line-break means a simple string match won't work and the PHP token must be converted
154
+ * to a regexp that matches more than one whitespace character.
155
+ *
156
+ * This example is tricky because the <time> is an inline tag so whitespace is significant. The inner
157
+ * PHP codeblock has a space before it, but not after: <time> <?php ... ?></time>
158
+ * More here: @link https://prettier.io/blog/2018/11/07/1.15.0.html#whitespace-sensitive-formatting
159
+ *
160
+ * Input:
161
+ * <time class="type-eyebrow" datetime="<?= get_the_date('c') ?>"> <?= date('F j, Y', get_post_time()) ?></time>
162
+ *
163
+ * Expected:
164
+ * <time class="type-eyebrow" datetime="<?= get_the_date('c') ?>">
165
+ * <?= date('F j, Y', get_post_time()) ?></time>
166
+ *
167
+ * This is an edge case on line-length.
168
+ * TODO: I think the token replacement pattern needs to replace the literal space between ___ and /> with a regex token
169
+ * so any acquired whitespace from prettier's HTML formatter.
170
+ *
171
+ */
172
+ test("extra space bug", async () => {
173
+ const input = `<time class="type" datetime="<?= get_the_date('c') ?>"> <?= date('F j, Y', get_post_time()) ?></time>`;
174
+ // const input = `<time class="typ" datetime="<?= get_the_date('c') ?>"> <?= date('F j, Y', get_post_time()) ?></time>`;
175
+ const { tokenizedHTML, phpCodeBlocks } = tokenizeHTML(input);
176
+
177
+ const htmlFormatted = await prettier.format(tokenizedHTML, {
178
+ ...prettierConfig,
179
+ ...htmlOptions,
180
+ parser: "html",
181
+ embeddedLanguageFormatting: "auto",
182
+ });
183
+
184
+ const formattedContent = unTokenizeHTML(htmlFormatted, phpCodeBlocks);
185
+ console.log({
186
+ phpCodeBlocks,
187
+ tokenizedHTML,
188
+ htmlFormatted,
189
+ formattedContent,
190
+ });
191
+
192
+ expect(tokenizedHTML).toContain("_php_0___");
193
+ expect(tokenizedHTML).toContain("<php_1___");
194
+ expect(htmlFormatted).toContain("_____\n/>");
195
+ expect(formattedContent).not.toContain("<php_1___");
196
+ });
138
197
  });