Skip to content

Commit

Permalink
feat: support generator unwrap
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 committed Feb 20, 2024
1 parent b12087e commit 3d3422f
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 17 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,25 @@ Your automated markdown maintainer!

## Contribution

<!-- automd:fetch url="gh:unjs/.github/main/snippets/readme-contrib-pnpm.md" -->

<details>
<summary>Local development</summary>

- Clone this repository
- Install the latest LTS version of [Node.js](https://nodejs.org/en/)
- Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable`
- Install dependencies using `pnpm install`
- Run unit tests using `pnpm dev`
- Run playground test using `pnpm play`
- Run tests using `pnpm dev` or `pnpm test`

</details>


<!-- /automd -->

## License

Made with 💛 Published under [MIT License](./LICENSE).
Made with 💛 Published under the [MIT License](./LICENSE).

<!-- automd:with-automd -->

Expand Down
13 changes: 10 additions & 3 deletions src/_parse.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { destr } from "destr";

const AUTOMD_RE =
/^(?<open><!--\s*automd:(?<generator>.+?)\s+(?<args>.*?)\s*-->)(?<contents>.+?)(?<close>^<!--\s*\/automd\s*-->)/gims;

export interface Block {
generator: string;
rawArgs: string;
contents: string;
loc: { start: number; end: number };
_loc: { start: number; end: number };
}

export function findBlocks(md: string): Block[] {
const blocks: Block[] = [];

// Regex is stateful, so we need to reset it
const AUTOMD_RE =
/^(?<open><!--\s*automd:(?<generator>.+?)\s+(?<args>.*?)\s*-->)(?<contents>.+?)(?<close>^<!--\s*\/automd\s*-->)/gims;

for (const match of md.matchAll(AUTOMD_RE)) {
if (match.index === undefined || !match.groups) {
continue;
Expand All @@ -26,12 +28,17 @@ export function findBlocks(md: string): Block[] {
rawArgs: match.groups.args,
contents: match.groups.contents,
loc: { start, end },
_loc: { start: match.index, end: match.index + match[0].length },
});
}

return blocks;
}

export function containsAutomd(md: string) {
return /^<!--\s*automd:/gims.test(md);
}

export function parseRawArgs(rawArgs: string) {
const args = Object.create(null);

Expand Down
1 change: 1 addition & 0 deletions src/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface GenerateContext {
export interface GenerateResult {
contents: string;
issues?: string[];
unwrap?: boolean;
}

export interface Generator {
Expand Down
32 changes: 26 additions & 6 deletions src/transform.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import MagicString from "magic-string";
import builtinGenerators from "./generators";
import { GenerateContext, GenerateResult } from "./generator";
import { Block, findBlocks, parseRawArgs } from "./_parse";
import { Block, containsAutomd, findBlocks, parseRawArgs } from "./_parse";
import { Config, ResolvedConfig, resolveConfig } from "./config";

export interface TransformResult {
Expand Down Expand Up @@ -32,12 +32,16 @@ export async function transform(

for (const block of blocks) {
const result = await _transformBlock(block, config, generators);
if (result.unwrap) {
editor.overwrite(block._loc.start, block._loc.end, `${result.contents}`);
} else {
editor.overwrite(
block.loc.start,
block.loc.end,
`\n\n${result.contents}\n\n`,
);
}
updates.push({ block, result });
editor.overwrite(
block.loc.start,
block.loc.end,
`\n\n${result.contents}\n\n`,
);
}

const hasChanged = editor.hasChanged();
Expand Down Expand Up @@ -80,6 +84,22 @@ async function _transformBlock(

try {
const result = (await generator.generate(context)) as GenerateResult;

if (!result.unwrap && containsAutomd(result.contents)) {
result.unwrap = true;
}
if (result.unwrap) {
const nestedRes = await transform(result.contents, config);
result.contents = nestedRes.contents.trim();
// TODO: inherit time, issues, etc.
if (nestedRes.hasIssues) {
result.issues = [
...(result.issues || []),
...nestedRes.updates.flatMap((u) => u.result.issues || []),
];
}
}

return result;
} catch (_error: any) {
const error = `(${block.generator}) ${_error.message || _error}`;
Expand Down
66 changes: 61 additions & 5 deletions test/transform.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ import { transform } from "../src";

describe("transform", () => {
it("basic transform works", async () => {
const input = `
<!-- automd:test foo=bar -->
<!-- /automd -->
`.trim();
const input = `<!-- automd:test foo=bar -->\n\n<!-- /automd -->`;

const result = await transform(input, {
generators: {
Expand All @@ -31,15 +28,74 @@ describe("transform", () => {
expect(result.updates).toHaveLength(1);
expect(result.updates[0].block).toMatchInlineSnapshot(`
{
"_loc": {
"end": 46,
"start": 0,
},
"contents": "
",
"generator": "test",
"loc": {
"end": 29,
"end": 30,
"start": 28,
},
"rawArgs": "foo=bar",
}
`);
});

describe("unwrap", () => {
it("manual unwrap", async () => {
const input = `foo\n<!-- automd:test -->\n<!-- /automd -->\nbaz`;

const result = await transform(input, {
generators: {
test: {
name: "test",
generate() {
return {
contents: `bar`,
unwrap: true,
};
},
},
},
});

expect(result.contents).toMatchInlineSnapshot(`
"foo
bar
baz"
`);
});
it("auto unwrap", async () => {
const input = `a\n<!-- automd:test -->\n<!-- /automd -->\nd`;

const result = await transform(input, {
generators: {
test: {
name: "test",
generate() {
return {
contents: `b\n<!-- automd:with-automd lastUpdate=now -->\n<!-- /automd -->\nc`,
};
},
},
},
});

expect(result.contents).toMatchInlineSnapshot(`
"a
b
<!-- automd:with-automd lastUpdate=now -->
_🤖 docs are auto updated with [automd](https:/automd.unjs.io) (last updated: now)_
<!-- /automd -->
c
d"
`);
});
});
});

0 comments on commit 3d3422f

Please sign in to comment.