Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/sachinraja/shiki-renderer-pdf

PDF renderer for Shiki
https://github.com/sachinraja/shiki-renderer-pdf

pdf renderer shiki syntax-highlighting

Last synced: 9 days ago
JSON representation

PDF renderer for Shiki

Awesome Lists containing this project

README

        

# shiki-renderer-pdf

PDF renderer for Shiki

[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)

## Installation

```sh
npm install shiki-renderer-pdf shiki pdf-lib
```

## Usage

```js
import fs from 'node:fs'
import shiki from 'shiki'
import { PDFDocument } from 'pdf-lib'
import { getPdfRenderer, hexToRgb } from 'shiki-renderer-pdf'
;(async () => {
const highlighter = await shiki.getHighlighter({
theme: 'nord',
})

const pdfRenderer = getPdfRenderer({
bg: hexToRgb('#2E3440'),
fontSize: 12,
lineNumbers: {
bg: hexToRgb('#151B27'),
text: hexToRgb('#fff'),
},
})

const code = fs.readFileSync('gen-pdf.js', 'utf-8')

const tokens = highlighter.codeToThemedTokens(code, 'js')
const pdfDocument = await PDFDocument.create()

await pdfRenderer.renderToPdf(tokens, pdfDocument)

fs.writeFileSync('gen-pdf.js.pdf', await pdfDocument.save(), 'binary')

console.log('done: gen-pdf.js.pdf')
})()
```

[Result](https://github.com/sachinraja/shiki-renderer-pdf/blob/main/examples/_readme.pdf)

Read more about what you can do with `pdfDocument` [here](https://pdf-lib.js.org/).

### Custom Fonts

This requires an extra install - `@pdf-lib/fontkit`.

Please note that the renderer works best with fixed width fonts (the default is Courier).

The renderer expects you to setup the `pdfDocument` before passing it. `await PDFDocument.create()` will be enough for most cases, but you may need to do more for features like custom fonts:

```js
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import fs from 'node:fs'
import shiki from 'shiki'
import { PDFDocument } from 'pdf-lib'
import fontkit from '@pdf-lib/fontkit'
import { renderToPdf, hexToRgb } from 'shiki-renderer-pdf'

const __dirname = path.dirname(fileURLToPath(import.meta.url))

;(async () => {
const highlighter = await shiki.getHighlighter({ theme: 'nord' })

const pdfDocument = await PDFDocument.create()
pdfDocument.registerFontkit(fontkit)

const fontRegular = await pdfDocument.embedFont(
fs.readFileSync(path.join(__dirname, 'UbuntuMono-Regular.ttf'))
)
const fontBold = await pdfDocument.embedFont(
fs.readFileSync(path.join(__dirname, 'UbuntuMono-Bold.ttf'))
)
const fontItalic = await pdfDocument.embedFont(
fs.readFileSync(path.join(__dirname, 'UbuntuMono-Italic.ttf'))
)

const code = fs.readFileSync('gen-pdf.js', 'utf8')
const tokens = highlighter.codeToThemedTokens(code, 'js')

await renderToPdf(tokens, pdfDocument, {
defaultColor: rgb(1, 1, 1),
bg: hexToRgb('#2E3440'),
lineNumbers: {
bg: hexToRgb('#151B27'),
text: hexToRgb('#fff'),
},
fontSize: 14,
fontMap: {
regular: fontRegular,
bold: fontBold,
italic: fontItalic,
},
})
})()
```

[Result](https://github.com/sachinraja/shiki-renderer-pdf/blob/main/examples/custom-font.pdf)

## Examples

See the [examples](https://github.com/sachinraja/shiki-renderer-pdf/tree/main/examples) for more on how the renderer can be used.