Skip to content

Commit 9e30a2d

Browse files
committed
fix(core): do not escape braces in markdown code anymore
Signed-off-by: Emilien Escalle <[email protected]>
1 parent ab3cd9d commit 9e30a2d

File tree

8 files changed

+91
-72
lines changed

8 files changed

+91
-72
lines changed

.devcontainer/devcontainer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
"dbaeumer.vscode-eslint",
1616
"esbenp.prettier-vscode",
1717
"vitest.explorer"
18-
]
18+
],
19+
"settings": {
20+
"terminal.integrated.defaultProfile.linux": "zsh"
21+
}
1922
}
2023
}
2124
}

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
"version": "0.2.1",
44
"license": "MIT",
55
"scripts": {
6-
"build": "nx run-many --target=build --all --parallel",
7-
"lint": "nx run-many --target=lint --all --parallel",
8-
"lint:ci": "nx run-many --target=lint --all --parallel --output-file eslint-report.json --format json",
9-
"test": "nx run-many --target=test --all --parallel",
10-
"test:ci": "nx run-many --target=test --all --parallel --coverage --coverage.all",
6+
"build": "nx run-many --target=build --all --parallel --exclude=@ci-dokumentor/source",
7+
"lint": "nx run-many --target=lint --all --parallel --exclude=@ci-dokumentor/source",
8+
"lint:ci": "nx run-many --target=lint --all --parallel --exclude=@ci-dokumentor/source --output-file eslint-report.json --format json",
9+
"test": "nx run-many --target=test --all --parallel --exclude=@ci-dokumentor/source",
10+
"test:ci": "nx run-many --target=test --all --parallel --exclude=@ci-dokumentor/source --coverage --coverage.all",
1111
"all": "pnpm run build && pnpm run lint --fix && pnpm run test:ci",
1212
"docs:start": "nx start @ci-dokumentor/docs",
1313
"docs:serve": "nx serve @ci-dokumentor/docs",

packages/cicd/github-actions/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
The `@ci-dokumentor/cicd-github-actions` package provides GitHub Actions-specific CI/CD manifest parsing and documentation generation capabilities.
44

5-
**Documentation**: [CI/CD - GitHub Actions Package](../../docs/content/packages/cicd/github-actions/)
5+
**Documentation**: [CI/CD - GitHub Actions Package](../../docs/content/packages/cicd/github-actions/index.md)

packages/cicd/github-actions/src/section/inputs-section-generator.adapter.spec.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,13 +201,19 @@ describe('InputsSectionGenerator', () => {
201201
const result = await generator.generateSection({ formatterAdapter, manifest, repositoryProvider: mockRepositoryProvider, destination: 'README.md' });
202202

203203
// Assert
204-
// Curly braces are escaped to prevent template interpolation in MDX/Jekyll
205-
expect(result.toString()).toContain('$\\{\\{ github.token }}');
204+
expect(result.toString()).toEqual(`## Inputs
205+
206+
| **Input** | **Description** | **Required** | **Default** |
207+
| ------------------ | ------------------------------------------- | ------------ | --------------------- |
208+
| **\`github-token\`** | GitHub Token for deploying to GitHub Pages. | **false** | \`\${{ github.token }}\` |
209+
`);
206210
expect(result.toString()).toEqual(
207-
'## Inputs\n\n' +
208-
'| **Input** | **Description** | **Required** | **Default** |\n' +
209-
'| ------------------ | ------------------------------------------- | ------------ | ----------------------- |\n' +
210-
'| **`github-token`** | GitHub Token for deploying to GitHub Pages. | **false** | `$\\{\\{ github.token }}` |\n'
211+
`## Inputs
212+
213+
| **Input** | **Description** | **Required** | **Default** |
214+
| ------------------ | ------------------------------------------- | ------------ | --------------------- |
215+
| **\`github-token\`** | GitHub Token for deploying to GitHub Pages. | **false** | \`\${{ github.token }}\` |
216+
`
211217
);
212218
});
213219
});

packages/cli/src/lib/__snapshots__/cli.e2e.spec.ts.snap

Lines changed: 23 additions & 23 deletions
Large diffs are not rendered by default.

packages/core/src/formatter/markdown/markdown-code.generator.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { injectable } from 'inversify';
22
import { ReadableContent } from '../../reader/readable-content.js';
3+
import { MarkdownFormatterAdapter } from './markdown-formatter.adapter.js';
34

45
@injectable()
56
export class MarkdownCodeGenerator {
67

78
private static readonly TICK = '`';
9+
private static readonly TICK_CHAR_CODE = 0x60;
10+
private static readonly TILDE_CHAR_CODE = 0x7E;
811
private static readonly MIN_FENCE_LEN = 3;
912
private static readonly HTML_NEWLINE_ENTITY = '&#13;';
1013
private static readonly DEFAULT_LANGUAGE = new ReadableContent('text');
@@ -66,7 +69,7 @@ export class MarkdownCodeGenerator {
6669
inlineCode(content: ReadableContent): ReadableContent {
6770
return ReadableContent.empty().append(
6871
MarkdownCodeGenerator.TICK,
69-
content.escape([MarkdownCodeGenerator.TICK, '*', '{']),
72+
content.escape([MarkdownCodeGenerator.TICK, MarkdownFormatterAdapter.ITALIC_DELIMITER]).htmlEscape(),
7073
MarkdownCodeGenerator.TICK
7174
);
7275
}
@@ -222,24 +225,24 @@ export class MarkdownCodeGenerator {
222225
const contentSize = content.getSize();
223226
let pos = 0;
224227
while (pos < contentSize) {
225-
const backtickIdx = content.search(0x60 /* ` */, pos);
226-
const tildeIdx = content.search(0x7E /* ~ */, pos);
228+
const backtickIdx = content.search(MarkdownCodeGenerator.TICK_CHAR_CODE, pos);
229+
const tildeIdx = content.search(MarkdownCodeGenerator.TILDE_CHAR_CODE, pos);
227230
let idx = -1;
228231
let marker = 0;
229232
if (backtickIdx === -1 && tildeIdx === -1) {
230233
break;
231234
}
232235
else if (backtickIdx === -1) {
233-
idx = tildeIdx; marker = 0x7E;
236+
idx = tildeIdx; marker = MarkdownCodeGenerator.TILDE_CHAR_CODE;
234237
}
235238
else if (tildeIdx === -1) {
236-
idx = backtickIdx; marker = 0x60;
239+
idx = backtickIdx; marker = MarkdownCodeGenerator.TICK_CHAR_CODE;
237240
}
238241
else if (backtickIdx < tildeIdx) {
239-
idx = backtickIdx; marker = 0x60;
242+
idx = backtickIdx; marker = MarkdownCodeGenerator.TICK_CHAR_CODE;
240243
}
241244
else {
242-
idx = tildeIdx; marker = 0x7E;
245+
idx = tildeIdx; marker = MarkdownCodeGenerator.TILDE_CHAR_CODE;
243246
}
244247

245248
if (idx === -1) {

packages/core/src/formatter/markdown/markdown-formatter.adapter.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import { MarkdownCodeGenerator } from './markdown-code.generator.js';
99

1010
@injectable()
1111
export class MarkdownFormatterAdapter implements FormatterAdapter {
12+
static readonly ITALIC_DELIMITER = '*';
13+
private static readonly BOLD_DELIMITER = '**';
14+
1215
private options: FormatterOptions = {
1316
linkFormat: LinkFormat.Auto
1417
};
@@ -76,13 +79,17 @@ export class MarkdownFormatterAdapter implements FormatterAdapter {
7679
}
7780

7881
bold(content: ReadableContent): ReadableContent {
79-
// Enhanced: Use instance method with direct string support
80-
return new ReadableContent('**').append(content.escape('**'), '**');
82+
return new ReadableContent(MarkdownFormatterAdapter.BOLD_DELIMITER).append(
83+
content.escape(MarkdownFormatterAdapter.BOLD_DELIMITER),
84+
MarkdownFormatterAdapter.BOLD_DELIMITER
85+
);
8186
}
8287

8388
italic(input: ReadableContent): ReadableContent {
84-
// Enhanced: Use instance method with direct string support
85-
return new ReadableContent('*').append(input.escape('*'), '*');
89+
return new ReadableContent(MarkdownFormatterAdapter.ITALIC_DELIMITER).append(
90+
input.escape(MarkdownFormatterAdapter.ITALIC_DELIMITER),
91+
MarkdownFormatterAdapter.ITALIC_DELIMITER
92+
);
8693
}
8794

8895
code(content: ReadableContent, language?: ReadableContent): ReadableContent {
@@ -102,7 +109,7 @@ export class MarkdownFormatterAdapter implements FormatterAdapter {
102109
// If the text is already a single inline markdown link or image (e.g. "![...](...)" or "[...]()"),
103110
// don't escape it - callers sometimes pass pre-formatted markdown (badges) as the link text.
104111
const isInlineMarkdown = this.contentLooksLikeInlineMarkdown(text);
105-
// Enhanced: Use instance method with direct string support
112+
106113
return new ReadableContent('[')
107114
.append(
108115
isInlineMarkdown ? text : text.escape(['[', ']']),
@@ -151,9 +158,9 @@ export class MarkdownFormatterAdapter implements FormatterAdapter {
151158
badge(label: ReadableContent, url: ReadableContent): ReadableContent {
152159
return ReadableContent.empty().append(
153160
'![',
154-
label.escape(['*', ')']),
161+
label.escape([MarkdownFormatterAdapter.ITALIC_DELIMITER, ')']),
155162
'](',
156-
url.escape(['*', ')']),
163+
url.escape([MarkdownFormatterAdapter.ITALIC_DELIMITER, ')']),
157164
')'
158165
);
159166
}

packages/docs/content/integrations/github-action.md

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -74,28 +74,28 @@ CI Dokumentor can be used directly as a GitHub Action in your workflows, making
7474
7575
## Inputs
7676
77-
| **Input** | **Description** | **Required** | **Default** |
78-
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------ | ----------------------- |
79-
| **`source`** | Source manifest file path(s) to handle. Supports: | **true** | - |
80-
| | - Single file: `action.yml` | | |
81-
| | - Multiple files (space-separated): `action.yml .github/workflows/ci.yml` | | |
82-
| | - Multiple files (newline-separated): Use multiline YAML string | | |
83-
| | - Glob patterns: `*.yml` or `.github/workflows/*.yml` | | |
84-
| **`destination`** | Destination path for generated documentation (optional; destination is auto-detected if not specified by the adapter). | **false** | - |
85-
| | Only applicable when processing a single file. | | |
86-
| **`repository`** | Repository platform (auto-detected if not specified). | **false** | - |
87-
| **`cicd`** | CI/CD platform (`github-actions`, `gitlab-ci`, etc.). | **false** | - |
88-
| **`include-sections`** | Comma-separated list of sections to include. | **false** | - |
89-
| **`exclude-sections`** | Comma-separated list of sections to exclude. | **false** | - |
90-
| **`dry-run`** | Whether to perform a dry run (no files are written). | **false** | `false` |
91-
| **`version`** | Version to document (auto-detected if not specified). | **false** | - |
92-
| **`extra-badges`** | JSON array of extra badges to include in the documentation. | **false** | - |
93-
| | Each badge should have `label`, `url`, and optional `linkUrl` properties. | | |
94-
| **`format-link`** | Transform bare URLs to links. | **false** | `auto` |
95-
| | Types: `auto` (autolinks), `full` (full links), `false` (disabled). | | |
96-
| **`concurrency`** | Maximum number of files to process concurrently when processing multiple files. | **false** | `5` |
97-
| **`github-token`** | The GitHub token used to fetch repository information. | **false** | `$\{\{ github.token }}` |
98-
| **`ci-dokumentor-version`** | Version of CI Dokumentor to use. See [https://github.com/hoverkraft-tech/ci-dokumentor/releases](https://github.com/hoverkraft-tech/ci-dokumentor/releases). | **false** | `latest` |
77+
| **Input** | **Description** | **Required** | **Default** |
78+
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------ | --------------------- |
79+
| **`source`** | Source manifest file path(s) to handle. Supports: | **true** | - |
80+
| | - Single file: `action.yml` | | |
81+
| | - Multiple files (space-separated): `action.yml .github/workflows/ci.yml` | | |
82+
| | - Multiple files (newline-separated): Use multiline YAML string | | |
83+
| | - Glob patterns: `*.yml` or `.github/workflows/*.yml` | | |
84+
| **`destination`** | Destination path for generated documentation (optional; destination is auto-detected if not specified by the adapter). | **false** | - |
85+
| | Only applicable when processing a single file. | | |
86+
| **`repository`** | Repository platform (auto-detected if not specified). | **false** | - |
87+
| **`cicd`** | CI/CD platform (`github-actions`, `gitlab-ci`, etc.). | **false** | - |
88+
| **`include-sections`** | Comma-separated list of sections to include. | **false** | - |
89+
| **`exclude-sections`** | Comma-separated list of sections to exclude. | **false** | - |
90+
| **`dry-run`** | Whether to perform a dry run (no files are written). | **false** | `false` |
91+
| **`version`** | Version to document (auto-detected if not specified). | **false** | - |
92+
| **`extra-badges`** | JSON array of extra badges to include in the documentation. | **false** | - |
93+
| | Each badge should have `label`, `url`, and optional `linkUrl` properties. | | |
94+
| **`format-link`** | Transform bare URLs to links. | **false** | `auto` |
95+
| | Types: `auto` (autolinks), `full` (full links), `false` (disabled). | | |
96+
| **`concurrency`** | Maximum number of files to process concurrently when processing multiple files. | **false** | `5` |
97+
| **`github-token`** | The GitHub token used to fetch repository information. | **false** | `${{ github.token }}` |
98+
| **`ci-dokumentor-version`** | Version of CI Dokumentor to use. See [https://github.com/hoverkraft-tech/ci-dokumentor/releases](https://github.com/hoverkraft-tech/ci-dokumentor/releases). | **false** | `latest` |
9999

100100
<!-- inputs:end -->
101101

0 commit comments

Comments
 (0)