shiki
shiki copied to clipboard
Decoration API
Offer a decoration API that allows marking specific ranges with:
- bg color
- font settings
- text decorations
- links
This is easy to use programmatically. The hard problem is how should the original Markdown look like.
Use cases. Applying these effects for a list of ranges. No range that spans multi line.
- Use italic for a specific range
- Use underline for a specific range
- Mark a range as link
- Give a range a background color
I'm thinking along these lines:
```js [[line | text or range | style]]
console.log('shiki');
```
- Line: A 0-based line number
- Text: The text to match. For example,
log
. - Range: Start-End. For example,
log
is 8-11. Use this iftext
is ambiguous. - Style:
-
i
: italic -
u
: underline -
http(s?)://example.org
. If the style begins withhttp://
orhttps://
, apply link effect, which shows underline on hover and open URL in new tab if clicked -
#aabbcc
. If the style begins with#
, parse it as color.
-
So it could look like:
```js [[0 | log | #ff7B08], [0 | 7-8 | u], [0 | 'shiki' | https://shiki.matsu.io/]]
console.log('shiki');
```
What do you think, @Atinux?
Also @ulivz I'd appreciate it a lot if you can give some feedback since you are leading Vuepress development now. Think Shiki is already better than highlightjs / prism and I'd want to make it a good highlighter for Vuepress too 😉
Hi, are there currently any plans to actually implement this feature ?
I wanted to gather some feedback before proceeding, because @Atinux asked for this. But it seems he is busy. I'll ask again.
Would love to see this : )
hi @octref , any plans to bring these features in? They look amazing
I wonder if we make the highlighting API be consistent with gatsby-remark-prismjs - https://github.com/andrewbranch/gatsby-remark-vscode#line-highlighting
Thinking about something like this API below. How each markdown parser would like to integrate with the API is up to them. @EldoranDev @jlkiri @stefanprobst @Enter-tainer I see each of you have written a remark + shiki plugin — would the API below enable you do what https://github.com/andrewbranch/gatsby-remark-vscode is doing?
interface BaseLineDecoration {
/**
* The line to apply decoration to.
* Line is 0 based.
*/
line: number
}
/**
* Render line with specified background color
*/
export interface LineBgColorDecoration extends BaseLineDecoration {
/**
* 3/6/8 digit hex code like `#fff` or color like `cadetblue`.
*/
bgColor: string
}
/**
* Render line with line number
*/
export interface LineNumberDecoration extends BaseLineDecoration {
/**
* Line number such as `1` or `01`
*/
lineNumber: string
}
/**
* A decoration applied to a line
*/
export type LineDecoration = LineBgColorDecoration | LineNumberDecoration
interface BaseTokensDecoration {
/**
* The range that includes all tokens. Only tokens that fully
* fall into the range will be matched.
* Multi-line is not supported.
* Line is 0 based.
* `startIndex` is inclusive and `endIndex` not inclusive.
*/
range: {
line: number
startIndex: number
endIndex: number
}
}
/**
* Render matched tokens with `<a>` tag
*
* Cannot overlap with other link decorations.
*/
export interface TokensLinkDecoration extends BaseTokensDecoration {
/**
* `href` value of the link
*/
link: string
}
/**
* Render matched tokens with specified font style
*/
export interface TokensFontStyleDecoration extends BaseTokensDecoration {
/**
* The font style
*/
fontStyle: FontStyle
}
/**
* Render matched tokens with specified background color
*/
export interface TokensBgColorDecoration extends BaseTokensDecoration {
/**
* 3/6/8 digit hex code like `#fff` or color like `cadetblue`.
*/
bgColor: string
}
/**
* A decoration applied to tokens in the matched range
*/
export type TokensDecoration =
| TokensLinkDecoration
| TokensFontStyleDecoration
| TokensBgColorDecoration
export interface HtmlRendererOptions {
langId?: string
fg?: string
bg?: string
/**
* Decorations applied to lines
*/
lineDecorations?: LineDecoration[]
/**
* Decorations applied to tokens
*/
tokensDecorations?: TokensDecoration[]
}
@octref I haven't touched remark
for a long time. If there is a way to get lines I want to highlight from remark
, then yes, I would use that information for each code block and pass it to something like highlighter.codeToHtml
(not to getHighlighter
because it would then apply to every code block)
For shiki-twoslash, I ended up re-using @andrewbranch's code-fencing syntax from gatsby-vscode-remark
https://github.com/microsoft/TypeScript-website/blob/54415373f08ef8d707c0dca799b7a454d56ec754/packages/shiki-twoslash/src/parseCodeFenceInfo.ts#L1