Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decoration API #5

Closed
octref opened this issue Jan 23, 2019 · 11 comments · Fixed by #574
Closed

Decoration API #5

octref opened this issue Jan 23, 2019 · 11 comments · Fixed by #574

Comments

@octref
Copy link
Collaborator

octref commented Jan 23, 2019

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.

@octref
Copy link
Collaborator Author

octref commented Jan 30, 2019

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 if text is ambiguous.
  • Style:
    • i: italic
    • u: underline
    • http(s?)://example.org. If the style begins with http:// or https://, 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 😉

@EldoranDev
Copy link

Hi, are there currently any plans to actually implement this feature ?

@octref
Copy link
Collaborator Author

octref commented Feb 17, 2019

I wanted to gather some feedback before proceeding, because @atinux asked for this. But it seems he is busy. I'll ask again.

@wesbos
Copy link
Contributor

wesbos commented Apr 4, 2019

Would love to see this : )

@Ir1d
Copy link

Ir1d commented Feb 8, 2020

hi @octref , any plans to bring these features in? They look amazing

@orta
Copy link
Contributor

orta commented Feb 2, 2021

I wonder if we make the highlighting API be consistent with gatsby-remark-prismjs - https://github.com/andrewbranch/gatsby-remark-vscode#line-highlighting

@octref
Copy link
Collaborator Author

octref commented Apr 8, 2021

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[]
}

@jlkiri
Copy link

jlkiri commented Apr 30, 2021

@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)

@orta
Copy link
Contributor

orta commented Apr 30, 2021

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

@muenzpraeger
Copy link
Collaborator

Can't we potentially solve this via #380?

@antfu
Copy link
Member

antfu commented Jan 26, 2024

I would suggest the core should not have an opinion on how code-fence meta string should be handled. Instead, allowing transformers to provide their own handling

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants