Skip to content

Commit ab50a77

Browse files
committed
Fix title being parsed as highlight text in code blocks, display titles instead of language name when title present
1 parent cce65cd commit ab50a77

5 files changed

Lines changed: 46 additions & 17 deletions

File tree

‎_TODO.md‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -147,25 +147,19 @@ See comp images in Breadcrumbs component directory
147147

148148
## Code Block Problems
149149

150-
- Inline code blocks are not wrapping. They're breaking to a new line. An example is in the "Scenario: CRD Sync Order Problem" section of `argocd-sync-failures-gitops-debugging-troubleshooting#specific-failure-scenarios`.
151-
152150
- I aliased 'promql' to 'go'. When a code fence using the alias is rendered with the language set to 'promql', it shows as 'go' incorrectly because of the alias. Also we need custom handling for all language names that are displayed: html should be uppercase, typescript as TypeScript, etc. Also we don't want all aliased names to show the alias - for example using the aliases 'ts', 'js', and 'md' would be better to show the full language names.
153151

154-
- We're getting random highlighting in code blocks, like the word "app" in teh first code block in `http://localhost:4321/deep-dive/argocd-sync-failures-gitops-debugging-troubleshooting#sync-waves-and-resource-ordering`
152+
- We're getting random highlighting in code blocks, like the word "app" in the first code block in `argocd-sync-failures-gitops-debugging-troubleshooting/pdf.astro`. If the problem is not straight forward, let's discuss the fix first. Here's outerhtml of the block from chrome inspector:
155153

156154
- The "go" language code block in `src/content/articles/api-versioning-deprecation-sunset-headers-migration/index.mdx` is not being combined with the "typescript", "python", and "ruby" tabbed code block. Same with "python" block in "### Admission Control Strategies" section of `src/content/articles/backpressure-load-shedding-admission-control-overload/index.mdx`, plus the line numbering is weird in the code block.
157155

158-
- The title for a code block with yaml as the language type in "Sync wave annotations controlling resource application order" section of `src/content/articles/argocd-sync-failures-gitops-debugging-troubleshooting/index.mdx` is not displaying, it's showing the YAML language tag instead of the title. Also, the word "app" is being highlighted for some reason in this code block.
159-
160-
- Code block formatting for 'text' language is very plain.
161-
162156
- The "❌" symbol is not showing in sql code block, it's rendering as a plain "X". But "✅" renders okay. `src/content/articles/database-schema-migrations-continuous-deployment-zero-downtime/index.mdx`
163157

164158
- Language "haproxy" is not highlighting Shiki, need to adjust allowed languages in config
165159

166160
- add "cel" language to code blocks
167161

168-
- The code language is in teh tab order and getting focus-visible
162+
- The code language is in the tab order and getting focus-visible
169163

170164
## Callout Issues
171165

‎src/components/Code/CodeTabs/client/index.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ function getTabLabel(pre: HTMLPreElement): string | null {
4242
const explicit = pre.getAttribute('data-code-tabs-tab')
4343
if (explicit && explicit.trim()) return explicit.trim()
4444

45+
// Use title from code fence meta (e.g. title="otel-tail-sampling.yaml")
46+
// in place of the language label when present.
47+
const codeTitle = pre.getAttribute('data-code-title')
48+
if (codeTitle && codeTitle.trim()) return codeTitle.trim()
49+
4550
const language = pre.getAttribute('data-language')
4651
if (!language || !language.trim()) return null
4752
if (EXCLUDED_SINGLE_TAB_LANGUAGES.has(language.trim().toLowerCase())) return null

‎src/lib/config/markdown.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,9 +445,9 @@ export const markdownConfig: Partial<MdxOptions> = {
445445
theme: shikiConfigOptions.theme,
446446
themeRegistrations: shikiConfigOptions.themeRegistrations,
447447
langAlias: shikiConfigOptions.langAlias,
448-
wrap: true,
448+
wrap: shikiConfigOptions.wrap,
449449
transformers: shikiTransformers,
450-
excludeLangs: ['text', 'mermaid', 'math'],
450+
excludeLangs: shikiConfigOptions.excludeLangs,
451451
},
452452
],
453453
/**

‎src/lib/config/shiki.ts‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ import {
88
transformerNotationErrorLevel,
99
} from '@shikijs/transformers'
1010

11+
export const langAlias = {
12+
js: 'javascript',
13+
ts: 'typescript',
14+
md: 'markdown',
15+
promql: 'go',
16+
}
17+
1118
const insMetaRegex = /(?:^|\s)ins=\{([^}]+)\}/
1219
const delMetaRegex = /(?:^|\s)del=\{([^}]+)\}/
1320
const errorMetaRegex = /(?:^|\s)error=\{([^}]+)\}/
@@ -117,11 +124,7 @@ export const shikiConfigOptions = {
117124
fontStyle: true,
118125
}),
119126
],
120-
langAlias: {
121-
js: 'javascript',
122-
ts: 'typescript',
123-
md: 'markdown',
124-
promql: 'go',
125-
},
127+
excludeLangs: ['mermaid', 'math'],
128+
langAlias,
126129
wrap: true,
127130
} as const

‎src/lib/markdown/plugins/rehype-shiki/index.ts‎

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,23 @@ function extractPre(highlighted: Root | Element): Element | null {
209209
return null
210210
}
211211

212+
/**
213+
* Extract and strip `title="..."` (or `title='...'` or `title=word`) from a
214+
* code-fence meta string. The title is a display-only concern and must be
215+
* removed before the meta reaches Shiki transformers—otherwise path separators
216+
* like `/app/` get misinterpreted as `/word/` highlight patterns by
217+
* `transformerMetaWordHighlight`.
218+
*/
219+
function extractTitle(meta: string): { title: string | undefined; cleaned: string } {
220+
const titleRegex = /\btitle=(?:"([^"]*)"|'([^']*)'|(\S+))/
221+
const match = titleRegex.exec(meta)
222+
if (!match) return { title: undefined, cleaned: meta }
223+
224+
const title = (match[1] ?? match[2] ?? match[3] ?? '').trim() || undefined
225+
const cleaned = meta.replace(match[0], '').trim()
226+
return { title, cleaned }
227+
}
228+
212229
const DEFAULT_EXCLUDED_LANGS = ['mermaid', 'math']
213230

214231
const rehypeShiki: Plugin<[RehypeShikiOptions], Root> = (options: RehypeShikiOptions) => {
@@ -254,6 +271,7 @@ const rehypeShiki: Plugin<[RehypeShikiOptions], Root> = (options: RehypeShikiOpt
254271
lang: string
255272
codeText: string
256273
metaRaw: string | undefined
274+
title: string | undefined
257275
}> = []
258276

259277
visit(
@@ -283,13 +301,18 @@ const rehypeShiki: Plugin<[RehypeShikiOptions], Root> = (options: RehypeShikiOpt
283301

284302
const metaRaw = typeof metaValue === 'string' && metaValue.trim() ? metaValue.trim() : undefined
285303

304+
const { title, cleaned: metaForShiki } = metaRaw
305+
? extractTitle(metaRaw)
306+
: { title: undefined, cleaned: undefined }
307+
286308
replacements.push({
287309
parent,
288310
index,
289311
original: node,
290312
lang,
291313
codeText: stripTrailingFenceNewline(codeText),
292-
metaRaw,
314+
metaRaw: metaForShiki || undefined,
315+
title,
293316
})
294317
}
295318
)
@@ -355,6 +378,10 @@ const rehypeShiki: Plugin<[RehypeShikiOptions], Root> = (options: RehypeShikiOpt
355378

356379
highlightedPre.properties['data-language'] = replacement.lang
357380

381+
if (replacement.title) {
382+
highlightedPre.properties['data-code-title'] = replacement.title
383+
}
384+
358385
highlightedPre.properties['className'] = mergeClassNames(
359386
highlightedPre.properties['className'],
360387
[

0 commit comments

Comments
 (0)