Skip to content
Merged
Changes from all commits
Commits
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
117 changes: 109 additions & 8 deletions automation/source-repo-templates/api-docs.dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,16 +176,117 @@ jobs:
} > "$OUTPUT_DIR/README.md"

- name: Prefix bare-filename intra-page links with ./
# Same pattern as the TypeScript template: Mintlify rejects
# bare-filename .md links as broken; prefixing with ./
# forces the resolver to treat them as relative paths.
# Mintlify rejects bare-filename .md links as broken;
# prefixing with ./ makes the resolver treat them as
# relative paths.
#
# Cannot use a plain sed regex here because DefaultDocumentation
# output diverges from the simple `[text](path.md)` form on two
# axes:
# 1. Link titles: `[text](path.md 'qualified.Type')` —
# sed regex expects `)` immediately after `.md`.
# 2. Method-overload pages have parens in the filename, e.g.
# `Foo.Bar(string,int).md` — character classes that exclude
# `)` reject these outright.
# A paren-balanced Python walker handles both shapes; sed cannot
# without per-character state.
working-directory: ${{ env.OUTPUT_DIR }}
run: |
find . -type f -name '*.md' -print0 | while IFS= read -r -d '' f; do
sed -E -i \
's|\]\(([A-Za-z0-9][^)/]*\.md(#[^)]*)?)\)|](./\1)|g' \
"$f"
done
python3 - <<'PY'
import pathlib

def is_external(u: str) -> bool:
return u.startswith((
"http://", "https://", "mailto:", "/", "#", "./", "../",
))

def transform_inline(line: str) -> str:
out, i, n = [], 0, len(line)
while i < n:
j = line.find("](", i)
Comment on lines +205 to +206
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current walker does not account for inline code spans (e.g., code-enclosed links). According to the general rules for Markdown post-processing, the logic should respect CommonMark inline code span rules—specifically by counting backtick run lengths—to avoid incorrectly modifying content inside code snippets. This ensures that examples or documentation about links are not inadvertently rewritten.

              while i < n:
                  if line[i] == chr(96):
                      r = 0
                      while i + r < n and line[i + r] == chr(96): r += 1
                      end = line.find(chr(96) * r, i + r)
                      if end != -1:
                          out.append(line[i:end + r])
                          i = end + r
                          continue
                  j = line.find("](", i)
References
  1. When processing Markdown/MDX files to escape curly braces for JSX compatibility, ensure the logic ignores content within inline code spans (backticks) to prevent breaking code snippets.

if j == -1:
out.append(line[i:])
break
out.append(line[i:j+2])
i = j + 2
# Walk URL: paren-balanced, ends at depth-0 ) or whitespace
depth, url_end, scan = 0, -1, i
while scan < n:
c = line[scan]
if c == "(":
depth += 1
elif c == ")":
if depth == 0:
url_end = scan
break
depth -= 1
elif c.isspace() and depth == 0:
url_end = scan
break
scan += 1
if url_end == -1:
out.append(line[i:])
break
url = line[i:url_end]
# Find matching outer ), tracking quote/depth for titles
scan = url_end
in_quote, depth = None, 0
while scan < n:
c = line[scan]
if in_quote:
if c == in_quote:
in_quote = None
scan += 1
continue
if c in ("'", '"'):
in_quote = c
scan += 1
continue
if c == "(":
depth += 1
elif c == ")":
if depth == 0:
break
depth -= 1
scan += 1
if scan >= n:
out.append(line[i:])
break
rest = line[url_end:scan]
url_no_anchor = url.partition("#")[0]
if url and not is_external(url) and url_no_anchor.endswith(".md"):
url = "./" + url
out.append(url)
out.append(rest)
out.append(")")
i = scan + 1
return "".join(out)

def transform(text: str) -> str:
out, in_fence = [], False
for raw in text.splitlines(keepends=True):
if raw.endswith("\r\n"):
line, eol = raw[:-2], "\r\n"
elif raw.endswith("\n"):
line, eol = raw[:-1], "\n"
else:
line, eol = raw, ""
s = line.lstrip()
if s.startswith("```") or s.startswith("~~~"):
in_fence = not in_fence
out.append(line); out.append(eol); continue
if in_fence:
out.append(line); out.append(eol); continue
out.append(transform_inline(line))
out.append(eol)
return "".join(out)

for p in pathlib.Path(".").rglob("*.md"):
orig = p.read_text(encoding="utf-8")
new = transform(orig)
if new != orig:
p.write_text(new, encoding="utf-8")
PY

- name: Escape curly braces outside code regions (MDX safety)
# Mintlify parses .md as MDX. Any literal `{ ... }` in prose
Expand Down
Loading