Repository: slidevjs/slidev
File: packages/slidev/node/export.ts (TypeScript)

Code before:
  async function genPagePng() {
    await go('print')
    await fs.emptyDir(output)
    const slides = await page.locator('.slide-container')
    const count = await slides.count()
    for (let i = 0; i < count; i++) {
      progress.update(i + 1)
      let id = (await slides.nth(i).getAttribute('id')) || ''
      id = withClicks ? id : id.split('-')[0]
      const buffer = await slides.nth(i).screenshot()
      await fs.writeFile(path.join(output, `${id}.png`), buffer)
    }
  }

  async function genPageMd(slides: SlideInfo[]) {
    const files = await fs.readdir(output)
    const mds: string[] = files.map((file, i, files) => {
      const slideIndex = getSlideIndex(file)
      const mdImg = `![${slides[slideIndex]?.title}](./${
        path.join(output, file)
      })\n\n`
      if (
        (i + 1 === files.length
          || getSlideIndex(files[i + 1]) !== slideIndex)
        && slides[slideIndex]?.note
      )
        return `${mdImg}${slides[slideIndex]?.note}\n\n`

      return mdImg
    })

    if (!output.endsWith('.md'))
      output = `${output}.md`

    await fs.writeFile(output, mds.join(''))
  }

  function getSlideIndex(file: string): number {
    const slideId = file.substring(0, file.indexOf('.')).split('-')[0]
    return Number(slideId) - 1
  }

  progress.start(pages.length)

  if (format === 'pdf') {
    await genPagePdf()
  }
  else if (format === 'png') {
    await genPagePng()
  }
  else if (format === 'md') {

Review comment (suggestion):
Don't you want to manage the "deepness" of title ?
In that case you may also be interested in the `level` property.

Also please heck the following properties (`rawTree`, `treeWithActiveStatuses` and `tree`) from here https://github.com/slidevjs/slidev/blob/main/packages/client/logic/nav.ts#L79-L86
I think It would better to use the same logic and thus the same functions than the ones used for the `<Toc>` component
And then having a dedicated renderer for the outline.

Code after:

  const pages: number[] = parseRangeString(total, range)

  const { chromium } = await import('playwright-chromium')
  const browser = await chromium.launch({
    executablePath,
  })
  const context = await browser.newContext({
    viewport: {
      width,
      // Calculate height for every slides to be in the viewport to trigger the rendering of iframes (twitter, youtube...)
      height: height * pages.length,
    },
    deviceScaleFactor: 1,
  })
  const page = await context.newPage()
  const progress = createSlidevProgress(true)

  async function go(no: number | string, clicks?: string) {
    const path = `${no}?print${withClicks ? '=clicks' : ''}${clicks ? `&clicks=${clicks}` : ''}`
    const url = routerMode === 'hash'
      ? `http://localhost:${port}${base}#${path}`
      : `http://localhost:${port}${base}${path}`
    await page.goto(url, {
      waitUntil: 'networkidle',
      timeout,
    })
    await page.waitForLoadState('networkidle')
    await page.emulateMedia({ colorScheme: dark ? 'dark' : 'light', media: 'screen' })
    // Check for "data-waitfor" attribute and wait for given element to be loaded
    const elements = await page.locator('[data-waitfor]')
    const count = await elements.count()
    for (let index = 0; index < count; index++) {
      const element = await elements.nth(index)
      const attribute = await element.getAttribute('data-waitfor')
      if (attribute)
        await element.locator(attribute).waitFor()
    }
    // Wait for frames to load
    const frames = await page.frames()
    await Promise.all(frames.map(frame => frame.waitForLoadState()))
  }

  async function genPagePdf() {
    if (!output.endsWith('.pdf'))
      output = `${output}.pdf`
    await go('print')
    await page.pdf({
      path: output,
      width,
      height,