@anydigital/eleventy-bricks 0.28.0-alpha.3 → 0.28.0-alpha.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anydigital/eleventy-bricks",
3
- "version": "0.28.0-alpha.3",
3
+ "version": "0.28.0-alpha.4",
4
4
  "description": "A collection of helpful utilities and filters for Eleventy (11ty)",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -9,7 +9,7 @@
9
9
  "11ty": "cd ../ && NODE_OPTIONS='--preserve-symlinks' eleventy",
10
10
  "11ty:clean": "rm -r ../_site",
11
11
  "11ty:debug": "DEBUG=* npm run 11ty --",
12
- "tw": "tailwindcss -i ../src/_theme/styles.css -o ../_site/styles.css",
12
+ "tw": "tailwindcss -i ../_includes/styles.css -o ../_site/styles.css",
13
13
  "tw:debug": "DEBUG=* npm run tw --"
14
14
  }
15
15
  }
@@ -1,5 +1,3 @@
1
- /* CLI */
2
- import minimist from "minimist";
3
1
  /* Plugins */
4
2
  import { RenderPlugin } from "@11ty/eleventy";
5
3
  import eleventyBricksPlugin from "@anydigital/eleventy-bricks";
@@ -46,9 +44,7 @@ import yaml from "js-yaml";
46
44
  * @returns {Object} The Eleventy configuration object
47
45
  */
48
46
  export default function (eleventyConfig) {
49
- /* CLI support */
50
- const argv = minimist(process.argv.slice(2));
51
- const inputDir = argv.input || ".";
47
+ const inputDir = eleventyConfig.directories.input;
52
48
 
53
49
  /* Jekyll parity */
54
50
  eleventyConfig.addPassthroughCopy("assets");
@@ -64,7 +60,18 @@ export default function (eleventyConfig) {
64
60
  mdAutoRawTags: true,
65
61
  autoLinkFavicons: true,
66
62
  siteData: true,
67
- filters: ["attr_set", "attr_includes", "merge", "remove_tag", "if", "attr_concat", "fetch", "section", "strip_tag"],
63
+ filters: [
64
+ "attr_set",
65
+ "attr_includes",
66
+ "merge",
67
+ "remove_tag",
68
+ "if",
69
+ "attr_concat",
70
+ "fetch",
71
+ "section",
72
+ "strip_tag",
73
+ "unindent",
74
+ ],
68
75
  });
69
76
  if (pluginTOC) {
70
77
  eleventyConfig.addPlugin(pluginTOC, {
@@ -94,8 +101,8 @@ export default function (eleventyConfig) {
94
101
  /* Build */
95
102
  eleventyConfig.addPassthroughCopy(
96
103
  {
97
- "src/_public": ".",
98
- ...(inputDir !== "src" && { [`${inputDir}/_public`]: "." }),
104
+ _public: ".",
105
+ ...(inputDir !== "." && { [`${inputDir}/_public`]: "." }),
99
106
  },
100
107
  { expand: true }, // This follows/resolves symbolic links
101
108
  );
@@ -103,12 +110,4 @@ export default function (eleventyConfig) {
103
110
  /* Dev tools */
104
111
  // Follow symlinks in Chokidar used by 11ty to watch files
105
112
  eleventyConfig.setChokidarConfig({ followSymlinks: true });
106
-
107
- /* Config */
108
- return {
109
- dir: {
110
- input: inputDir,
111
- // includes: "_theme",
112
- },
113
- };
114
113
  }
@@ -18,7 +18,7 @@ export function fetchFilter(eleventyConfig) {
18
18
  }
19
19
 
20
20
  // Get the input directory from Eleventy config
21
- const inputDir = eleventyConfig.dir?.input || ".";
21
+ const inputDir = this.eleventy.directories.input;
22
22
 
23
23
  // Check if it's a URL or local path
24
24
  const isUrl = url.startsWith("http://") || url.startsWith("https://");
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Remove the minimal common indentation from a multi-line string
3
+ *
4
+ * Finds the smallest leading-whitespace count across all non-empty lines
5
+ * and strips that many characters from the beginning of every line.
6
+ *
7
+ * @param {string} content - The input string
8
+ * @returns {string} The unindented string
9
+ */
10
+ export function unindent(content) {
11
+ const lines = String(content ?? "").split("\n");
12
+ const minIndent = Math.min(...lines.filter((l) => l.trim()).map((l) => l.match(/^(\s*)/)[1].length));
13
+ return lines.map((l) => l.slice(minIndent)).join("\n");
14
+ }
15
+
16
+ /**
17
+ * unindent filter - Remove minimal common indentation
18
+ *
19
+ * Strips the smallest leading-whitespace indent shared by all non-empty
20
+ * lines, useful for dedenting captured or indented template blocks.
21
+ *
22
+ * Usage in templates:
23
+ * {{ content | unindent }}
24
+ *
25
+ * @param {Object} eleventyConfig - The Eleventy configuration object
26
+ */
27
+ export function unindentFilter(eleventyConfig) {
28
+ eleventyConfig.addFilter("unindent", unindent);
29
+ }
@@ -0,0 +1,49 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert";
3
+ import { unindent } from "./unindent.js";
4
+
5
+ test("unindent - removes common leading spaces", () => {
6
+ const input = " hello\n world";
7
+ assert.strictEqual(unindent(input), "hello\nworld");
8
+ });
9
+
10
+ test("unindent - removes common leading tabs", () => {
11
+ const input = "\tfoo\n\tbar";
12
+ assert.strictEqual(unindent(input), "foo\nbar");
13
+ });
14
+
15
+ test("unindent - preserves relative indentation", () => {
16
+ const input = " if true\n inner\n end";
17
+ assert.strictEqual(unindent(input), "if true\n inner\nend");
18
+ });
19
+
20
+ test("unindent - ignores blank lines when computing min indent", () => {
21
+ const input = " line1\n\n line2";
22
+ assert.strictEqual(unindent(input), "line1\n\nline2");
23
+ });
24
+
25
+ test("unindent - does nothing when already at zero indent", () => {
26
+ const input = "hello\nworld";
27
+ assert.strictEqual(unindent(input), "hello\nworld");
28
+ });
29
+
30
+ test("unindent - handles single line", () => {
31
+ assert.strictEqual(unindent(" hello"), "hello");
32
+ });
33
+
34
+ test("unindent - handles null input", () => {
35
+ assert.strictEqual(unindent(null), "");
36
+ });
37
+
38
+ test("unindent - handles undefined input", () => {
39
+ assert.strictEqual(unindent(undefined), "");
40
+ });
41
+
42
+ test("unindent - handles empty string", () => {
43
+ assert.strictEqual(unindent(""), "");
44
+ });
45
+
46
+ test("unindent - mixed indent levels, strips only the minimum", () => {
47
+ const input = " a\n b\n c";
48
+ assert.strictEqual(unindent(input), "a\n b\nc");
49
+ });
package/src/index.js CHANGED
@@ -15,6 +15,7 @@ import { stripTagFilter, stripTag } from "./filters/strip_tag.js";
15
15
  import { ifFilter, iff } from "./filters/if.js";
16
16
  import { attrConcatFilter, attrConcat } from "./filters/attr_concat.js";
17
17
  import { sectionFilter, section as sectionFn } from "./filters/section.js";
18
+ import { unindentFilter, unindent } from "./filters/unindent.js";
18
19
  import { siteData } from "./siteData.js";
19
20
 
20
21
  // Conditionally import fetchFilter only if @11ty/eleventy-fetch is available
@@ -58,6 +59,7 @@ export default function eleventyBricksPlugin(eleventyConfig, options = {}) {
58
59
  if: ifFilter,
59
60
  attr_concat: attrConcatFilter,
60
61
  section: sectionFilter,
62
+ unindent: unindentFilter,
61
63
  ...(fetchFilter && { fetch: fetchFilter }),
62
64
  };
63
65
 
@@ -92,6 +94,7 @@ export {
92
94
  ifFilter,
93
95
  attrConcatFilter,
94
96
  sectionFilter,
97
+ unindentFilter,
95
98
  fetchFilter,
96
99
  siteData,
97
100
  };
@@ -112,4 +115,5 @@ export {
112
115
  attrConcat,
113
116
  attrSet,
114
117
  sectionFn as section,
118
+ unindent,
115
119
  };
@@ -36,15 +36,6 @@ export function cleanLinkText(linkText, domain) {
36
36
  export function buildFaviconLink(attrs, domain, text) {
37
37
  let updatedAttrs = attrs;
38
38
 
39
- // Check if attrs already contains a class attribute
40
- if (/class\s*=\s*["']/.test(attrs)) {
41
- // Append whitespace-nowrap to existing class
42
- updatedAttrs = attrs.replace(/class\s*=\s*["']([^"']*)["']/i, 'class="$1 whitespace-nowrap"');
43
- } else {
44
- // Add new class attribute
45
- updatedAttrs = attrs + ' class="whitespace-nowrap"';
46
- }
47
-
48
39
  // Check if attrs already contains a target attribute
49
40
  if (!/target\s*=/.test(attrs)) {
50
41
  updatedAttrs = updatedAttrs + ' target="_blank"';