Repository: slidevjs/slidev
File: packages/parser/src/fs.ts (TypeScript)

Code before:

  const preparserExtensions: SlidevPreparserExtension[] = []
  const data = await parse(markdown, filepath, themeMeta, [], async (headmatter, exts: SlidevPreparserExtension[], filepath: string | undefined) => {
    preparserExtensions.splice(
      0,
      preparserExtensions.length,
      ...exts,
      ...preparserExtensionLoader ? await preparserExtensionLoader(headmatter, filepath) : [],
    )
    return preparserExtensions
  })

  const entries = new Set([
    filepath,
  ])

  for (let iSlide = 0; iSlide < data.slides.length;) {
    const baseSlide = data.slides[iSlide]
    if (!baseSlide.frontmatter.src) {
      iSlide++

      baseSlide.content = baseSlide.content.replaceAll(
        /^```(\w+?)\s*\[([\s\S]+?)\]([\s\S]*?)\n+^```/mg,
        (full, lang = '', external: string, rest: string) => {
          const [externalPath, externalRangeStr] = external.split(':').map(i => i.trim())
          const sourcePath = resolve(dir, 'snippets', externalPath)
          entries.add(sourcePath)
          let source: string
          if (!existsSync(sourcePath)) {
            lang = 'plaintext'
            source = `File not found: ${sourcePath}`
          }
          source = readFileSync(sourcePath, 'utf-8')
          if (externalRangeStr) {
            const lines = source.split(/\r?\n/g)
            source = parseRangeString(lines.length, externalRangeStr).map(i => lines[i - 1]).join('\n')
          }
          return `\`\`\`${lang} ${rest}\n${source}\n\`\`\``
        },
      )

      continue
    }

    data.slides.splice(iSlide, 1)

    if (baseSlide.frontmatter.hide)
      continue

    const srcExpression = baseSlide.frontmatter.src
    let path

Review comment (suggestion):
I am not sure should the snippets be put in `${dir}/snippets/${snippetName}` or somewhere else, or should use `userRoot` instead of `dir`.

Code after:

  const preparserExtensions: SlidevPreparserExtension[] = []
  const data = await parse(markdown, filepath, themeMeta, [], async (headmatter, exts: SlidevPreparserExtension[], filepath: string | undefined) => {
    preparserExtensions.splice(
      0,
      preparserExtensions.length,
      ...exts,
      ...preparserExtensionLoader ? await preparserExtensionLoader(headmatter, filepath) : [],
    )
    return preparserExtensions
  })

  const entries = new Set([
    filepath,
  ])

  for (let iSlide = 0; iSlide < data.slides.length;) {
    const baseSlide = data.slides[iSlide]
    if (!baseSlide.frontmatter.src) {
      iSlide++
      continue
    }

    data.slides.splice(iSlide, 1)

    if (baseSlide.frontmatter.hide)
      continue

    const srcExpression = baseSlide.frontmatter.src
    let path
    if (srcExpression.startsWith('/'))
      path = resolve(dir, srcExpression.substring(1))
    else if (baseSlide.source?.filepath)
      path = resolve(dirname(baseSlide.source.filepath), srcExpression)
    else
      path = resolve(dir, srcExpression)

    const raw = await fs.readFile(path, 'utf-8')
    const subSlides = await parse(raw, path, themeMeta, preparserExtensions)

    for (const [offset, subSlide] of subSlides.slides.entries()) {
      const slide: SlideInfo = { ...baseSlide }

      slide.source = {
        filepath: path,
        ...subSlide,
      }

      if (offset === 0 && !baseSlide.frontmatter.srcSequence) {
        slide.inline = { ...baseSlide }
        delete slide.inline.frontmatter.src