Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
a4a5f47
docs: design spec for configurable GitlabReadme TOC placement
ebuildy Jun 29, 2026
09b174c
docs: implementation plan for configurable GitlabReadme TOC placement
ebuildy Jun 29, 2026
24d21ef
Merge branch 'main' of github.com:ebuildy/docusaurus-plugin-gitlab
ebuildy Jun 30, 2026
dea1dd3
docs: design for GitLab include placeholders (webpack loader)
ebuildy Jun 30, 2026
0996446
docs: note remark auto-registration integration risk
ebuildy Jun 30, 2026
d9bcafa
docs: implementation plan for GitLab include placeholders
ebuildy Jun 30, 2026
5b08aca
docs: design spec for configurable GitlabReadme TOC placement
ebuildy Jun 29, 2026
df92b88
docs: implementation plan for configurable GitlabReadme TOC placement
ebuildy Jun 29, 2026
00587c9
feat: mode-aware TOC rendering in rehypeGitlabToc
ebuildy Jun 29, 2026
2bb031e
refactor: anchor inline TOC to first top-level heading
ebuildy Jun 29, 2026
c53c06e
feat: fetchReadme reads the toc attribute and returns sidebar entries
ebuildy Jun 29, 2026
aa691a1
refactor: align toc import extension and tighten cache-key test
ebuildy Jun 29, 2026
c716dbe
feat: pure TOC-item nesting and merge helpers
ebuildy Jun 29, 2026
3258404
feat: estree bridge to merge README headings into the page toc export
ebuildy Jun 29, 2026
a9b007d
refactor: bail out of toc round-trip on non-literal property values
ebuildy Jun 29, 2026
c94bb1a
feat: merge sidebar README headings into the page toc during transform
ebuildy Jun 29, 2026
40a728c
refactor: merge sidebar README TOCs in deterministic document order
ebuildy Jun 29, 2026
bfb4079
test: e2e coverage for GitlabReadme toc=sidebar
ebuildy Jun 29, 2026
a3455f2
docs: document the GitlabReadme toc attribute
ebuildy Jun 29, 2026
ea53bbd
test: e2e coverage for document-order sidebar TOC interleaving
ebuildy Jun 29, 2026
b717d4b
chore: example
ebuildy Jun 29, 2026
f78c45f
docs: design for GitLab include placeholders (webpack loader)
ebuildy Jun 30, 2026
e49927d
docs: note remark auto-registration integration risk
ebuildy Jun 30, 2026
9611e2a
docs: implementation plan for GitLab include placeholders
ebuildy Jun 30, 2026
4da6d10
docs: add examples/gitlab wiring to include-placeholders plan
ebuildy Jun 30, 2026
8e32fc3
refactor: extract buildContext into src/gitlab/context.ts
ebuildy Jun 30, 2026
46887fb
refactor: extract line-range and language helpers into src/gitlab/cod…
ebuildy Jun 30, 2026
bcbd452
feat: add raw-source fetchers for include placeholders
ebuildy Jun 30, 2026
5a2b909
feat: add include placeholder grammar parser
ebuildy Jun 30, 2026
0339858
feat: add frontmatter strip and code-range detection for includes
ebuildy Jun 30, 2026
09cd1d2
refactor: use typed mdast Root in codeRanges instead of casts
ebuildy Jun 30, 2026
02e151f
feat: add prose transform (assets, links, MDX escape) for includes
ebuildy Jun 30, 2026
83e3d0a
fix: match whitespace (not just space) before img src in include rewrite
ebuildy Jun 30, 2026
f7cbbfa
feat: add renderSource combining code-aware markdown + code-fence modes
ebuildy Jun 30, 2026
3e677d5
feat: add transformIncludes orchestration for placeholders
ebuildy Jun 30, 2026
1ba6b42
fix: single-pass position-based include substitution
ebuildy Jun 30, 2026
5f6badf
feat: add include context singleton and webpack loader
ebuildy Jun 30, 2026
fec4d7e
feat: add Docusaurus plugin wiring the include loader and theme css
ebuildy Jun 30, 2026
eded5ee
docs: explain enforce:pre requirement in gitlab plugin
ebuildy Jun 30, 2026
a4b1ea6
build: export ./plugin and guard the plugin default export
ebuildy Jun 30, 2026
a2e34f2
test: e2e coverage for include placeholders via native pipeline
ebuildy Jun 30, 2026
5a540e2
docs: document GitLab include placeholders
ebuildy Jun 30, 2026
c2825fe
feat: add outProcessors + built-in fixAutolinks for include markdown
ebuildy Jun 30, 2026
9ede881
feat: add built-in fixVoidTags for MDX-unsafe void elements in includes
ebuildy Jun 30, 2026
321cf30
feat: add opt-in stripToc to remove redundant Table of Contents from …
ebuildy Jun 30, 2026
a2fc976
feat: add built-in fixInlineStyles for HTML style attributes in includes
ebuildy Jun 30, 2026
f624a99
feat: add built-in convertAlerts for GitLab alerts -> Docusaurus admo…
ebuildy Jun 30, 2026
95d4c80
fix: avoid polynomial ReDoS in convertAlerts newline trim
ebuildy Jul 1, 2026
369f313
chore: edit gitlab example
ebuildy Jul 1, 2026
ebba1bc
fix: don't statically resolve dist/ in packaging test (breaks CI type…
ebuildy Jul 1, 2026
9c99dbb
chore: merge main
ebuildy Jul 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
# Guard: refuse to create a commit that wouldn't be signed.
# A pre-commit hook runs before the commit (and its signature) exist, so it can't
# verify a signature — but it can ensure signing is configured, so the commit that
# git is about to create will be signed. (True enforcement of *pushed* history is
# GitHub branch protection → "Require signed commits".)
if [ "$(git config --get commit.gpgsign)" != "true" ] || [ -z "$(git config --get user.signingkey)" ]; then
echo "✖ Commit signing is not configured — refusing to create an unsigned commit." >&2
echo " Configure it with:" >&2
echo " git config --global commit.gpgsign true" >&2
echo " git config --global user.signingkey <your-key>" >&2
exit 1
fi

npx lint-staged
116 changes: 116 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,116 @@ syntax-highlighted code block (via `prism-react-renderer`).
| `ref` | string | default branch | Branch, tag, or commit SHA |
| `lines` | string | whole file | Line range for code files, e.g. `"10-25"` (1-based, inclusive) |

## Include placeholders

Besides the JSX components, you can embed GitLab **markdown** and **files** with
text placeholders that are substituted **before** MDX parsing — so the content
flows through Docusaurus's own pipeline (table of contents, emoji, admonitions,
heading anchors, Prism highlighting, internal links) exactly as if you had written
it by hand.

### Setup

Register the plugin once. This is separate from the remark plugin in
[Setup](#setup) above — keep that for the JSX components:

```ts
// docusaurus.config.ts (ESM)
import gitlabPlugin from "@ebuildy/docusaurus-plugin-gitlab";

export default {
plugins: [
[
gitlabPlugin,
{
host: "https://gitlab.com",
token: process.env.GITLAB_TOKEN, // optional for public projects
},
],
],
// ...your presets, including remarkGitlab for the JSX components...
};
```

The plugin also contributes `theme.css` automatically (via `getClientModules`),
so the component/include styles load without a separate `customCss` entry.

### Syntax

| Placeholder | Effect |
|---|---|
| `{@includeGitlabReadme: group/sub/project}` | Inline the project README (default branch) |
| `{@includeGitlabReadme: ref@group/sub/project}` | …at a branch, tag, or commit SHA |
| `{@includeGitlabFile: group/sub/project/-/path/file.md}` | Inline a markdown file as markdown |
| `{@includeGitlabFile: ref@group/sub/project/-/src/app.ts#L10-25}` | Inline a code file as a highlighted block (optional line range) |

- The project path and the file path are separated by `/-/` — the same separator
GitLab uses in its URLs — which keeps nested subgroups unambiguous.
- A leading `ref@` pins the content to a branch, tag, or commit SHA.
- `{@includeGitlabFile}` decides by extension: `.md`/`.mdx`/`.markdown` are inlined
as markdown; everything else becomes a fenced, syntax-highlighted code block, with
an optional `#Lstart-end` line range (1-based, inclusive).
- Images are downloaded and localized, and repo-relative links are rewritten to
absolute GitLab URLs — same as `<GitlabReadme>`.
- Because the content becomes part of your page's markdown source, MDX-significant
characters in the remote content are escaped so a stray `{` or `<` can't break your
build. Code blocks are left verbatim.

> **Placeholders vs. components:** reach for the placeholders when you want GitLab
> markdown to render through Docusaurus's native pipeline (TOC, emoji, admonitions,
> highlighting). Reach for `<GitlabReadme>` / `<GitlabFile>` when you want a
> self-contained, pre-rendered HTML block. Both can coexist in the same site.

### Post-processing the generated markdown

GitLab markdown sometimes uses constructs that are valid CommonMark but **not**
valid MDX. Two built-in processors fix the common ones (both **on by default**):

- **`fixAutolinks`** — rewrites CommonMark autolinks like `<https://example.com>`
or `<contact@example.com>` (which MDX reads as JSX tags) into normal markdown
links (`[contact@example.com](mailto:contact@example.com)`). Disable with
`fixAutolinks: false`.
- **`fixVoidTags`** — self-closes HTML void elements like `<br>` or `<img …>`
(which MDX rejects with _"Expected a closing tag for `<br>`"_) into `<br/>`.
Disable with `fixVoidTags: false`.
- **`fixInlineStyles`** — converts HTML string `style="…"` attributes (which MDX/React
reject with _"The `style` prop expects a mapping … not a string"_) into JSX style
objects: `style="color: red"` → `style={{ color: "red" }}`. Disable with
`fixInlineStyles: false`.
- **`convertAlerts`** — translates GitLab/GitHub alert blockquotes into native
Docusaurus admonitions: `> [!note]` → `:::note`, `> [!tip]` → `:::tip`,
`> [!important]` → `:::info`, `> [!warning]` → `:::warning`, `> [!caution]` →
`:::danger`. Disable with `convertAlerts: false`.

Optionally, **`stripToc`** (default **off**) removes a README's own "Table of
Contents" section (the heading plus its list, up to the next heading of the same or
higher level) and any `[[_TOC_]]` marker — Docusaurus already renders a TOC in the
right sidebar. Enable with `stripToc: true`.

Add your own transforms with `outProcessors` — each receives the generated markdown
of a markdown include (after the built-in fixes) and returns the new markdown:

```ts
import gitlabPlugin, { fixAutolinks } from "@ebuildy/docusaurus-plugin-gitlab";

plugins: [
[
gitlabPlugin,
{
host: "https://gitlab.com",
// fixAutolinks: false, // opt out of the built-in
outProcessors: [
(md) => md.replace(/:tada:/g, "🎉"), // runs after fixAutolinks
],
},
],
];
```

`outProcessors` receive the whole generated markdown string (sync or async) and run
only on markdown includes (not on code-file fences). Fenced/inline code is the
caller's responsibility to preserve; the built-in `fixAutolinks` already skips it.

## Plugin options

| Option | Type | Default | Description |
Expand All @@ -201,6 +311,12 @@ syntax-highlighted code block (via `prism-react-renderer`).
| `cache` | `{ ttl: number }` \| `false` | `{ ttl: 3600 }` | On-disk cache TTL (seconds), or `false` to disable |
| `assetDir` | string | `static/gitlab-assets` | Where README images/badges are downloaded |
| `assetBaseUrl` | string | `/gitlab-assets` | URL path the downloaded assets are served from |
| `fixAutolinks` | boolean | `true` | Rewrite CommonMark autolinks in included markdown to MDX-safe links (include placeholders only) |
| `fixVoidTags` | boolean | `true` | Self-close HTML void elements (`<br>` → `<br/>`) in included markdown (include placeholders only) |
| `fixInlineStyles` | boolean | `true` | Convert HTML string `style="…"` attributes to JSX style objects in included markdown |
| `convertAlerts` | boolean | `true` | Translate GitLab alert blockquotes (`> [!note]`) to Docusaurus admonitions (`:::note`) in included markdown |
| `stripToc` | boolean | `false` | Remove a redundant "Table of Contents" section (and `[[_TOC_]]` marker) from included markdown |
| `outProcessors` | `Array<(md: string) => string \| Promise<string>>` | `[]` | Extra post-processors for included markdown, run after the built-in fixes |

The token is read at build time only. Provide it via an environment variable
(`GITLAB_TOKEN`) — never commit it.
Expand Down
Loading