[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_size = 2\nindent_style = space\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n"
  },
  {
    "path": ".eslintignore",
    "content": ".next\ncoverage\nlib\nnode_modules\nout\n"
  },
  {
    "path": ".eslintrc.js",
    "content": "const path = require('path')\nconst { workspaces } = require('./package.json')\n\nmodule.exports = {\n  root: true,\n  env: {\n    browser: true,\n    node: true,\n    es6: true,\n  },\n  extends: ['eslint:recommended', 'plugin:import/recommended', 'prettier'],\n  rules: {\n    // eslint-plugin-import cannot parse exports field in package.json.\n    // https://github.com/import-js/eslint-plugin-import/issues/1810\n    'import/no-unresolved': ['error', { ignore: ['^swiper'] }],\n    'import/order': ['error', { alphabetize: { order: 'asc' } }],\n  },\n  overrides: [\n    {\n      files: ['**/*.ts', '**/*.tsx'],\n      parser: '@typescript-eslint/parser',\n      plugins: ['@typescript-eslint'],\n      extends: [\n        'plugin:@typescript-eslint/recommended',\n        'plugin:import/typescript',\n        'prettier',\n      ],\n      rules: {\n        '@typescript-eslint/no-explicit-any': 'off',\n        '@typescript-eslint/explicit-function-return-type': 'off',\n        '@typescript-eslint/explicit-module-boundary-types': 'off',\n      },\n      settings: {\n        'import/resolver': {\n          typescript: {\n            project: ['', ...workspaces].map((dir) =>\n              path.join(dir, 'tsconfig.json')\n            ),\n          },\n        },\n      },\n    },\n  ],\n}\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\n\nupdates:\n  - package-ecosystem: npm\n    directory: '/'\n    reviewers:\n      - 'marp-team/maintainers'\n    schedule:\n      interval: daily\n    allow:\n      - dependency-name: '@marp-team/*'\n    versioning-strategy: increase\n\n  - package-ecosystem: github-actions\n    directory: '/'\n    reviewers:\n      - 'marp-team/maintainers'\n    schedule:\n      interval: weekly\n    # versioning-strategy: increase-if-necessary\n    open-pull-requests-limit: 0 # Dependabot does not allow relaxed versioning :(\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: Test\n\non:\n  - pull_request\n  - push\n\nenv:\n  CACHE_PREFIX: v1\n  YARN_VERSION: '^1.22.4'\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n\n      - uses: actions/setup-node@v3\n        with:\n          node-version-file: '.nvmrc'\n\n      - name: Install yarn\n        id: yarn\n        run: |\n          cd $HOME && yarn policies set-version $YARN_VERSION\n          echo \"::set-output name=cache_dir::$(yarn cache dir)\"\n\n      - uses: actions/cache@v3\n        with:\n          path: ${{ steps.yarn.outputs.cache_dir }}\n          key: yarn_cache-${{ env.CACHE_PREFIX }}-${{ hashFiles('**/yarn.lock') }}\n          restore-keys: yarn_cache-${{ env.CACHE_PREFIX }}-\n\n      - run: yarn install\n      - run: yarn audit\n\n      - name: Prettier formatting\n        run: yarn check:format\n\n      - name: ESLint\n        run: yarn lint:js\n\n      - name: TypeScript type checking\n        run: yarn check:ts\n"
  },
  {
    "path": ".gitignore",
    "content": "# Created by https://www.toptal.com/developers/gitignore/api/vim,node,linux,emacs,macos,windows,intellij,sublimetext,visualstudiocode\n# Edit at https://www.toptal.com/developers/gitignore?templates=vim,node,linux,emacs,macos,windows,intellij,sublimetext,visualstudiocode\n\n### Emacs ###\n# -*- mode: gitignore; -*-\n*~\n\\#*\\#\n/.emacs.desktop\n/.emacs.desktop.lock\n*.elc\nauto-save-list\ntramp\n.\\#*\n\n# Org-mode\n.org-id-locations\n*_archive\n\n# flymake-mode\n*_flymake.*\n\n# eshell files\n/eshell/history\n/eshell/lastdir\n\n# elpa packages\n/elpa/\n\n# reftex files\n*.rel\n\n# AUCTeX auto folder\n/auto/\n\n# cask packages\n.cask/\ndist/\n\n# Flycheck\nflycheck_*.el\n\n# server auth directory\n/server/\n\n# projectiles files\n.projectile\n\n# directory configuration\n.dir-locals.el\n\n# network security\n/network-security.data\n\n\n### Intellij ###\n# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider\n# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839\n\n# User-specific stuff\n.idea/**/workspace.xml\n.idea/**/tasks.xml\n.idea/**/usage.statistics.xml\n.idea/**/dictionaries\n.idea/**/shelf\n\n# AWS User-specific\n.idea/**/aws.xml\n\n# Generated files\n.idea/**/contentModel.xml\n\n# Sensitive or high-churn files\n.idea/**/dataSources/\n.idea/**/dataSources.ids\n.idea/**/dataSources.local.xml\n.idea/**/sqlDataSources.xml\n.idea/**/dynamic.xml\n.idea/**/uiDesigner.xml\n.idea/**/dbnavigator.xml\n\n# Gradle\n.idea/**/gradle.xml\n.idea/**/libraries\n\n# Gradle and Maven with auto-import\n# When using Gradle or Maven with auto-import, you should exclude module files,\n# since they will be recreated, and may cause churn.  Uncomment if using\n# auto-import.\n# .idea/artifacts\n# .idea/compiler.xml\n# .idea/jarRepositories.xml\n# .idea/modules.xml\n# .idea/*.iml\n# .idea/modules\n# *.iml\n# *.ipr\n\n# CMake\ncmake-build-*/\n\n# Mongo Explorer plugin\n.idea/**/mongoSettings.xml\n\n# File-based project format\n*.iws\n\n# IntelliJ\nout/\n\n# mpeltonen/sbt-idea plugin\n.idea_modules/\n\n# JIRA plugin\natlassian-ide-plugin.xml\n\n# Cursive Clojure plugin\n.idea/replstate.xml\n\n# SonarLint plugin\n.idea/sonarlint/\n\n# Crashlytics plugin (for Android Studio and IntelliJ)\ncom_crashlytics_export_strings.xml\ncrashlytics.properties\ncrashlytics-build.properties\nfabric.properties\n\n# Editor-based Rest Client\n.idea/httpRequests\n\n# Android studio 3.1+ serialized cache file\n.idea/caches/build_file_checksums.ser\n\n### Intellij Patch ###\n# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721\n\n# *.iml\n# modules.xml\n# .idea/misc.xml\n# *.ipr\n\n# Sonarlint plugin\n# https://plugins.jetbrains.com/plugin/7973-sonarlint\n.idea/**/sonarlint/\n\n# SonarQube Plugin\n# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin\n.idea/**/sonarIssues.xml\n\n# Markdown Navigator plugin\n# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced\n.idea/**/markdown-navigator.xml\n.idea/**/markdown-navigator-enh.xml\n.idea/**/markdown-navigator/\n\n# Cache file creation bug\n# See https://youtrack.jetbrains.com/issue/JBR-2257\n.idea/$CACHE_FILE$\n\n# CodeStream plugin\n# https://plugins.jetbrains.com/plugin/12206-codestream\n.idea/codestream.xml\n\n# Azure Toolkit for IntelliJ plugin\n# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij\n.idea/**/azureSettings.xml\n\n### Linux ###\n\n# temporary files which can be created if a process still has a handle open of a deleted file\n.fuse_hidden*\n\n# KDE directory preferences\n.directory\n\n# Linux trash folder which might appear on any partition or disk\n.Trash-*\n\n# .nfs files are created when an open file is removed but is still being accessed\n.nfs*\n\n### macOS ###\n# General\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two \\r\nIcon\n\n\n# Thumbnails\n._*\n\n# Files that might appear in the root of a volume\n.DocumentRevisions-V100\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n.VolumeIcon.icns\n.com.apple.timemachine.donotpresent\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n### macOS Patch ###\n# iCloud generated files\n*.icloud\n\n### Node ###\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n.pnpm-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# Snowpack dependency directory (https://snowpack.dev/)\nweb_modules/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional stylelint cache\n.stylelintcache\n\n# Microbundle cache\n.rpt2_cache/\n.rts2_cache_cjs/\n.rts2_cache_es/\n.rts2_cache_umd/\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variable files\n.env\n.env.development.local\n.env.test.local\n.env.production.local\n.env.local\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n.parcel-cache\n\n# Next.js build output\n.next\nout\n\n# Nuxt.js build / generate output\n.nuxt\ndist\n\n# Gatsby files\n.cache/\n# Comment in the public line in if your project uses Gatsby and not Next.js\n# https://nextjs.org/blog/next-9-1#public-directory-support\n# public\n\n# vuepress build output\n.vuepress/dist\n\n# vuepress v2.x temp and cache directory\n.temp\n\n# Docusaurus cache and generated files\n.docusaurus\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n# TernJS port file\n.tern-port\n\n# Stores VSCode versions used for testing VSCode extensions\n.vscode-test\n\n# yarn v2\n.yarn/cache\n.yarn/unplugged\n.yarn/build-state.yml\n.yarn/install-state.gz\n.pnp.*\n\n### Node Patch ###\n# Serverless Webpack directories\n.webpack/\n\n# Optional stylelint cache\n\n# SvelteKit build / generate output\n.svelte-kit\n\n### SublimeText ###\n# Cache files for Sublime Text\n*.tmlanguage.cache\n*.tmPreferences.cache\n*.stTheme.cache\n\n# Workspace files are user-specific\n*.sublime-workspace\n\n# Project files should be checked into the repository, unless a significant\n# proportion of contributors will probably not be using Sublime Text\n# *.sublime-project\n\n# SFTP configuration file\nsftp-config.json\nsftp-config-alt*.json\n\n# Package control specific files\nPackage Control.last-run\nPackage Control.ca-list\nPackage Control.ca-bundle\nPackage Control.system-ca-bundle\nPackage Control.cache/\nPackage Control.ca-certs/\nPackage Control.merged-ca-bundle\nPackage Control.user-ca-bundle\noscrypto-ca-bundle.crt\nbh_unicode_properties.cache\n\n# Sublime-github package stores a github token in this file\n# https://packagecontrol.io/packages/sublime-github\nGitHub.sublime-settings\n\n### Vim ###\n# Swap\n[._]*.s[a-v][a-z]\n!*.svg  # comment out if you don't need vector files\n[._]*.sw[a-p]\n[._]s[a-rt-v][a-z]\n[._]ss[a-gi-z]\n[._]sw[a-p]\n\n# Session\nSession.vim\nSessionx.vim\n\n# Temporary\n.netrwhist\n# Auto-generated tag files\ntags\n# Persistent undo\n[._]*.un~\n\n### VisualStudioCode ###\n.vscode/*\n!.vscode/settings.json\n!.vscode/tasks.json\n!.vscode/launch.json\n!.vscode/extensions.json\n!.vscode/*.code-snippets\n\n# Local History for Visual Studio Code\n.history/\n\n# Built Visual Studio Code Extensions\n*.vsix\n\n### VisualStudioCode Patch ###\n# Ignore all local history of files\n.history\n.ionide\n\n# Support for Project snippet scope\n.vscode/*.code-snippets\n\n# Ignore code-workspaces\n*.code-workspace\n\n### Windows ###\n# Windows thumbnail cache files\nThumbs.db\nThumbs.db:encryptable\nehthumbs.db\nehthumbs_vista.db\n\n# Dump file\n*.stackdump\n\n# Folder config file\n[Dd]esktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msix\n*.msm\n*.msp\n\n# Windows shortcuts\n*.lnk\n\n# End of https://www.toptal.com/developers/gitignore/api/vim,node,linux,emacs,macos,windows,intellij,sublimetext,visualstudiocode\n"
  },
  {
    "path": ".nvmrc",
    "content": "18.18.2\n"
  },
  {
    "path": ".prettierignore",
    "content": ".next\nnode_modules\nout\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018- Marp team (marp-team@marp.app)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n  <p>\n    <img src=\"marp.png#gh-light-mode-only\" alt=\"Marp\" width=\"450\" />\n    <img src=\"marp-dark.png#gh-dark-mode-only\" alt=\"Marp\" width=\"450\" />\n  </p>\n  <p>\n    <strong>Marp</strong>: Markdown Presentation Ecosystem\n  </p>\n</div>\n\n**Marp** is the ecosystem to write your presentation with plain Markdown.\n\n<div align=\"center\">\n\n### [🌐 Website ▶︎](https://marp.app)&emsp;|&emsp;[💬 Discussion forum ▶︎](https://github.com/marp-team/marp/discussions)&emsp;|&emsp;[😎 Awesome list ▶︎](https://github.com/marp-team/awesome-marp)\n\n</div>\n\n## Marp family\n\nOur project is spread over many repos in order to focus on a limited scope per repository.\n\nThis repo (**[marp-team/marp][marp]**) is an entrance to the Marp family, and places [our website](https://marp.app/) in `/website`.\n\n### Framework / Core\n\n|                       Name | Description                                                                                 | Release                                                   |\n| -------------------------: | :------------------------------------------------------------------------------------------ | :-------------------------------------------------------- |\n|               **[Marpit]** | The skinny framework for creating slide deck from Markdown. ([marpit.marp.app])             | [![@marp-team/marpit][badge-marpit]][marpit-npm]          |\n| **[Marp Core][marp-core]** | The core of Marp converter with practical features and [built-in themes][marp-core-themes]. | [![@marp-team/marp-core][badge-marp-core]][marp-core-npm] |\n\n### Apps\n\n|                     Name | Description                                                                                      | Release                                                |\n| -----------------------: | :----------------------------------------------------------------------------------------------- | :----------------------------------------------------- |\n| **[Marp CLI][marp-cli]** | [Marp Core][marp-core] / [Marpit]'s CLI interface to convert into HTML, PDF, PPTX, and image(s). | [![@marp-team/marp-cli][badge-marp-cli]][marp-cli-npm] |\n\n### Integrations\n\n|                                Name | Description                                                                       | Release                                                     |\n| ----------------------------------: | :-------------------------------------------------------------------------------- | :---------------------------------------------------------- |\n| **[Marp for VS Code][marp-vscode]** | A [VS Code][vscode] extension to preview the slide deck written in Marp Markdown. | [![VS Marketplace][badge-marp-vscode]][marp-vscode-release] |\n\n<details>\n<summary>See outdated/inactive projects...</summary><br />\n\n|                     Name | Description                                                      | Release                                                      |\n| -----------------------: | :--------------------------------------------------------------- | :----------------------------------------------------------- |\n|     [Marp Web][marp-web] | The Web interface of Marp based on [PWA] and [Preact] framework. | [![tech demo][badge-marp-web]][marp-web-site]                |\n| [Marp React][marp-react] | Marp renderer component for [React].                             | [![@marp-team/marp-react][badge-marp-react]][marp-react-npm] |\n|     [Marp Vue][marp-vue] | Marp renderer component for [Vue].                               | [![@marp-team/marp-vue][badge-marp-vue]][marp-vue-npm]       |\n\nAnd there is a gravesite of classic Marp app in https://github.com/yhatt/marp. :ghost:\n\n[marp-web]: https://github.com/marp-team/marp-web\n[marp-react]: https://github.com/marp-team/marp-react\n[marp-vue]: https://github.com/marp-team/marp-vue\n[pwa]: https://en.wikipedia.org/wiki/Progressive_Web_Apps\n[preact]: https://preactjs.com/\n[react]: https://reactjs.org/\n[vue]: https://vuejs.org/\n[marp-web-site]: https://web.marp.app/\n[marp-react-npm]: https://www.npmjs.com/package/@marp-team/marp-react\n[marp-vue-npm]: https://www.npmjs.com/package/@marp-team/marp-vue\n[badge-marp-web]: https://img.shields.io/badge/%E2%80%8B-tech%20demo-%230288d1.svg?style=flat-square&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAUUlEQVQokWNgGD6AqePif3Sx9B2PMcQwNKFrTN/x+D9ejTBNyBphmnBqRNYE04isCatGdE1MHRf/o2vC0IhNE1PaXPwacWnCqxGfJoI2Dn4AAN0ZrMM1VUFvAAAAAElFTkSuQmCC\n[badge-marp-react]: https://img.shields.io/npm/v/@marp-team/marp-react.svg?style=flat-square&logo=npm\n[badge-marp-vue]: https://img.shields.io/npm/v/@marp-team/marp-vue.svg?style=flat-square&logo=npm\n\n</details>\n\n[yhatt/marp]: https://github.com/yhatt/marp\n[marp]: https://github.com/marp-team/marp\n[marpit]: https://github.com/marp-team/marpit\n[marp-core]: https://github.com/marp-team/marp-core\n[marp-core-themes]: https://github.com/marp-team/marp-core/tree/main/themes\n[marp-cli]: https://github.com/marp-team/marp-cli\n[marp-vscode]: https://github.com/marp-team/marp-vscode\n[vscode]: https://code.visualstudio.com/\n[marpit.marp.app]: https://marpit.marp.app/\n[marpit-npm]: https://www.npmjs.com/package/@marp-team/marpit\n[marp-core-npm]: https://www.npmjs.com/package/@marp-team/marp-core\n[marp-cli-npm]: https://www.npmjs.com/package/@marp-team/marp-cli\n[marp-vscode-release]: https://marketplace.visualstudio.com/items?itemName=marp-team.marp-vscode\n[badge-marpit]: https://img.shields.io/npm/v/@marp-team/marpit.svg?style=flat-square&logo=npm\n[badge-marp-core]: https://img.shields.io/npm/v/@marp-team/marp-core.svg?style=flat-square&logo=npm\n[badge-marp-cli]: https://img.shields.io/npm/v/@marp-team/marp-cli.svg?style=flat-square&logo=npm\n[badge-marp-vscode]: https://img.shields.io/visual-studio-marketplace/v/marp-team.marp-vscode.svg?style=flat-square&logo=visual-studio-code&label=Marketplace\n\n## Ecosystem\n\nMarp ecosystem has a lot of cool stuffs for making awesome presentation. Check out **[the awesome list of Marp](https://github.com/marp-team/awesome-marp)**. 😎\n\n## Contributing\n\nMarp and sub-projects are following the [contributing guideline of marp-team][contributing]. Please read this before starting work in our projects.\n\n[contributing]: https://github.com/marp-team/.github/blob/master/CONTRIBUTING.md\n\n## Author\n\nManaged by [@marp-team](https://github.com/marp-team).\n\n- <img src=\"https://github.com/yhatt.png\" width=\"16\" height=\"16\"/> Yuki Hattori ([@yhatt](https://github.com/yhatt))\n\n## Sponsors\n\nWe are supported by them! Thanks for our sponsors! :heart:\n\n<!-- [NOTE] Sort sponsors by name when modify. -->\n\n### Organization sponsors\n\n<!-- Logo and links for top-tier sponsors (The image should be up to 400px on a side) -->\n\n<p align=\"center\">\n  <a href=\"https://github.com/markslides\"><img src=\"https://github.com/markslides.png\" width=\"64\" height=\"64\" alt=\"@markslides\" valign=\"middle\" hspace=\"4\" /></a>\n</p>\n\n<!-- [TODO] For mid-tier sponsors: As the same format as personal sponsors, add small icons and links to GitHub organization. -->\n<!--\n<p>\n  <a href=\"https://github.com/xxxxxx\"><img src=\"https://github.com/xxxxxx.png\" width=\"32\" height=\"32\" alt=\"xxxxxx\" /></a>\n</p>\n-->\n\n### Personal sponsors\n\n<!-- [TODO] Currently shows maintainer's sponsors. We should show sponsors for all Marp team members in future. -->\n\n<p align=\"center\">\n  <img alt=\"Personal sponsors\" src=\"https://yhatt.github.io/yhatt/sponsors.svg\" />\n</p>\n\n> Do you want to sponsor [the member of Marp team](https://github.com/orgs/marp-team/people)? See [GitHub Sponsors](https://github.com/sponsors) profile(s) from \"♥︎ Sponsor\" button [at the top of repository](https://github.com/marp-team/marp).\n\n## License\n\n[MIT License](LICENSE)\n"
  },
  {
    "path": "netlify.toml",
    "content": "[build]\n  publish = \"website/out\"\n  command = \"yarn workspace @marp-team/marp-website export\"\n\n[[headers]]\n  for = \"/*\"\n  [headers.values]\n    Permissions-Policy = \"interest-cohort=()\"\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"@marp-team/marp\",\n  \"description\": \"The entrance repository of Markdown presentation ecosystem\",\n  \"private\": true,\n  \"license\": \"MIT\",\n  \"author\": {\n    \"name\": \"Marp team\",\n    \"url\": \"https://github.com/marp-team\"\n  },\n  \"contributors\": [\n    {\n      \"name\": \"Yuki Hattori\",\n      \"url\": \"https://github.com/yhatt\"\n    }\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/marp-team/marp\"\n  },\n  \"workspaces\": [\n    \"website\"\n  ],\n  \"prettier\": {\n    \"semi\": false,\n    \"singleQuote\": true\n  },\n  \"scripts\": {\n    \"check:format\": \"yarn -s format -c\",\n    \"check:ts\": \"yarn lage check:ts\",\n    \"format:write\": \"yarn -s format --write\",\n    \"format\": \"prettier \\\"**/*.{css,js,jsx,json,md,mdx,scss,ts,tsx,yaml,yml}\\\"\",\n    \"lint:js\": \"eslint --report-unused-disable-directives --cache .\",\n    \"website\": \"yarn workspace @marp-team/marp-website dev\"\n  },\n  \"devDependencies\": {\n    \"@tsconfig/recommended\": \"^1.0.1\",\n    \"@types/node\": \"~18.11.18\",\n    \"@typescript-eslint/eslint-plugin\": \"^5.47.1\",\n    \"@typescript-eslint/parser\": \"^5.47.1\",\n    \"eslint\": \"^8.30.0\",\n    \"eslint-config-prettier\": \"^8.3.0\",\n    \"eslint-import-resolver-typescript\": \"^3.5.2\",\n    \"eslint-plugin-import\": \"^2.25.4\",\n    \"lage\": \"^1.9.6\",\n    \"prettier\": \"^2.8.1\",\n    \"typescript\": \"^4.9.4\"\n  },\n  \"resolutions\": {\n    \"json5\": \"^2.2.2\"\n  }\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"extends\": \"@tsconfig/recommended/tsconfig.json\",\n  \"compilerOptions\": {\n    \"lib\": [\"es2015\", \"dom\"],\n    \"noImplicitAny\": false,\n    \"resolveJsonModule\": true,\n    \"strict\": true\n  }\n}\n"
  },
  {
    "path": "website/.eslintrc.js",
    "content": "const path = require('path')\n\nmodule.exports = {\n  extends: ['next', 'prettier'],\n  rules: {\n    '@next/next/no-html-link-for-pages': [\n      'error',\n      path.join(__dirname, 'pages'),\n    ],\n\n    // Marp website is completely static. Automatic Image Optimization by Next.js requires a server for on-demand conversion.\n    '@next/next/no-img-element': 'off',\n  },\n}\n"
  },
  {
    "path": "website/assets.d.ts",
    "content": "declare module '*.yaml' {\n  const yaml: any\n  export = yaml\n}\n"
  },
  {
    "path": "website/babel.config.js",
    "content": "const path = require('path')\n\nmodule.exports = {\n  presets: [\n    [\n      'next/babel',\n      {\n        'styled-jsx': {\n          plugins: [\n            [\n              require.resolve('styled-jsx-plugin-postcss'),\n              { path: path.resolve(__dirname, './postcss.config.js') },\n            ],\n          ],\n        },\n      },\n    ],\n  ],\n}\n"
  },
  {
    "path": "website/blog/202205-ecosystem-update.md",
    "content": "---\ntitle: 'Ecosystem update: Marp Core v3 & Slide transitions in CLI v2'\ndate: 2022-05-26\ndescription: Introduce a stable release of Marp Core v3, and updated CLI v2 with an entirely new slide transition experiment.\nauthor: Yuki Hattori\ngithub: yhatt\nimage: /og-images/202205-ecosystem-update.jpg\n---\n\nWe are so excited to introduce a stable release of **[Marp Core](https://github.com/marp-team/marp-core) v3**, and **[Marp CLI](https://github.com/marp-team/marp-cli) v2** update with [an entirely new slide transition experiment](#slide-transition-experiment).\n\n- **[Marp Core v3](#marp-core-v3)**: MathJax rendering as default, updated `default` theme, and new components for auto-scaling.\n- **[Marp CLI v2](#marp-cli-v2)**: Bundled core v3, and [brand-new slide transition experiment](#slide-transition-experiment) with 33 built-in effects + CSS custom transitions.\n\n<!-- more -->\n\n# Marp Core v3\n\n[We had released Marp Core v3.0.0 as a release candidate in November 2021.](https://github.com/marp-team/marp-core/releases/tag/v3.0.0) For a half year, it had been available in the `next` tag as an opt-in engine of Marp CLI, and had accepted feedback from the community.\n\nThis month [v3.2.0](https://github.com/marp-team/marp-core/releases/tag/v3.2.0) has become a stable release, and **we are starting work to make v3 core the default in downstream Marp tools gradually.**\n\nAn updated Marp Core v3 has some major changes, but we also have worked to keep backward compatibility in many existing slides. Most slide authors should not be concerned about regressions as long as your tweaks to the slide theme are not complicated.\n\nIf you are a theme author, you may have to modify some of the styles. This update includes a brand-new auto scaling component, the change of `default` theme caused by the update of [`github-markdown-css`](https://github.com/sindresorhus/github-markdown-css), and so on.\n\nEven so, you should not too worry: We worked to v3 core to reduce friction between Marp's CSS and common CSS, so I think the complex part of our theming system (e.g. styling auto-scaled element) must be easier to understand than v2.\n\n## Notable changes\n\n### Drop support for End-of-Life Node.js\n\nFirst, Marp Core v3 has dropped support for end-of-life Node.js 10.\n\nWe have supported EoL Node.js v12 yet, but continuous support may not guarantee depending on the support status of dependency modules. We recommend following up on [the active LTS Node.js](https://nodejs.org/).\n\n> Check out https://endoflife.date/nodejs to know which version of Node.js is EoL.\n\n### MathJax is a default typesetting library for math\n\n[katex]: https://katex.org/\n[mathjax]: https://www.mathjax.org/\n\nMarp Core v3 has changed the default library for rendering math, from [KaTeX] to [MathJax].\n\nMarp had used [KaTeX] as a default library for long years for taking better performance. But currently, this opinion has become the past thinking with the advent of MathJax 3. [See this interesting insight.](https://groups.google.com/g/mathjax-users/c/aboJLMb50uQ/m/Y77FexF_AwAJ)\n\nAnd some incompatibilities of KaTeX with Marp Core's auto scaling feature that are hard to fix had given us a headache. ([marp-team/marp-core#159](https://github.com/marp-team/marp-core/issues/159), [marp-team/marp-core#236](https://github.com/marp-team/marp-core/issues/236))\n\nMathJax implementation in Marp Core has more reliable rendering than KaTeX. In addition, it also has more TeX function supports, and no network is required to show.\n\nNow a lot of Markdown flavors have adopted MathJax for math typesetting (e.g. [GitHub](https://github.blog/2022-05-19-math-support-in-markdown/)), and we expect Marp Markdown would get higher compatibility in several Markdown services.\n\n#### `math` global directive\n\nIf your Markdown is not yet ready to migrate math typesettings into MathJax, you can continue to use KaTeX as a math typesetting library by setting [`math` global directive](https://github.com/marp-team/marp-core#math-global-directive) as `katex`.\n\n```markdown\n---\nmath: katex\n---\n\nContinue to use KaTeX: $ax^2+bc+c$\n```\n\nWe have no plans to remove KaTeX integration for a while. So you can keep rendering math with KaTeX if you're using KaTeX specific syntaxes or met rendering performance issues in MathJax.\n\n> For smooth migration of exist slides to v3, Marp for VS Code is [annotating to math use without `math` global directive](https://github.com/marp-team/marp-vscode#diagnostics) since a year ago.\n\n### Renewed auto-scaling component\n\nMarp Core has a tiny runtime script to activate element auto-scaling for a code block, math block, and [fitting header `# <!--fit--> header`](https://github.com/marp-team/marp-core#fitting-header). v3 has updated auto scaling logic into [Web Components](https://developer.mozilla.org/docs/Web/Web_Components) based, to improve output lucidity and compatibility with some CSS selectors.\n\nThis update does not change the actual auto-scaling behavior from v2, so most Markdown slide authors should not need to take care of that. But if you have a custom theme that was styled to auto-scaling elements, you should review and modify CSS declarations in your theme to match with v3.\n\nPlease refer to the pull request **[marp-team/marp-core#263](https://github.com/marp-team/marp-core/pull/263)** for details of auto-scaling components.\n\n### Updated `default` theme\n\nTo provide a familiar Markdown style to users as default, Marp Core `default` theme is based on [GitHub's Markdown CSS](https://github.com/sindresorhus/github-markdown-css).\n\nThe latest Marp Core has included the following updates about `default` theme:\n\n- Updated color schemes based on the latest [github-markdown-css v5](https://github.com/sindresorhus/github-markdown-css)\n- Match colors for code highlight with GitHub style\n- Allow color customization through CSS variables ([See theme docs](https://github.com/marp-team/marp-core/tree/main/themes#custom-color-css-variables))\n\n````markdown:marp\n<!-- paginate: true -->\n<style>:root { font-size: 40px; }</style>\n\n# This is a new `default` theme\n\n```markdown\n<!-- theme: default -->\n\n# This is a new `default` theme\n```\n\n---\n\n<!-- class: invert -->\n\n# Updated `invert` color scheme\n\nbased on GitHub dark mode\n\n```markdown\n<!-- class: invert -->\n```\n\n````\n\n### URL without HTTP(S) scheme does no longer auto-linkify\n\nMarp Core up to v2 had detected URL-like strings and converted them to hyperlinks automatically. However, that was too fuzzy and often brought linkify in not intended words, such as \"[Amazon.com](https://amazon.com/)\" and \"[ML.NET](https://dotnet.microsoft.com/apps/machinelearning-ai/ml-dotnet)\".\n\nBut there are no more fuzzy links in v3! Now auto link feature requires the URL string with `https://` or `http://` scheme.\n\nPlease make a Markdown link `[Amazon.com](https://amazon.com/)` explicitly if you want the hyperlink in previously auto-linked words.\n\n# Marp CLI v2\n\nAccording to the time to become core v3 stable, we also worked on **[a major update of Marp CLI](https://github.com/marp-team/marp-cli/releases/tag/v2.0.0)** to bundle a new core.\n\nThere are no major changes in the general use of Marp CLI, and I believe your CLI workflow would never break by this update in most cases.\n\nSo what feature is a \"major\" update of CLI? [_Perhaps you may have interested in a hidden gem..._ 💎](#slide-transition-experiment)\n\n## Notable changes\n\n### Required Node.js v14 and later\n\nThe new release of Marp CLI is required **the latest Node.js v14 and later**, because depending modules such as Puppeteer (for PDF/PPTX generation) were dropped support for EoL Node.js versions v12 and older.\n\n### Bundled Marp Core v3\n\nAs described earlier, Marp CLI v2 has bundled an updated Marp Core v3.2.0 as a core engine.\n\n```bash\n$ marp --version\n@marp-team/marp-cli v2.0.0 (w/ @marp-team/marp-core v3.2.0)\n```\n\n###### Continue to use v2 core in Marp CLI\n\nWe recommend getting ready for using the updated v3 core, but Marp CLI also can stick to the v2 core by installing `@marp-team/marp-core@^2` to your project individually.\n\n```bash\nnpm i --save-dev @marp-team/marp-cli @marp-team/marp-core@^2\nnpx marp ./your-markdown.md\n```\n\nIt's useful when your Markdown slide files are not ready for v3 core. But please keep in mind we would hardly provide more updates to v2 core, and **continuous use may bring a risk of unpatched security issues.**\n\n# Slide transitions\n\nA really loving part of this CLI update for me is **[a brand-new slide transition in `bespoke` HTML template.](https://github.com/marp-team/marp-cli/issues/447)**\n\nWe had started testing experimental slide transition effects since [Marp CLI v1.4.0](https://github.com/marp-team/marp-cli/releases/tag/v1.4.0) (Aug 2021). `--bespoke.transition` CLI option had been working well, but not so practical compared to the common presentation tools.\n\nAs a result of catching up on the new spec of [View Transitions API proposal][view transitions api] in Marp CLI v2, I'm so excited to provide powerful transition features that are in no other Markdown slide tools, such as CSS custom transition effects and morphing animations!\n\n[view transitions api]: https://www.w3.org/TR/css-view-transitions-1/\n\n> The slide transitions feature has made stable in v2.4.0. You can dive into all about of transitions at [the documentation of Marp CLI transitions][transition-docs].\n\n[transition-docs]: https://github.com/marp-team/marp-cli/blob/main/docs/bespoke-transitions/README.md\n\n## Quick look\n\n![Marp CLI transition showcase poster=/assets/202205-ecosystem-update/transition-showcase-poster.jpg controls](https://user-images.githubusercontent.com/3993388/169697466-283dd2f2-b6e5-4b33-86d4-b10cc0a6c3e9.mp4)\n\n- **[33 built-in transitions](https://github.com/marp-team/marp-cli/blob/main/docs/bespoke-transitions/README.md#built-in-transitions)**: Marp CLI provides a lot of transition effects out of the box.\n- **[Define custom transitions via CSS](https://github.com/marp-team/marp-cli/blob/main/docs/bespoke-transitions/README.md#custom-transitions)**: Markdown author and theme designer can define the custom transition through `@keyframes` declaration in CSS.\n- **[Morphing animations](https://github.com/marp-team/marp-cli/blob/main/docs/bespoke-transitions/README.md#morphing-animations)**: [`view-transition-name` CSS property](https://www.w3.org/TR/css-view-transitions-1/#view-transition-name-prop) supplied by View Transition API helps to make morphing animation while transition.\n\n## Usage\n\nThe slide transitions in HTML output can opt in and out through `--bespoke.transition` CLI option. _It is only working in the browser that supports [View Transitions API], such as Chrome/Chromium 110 and later._\n\nThe `--preview` CLI option is helpful see transition effects surely. Try this in Marp CLI v2.4.0+ to open a preview window for the transition showcase:\n\n```bash\ncurl -o ./showcase.md https://gist.githubusercontent.com/yhatt/d9e86ee53eb8816aaf9c996e773b6f82/raw/transition-showcase.md\nmarp --preview ./showcase.md\n```\n\n## Showcase\n\nYou can see online demo slides about Marp CLI brand new transitions! See them in the browser that supports [View Transitions API].\n\n- **[Marp CLI page transition showcase](https://marp-cli-page-transitions.glitch.me/)**: The showcase of built-in transitions\n- **[Custom transitions example](https://marp-cli-page-transitions.glitch.me/custom.html)**: Some examples and ideas about custom transitions\n- **[Transition with morphing animation](https://marp-cli-page-transitions.glitch.me/morph.html)**: An example of morphing animation powered by [View Transitions API].\n\n## `transition` local directive\n\nYou can set and change the kind of transition through `transition` local directive.\n\n```markdown\n---\ntransition: fade\n---\n\nFade transition with 0.5s duration\n\n---\n\n<!-- transition: cover 1s -->\n\nChanged the kind of transition to `cover` with 1s duration\n\n---\n\n<!-- _transition: none -->\n\nDisabled transition for this slide\n\n---\n\nGot back to cover transition\n```\n\nEach transition has a default 0.5s duration, but you can also set custom duration by space-separated value such as `<!-- transition: fade 1s -->`.\n\n## Custom transition\n\nThe custom transition can define through just a few conventional [`@keyframes` at-rules](https://developer.mozilla.org/docs/Web/CSS/@keyframes) within the inline `<style>` element or custom theme CSS.\n\n<!-- prettier-ignore-start -->\n\n```css\n/* Simple definition: \"dissolve\" custom transition */\n@keyframes marp-transition-dissolve {\n  from { opacity: 1; }\n  to { opacity: 0; }\n}\n\n/* Splitted definitions: \"triangle\" custom transition */\n@keyframes marp-incoming-transition-triangle {\n  from { clip-path: polygon(0% 0%, 0% 0%, 0% 0%); }\n  to { clip-path: polygon(0% 0%, 200% 0%, 0% 200%); }\n}\n@keyframes marp-incoming-transition-backward-triangle {\n  from { clip-path: polygon(100% 100%, 100% 100%, 100% 100%); }\n  to { clip-path: polygon(-100% 100%, 100% -100%, 100% 100%); }\n}\n\n/* With backward animations: Overloading \"zoom\" transition */\n@keyframes marp-incoming-transition-zoom {\n  from { transform: scale(0); }\n  to { transform: scale(1); }\n}\n@keyframes marp-outgoing-transition-backward-zoom {\n  from { transform: scale(1); }\n  to { transform: scale(0); }\n}\n@keyframes marp-incoming-transition-backward-zoom {\n  /* Define empty keyframes to disable fallback into incoming animation */\n}\n```\n\n<!-- prettier-ignore-end -->\n\nIt only has a relatively simple definition(s) but great flexibility, and brings out boundless creativity of CSS animation! 🤩\n\n**[👉 Marp CLI: How to make custom transition](/blog/how-to-make-custom-transition)**\n\nWe are really looking forward to what creative transition effects our community will create!\n\n## Morphing animations\n\nThanks to the browser's [View Transitions API], we can apply morphing animations during a transition effect. This is similar to PowerPoint Morph and Keynote Magic Move.\n\nJust sprinkle a few CSS properties!\n\n![Morphing animations](https://raw.githubusercontent.com/marp-team/marp-cli/main/docs/bespoke-transitions/images/morphing-animation.gif ' ')\n\n```markdown\n---\ntheme: gaia\ntransition: fade\nstyle: |\n  /* ⬇️ Mark the image of \"1\" in every pages as morphable image named as \"one\" ⬇️ */\n  img[alt=\"1\"] {\n    view-transition-name: one;\n    contain: layout;\n  }\n\n  /* Generic image styling for number icons */\n  img:is([alt=\"1\"], [alt=\"2\"], [alt=\"3\"]) {\n    height: 64px;\n    position: relative;\n    top: -0.1em;\n    vertical-align: middle;\n    width: 64px;\n  }\n---\n\n# Today's topics\n\n- ![1](https://icongr.am/material/numeric-1-circle.svg?color=666666) Introduction\n- ![2](https://icongr.am/material/numeric-2-circle.svg?color=666666) Features\n- ![3](https://icongr.am/material/numeric-3-circle.svg?color=666666) Conclusion\n\n---\n\n<!-- _class: lead -->\n\n![1 w:256 h:256](https://icongr.am/material/numeric-1-circle.svg?color=ff9900)\n\n# Introduction\n\n---\n\n# ![1](https://icongr.am/material/numeric-1-circle.svg?color=666666) Introduction\n\nMarp is an open-sourced Markdown presentation ecosystem.\n```\n\n**[👉 See details at the documentation about transitions on Marp CLI repository...](https://github.com/marp-team/marp-cli/blob/main/docs/bespoke-transitions/README.md#morphing-animations)**\n\n# Deprecations\n\nFinally, we have to mention that the latest update has a deprecated Markdown syntax in the Marp ecosystem. It is still can use for now with deprecation warnings and will be obsolete in future Marp tools.\n\n> We have planned to work on [an auto-fixable diagnostic for VS Code extension](https://github.com/marp-team/marp-vscode#diagnostics), to make it easier to update the use of deprecated syntaxes.\n\n### Shorthand for setting colors (Marpit framework)\n\n[Marpit framework](https://marpit.marp.app/) had been provided the color setting shorthand through Markdown image syntax, such as `![](red)` and `![bg](yellow)`. This syntax had been allowed to set a corresponding color style like `color: red` and `background-color: yellow` to only a current slide page.\n\nThese are rarely used in reality, and now we have considered as harmful from the point of view of Markdown (CommonMark) compatibility.\n\nMarpit framework has already provided [`color` / `backgroundColor` local directives](https://marpit.marp.app/directives?id=backgrounds), and setting [scoped local directives](https://marpit.marp.app/directives?id=apply-to-a-single-page-spot-directives) to the slide will bring the same result.\n\nIf you are using these shorthands for setting colors, please replace them with the alternative scoped local directive.\n\n|  Shorthands  |        Should replace to         |\n| :----------: | :------------------------------: |\n|  `![](red)`  |      `<!-- _color: red -->`      |\n| `![bg](red)` | `<!-- _backgroundColor: red -->` |\n\n> _Track the state of progress at [marp-team/marpit#331](https://github.com/marp-team/marpit/issues/331)._\n\n# Community\n\nJoin the Marp community! Our [GitHub Discussions](https://github.com/orgs/marp-team/discussions) is a community forum that gathered discussions all about Marp, and allows you to connect with Marp team and other Marp users. Of course, we welcome your feedback for this ecosystem update too. 😀\n\n- [**Go to GitHub Discussions**](https://github.com/orgs/marp-team/discussions)\n- [The support guideline of Marp project](https://github.com/marp-team/.github/blob/master/SUPPORT.md)\n\n<!--\n# Titbit\n\nMarpit framework is 5th year and I feel that is beginning to gather a few of dust. Therefore I'm trying to design a new polished engine, as a personal weekend experiment toward the next core v4.\n\nCurrently I don't want you too to count on it. I'm just working on for getting a long-lived ecosystem with modern CSS rules :)\n-->\n"
  },
  {
    "path": "website/blog/how-to-make-custom-transition.md",
    "content": "---\ntitle: 'Marp CLI: How to make custom transition'\ndate: 2022-05-28\ndescription: Marp CLI v2.4.0+ and Marp for VS Code v2.5.0+ have a stable support for page transitions with many useful built-in effects. But if you had not satisfied with any effects? Make your effects with CSS!\nauthor: Yuki Hattori\ngithub: yhatt\nimage: /og-images/how-to-make-custom-transition.jpg\n---\n\n[readme]: https://github.com/marp-team/marp-cli/blob/main/docs/bespoke-transitions/README.md\n[built-in]: https://github.com/marp-team/marp-cli/blob/main/docs/bespoke-transitions/README.md#built-in-transitions\n[view transitions api]: https://www.w3.org/TR/css-view-transitions-1/\n\n**[Marp CLI v2](/blog/202205-ecosystem-update#marp-cli-v2)** has supported [brand-new page transitions for the `bespoke` HTML template](/blog/202205-ecosystem-update#slide-transition-experiment). You can use this stable transition support in either Marp CLI v2.4.0+ or Marp for VS Code v2.5.0+.\n\nEffective transitions will help make a dramatic presentation. Adding a touch of effects to slides is often common in great talks. By viewing HTML slide in the browser that supports [View Transitions API] (Chrome 110+), or Marp CLI with `--preview` option, you can start to use [varied 33 transition effects][built-in] out of the box, by [just a simple definition `transition` directive](https://github.com/marp-team/marp-cli/blob/main/docs/bespoke-transitions/README.md#transition-local-directive).\n\nBuilt-in transitions should be useful for 90% of Marp users. But what you can do if there are no effects you are satisfied with? Make your effects in CSS! Marp can register your custom animation set declared in CSS as a named transition, and use it in the Markdown slide.\n\n<!-- more -->\n\n### Index\n\nThis article will describe the following things:\n\n1. **[The anatomy of a transition](#the-anatomy-of-a-transition)**: How the transition effect will work in Marp\n1. **[Declare custom transitions](#declare-custom-transitions)**: How to register custom transitions by CSS\n1. **[Helpful tips for making your transition](#tips)**\n\n[See also the official documentation about transitions in Marp CLI.][readme]\n\n_If using [built-in transitions made by us][built-in] was enough, you don't need to read this article._ Please save your time, with keeping enjoying our transitions in your Markdown slide! :)\n\n> In this article, the word \"transition\" is meaning the slide transition effect in Marp. Please note that it is not meaning [`transition` property in CSS](https://developer.mozilla.org/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions).\n\n# The anatomy of a transition\n\nThe first what the custom transition author has to know is \"How the page transition effect is realized in a presentation slide\".\n\nLet's consider what is happening when the slide page was navigated from 1 to 2. If no transitions were set to the slide, the first page will just disappear, and appear on the second page immediately. If it has a transition effect, a certain time for playing animations will insert between switching pages.\n\n![The anatomy of a transition](/assets/how-to-make-custom-transition/transition-diagram.jpg 'The anatomy of a transition')\n\nAn important thing during transition is that 2 slides are presented in the view at the same time like layers. All kinds of effects produce smooth transitions by applying specific animations to one or both slides.\n\nIn Marp, the slide page that was shown before transition calls as **\"Outgoing slide\"**, and the next page to appear after transition calls as **\"Incoming slide\"**. Slide pages may have an inverse relationship when brought the backward navigation, but the meaning of \"incoming\" and \"outgoing\" is always consistent.\n\nIf you could figure them out, you probably also grasp that you have to respect the following 2 principles:\n\n- **The outgoing slide** should have **an animation to hide** the slide.\n- **The incoming slide** should have **an animation to show** the slide.\n\nIf either or both was not respected in a transition effect, it would become a weird transition.\n\n> Marp CLI's `bespoke` template will make two slide layers when navigated, and apply suitable animation keyframes declared in CSS.\n\n# Declare custom transitions\n\n## Simple keyframe declaration\n\nLet's get started with a simple keyframe declaration for [the dissolve effect (also known as the cross-fade effect)](<https://en.wikipedia.org/wiki/Dissolve_(filmmaking)>), to learn how to set custom transition animation. Marp uses [standard syntax for CSS animation `@keyframes`](https://developer.mozilla.org/docs/Web/CSS/@keyframes) to declare transitions.\n\nWhen applying the dissolve effect to transition principles, you can derive that the effect needs these animations:\n\n- The outgoing slide has an animation to **decrease opacity from 100% to 0%**.\n- The incoming slide has an animation to **increase opacity from 0% to 100%**.\n\nThere are opposite changes with each other. In this case, you can define animations for both slide layers by one `@keyframes` declaration.\n\nFirst, declare `@keyframes` at-rule with the conventional name specified by Marp in your Markdown.\n\n```markdown\n---\ntransition: dissolve\nstyle: |\n  @keyframes marp-transition-dissolve {\n    /* ... */\n  }\n---\n\n# Slide 1\n\n---\n\n<!-- _class: invert -->\n\n# Slide 2\n```\n\n**`marp-transition-xxxxxxxx`** is the rule of animation name to register the transition with a simple declaration. For using declared transition in Marp slide, assign `transition` local directive with the name declared in `xxxxxxxx`.\n\n> This example is using [`style` global directive](https://marpit.marp.app/directives?id=tweak-theme-style) to declare keyframes. Of course, you also can use [the inline `<style>` element](https://marpit.marp.app/theme-css?id=tweak-style-through-markdown) or [custom theme CSS](https://marpit.marp.app/theme-css) to declare.\n\nWell, declare animation details at keyframes. In a simple declaration, you only have to set animation for the outgoing slide. For the incoming slide, Marp will set the animation in the reverse direction automatically.\n\n```css\n@keyframes marp-transition-dissolve {\n  from {\n    opacity: 1;\n  }\n  to {\n    opacity: 0;\n  }\n}\n```\n\n> This example has been declared `from` keyframe for clarity, but you can omit it because `opacity: 1` is a default style.\n\nDid you want more? That's it! Try to test this transition in the HTML slide with the browser that supports [View Transitions API], or [a preview window in Marp CLI](https://github.com/marp-team/marp-cli#preview-window---preview---p).\n\n```bash\nnpx @marp-team/marp-cli@^2.4.0 --preview ./transition.md\n```\n\nYou have made the first custom transition!\n\n![autoplay The dissolve effect with timeline diagram](/assets/how-to-make-custom-transition/dissolve-opacity.mp4)\n\nIn this article, the example is simplified for teaching how to make a custom transition, and there is a bit of difference from the built-in transition `fade` for getting the same effect. `dissolve` effect is looking good, but there is [a general pitfall about cross fading](https://jakearchibald.com/2021/dom-cross-fade/).\n\n## Split animations into outgoing and incoming\n\nA simple declaration should work in some transition types well, but it's not that all transitions have exactly contrary animations to each other. In reality, different animations for the outgoing slide and incoming slide are required in most cases.\n\nFor example, the slide up effect must have these animations:\n\n- The outgoing slide should **move from the viewport to the upper outer**.\n- The incoming slide should **move from the lower outer to the viewport**.\n\nSo you can declare split animations for each layer rather than declaring a single animation. Set `@keyframes` with the prefix of the target transition: **`marp-outgoing-transition-xxxxxxxx`** and **`marp-incoming-transition-xxxxxxxx`**.\n\n```markdown\n---\ntransition: slide-up\nstyle: |\n  @keyframes marp-outgoing-transition-slide-up {\n    from { transform: translateY(0%); }\n    to { transform: translateY(-100%); }\n  }\n  @keyframes marp-incoming-transition-slide-up {\n    from { transform: translateY(100%); }\n    to { transform: translateY(0%); }\n  }\n---\n\n# Slide 1\n\n---\n\n<!-- _class: invert -->\n\n# Slide 2\n```\n\nUnlike the simple transition, there is no auto-reversed animation in the incoming slide. Each animation should define in the right direction.\n\n![The timeline diagram of slide-up transition](/assets/how-to-make-custom-transition/slide-up-translate-y.png 'The timeline diagram of slide-up transition')\n\n## Transition for backward navigation\n\nIf you have tested the above slide-up transition example, you may have noticed that is having a move to up also when slide navigation going to back has occurred.\n\n![Wrong direction in slide up transition](/assets/how-to-make-custom-transition/slide-up-wrong-direction.gif ' ')\n\nIt brings a wrong user interaction and is not intuitive. You should want to provide the animation for the correct direction when occurred backward navigation.\n\nWe are providing several solutions to deal with this.\n\n### `--marp-transition-direction` CSS variable\n\nWhile playing transition, `--marp-transition-direction` [CSS custom property (as known as CSS variables)](https://developer.mozilla.org/docs/Web/CSS/Using_CSS_custom_properties) will be available in `@keyframes`.\n\nIt provides `1` in forwarding navigation, or `-1` in backward navigation. Using [`var(--marp-transition-direction)`](https://developer.mozilla.org/docs/Web/CSS/var) together with [`calc()`](https://developer.mozilla.org/docs/Web/CSS/calc) function would be useful to calculate the position in response to the direction of slide navigation.\n\n<!-- prettier-ignore-start -->\n\n```css\n@keyframes marp-outgoing-transition-slide-up {\n  from { transform: translateY(0%); }\n  to { transform: translateY(calc(var(--marp-transition-direction, 1) * -100%)); }\n}\n@keyframes marp-incoming-transition-slide-up {\n  from { transform: translateY(calc(var(--marp-transition-direction, 1) * 100%)); }\n  to { transform: translateY(0%); }\n}\n```\n\n<!-- prettier-ignore-end -->\n\nAnd now, the slide-up custom transition is working completely in both directional navigation!\n\n![Slide up transition with correct directions](/assets/how-to-make-custom-transition/slide-up-correct-direction.gif ' ')\n\n> NOTE: Any other CSS variables defined in the context of animation keyframes cannot use in keyframes.\n\n### Set custom animations for backward transition\n\nAlternatively, you also can set more animation keyframes that are specific for backward navigation.\n\nDeclare `@keyframes` with the **`backward-` prefix to the custom transition name**, just like as **`marp-transition-backward-xxxxxxxx`**. It is available in both simple keyframes declaration and split keyframes declaration.\n\n<!-- prettier-ignore-start -->\n\n```css\n@keyframes marp-incoming-transition-triangle {\n  /* Wipe effect from left top */\n  from { clip-path: polygon(0% 0%, 0% 0%, 0% 0%); }\n  to { clip-path: polygon(0% 0%, 200% 0%, 0% 200%); }\n}\n\n@keyframes marp-incoming-transition-backward-triangle {\n  /* Wipe effect from right bottom */\n  from { clip-path: polygon(100% 100%, 100% 100%, 100% 100%); }\n  to { clip-path: polygon(-100% 100%, 100% -100%, 100% 100%); }\n}\n```\n\n<!-- prettier-ignore-end -->\n\nIn backward navigation, each layer will try to use the backward keyframes first, and fall back to the normal keyframes if not declared. To disable unintended fallback in backward animations, set an empty declaration of `@keyframes`.\n\n<!-- prettier-ignore-start -->\n\n```css\n@keyframes marp-outgoing-transition-zoom-out {\n  from { transform: scale(1); }\n  to { transform: scale(0); }\n}\n@keyframes marp-incoming-transition-zoom-out {\n  /* Send the incoming slide layer to back */\n  from { z-index: -1; }\n  to { z-index: -1; }\n}\n\n/* ⬇️ Declare empty keyframes to disable fallback ⬇️ */\n@keyframes marp-outgoing-transition-backward-zoom-out {}\n@keyframes marp-incoming-transition-backward-zoom-out {\n  from { transform: scale(0); }\n  to { transform: scale(1); }\n}\n```\n\n<!-- prettier-ignore-end -->\n\nOK, I've described all about declarations for the custom transition!\n\n# Tips\n\n## Easing function\n\nEach transition has a linear easing by default. You can specify [`animation-timing-function` property within individual keyframes](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-timing-function#:~:text=A%20keyframe%27s%20timing%20function%20is%20applied%20on%20a%20property%2Dby%2Dproperty%20basis%20from%20the%20keyframe%20on%20which%20it%20is%20specified%20until%20the%20next%20keyframe%20specifying%20that%20property%2C%20or%20until%20the%20end%20of%20the%20animation%20if%20there%20is%20no%20subsequent%20keyframe%20specifying%20that%20property) if you want.\n\n> Setting [`animation-timing-function: step-end;`](https://developer.mozilla.org/docs/Web/CSS/animation-timing-function#step-end) to a keyframe can make paused animation until the next keyframe.\n\n## Duration\n\nWe have a fixed duration time of `0.5s` as default for every transition. If you want to set a different default duration for your custom transition, please set `--marp-transition-duration` property in the first keyframe (`from` or `0%`).\n\n<!-- prettier-ignore-start -->\n\n```css\n@keyframes marp-incoming-transition-gate {\n  from {\n    /* Set the default duration of the \"gate\" transition as 1 second. */\n    --marp-transition-duration: 1s;\n\n    clip-path: inset(0 50%);\n  }\n  to { clip-path: inset(0); }\n}\n\n@keyframes marp-outgoing-transition-backward-gate {\n  from {\n    /* You also can set a different default for backward transition as necessary. */\n    /* --marp-transition-duration: 1.5s; */\n\n    clip-path: inset(0);\n  }\n  to { clip-path: inset(0 50%); }\n}\n@keyframes marp-incoming-transition-backward-gate {\n  from { z-index: -1; }\n  to { z-index: -1; }\n}\n```\n\n<!-- prettier-ignore-end -->\n\nThe slide author can override the default duration at any time, through the `transition` local directive in Markdown (`<!-- transition: fade 2s -->`).\n\n## Fixed property\n\nIf some of the properties required a fixed value while playing transition, try to set the same declaration into `from` (0%) and `to` (100%).\n\n<!-- prettier-ignore-start -->\n\n```css\n@keyframes marp-outgoing-transition-pin {\n  /* Use fixed transform-origin */\n  from {\n    transform-origin: top left;\n    animation-timing-function: ease-in;\n  }\n  to {\n    transform-origin: top left;\n    transform: rotate(90deg);\n  }\n}\n\n@keyframes marp-incoming-transition-pin {\n  /* Send the incoming slide layer to back */\n  from { z-index: -1; }\n  to { z-index: -1; }\n}\n```\n\n<!-- prettier-ignore-end -->\n\n## Layer order\n\n[As presented in a diagram earlier](#the-anatomy-of-a-transition), the incoming slide layer always will be stacked on the top of the outgoing slide layer. According to the kind of transition, this order may be not suitable.\n\nA fixed property [`z-index: -1`](https://developer.mozilla.org/docs/Web/CSS/z-index) is helpful to send the incoming slide layer to back.\n\n> A fixed `z-index: 1` to the outgoing slide (send to front) is also getting the same result, but currently setting a positive number to `z-index` may bring animation jank in Chrome.\n\n## Change layer order during a transition\n\nIf you want to swap the order of layers during animation, try to animate `z-index` property.\n\n<!-- prettier-ignore-start -->\n\n```css\n@keyframes marp-incoming-transition-swap {\n  /* Incoming slide will swap from `back` to `front` at 50% of animation */\n  from { z-index: -1; }\n  to { z-index: 0; }\n\n  /* Declarations for moving animation */\n  0% { transform: translateX(0); }\n  50% { transform: translateX(50%); }\n  100% { transform: translateX(0); }\n}\n\n@keyframes marp-outgoing-transition-swap {\n  0% { transform: translateX(0); }\n  50% { transform: translateX(-50%); }\n  100% { transform: translateX(0); }\n}\n```\n\n<!-- prettier-ignore-end -->\n\n`z-index` is always taking an integer value, and interpolated `z-index` value by animation does not take any decimal points too. So animating from `z-index: -1` to `z-index: 0` is exactly meaning to set `-1` at the first half of duration and `0` at the last half, except if using a non-linear easing function.\n\n## Frequently used properties in transition\n\n[There are a lot of animatable CSS properties](https://developer.mozilla.org/docs/Web/CSS/CSS_animated_properties), and the following properties are frequently animated in built-in transitions.\n\n- [`opacity`](https://developer.mozilla.org/docs/Web/CSS/opacity)\n- [`transform`](https://developer.mozilla.org/docs/Web/CSS/transform)\n- [`filter`](https://developer.mozilla.org/docs/Web/CSS/filter)\n- [`clip-path`](https://developer.mozilla.org/docs/Web/CSS/clip-path)\n- [`mask-image`](https://developer.mozilla.org/docs/Web/CSS/mask-image) (`-webkit-mask-image`)\n- [`box-shadow`](https://developer.mozilla.org/docs/Web/CSS/box-shadow)\n- [`z-index`](https://developer.mozilla.org/docs/Web/CSS/z-index)\n\n# Try it!\n\nTransitions for Marp CLI's bespoke template backed by [View Transitions API] in the browser, provides flexibility to design your talk as you like. Custom transition brings out your boundless creativity, without complex JS codings, just declarative definitions in CSS.\n\nWe are really looking forward to what creative transition effects our community will create!\n\nShare the custom transition you've made with [Marp community](https://github.com/orgs/marp-team/discussions). You can provide custom theme CSS including a bunch of custom transitions too.\n"
  },
  {
    "path": "website/blog/marp-for-vs-code-v1.md",
    "content": "---\ntitle: 'Marp for VS Code v1: IntelliSense for Marp directives'\ndate: 2021-05-20\ndescription: I'm happy to announce Marp for VS Code has reached to the stable release v1! This release includes IntelliSense for Marp directives and getting more affinity with VS Code features to get better writing experience.\nauthor: Yuki Hattori\ngithub: yhatt\nimage: /og-images/marp-for-vs-code-v1.jpg\n---\n\nWe are continuing development to make stable Marp tools. And today, I'm happy to announce [Marp for VS Code] has reached to the stable release v1!\n\nTools of Marp ecosystem are made for potentially covering various situations, and especially Marp for VS Code is made for the daily use for the most of users.\n\nThis extension can change the familiar Markdown preview into slides preview during editing Marp Markdown. You can write and edit slides by text rapidly together with checking the appearance of slides, and export into PDF/PPTX easily. [Custom theme support](https://github.com/marp-team/marp-vscode#use-custom-theme-css-shield) is useful to create your own theme with CSS.\n\nIn this release, we have added IntelliSense extension for Marp directives and got more affinity with [VS Code] features. It provides better experience as integrated environment to write the presentation.\n\n[vs code]: https://code.visualstudio.com/\n[marp for vs code]: https://marketplace.visualstudio.com/items?itemName=marp-team.marp-vscode\n\n<!-- more -->\n\n[**➡️ Go to Visual Studio Marketplace to get Marp for VS Code**][marp for vs code]\n\n# History\n\n[![Marp for VS Code](https://raw.githubusercontent.com/marp-team/marp-vscode/main/docs/screenshot.png ' ')][marp for vs code]\n\nMarp for VS Code has started development since 2019, to replace GUI interface from [the classic Marp app](https://yhatt.github.io/marp). It is focusing to provide better experience for writing Marp presentation.\n\n[We had also thought making another Web app as a primary project at that time](/blog/the-story-of-marp-next#marp-web-tech-demo), but VS Code has drastically grown as time goes by. It is covering Web and mobile devices through [GitHub Codespaces](https://visualstudio.microsoft.com/services/github-codespaces/). Thus, we are still continuing development VS Code extension as an official Marp integration for GUI.\n\n# New features\n\n## IntelliSense for Marp directives 🤓\n\n[Directives](https://marpit.marp.app/directives), the inherited feature from [Marpit framework](https://marpit.marp.app/), is an important syntax to write the deck in Marp.\n\nOur extension is depending on 3 different Marp projects that have unique directives. User had been hard to know all of supported directives because the guidance of them has scattered into each tools.\n\nSo we have extended [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense) to cover all of supported Marp directives! Marp for VS Code is now providing powerful editing features for directives: Auto completion, syntax highlight, hover help, and diagnostics.\n\n### Auto completion\n\nHit `Ctrl` + `Space` within [the front-matter](https://marpit.marp.app/directives?id=front-matter) or [HTML comment](https://marpit.marp.app/directives?id=html-comment) to show the list of directives. You can peek the help of selected directive by hitting `Ctrl` + `Space` again.\n\n![Auto completion](/assets/marp-for-vs-code-v1/auto-completion.png 'We remember all, you may forget them 😛')\n\nI worked hard into refactor of a parser for Marp Markdown to get this improvement. This change would make easier to add new language feature like auto-completion for [the extended image syntax](https://marpit.marp.app/image-syntax) in the future.\n\n### Syntax highlight and hover help\n\nWhen enabled Marp feature, recognized directives are highlighted by the different color from around. It's useful for finding out meaningless definitions.\n\nAnd you can peek the help of directive when hovering the cursor.\n\n![Syntax highlight and hover help](/assets/marp-for-vs-code-v1/hover-help.png 'Point at the directive if you were lost 👆')\n\n### Diagnostics\n\nIt is accurately not new feature but I'm sure the most of users have not seen because it had used just for migrating outdated syntax.\n\nIn this update, we have added some helpful diagnostics for Marp directives. For example, Marp for VS Code can notify not recognized theme name that is specified by `theme` directive.\n\n![Diagnostics](/assets/marp-for-vs-code-v1/diagnostics.png 'Detected diagnostics will be listed in \"Problems\"')\n\n## Virtual workspace support 🌐\n\nVS Code is still evolving to cover various situations: [Editing remote files](https://code.visualstudio.com/docs/remote/remote-overview), [collaborating with others](https://code.visualstudio.com/learn/collaboration/live-share), and something useful provided by [a lot of third-party extension](https://marketplace.visualstudio.com/vscode). Marp for VS Code is also making an effort to cover them as far as possible.\n\nIn the recent update, we have improved the export command and custom theme support within a virtual workspace by followed [the call to action from VS Code team](https://code.visualstudio.com/updates/v1_56#_define-whether-your-extension-supports-a-virtual-workspace).\n\nNo problem even if you don't know the virtual workspace! In short, Marp features will become to work correctly in various situation.\n\n### Details\n\nPreviously an export command had assumed to deal only local files. So the result of command might miss some resources that have not located in local file system.\n\nWe are dealing with this by internally serving resources located in a virtual workspace via HTTP while processing of export ([marp-team/marp-vscode#225](https://github.com/marp-team/marp-vscode/pull/225)). By doing this, the result of export command within [a remote repository](https://code.visualstudio.com/updates/v1_56#_remote-repositories-remotehub), a coming feature of VS Code to edit the content of GitHub repository without clone/download, can include resources correctly.\n\nThis behavior is under verifying and may fail to resolve resources in some cases (e.g. [marp-team/marp-vscode#238](https://github.com/marp-team/marp-vscode/issues/238)). We are welcome more feedbacks about the export command in a virtual workspace!\n\n## Workspace Trust 🛡️\n\n[Workspace Trust](https://github.com/microsoft/vscode/issues/106488) is a unified security model for the whole of VS Code. Currently it's an opt-in feature (VS Code 1.56) but it's going to be enabled by default soon. [VS Code team is calling to action into extension authors also for this.](https://code.visualstudio.com/updates/v1_56#_workspace-trust-extension-api)\n\nBased on reflection of [the outdated Marp app](https://yhatt.github.io/marp), Marp team is thinking about users security first. Actually we were passive for supporting a feature that have potentially security concerns (e.g. [marp-team/marp-vscode#123](https://github.com/marp-team/marp-vscode/pull/123)). Making ready for Workspace Trust will become available to contain more advanced features.\n\nMarp for VS Code v1 is supporting Workspace Trust. If the current workspace is not trusted, you can only use basic Marp features (Markdown preview and IntelliSense).\n\n### Restricted features in untrusted workspace\n\n- Export command\n- Using custom themes configured in workspace: `markdown.marp.themes`\n- Enabling HTML tags in Markdown: `markdown.marp.enableHtml`\n\n# Conclusion\n\nMarp for VS Code is focusing into providing the great experience to write presentation. IntelliSense for Marp directives is a big improvement for that. We are going to continue making an effort to cover update of VS Code.\n\nAnd Marp team is always thinking about security. Supporting VS Code's Workspace Trust is an important thing to save you from maliciousness.\n\nIn addition, a way of thinking about the trusted workspace would open the door to more useful features that were prevented by security concerns: Custom Marp CLI configuration, playing presentation, and so on.\n\n## What's next?\n\nThere are no determined things. But supporting Workspace Trust has taken a step toward some advanced features.\n\nWe are planning some well-known features in the other presentation software to reduce friction of moving from familiar tools: the sidebar with slide thumbnails ([marp-team/marp#42](https://github.com/marp-team/marp/discussions/42)), presentation button in lower-right, and so on.\n\n![Sidebar in development](/assets/marp-for-vs-code-v1/plan-sidebar.gif 'Sidebar in development')\n\nEnjoy writing presentation with our extension! And join to [our discussion forum](https://github.com/marp-team/marp/discussions) if you want more Marp tips.\n\n[**➡️ Go to Visual Studio Marketplace to get Marp for VS Code**][marp for vs code]\n"
  },
  {
    "path": "website/blog/marpit-v2-marp-core-v2-and-marp-cli-v1.md",
    "content": "---\ntitle: Marpit v2, Marp Core v2, and Marp CLI v1\ndate: 2021-05-06\ndescription: I'm so glad to announce shipping Marpit framework v2, Marp Core v2, and Marp CLI v1! Especially, Marp CLI is getting stable now!\nauthor: Yuki Hattori\ngithub: yhatt\n---\n\n[marpit framework]: https://marpit.marp.app/\n[marp core]: https://github.com/marp-team/marp-core\n[marp cli]: https://github.com/marp-team/marp-cli\n\nI'm so glad to announce shipping [Marpit framework] v2, [Marp Core] v2, and [Marp CLI] v1! Especially, Marp CLI is getting stable now!\n\nThey are major update that may be including some breaking changes. However, we have not intended to include any drastic changes. We have recognized well that user hates to break the existing slide.\n\nThe biggest reason why bumped major version is ending support for outdated Node.js 10. It has reached to End-of-Life and we are just following that.\n\nMarpit and Marp Core still can use in EOL Node 10, but we are just making a window time for transition. By the security reason, we don't recommend to use outdated Node.js.\n\n<!-- more -->\n\n# Release notes\n\n## [Marpit framework: v2.0.0](https://github.com/marp-team/marpit/releases/tag/v2.0.0)\n\n### Breaking\n\n- Marpit requires Node.js >= 10 to install ([#284](https://github.com/marp-team/marpit/pull/284))\n\n### Fixed\n\n- Reset CSS columns in advanced background ([#283](https://github.com/marp-team/marpit/pull/283))\n\n### Changed\n\n- Upgrade to PostCSS 8 ([#260](https://github.com/marp-team/marpit/issues/260), [#284](https://github.com/marp-team/marpit/pull/284))\n- Upgrade Node and dependent packages to the latest version ([#285](https://github.com/marp-team/marpit/pull/285))\n\n### Removed\n\n- Remove deprecated `markdownItPlugins`, the getter of plugin interface for markdown-it ([#286](https://github.com/marp-team/marpit/pull/286))\n\n## [Marp Core: v2.0.0](https://github.com/marp-team/marp-core/releases/tag/v2.0.0)\n\n### Added\n\n- Allow color customization through CSS variables in Gaia and Uncover theme ([#209](https://github.com/marp-team/marp-core/issues/209), [#221](https://github.com/marp-team/marp-core/pull/221))\n\n> May break appearance of existing presentation if you have a slide with custom style.\n\n### Changed\n\n- Upgrade Marpit to [v2.0.0](https://github.com/marp-team/marpit/releases/v2.0.0) ([#220](https://github.com/marp-team/marp-core/pull/220))\n- Upgrade Node LTS and dependent packages to the latest version ([#222](https://github.com/marp-team/marp-core/pull/222))\n\n## [Marp CLI: v1.0.0](https://github.com/marp-team/marp-cli/releases/tag/v1.0.0)\n\n### Breaking\n\n- Dropped Node 10 support ([#338](https://github.com/marp-team/marp-cli/pull/338))\n\n### Added\n\n- Build Docker container image for ARM64 ([#328](https://github.com/marp-team/marp-cli/issues/328), [#339](https://github.com/marp-team/marp-cli/pull/339))\n- Allow `MARP_USER` env for Docker image to set an explicit UID/GID ([#334](https://github.com/marp-team/marp-cli/pull/334) by [@davebaird](https://github.com/davebaird))\n- Test against Node 16 for Windows ([#338](https://github.com/marp-team/marp-cli/pull/338))\n\n### Changed\n\n- Upgrade [Marpit v2.0.0](https://github.com/marp-team/marpit/releases/tag/v2.0.0) and [Marp Core v2.0.0](https://github.com/marp-team/marp-core/releases/tag/v2.0.0) ([#338](https://github.com/marp-team/marp-cli/pull/338))\n- Upgrade Node and dependent packages to the latest version ([#338](https://github.com/marp-team/marp-cli/pull/338))\n\n# What's Next?\n\nI've posted about [the unified docs, and future plans for our toolset in the last article](/blog/re-creation-of-marp-website). But it was a mistake! Marp team is still alone and I cannot take full-time working for that, so the most of planned features are delayed. Sorry for late.\n\nFor helping us, contribution in [Marp discussion forum](https://github.com/marp-team/marp/discussions) will be good start.\n\n## Marpit framework v3\n\nWe have ve already started for working Marpit v3 on [`v3` branch](https://github.com/marp-team/marpit/tree/v3).\n\nIt's going to be rewritten fully by TypeScript. We are planning to separate Marp slide specific plugins internally, for improvement of collaboration with other slide renderers. In addition, I want to support async conversion by returning Promise in `render()`.\n\nWe also had considered about changing Markdown parser, but we decided not to change. Some Marp users are depending on third party plugins, and it would make a lot of breakings if changed.\n\n# Thanks\n\nOver 5 years have passed from the first release of classic Marp. For keeping maintainability for long time, Marp ecosystem is still aiming to \"minimal\". And now, Marp has used by projects hosted on [Microsoft](https://github.com/microsoft/lage), [Google](https://github.com/google/applied-machine-learning-intensive), and [Facebook](https://github.com/facebookincubator/cargo-guppy).\n\nIn the last year, we opened our [discussion forum](https://github.com/marp-team/marp/discussions) to accept asking and reporting for the whole of Marp toolset. And we have received many feedbacks and contributions from users.\n\nThanks for our community! Marp will keep a growth with users.\n"
  },
  {
    "path": "website/blog/re-creation-of-marp-website.md",
    "content": "---\ntitle: Re-creation of Marp website for the unified docs\ndate: 2020-08-22\ndescription: We are announcing that Marp team is working to the re-creation of marp.app website for hosting the unified documentation.\nauthor: Yuki Hattori\ngithub: yhatt\n---\n\n[marpit framework]: https://marpit.marp.app/\n[marp core]: https://github.com/marp-team/marp-core\n[marp cli]: https://github.com/marp-team/marp-cli\n[marp for vs code]: https://marketplace.visualstudio.com/items?itemName=marp-team.marp-vscode\n\nI could not have imagined that now we are living in a unique pandemic era when I wrote [the last article](/blog/the-story-of-marp-next). Even under those severe circumstances, I'm still making progress of Marp.\n\nMarp gives some tools for making a convincing slide deck with fewer efforts, and they get loved by a lot of users. In early this year, [Marp Core] has reached the stable v1 release, and our tools around the core are keeping steps with it. Needless to mention here, we will keep going to enhance our tools.\n\nToday we are announcing that **Marp team is working to the re-creation of [marp.app](/) website for hosting the unified documentation**. If you are reading this article, you should have already seen the re-created website! Currently the unified docs is not yet ready but we are going to announce here as soon as getting ready.\n\n<!-- more -->\n\n# For the unified documentation\n\nAs Marp ecosystem spreads out, Marp team has become to regard the lack of unified documentation as an important issue. Our docs are scattered to many repos per tool, and it would make confusion when learning overall of Marp. In addition, we often have been asked basics of Marp in the issue tracker and sometimes even prevent our works for evolving Marp.\n\nFor making users take advantage of Marp easier, I'm going to work improving the documentation together with evolving Marp tools.\n\n## Re-created [marp.app](/)\n\nThe re-created web page is the first step for building the unified docs. I had tried various tools to build the website and found a place to rest in [Next.js](https://nextjs.org/) and [Tailwind CSS](https://tailwindcss.com/). I believe we will be able to build more useful documentation pages by these.\n\nIt is managed in our entrance repository [marp-team/marp](https://github.com/marp-team/marp) as same as before. If shipped new documentation, we would accept some improvements in the documentation from the community.\n\n---\n\n## Mid-term plans for Marp tools\n\nMight as well, finally let me share some mid-term plans for each tools I'll work shortly.\n\n- [Marpit framework]: Enhance directives\n- [Marp Core]: Add new built-in theme and simplify auto-scaling feature\n- [Marp CLI]: Handout template\n- [Marp for VS Code]: Better auto-completion for Marp directives\n\nWe also had announced [long-term plans earlier](/blog/the-story-of-marp-next): [Marp Web](https://web.marp.app/), Marp integration modules with [React](https://github.com/marp-team/marp-react) and [Vue](https://github.com/marp-team/marp-react), and [Marpit v2](https://github.com/marp-team/marpit/issues/194). However, _they are not yet in active and may need to reconsider plans because we have not enough positive feedbacks from community._\n"
  },
  {
    "path": "website/blog/the-story-of-marp-next.md",
    "content": "---\ntitle: The story of Marp Next\ndate: 2019-06-06\ndescription: Today, I'm so excited to introduce the story of Marp Next! The full-rewritten Marp is not only just a writer. To be usable in various situations, we build a brand-new Marp ecosystem consisted of multiple modules.\nauthor: Yuki Hattori\ngithub: yhatt\nimage: /og-images/the-story-of-marp-next.png\n---\n\nThe first version of [Marp](https://yhatt.github.io/marp/) was released at almost 3 years ago. At first, it was started from a simple tool for personal usage called \"mdSlide\". And now, Marp has been used by a lot of users who would recognize the real value of the presentation writer. Marp is amassed around [8,000 stars](https://github.com/yhatt/marp/stargazers) until now.\n\nHowever, our headache brought from lacked maintainability to develop. We had received so many requests to the old Marp app, and it has to evolve to keep providing the best writing environment of presentation deck.\n\nToday, I'm so excited to introduce the story of Marp Next! The full-rewritten Marp is not only just a writer. To be usable in various situations, we build **a brand-new Marp ecosystem** consisted of multiple modules. They are developed with JavaScript and TypeScript, and much more maintainable than the previous Marp.\n\n<!-- more -->\n\n# Marp ecosystem\n\nMarp Next has two core components: **[Marpit]** framework and **[Marp Core]**. Tools by Marp ecosystem are usually based on these.\n\n## Marpit\n\n**[Marpit]** is _the skinny framework_ for creating HTML slide deck from Markdown. It is designed to convert Markdown into only minimum assets consisted of static HTML and CSS, and the output can convert into PDF slide deck by printing through Chrome / Chromium.\n\nMarpit has created for using as the base of Marp ecosystem, but it is also independent framework. You may integrate Marpit's Markdown conversion with your tool, even if it's not Marp: [reveal.js](https://codesandbox.io/embed/nw80vrxvpp), [WebSlides](https://codesandbox.io/embed/j3wo2091yw), and so on.\n\n[marpit]: https://marpit.marp.app/\n\n### [Marpit Markdown]: Keep compatibility with a plain Markdown document\n\nWe had received [many requests][issues] to the old Marp, about the additional syntax to help creating beautiful slide deck. On the other hand, we also have received a request that [must respect Markdown syntax strictly](https://github.com/yhatt/marp/issues/87). We have to deal with these contradicted issues.\n\nAdditional syntax provided by Marpit should never break [CommonMark](https://commonmark.org/) document. Thus, the result of rendering keeps looking nice even if you open the Marpit Markdown in a general Markdown editor. And you can even extend the additional syntax via [markdown-it plugins](https://marpit.marp.app/usage?id=extend-marpit-by-plugins) if you need.\n\n[marpit markdown]: https://marpit.marp.app/markdown\n[issues]: https://github.com/yhatt/marp/issues\n\n### [Theme CSS]: Design your deck with clean markup\n\nMarpit has the theming system to allow designing everything of slides by CSS.\n\nThe old Marp had the _limited_ theming system and required deep diving to internal for customization: Build system, [Sass], the logic of Marp app, and so on. So we had to create a brand-new theming system for easy customization of theme with only general CSS knowledge.\n\nMarpit's it only requires a pure CSS, and no additional knowledges! You have only to focus styling HTML semantic elements. It means that you can create theme CSS from now!\n\nIn addition, Marpit has the pixel-perfect slide system like PowerPoint and Keynote. Theme creator never needs to worry about the responsive layout, and could provide design exactly as the author wanted with less effort.\n\n[theme css]: https://marpit.marp.app/theme-css\n[sass]: https://sass-lang.com/\n\n### [Inline SVG slide]&nbsp;(Experimental)\n\nOur unique idea is wrapping each slides by inline SVG. It might feel a bit strange, but makes many advantages.\n\n- Supports pixel-perfect scaling via style definition and **realizes Zero-JS slide deck**.\n- Isolates Markdown contents and prevents that injected DOM by Marpit's advanced feature breaks design defined in theme CSS.\n\nThanks to the power of SVG, we can keep a framework simple and maintainable. [Marp Core] is based on inline SVG slide by default.\n\n[inline svg slide]: https://marpit.marp.app/inline-svg\n\n## Marp Core\n\n**[Marp Core]** is a base converter for our projects extended from Marpit. In short, it is a battery-included Marpit.\n\nMarpit only has bare essential features, so it might have not enough to start writing your deck. Marp Core provides the practical syntax, additional features, and built-in themes.\n\nMany of the features are based on the old desktop app, and have improved to be suitable to Marpit. Of course, we added the new features for creating more beautiful deck.\n\n[marp core]: https://github.com/marp-team/marp-core\n\n- Built-in themes (Default, Gaia, and _new_ Uncover theme)\n- Included Emoji support 😁\n- [KaTeX](https://katex.org/) Math typesetting\n- `size` global directive\n- Auto scaling features (_new_)\n  - Fitting header via `<!-- fit -->` annotation\n  - Scale-down overflowed fence, code, and math block\n\n# Applications\n\n## Marp CLI\n\n[marp cli]: https://github.com/marp-team/marp-cli\n\n**[Marp CLI]** is a CLI interface of Marpit and Marp Core converter. It's a Swiss-Army knife for Marp slide deck!\n\n[![Marp CLI](https://raw.githubusercontent.com/marp-team/marp-cli/main/docs/images/marp-cli.gif ' ')][marp cli]\n\nYou can use it right now by running `npx @marp-team/marp-cli` if [Node.js](https://nodejs.org/) is installed.\n\n- Export to HTML, PDF, and image\n- Watch the change of your Markdown and theme (`--watch`)\n- Open preview window for presentation (`--preview`)\n- Full-customizable engine based on Marpit framework\n\nMarp had a text editor originally, but you might think that want to write the slide deck with your favorite editor. If you use Vim, you would feel uncomfortable not to be usable Vim style key-binding. From now on, use Marp CLI's watch mode together with original Vim!\n\nAnd Marp CLI can create really practicable static HTML as like as a presentation mode! It is powered by deep integration with [Bespoke.js](https://github.com/bespokejs/bespoke).\n\nThanks to [Netlify], [Now], and more hosting services, Marp CLI also brings a efficient Git management for creating slide deck just like [GitPitch]. I've created [an example slide](https://yhatt-marp-cli-example.netlify.com/) managed via [GitHub repository](https://github.com/yhatt/marp-cli-example) as a good starter to help writing your slide deck. Try to use it via \"Deploy to Netlify\" button on [README](https://github.com/yhatt/marp-cli-example/blob/master/README.md#usage)!\n\n[netlify]: https://www.netlify.com/\n[now]: https://zeit.co/now/\n[gitpitch]: https://gitpitch.com/\n\n## Marp Web (_tech demo_)\n\n**[Marp Web]** is a Web interface of Marp presentation writer. It allows writing your slide deck as like as a traditional desktop app.\n\n> The current Marp Web is just a tech demo. We are planning to re-implement Marp Web based on well-known framework (like React) for building SPA.\n\n[marp web]: https://web.marp.app/\n\n### Progressive Web Apps\n\nIt made [some strong oppositions by users that is using Marp in offline](https://github.com/yhatt/marp/issues/174#issuecomment-294594856) when an idea of migration to web-based app is proposed for keeping maintainability of Marp. It was caused that a thinking of PWA was not general at that time.\n\nAnd 2 years later, the time has come to use PWA! After the first access to **[https://web.marp.app/][marp web]**, Marp Web would be ready to use in both of online and offline. Online resources to use the web interface would be cached in your browser, and use them when network is offline.\n\n[![Marp Web + Progressive Web Apps](https://raw.githubusercontent.com/marp-team/marp-web/master/desktop-pwa.png ' ')][marp web]\n\n### Use via any devices\n\nBy migrating to the web-based app, Marp will be able using in mobile device: Android and iOS. That's sure it's well suited to the tablet device like iPad.\n\n![Marp Web on iPad](https://user-images.githubusercontent.com/3993388/50569518-5305c800-0daa-11e9-8fa4-08053c9b51cd.png ' ')\n\nMarp Web would work also in Chrome OS well. Marp especially has many users in the field of education, and supporting Chrome OS that has large share in its field is meaningful.\n\n### Blazing-fast live preview ⚡️\n\nWe think Marp's important feature is a blazing-fast live preview. In the web-based app, realizing the same feature had many difficulties.\n\nIn currently published tech-demo, you can try Marp's really fast preview on the web. The preview applies as soon as typing, and it would not block your typing even if you have a large Markdown slides over than 100 pages.\n\n# Integrations\n\nThe modularized Marp Core brought Marp integrations for some tools.\n\n## [Marp for VS Code][marp vscode]\n\nHonestly, I don't think to want to make a new editor because there are many great Markdown editors in the world. I had been thinking it would be awesome if Marp could integrate with a something else powerful Markdown editor. And now, Marp can use in [Visual Studio Code](https://code.visualstudio.com/)!\n\n![Marp for VS Code](/assets/marp-for-vs-code.png ' ')\n\nIt was realized because VS Code is using the same Markdown engine (markdown-it) as Marpit framework. Of course, you can export slides as PDF and HTML easily, powered by [Marp CLI].\n\n[marp vscode]: https://marketplace.visualstudio.com/items?itemName=marp-team.marp-vscode\n\n## [Marp React] &amp; [Marp Vue] (In development)\n\n[marp react]: https://github.com/marp-team/marp-react\n[marp vue]: https://github.com/marp-team/marp-vue\n\nMarp's blazing fast live-preview is not only for ours! We provide Marp renderer component into [React][marp react] and [Vue][marp vue]. Both Marp React and Marp Vue have supported the incremental update using framework's virtual DOM, and they are been easy to build your app.\n\nEspecially, Marp React would become to the base of the future of [Marp Web].\n\n# Migration plan\n\n## Desktop app ([yhatt/marp](https://github.com/yhatt/marp))\n\nIf you are using an old Marp application, **you should migrate to use Marp Next tools.** I NEVER recommend continue to use the old Marp, because _its maintainance has stopped 2 years ago and there is concern about security issues._\n\nIn future, the main interface would become to Marp Web. We have bet to PWA technology that has a lot of advantages. The desktop app is planned as \"Marp Desktop\" but it just may become a wrapper of Web interface.\n\nI would stop publishing the old Marp and archive its repository if Marp Web has grown to become replaceable the old Marp.\n\n## Your slide deck\n\nYour Markdown slides written in the old Marp syntax should rewrite to suit to the brand-new Marp ecosystem.\n\nIn a new Marp, we have reconsidered Markdown syntax based on feedback to the old Marp app. So, some syntaxes are losing compatibility.\n\n### Syntax\n\n- In Marp Core, non-whitelisted HTML elements are disabled by default because of security reason. Currently our whitelist includes only `<br>` element. Some Marp Next tools has provided preference to enable HTML, but you should take care for enabling HTML in untrusted Markdown.\n\n### Directives\n\n- Directives would be parsed by YAML parser tuned for Marp (Marpit). Thus spot directive prefix `*` is changed to `_` for keeping YAML syntax.\n- `$` prefix no longer required to global directives.\n- Slide size still can choose from \"16:9\" and \"4:3\", through `size` global directive (provided by Marp Core). If you want to use custom size or you're using Marpit framework, please use [theme CSS](https://marpit.marp.app/theme-css?id=slide-size).\n- `page_number` directive is renamed to `paginate`.\n- `template` directive is renewed to use `class` directive. It can define HTML class per slides.\n- `prerender` directive is removed. It brings user confusing about exported PDF quality.\n\n### Image\n\n- Background image `![bg]()` has no filter applied by default. Try using `![bg opacity]()` if you want.\n- The inline image is no longer scalable by percentage `![50%]()`. (It's not supported in Firefox) Instead you can use `width` (`w`) and `height` (`w`) keyword to resize image as like as `![width:300px]()`.\n- `![center]()` won't work. It requires changing image to the block element and brings confusion to theme author. You can tweak style if you still want.\n\n```html\n<style>\n  img[alt~='center'] {\n    display: block;\n    margin-left: auto;\n    margin-right: auto;\n  }\n</style>\n```\n\n# Try Marp Next!\n\nMarp Next just focuses to build the ecosystem for Markdown slide deck with pure open source. We expect to expand Marp productivity together with open source community.\n\nWe still have stood at the beginning of the brand-new ecosystem. Are you interested to Marp team and our ecosystem? We welcome to start your contribution! See [our contributing guideline](https://github.com/marp-team/.github/blob/master/CONTRIBUTING.md) and get started!\n\n> PS. [GitHub Sponsors](https://github.com/sponsors/yhatt) is also good contribution if you want to help my working for open source.\n"
  },
  {
    "path": "website/components/Button.tsx",
    "content": "import classNames from 'classnames'\nimport { ReactNode } from 'react'\n\nexport type ButtonProps = {\n  children?: ReactNode\n  color?: 'primary'\n  href?: string\n  outline?: boolean\n  [key: string]: unknown\n}\n\nexport const Button = ({\n  children,\n  className,\n  color,\n  href,\n  outline,\n  ...rest\n}: ButtonProps) => {\n  const Tag = href ? 'a' : 'button'\n  const attrs = {\n    ...rest,\n    ...(Tag === 'a' ? { href, role: 'button', tabIndex: 0 } : {}),\n  }\n\n  return (\n    <Tag\n      {...attrs}\n      className={classNames(\n        Tag === 'a' && 'custom-anchor',\n        'button',\n        color,\n        { btnOutline: outline },\n        className as any\n      )}\n    >\n      {children}\n      <style jsx>{`\n        .button {\n          @apply relative inline-block select-none appearance-none rounded-full bg-white text-center font-bold no-underline shadow-md;\n\n          padding: 0.625em 1.25em;\n          transition: color, background-color, opacity;\n        }\n\n        @screen md {\n          .button {\n            @apply tracking-wider;\n          }\n        }\n\n        .button:hover {\n          @apply bg-background duration-150;\n        }\n        .button:hover:active {\n          @apply duration-0 bg-gray-300 outline-none ring-1 ring-white ring-offset-2;\n        }\n        .button:focus {\n          @apply outline-none ring-1 ring-white ring-offset-2;\n        }\n\n        /* Primary color */\n        .button.primary {\n          @apply bg-marp-brand text-white;\n\n          background-image: linear-gradient(\n            30deg,\n            transparent,\n            rgba(255, 255, 255, 0.3)\n          );\n        }\n        .button.primary:hover {\n          @apply bg-marp-darken;\n        }\n        .button.primary:hover:active {\n          @apply bg-marp-dark;\n        }\n\n        /* Outline */\n        .button.btnOutline {\n          @apply text-foreground;\n        }\n        .button.btnOutline::after {\n          @apply pointer-events-none absolute inset-0 block border-2 border-current;\n\n          border-radius: inherit;\n          content: '';\n          transition: inherit;\n        }\n\n        .button.btnOutline.primary {\n          @apply text-marp-darken bg-white;\n\n          background-image: none;\n        }\n        .button.btnOutline.primary:hover {\n          @apply bg-marp-darken text-white;\n        }\n        .button.btnOutline.primary:hover::after {\n          @apply opacity-0;\n        }\n      `}</style>\n    </Tag>\n  )\n}\n"
  },
  {
    "path": "website/components/CodeBlock.tsx",
    "content": "/* eslint-disable react/jsx-key */\nimport classNames from 'classnames'\nimport Highlight, {\n  defaultProps,\n  Language,\n  PrismTheme,\n} from 'prism-react-renderer'\nimport nightOwlLight from 'prism-react-renderer/themes/nightOwlLight'\nimport { useRef, useState, MouseEvent } from 'react'\nimport { Button } from 'components/Button'\n\nconst theme: PrismTheme = {\n  plain: {\n    ...nightOwlLight.plain,\n    backgroundColor: '#f5f5f5',\n  },\n  styles: [\n    ...nightOwlLight.styles,\n    { types: ['italic'], style: { fontStyle: 'italic' } },\n    { types: ['important', 'bold'], style: { fontWeight: 'bold' } },\n  ],\n}\n\nexport type CodeBlockProps = {\n  children: string\n  copyButton?: boolean\n  language: Language\n  lineNumber?: boolean\n  [key: string]: unknown\n}\n\nexport const CodeBlock = ({\n  children,\n  className,\n  copyButton,\n  language,\n  lineNumber = false,\n  ...rest\n}: CodeBlockProps) => {\n  const [copied, setCopied] = useState(false)\n  const copiedTimer = useRef<number | undefined>(undefined)\n\n  return (\n    <>\n      <Highlight\n        {...defaultProps}\n        code={children}\n        language={language}\n        theme={theme}\n      >\n        {({ className: cn, style, tokens, getLineProps, getTokenProps }) => (\n          <div className={classNames('code-block-container', className as any)}>\n            <pre\n              className={classNames(lineNumber && 'line-number', cn)}\n              style={style}\n              {...rest}\n            >\n              <code className=\"code-block\">\n                <ol className=\"code-block\">\n                  {tokens.map((line, i) => {\n                    const lineProps = getLineProps({ line, key: i })\n\n                    return (\n                      <li\n                        {...lineProps}\n                        className={classNames(\n                          lineProps.className,\n                          'code-block'\n                        )}\n                      >\n                        {line.map((token, key) =>\n                          token.empty ? (\n                            <br key={key} />\n                          ) : (\n                            <span {...getTokenProps({ token, key })} />\n                          )\n                        )}\n                      </li>\n                    )\n                  })}\n                </ol>\n              </code>\n            </pre>\n            {copyButton && (\n              <div className=\"copy-btn-container\">\n                <Button\n                  className={copied ? 'copied' : undefined}\n                  onClick={(e: MouseEvent<HTMLButtonElement>) => {\n                    const tmpTextarea = document.createElement('textarea')\n                    tmpTextarea.value = children\n\n                    tmpTextarea.style.position = 'absolute'\n                    tmpTextarea.style.left = '0'\n                    tmpTextarea.style.top = '0'\n                    tmpTextarea.style.opacity = '0'\n                    tmpTextarea.style.pointerEvents = 'none'\n\n                    document.body.appendChild(tmpTextarea)\n                    tmpTextarea.select()\n\n                    document.execCommand('copy')\n                    document.body.removeChild(tmpTextarea)\n                    e.currentTarget.focus()\n\n                    // Update React state\n                    setCopied(true)\n\n                    if (copiedTimer.current !== undefined) {\n                      window.clearTimeout(copiedTimer.current)\n                    }\n\n                    copiedTimer.current = window.setTimeout(() => {\n                      copiedTimer.current = undefined\n                      setCopied(false)\n                    }, 1000)\n                  }}\n                >\n                  {copied ? 'Copied!' : 'Copy'}\n                </Button>\n              </div>\n            )}\n          </div>\n        )}\n      </Highlight>\n      <style jsx>{`\n        .code-block-container {\n          @apply relative;\n        }\n\n        .prism-code {\n          @apply overflow-x-auto overflow-y-hidden whitespace-pre break-words rounded-md border text-sm leading-5;\n\n          font-family: inherit;\n          background-image: var(--noise-image);\n        }\n\n        .prism-code code {\n          @apply inline-block min-w-full p-4 font-mono;\n        }\n\n        .prism-code.line-number {\n          @apply whitespace-pre-wrap;\n        }\n\n        .prism-code.line-number ol {\n          counter-reset: line 0;\n        }\n\n        .prism-code.line-number li {\n          @apply relative pl-12;\n\n          counter-increment: line;\n        }\n\n        .prism-code.line-number li::before {\n          @apply absolute inset-0 w-12 pr-3 text-right text-xs leading-5 text-gray-500;\n\n          content: counter(line);\n        }\n\n        .copy-btn-container {\n          @apply absolute top-0 right-0 m-3;\n        }\n\n        .copy-btn-container :global(button) {\n          @apply w-24 py-1 text-xs opacity-0 transition-opacity duration-300;\n        }\n\n        .code-block-container:hover .copy-btn-container :global(button),\n        .copy-btn-container :global(button):focus {\n          @apply opacity-100;\n        }\n      `}</style>\n    </>\n  )\n}\n"
  },
  {
    "path": "website/components/Footer.tsx",
    "content": "import { ScrollToTop } from 'components/ScrollToTop'\n\nexport const Footer = () => (\n  <footer>\n    <div className=\"container mx-auto table\">\n      <p className=\"mx-6 my-5 mr-20 leading-loose\">\n        Copyright © 2019-{process.env.BUILD_YEAR} Marp team.&emsp;\n        <iframe\n          className=\"inline-block align-text-top\"\n          src=\"https://ghbtns.com/github-btn.html?user=marp-team&amp;repo=marp&amp;type=star&amp;count=true\"\n          frameBorder={0}\n          scrolling=\"0\"\n          width={150}\n          height={20}\n          title=\"GitHub\"\n          loading=\"lazy\"\n        ></iframe>\n      </p>\n      <ScrollToTop />\n    </div>\n    <style jsx>{`\n      footer {\n        @apply bg-gray-800 text-gray-500;\n\n        min-height: 4.5rem;\n        background-image: var(--noise-image);\n      }\n    `}</style>\n  </footer>\n)\n"
  },
  {
    "path": "website/components/Header.tsx",
    "content": "import classNames from 'classnames'\nimport Link from 'next/link'\nimport MarpLogo from 'public/assets/marp-logo.svg'\n\nconst handleMouseUp = (e: React.MouseEvent<HTMLElement>) =>\n  e.currentTarget.blur()\n\nexport type ItemSlug = 'docs' | 'blog'\n\nexport const Header = ({ activeItem }: { activeItem?: ItemSlug }) => (\n  <>\n    <header className=\"header\">\n      <Link href=\"/\" legacyBehavior>\n        <a\n          className=\"custom-anchor header-item\"\n          role=\"link\"\n          tabIndex={0}\n          onMouseUp={handleMouseUp}\n        >\n          <MarpLogo className=\"block h-16 w-16 p-2 md:h-20 md:w-20 md:p-3\" />\n          <span className=\"sr-only\">Marp</span>\n        </a>\n      </Link>\n      <nav className=\"ml-2\">\n        <ul className=\"flex h-16 items-stretch md:h-20\">\n          {process.env.NEXT_PUBLIC_DOCS && (\n            <li className=\"relative flex items-center justify-center\">\n              <Link href=\"/docs\" legacyBehavior>\n                <a\n                  className={classNames('custom-anchor header-item nav-item', {\n                    active: activeItem === 'docs',\n                  })}\n                  role=\"link\"\n                  tabIndex={0}\n                  onMouseUp={handleMouseUp}\n                >\n                  <span>Docs</span>\n                </a>\n              </Link>\n            </li>\n          )}\n          <li className=\"relative flex items-center justify-center\">\n            <Link href=\"/blog\" legacyBehavior>\n              <a\n                className={classNames('custom-anchor header-item nav-item', {\n                  active: activeItem === 'blog',\n                })}\n                role=\"link\"\n                tabIndex={0}\n                onMouseUp={handleMouseUp}\n              >\n                <span>Blog</span>\n              </a>\n            </Link>\n          </li>\n          <li className=\"relative flex items-center justify-center\">\n            <a\n              href=\"https://github.com/marp-team/marp\"\n              target=\"_blank\"\n              rel=\"noopener noreferrer\"\n              className=\"custom-anchor header-item nav-item\"\n              onMouseUp={handleMouseUp}\n            >\n              <span>GitHub</span>\n            </a>\n          </li>\n        </ul>\n      </nav>\n      <style jsx>{`\n        :global(:root) {\n          @apply [--header-height:theme(spacing.16)] md:[--header-height:theme(spacing.20)];\n        }\n\n        .header {\n          @apply fixed top-0 left-0 z-50 flex h-[var(--header-height)] w-full justify-center bg-white shadow-sm;\n        }\n\n        .header-item {\n          @apply text-current no-underline outline-none;\n        }\n\n        .header-item > :global(svg) {\n          @apply transition-transform duration-200;\n        }\n\n        .header-item:hover:active > :global(svg) {\n          @apply duration-0 scale-125 transform shadow-none;\n        }\n\n        @media not all and (hover: none) {\n          .header-item:hover:active > :global(svg) {\n            @apply scale-110;\n          }\n        }\n\n        .nav-item {\n          @apply font-rounded mx-2 text-lg font-medium uppercase leading-none outline-none;\n        }\n\n        .nav-item::before {\n          @apply absolute inset-0;\n\n          content: '';\n        }\n\n        .header-item:focus-visible,\n        .nav-item:focus-visible::before {\n          @apply bg-gray-200;\n        }\n\n        .header-item:not(.nav-item) {\n          -webkit-tap-highlight-color: transparent;\n        }\n\n        @screen md {\n          .nav-item {\n            @apply mx-3 tracking-wider;\n          }\n        }\n\n        .nav-item > span {\n          @apply relative z-10;\n        }\n\n        .nav-item > span::after {\n          @apply absolute inset-x-0 mt-1 block h-1 transition-all duration-300;\n\n          content: '';\n          top: 100%;\n        }\n\n        .nav-item:hover > span::after,\n        .nav-item:focus-within > span::after {\n          box-shadow: inset 0 -0.25rem theme('colors.gray.400');\n        }\n\n        .nav-item.active > span::after {\n          @apply duration-0;\n          box-shadow: inset 0 -0.25rem theme('colors.marp.brand');\n        }\n\n        .nav-item:hover:active > span::after {\n          @apply duration-0;\n          box-shadow: inset 0 -0.25rem theme('colors.marp.dark');\n        }\n      `}</style>\n    </header>\n  </>\n)\n"
  },
  {
    "path": "website/components/Layout.tsx",
    "content": "import Head from 'next/head'\nimport { useRouter } from 'next/router'\nimport { Footer } from 'components/Footer'\nimport { Header, ItemSlug } from 'components/Header'\nimport { generateTitle } from 'utils/title'\nimport { absoluteUrl } from 'utils/url'\n\nexport type LayoutProps = React.PropsWithChildren<{\n  activeItem?: ItemSlug\n  canonical?: string\n  description?: string\n  image?: string\n  noIndex?: boolean\n  title?: string | string[]\n  type?: string\n}>\n\nconst defaultDescription =\n  'Marp (also known as the Markdown Presentation Ecosystem) provides an intuitive experience for creating beautiful slide decks. You only have to focus on writing your story in a Markdown document.'\n\nexport const Layout: React.FC<LayoutProps> = ({\n  activeItem,\n  canonical: _canonical,\n  children,\n  description = defaultDescription,\n  image: _image,\n  noIndex,\n  title: _title,\n  type = 'article',\n}) => {\n  const router = useRouter()\n\n  const canonical = absoluteUrl(_canonical || router.asPath).href\n  const image = _image || '/assets/og-image.png'\n  const title = typeof _title === 'string' ? _title : generateTitle(_title)\n\n  return (\n    <>\n      <Head>\n        <title key=\"title\">{title}</title>\n        {description && (\n          <>\n            <meta name=\"description\" key=\"description\" content={description} />\n            <meta\n              property=\"og:description\"\n              key=\"og:description\"\n              content={description}\n            />\n          </>\n        )}\n        {canonical && (\n          <>\n            <link rel=\"canonical\" key=\"canonical\" href={canonical} />\n            <meta property=\"og:url\" key=\"og:url\" content={canonical} />\n          </>\n        )}\n        <meta property=\"og:title\" key=\"og:title\" content={title} />\n        <meta property=\"og:type\" key=\"og:type\" content={type} />\n        <meta\n          property=\"og:image\"\n          key=\"og:image\"\n          content={absoluteUrl(image).href}\n        />\n        <meta\n          property=\"twitter:card\"\n          key=\"twitter:card\"\n          content={\n            type === 'website' || _image ? 'summary_large_image' : 'summary'\n          }\n        />\n        {noIndex && <meta name=\"robots\" content=\"noindex,nofollow\" />}\n      </Head>\n      <Header activeItem={activeItem} />\n      <main className=\"relative mt-16 md:mt-20\">\n        {children}\n        <style jsx>{`\n          main {\n            min-height: calc(100vh - 8.5rem);\n          }\n\n          @screen md {\n            main {\n              min-height: calc(100vh - 9.5rem);\n            }\n          }\n        `}</style>\n      </main>\n      <Footer />\n    </>\n  )\n}\n"
  },
  {
    "path": "website/components/Marp.tsx",
    "content": "import { Marp as MarpCore } from '@marp-team/marp-core'\nimport classNames from 'classnames'\nimport postcss, { Plugin } from 'postcss'\nimport postcssImportUrl from 'postcss-import-url'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { Swiper as SwiperClass } from 'swiper'\nimport { Swiper, SwiperSlide } from 'swiper/react'\nimport { useFontFace } from 'utils/hooks/useFontFace'\n\nexport type RenderedMarp = ReturnType<\n  typeof generateRenderedMarp\n> extends Promise<infer T>\n  ? T\n  : never\n\nexport type MarpProps = {\n  border?: boolean\n  className?: string\n  rendered: Pick<RenderedMarp, 'css' | 'html' | 'fonts'>\n  page?: number\n}\n\nconst postcssStripFontFace = Object.assign(\n  (): Plugin => ({\n    postcssPlugin: 'marp-strip-font-face',\n    AtRule: (rule, { result }) => {\n      if (rule.name === 'font-face') {\n        result['fonts'] = [...(result['fonts'] || []), rule]\n        rule.remove()\n      }\n    },\n  }),\n  { postcss: true as const }\n)\n\nexport const generateRenderedMarp = async (markdown: string) => {\n  const marp = new MarpCore({\n    container: false,\n    script: false,\n    printable: false,\n  })\n\n  const { css, html } = marp.render(markdown, { htmlAsArray: true })\n\n  const result = await postcss()\n    .use(postcssImportUrl)\n    .use(postcssStripFontFace)\n    .process(css, { from: undefined })\n\n  const fonts: string[] = (result['fonts'] || []).map((font) => font.toString())\n\n  return { markdown, html, css: result.css, fonts }\n}\n\nexport const Marp = ({\n  border = true,\n  className,\n  rendered: { css, html, fonts },\n  page = 1,\n}: MarpProps) => {\n  const element = useRef<HTMLDivElement>(null)\n\n  useFontFace(fonts)\n\n  useEffect(() => {\n    if (!element.current) return\n    if (!element.current.shadowRoot)\n      element.current.attachShadow({ mode: 'open' })\n\n    // Render Marp slide to shadow root (tailwind default styles will break Marp slide CSS)\n    const root = element.current.shadowRoot as ShadowRoot\n\n    root.innerHTML =\n      html[page - 1] +\n      `<style>${css}</style><style>:host{all:initial;}:host>[data-marpit-svg]{vertical-align:top;}</style>`\n\n    // eslint-disable-next-line @typescript-eslint/no-var-requires\n    return require('@marp-team/marp-core/browser').browser(root)\n  }, [css, html, page])\n\n  return (\n    <div className={classNames(border && 'border shadow-lg', className)}>\n      <span ref={element} />\n    </div>\n  )\n}\n\nexport const MarpSlides = (props) => {\n  const htmlRaw: string = props['data-html']\n  const css: string = props['data-css']\n  const fontsRaw: string = props['data-fonts']\n\n  const [activePageIdx, setActivePageIdx] = useState(0)\n  const swiper = useRef<SwiperClass>()\n  const html = useMemo(() => JSON.parse(htmlRaw) as string[], [htmlRaw])\n  const multiple = html.length > 1\n  const fonts = useMemo(() => JSON.parse(fontsRaw) as string[], [fontsRaw])\n\n  const handleActiveIndexChange = useCallback((instance: SwiperClass) => {\n    setActivePageIdx(instance.activeIndex)\n  }, [])\n\n  const handleSwiper = useCallback(\n    (instance: SwiperClass) => {\n      swiper.current = instance\n      handleActiveIndexChange(instance)\n    },\n    [handleActiveIndexChange]\n  )\n\n  return (\n    <section className={classNames('marp-slides', multiple && 'multiple')}>\n      {multiple && (\n        <button\n          aria-label=\"Prev\"\n          className=\"marp-navigation left-0\"\n          disabled={activePageIdx <= 0}\n          onClick={() => swiper.current?.slidePrev()}\n          translate=\"no\"\n        >\n          &laquo;\n        </button>\n      )}\n      <Swiper\n        enabled={multiple.toString() as any}\n        allowTouchMove={multiple}\n        speed={200}\n        onActiveIndexChange={handleActiveIndexChange}\n        onSwiper={handleSwiper}\n      >\n        {html.map((h, i) => (\n          <SwiperSlide key={h}>\n            <div inert={activePageIdx === i ? undefined : ''}>\n              <Marp\n                border={false}\n                rendered={{ html, css, fonts }}\n                page={i + 1}\n              />\n            </div>\n          </SwiperSlide>\n        ))}\n      </Swiper>\n      {multiple && (\n        <button\n          aria-label=\"Next\"\n          className=\"marp-navigation right-0\"\n          disabled={activePageIdx >= html.length - 1}\n          onClick={() => swiper.current?.slideNext()}\n          translate=\"no\"\n        >\n          &raquo;\n        </button>\n      )}\n      <style jsx>{`\n        .marp-slides {\n          @apply relative my-6 mx-auto w-full max-w-sm border bg-gray-200 shadow-lg lg:max-w-lg;\n        }\n        .marp-slides.multiple {\n          @apply px-8;\n        }\n\n        .marp-navigation {\n          @apply absolute inset-y-0 z-10 w-8 appearance-none bg-gray-300 text-4xl text-gray-600 outline-none;\n\n          user-select: none;\n        }\n        .marp-navigation:hover:not(:disabled) {\n          @apply bg-gray-400;\n        }\n        .marp-navigation:hover:active {\n          @apply text-gray-700;\n        }\n        .marp-navigation:disabled {\n          @apply pointer-events-none text-opacity-30;\n        }\n        .marp-navigation:focus-visible {\n          @apply ring-marp-brand ring-2;\n        }\n      `}</style>\n    </section>\n  )\n}\n"
  },
  {
    "path": "website/components/ScrollToTop.tsx",
    "content": "import { ArrowUpIcon } from '@primer/octicons-react'\nimport { useCallback } from 'react'\n\nexport const ScrollToTop = () => {\n  const handleClick = useCallback<React.MouseEventHandler<HTMLElement>>((e) => {\n    window.scrollTo({ top: 0 })\n    e.currentTarget.blur()\n  }, [])\n\n  return (\n    <div className=\"scroll-to-top\">\n      <button onClick={handleClick} title=\"Scroll to top\">\n        <ArrowUpIcon className=\"scroll-to-top-icon\" />\n        <span className=\"sr-only\">Scroll to top</span>\n      </button>\n      <style jsx>{`\n        .scroll-to-top {\n          @apply pointer-events-none fixed right-0 bottom-0 z-50;\n\n          filter: drop-shadow(0 0px 7px rgba(0, 0, 0, 0.3))\n            drop-shadow(0 0px 4px rgba(0, 0, 0, 0.15));\n        }\n        button {\n          @apply bg-marp-light pointer-events-auto h-20 w-20 appearance-none align-top text-white;\n\n          clip-path: polygon(100% 0, 100% 100%, 0 100%);\n        }\n        button:hover {\n          @apply bg-marp-brand;\n        }\n        button:focus {\n          @apply outline-none;\n        }\n        button:focus,\n        button:hover:active {\n          @apply bg-marp-dark;\n        }\n        button :global(.scroll-to-top-icon) {\n          height: auto;\n          left: 52%;\n          position: absolute;\n          top: 52%;\n          width: 35%;\n        }\n      `}</style>\n    </div>\n  )\n}\n"
  },
  {
    "path": "website/components/Title.tsx",
    "content": "// eslint-disable-next-line @typescript-eslint/ban-types\nexport const Title: React.FC<React.PropsWithChildren<{}>> = ({ children }) => (\n  <section className=\"bg-marp-brand border-b py-3  text-white\">\n    <h1 className=\"font-rounded text-center text-3xl font-bold uppercase\">\n      {children}\n      <style jsx>{`\n        & :global(a),\n        & :global(a:hover),\n        & :global(a:hover:active) {\n          @apply text-current no-underline;\n        }\n        & :global(a:focus-visible) {\n          @apply underline outline-none;\n        }\n      `}</style>\n    </h1>\n  </section>\n)\n"
  },
  {
    "path": "website/components/Typography.tsx",
    "content": "// eslint-disable-next-line @typescript-eslint/ban-types\nexport const Typography: React.FC<React.PropsWithChildren<{}>> = ({\n  children,\n}) => (\n  <div className=\"typography\">\n    {children}\n    <style jsx>{`\n      .typography {\n        @apply break-words text-base leading-relaxed;\n      }\n      .typography :global(p) {\n        @apply my-4;\n      }\n      .typography :global(h1) {\n        @apply relative mt-8 mb-5 text-3xl font-bold;\n      }\n      .typography :global(h2) {\n        @apply relative mt-8 mb-5 text-2xl font-bold;\n      }\n      .typography :global(h3) {\n        @apply relative mt-8 mb-4 text-xl font-bold;\n      }\n      .typography :global(h4) {\n        @apply relative mt-6 mb-4 text-lg font-bold;\n      }\n      .typography :global(h5) {\n        @apply relative mt-6 mb-4 text-base font-bold;\n      }\n      .typography :global(h6) {\n        @apply relative mt-6 mb-4 text-sm font-bold text-gray-600;\n      }\n      .typography :global(.anchor-link) {\n        @apply absolute inset-0 my-auto -ml-5 hidden w-5 overflow-hidden whitespace-nowrap bg-left bg-no-repeat;\n\n        background-size: 1rem 1rem;\n        background-image: url('https://icongr.am/octicons/link.svg?color=718096');\n      }\n      .typography :global(h1:hover > .anchor-link),\n      .typography :global(h2:hover > .anchor-link),\n      .typography :global(h3:hover > .anchor-link),\n      .typography :global(h4:hover > .anchor-link),\n      .typography :global(h5:hover > .anchor-link),\n      .typography :global(h6:hover > .anchor-link) {\n        @apply block;\n      }\n      .typography :global(hr) {\n        @apply my-8;\n      }\n      .typography :global(blockquote) {\n        @apply border-marp-light my-6 border-l-4 pl-5 text-gray-600;\n      }\n      .typography :global(blockquote blockquote) {\n        border-left-width: 3px;\n      }\n      .typography :global(blockquote blockquote blockquote) {\n        @apply border-l-2;\n      }\n      .typography :global(ul) {\n        @apply my-6 ml-8 mr-3 list-disc;\n      }\n      .typography :global(ul ul) {\n        list-style-type: circle;\n      }\n      .typography :global(ul ul ul) {\n        list-style-type: square;\n      }\n      .typography :global(ol:not(.code-block)) {\n        @apply my-6 ml-8 mr-3 list-decimal;\n      }\n      .typography :global(ul ul),\n      .typography :global(ul ol:not(._)),\n      .typography :global(ol:not(._) ul),\n      .typography :global(ol:not(._) ol:not(._)) {\n        @apply my-0 mr-0;\n      }\n      .typography :global(li:not(.code-block)) {\n        @apply my-1;\n      }\n      .typography :global(code:not(.code-block)) {\n        @apply rounded border border-gray-400 bg-gray-200;\n\n        font-size: 0.9em;\n        padding: 0.15em 0.35em;\n      }\n      .typography :global(pre) {\n        @apply my-6;\n      }\n      .typography :global(img) {\n        @apply inline;\n      }\n      .typography :global(figure) {\n        @apply my-6;\n      }\n      .typography :global(figure img) {\n        @apply mx-auto block;\n        max-width: min(theme('screens.md'), 100%);\n      }\n      .typography :global(figcaption) {\n        @apply mx-auto my-4 w-11/12 text-center text-sm text-gray-600;\n      }\n      .typography :global(table) {\n        @apply mx-auto my-8 max-w-full;\n      }\n      .typography :global(td),\n      .typography :global(th) {\n        @apply border-b border-gray-400 p-2 text-sm;\n      }\n      .typography :global(thead tr:last-child td),\n      .typography :global(thead tr:last-child th) {\n        @apply border-b-2;\n      }\n\n      @screen sm {\n        .typography :global(td),\n        .typography :global(th) {\n          @apply py-2 px-4;\n        }\n      }\n\n      @screen md {\n        .typography :global(td),\n        .typography :global(th) {\n          @apply text-base;\n        }\n      }\n\n      .typography > :global(*:first-child),\n      .typography > :global(*:first-child *:first-child) {\n        @apply mt-0;\n      }\n      .typography > :global(*:last-child),\n      .typography > :global(*:last-child *:last-child) {\n        @apply mb-0;\n      }\n    `}</style>\n  </div>\n)\n"
  },
  {
    "path": "website/components/blog/BlogHeader.tsx",
    "content": "import Link from 'next/link'\nimport { formatDate, formatDateShort } from 'utils/date'\n\nexport type BlogHeaderProps = {\n  author?: string\n  date?: Date\n  github?: string\n  slug: string\n  title: string\n}\n\nexport const BlogHeader = ({\n  author,\n  date,\n  github,\n  slug,\n  title,\n}: BlogHeaderProps) => (\n  <div className=\"text-center text-gray-600\">\n    <Link href={`/blog/${slug}`}>\n      <h1 className=\"text-gradient text-3xl font-bold md:text-4xl\">{title}</h1>\n    </Link>\n    {date && (\n      <p className=\"mt-4\">\n        <time dateTime={formatDateShort(date)}>{formatDate(date)}</time>\n      </p>\n    )}\n    <p className=\"author\">\n      {(author || github) && (\n        <>\n          {github && (\n            <img\n              src={`https://github.com/${github}.png`}\n              alt={author || github}\n              className=\"mr-4 h-16 w-16 rounded-full bg-white shadow-md\"\n              width={64}\n              height={64}\n            />\n          )}\n          <span className=\"leading-relaxed\">\n            by{' '}\n            {author && (\n              <>\n                {author}\n                {github && <br />}\n              </>\n            )}\n            {github && (\n              <a\n                href={`https://github.com/${github}`}\n                target=\"_blank\"\n                rel=\"noopener noreferrer\"\n              >\n                @{github}\n              </a>\n            )}\n          </span>\n        </>\n      )}\n      <style jsx>{`\n        .author {\n          @apply -mx-6 mt-5 flex items-center text-left;\n        }\n\n        .author::before,\n        .author::after {\n          @apply mx-6 block h-px flex-1 bg-gray-400;\n\n          content: '';\n        }\n\n        .author:empty {\n          @apply mx-0 h-px;\n        }\n\n        .author:empty::before,\n        .author:empty::after {\n          @apply mx-0;\n        }\n      `}</style>\n    </p>\n  </div>\n)\n"
  },
  {
    "path": "website/components/docs/Breadcrumb.tsx",
    "content": "import Link from 'next/link'\n\nexport type BreadcrumbProps = {\n  breadcrumbs: {\n    key: string\n    link?: string\n    title: string\n  }[]\n}\n\nexport const Breadcrumb = ({ breadcrumbs }: BreadcrumbProps) => (\n  <ol>\n    {breadcrumbs.map(({ key, title, link }) => (\n      <li key={key}>{link ? <Link href={link}>{title}</Link> : title}</li>\n    ))}\n    <style jsx>{`\n      ol {\n        @apply inline-flex flex-1 flex-nowrap whitespace-nowrap;\n      }\n      li {\n        @apply block;\n      }\n      li::after {\n        @apply bg-no-repeat pl-6;\n\n        background-image: url('https://icongr.am/octicons/triangle-right.svg?color=718096');\n        background-position: 0.25rem center;\n        background-size: 1rem 1rem;\n        content: '';\n      }\n      li:last-child {\n        @apply font-bold;\n      }\n      li:last-child::after {\n        @apply hidden;\n      }\n    `}</style>\n  </ol>\n)\n"
  },
  {
    "path": "website/components/docs/Layout.tsx",
    "content": "import { useMedia, useMediaLayout } from 'use-media'\nimport { BreadcrumbProps } from './Breadcrumb'\nimport { NavigationProps } from './Navigation'\nimport { Desktop } from './layouts/Desktop'\nimport { Mobile } from './layouts/Mobile'\nimport { Layout } from 'components/Layout'\n\nexport type LayoutProps = React.PropsWithChildren<\n  BreadcrumbProps & NavigationProps\n>\n\nconst useMediaIsomorphic =\n  typeof window === 'undefined' ? useMedia : useMediaLayout\n\nconst DocsLayout: React.FC<LayoutProps> = (props) => {\n  const isDesktop = useMediaIsomorphic({ minWidth: '768px' }, false)\n  const Container = isDesktop ? Desktop : Mobile\n\n  return (\n    <Layout\n      activeItem=\"docs\"\n      canonical={`/docs/${props.slug.join('/')}`}\n      title={[props.breadcrumbs.map((b) => b.title).join(' > '), 'Docs']}\n      noIndex={!process.env.NEXT_PUBLIC_DOCS}\n    >\n      <Container {...props} />\n    </Layout>\n  )\n}\n\nexport { DocsLayout as Layout }\n"
  },
  {
    "path": "website/components/docs/Navigation.tsx",
    "content": "import classNames from 'classnames'\nimport Link from 'next/link'\n\nexport type NavigationProps = {\n  manifest: Record<string, any>\n  slug: string[]\n}\n\nexport const Navigation = ({\n  manifest,\n  slug: currentSlug,\n}: NavigationProps) => {\n  const activePage = `/docs/${currentSlug.join('/')}`\n\n  return (\n    <div>\n      {Object.entries<any>(manifest).map(([slug, meta]) => (\n        <ul className=\"category\" key={slug}>\n          <li>\n            {meta.title && <h3 className=\"category-title\">{meta.title}</h3>}\n            {meta.pages && (\n              <ul>\n                {Object.entries<any>(meta.pages).map(([pSlug, pMeta]) => {\n                  const href = `/docs/${slug}/${pSlug}`\n\n                  return (\n                    <Link href={href} key={pSlug} legacyBehavior>\n                      <a\n                        className={classNames(\n                          'page-link custom-anchor',\n                          href === activePage && 'active'\n                        )}\n                      >\n                        <li>{pMeta.title}</li>\n                      </a>\n                    </Link>\n                  )\n                })}\n              </ul>\n            )}\n          </li>\n        </ul>\n      ))}\n      <style jsx>{`\n        .category {\n          @apply mt-6;\n        }\n        .category:first-child {\n          @apply mt-0;\n        }\n        .category-title {\n          @apply font-rounded mb-2 text-xl font-bold uppercase text-gray-700;\n        }\n\n        .page-link {\n          @apply text-marp-darken mt-1 block rounded py-1 px-2 outline-none;\n\n          transition-property: background-color, border-color, fill, stroke;\n        }\n        .page-link:hover,\n        .page-link:focus {\n          @apply text-marp-dark bg-gray-200 duration-300;\n        }\n        .page-link:hover:active {\n          @apply duration-0 bg-gray-300;\n        }\n        .page-link:focus-visible {\n          @apply ring-1 ring-white ring-offset-2;\n        }\n\n        .page-link.active {\n          @apply from-marp-brand to-marp-dark duration-0 bg-gradient-to-br font-bold text-white;\n        }\n        .page-link.active:hover:active {\n          @apply bg-marp-dark from-marp-dark to-marp-darkest;\n        }\n      `}</style>\n    </div>\n  )\n}\n"
  },
  {
    "path": "website/components/docs/layouts/Desktop.tsx",
    "content": "import {\n  CSSProperties,\n  useLayoutEffect,\n  useRef,\n  useState,\n  useMemo,\n} from 'react'\nimport { Breadcrumb } from 'components/docs/Breadcrumb'\nimport { LayoutProps } from 'components/docs/Layout'\nimport { Navigation } from 'components/docs/Navigation'\n\nexport const Desktop: React.FC<LayoutProps> = ({\n  breadcrumbs,\n  children,\n  manifest,\n  slug,\n}) => {\n  const sidebarRef = useRef<HTMLDivElement>(null)\n  const sidebarContentRef = useRef<HTMLDivElement>(null)\n  const headerHeightDetecterRef = useRef<HTMLDivElement>(null)\n\n  const [stickyGap, setStickyGap] = useState(0)\n  const [isScrollDown, setIsScrollDown] = useState(true)\n  const [sidebarScrollable, setSidebarScrollable] = useState(false)\n\n  useLayoutEffect(() => {\n    let previousScrollY = window.scrollY\n\n    const handleScroll = () => {\n      // Get header height\n      const headerHeight = headerHeightDetecterRef.current?.clientHeight || 80\n\n      // Detect whether sidebar is scrollable\n      const sidebarElm = sidebarRef.current\n      const sidebarRect = sidebarElm?.getBoundingClientRect()\n      const parentElm = sidebarElm?.parentElement\n      const parentRect = parentElm?.getBoundingClientRect()\n\n      if (sidebarContentRef.current && sidebarRect && parentRect) {\n        const viewHeight = Math.max(\n          0,\n          Math.min(window.innerHeight, parentRect.bottom) - headerHeight\n        )\n\n        setSidebarScrollable(\n          viewHeight < sidebarContentRef.current.clientHeight\n        )\n      }\n\n      // Handle scroll\n      const resetStickyGap = (base: 'top' | 'bottom') => {\n        if (sidebarRect && parentRect) {\n          setStickyGap(sidebarRect[base] - parentRect[base])\n        }\n      }\n\n      const { scrollY } = window\n      const scrollDelta = scrollY - previousScrollY\n\n      if (scrollDelta < 0) {\n        // Scroll up\n        setIsScrollDown((prev) => {\n          if (prev) resetStickyGap('bottom')\n          return false\n        })\n      } else {\n        // Scroll down\n        setIsScrollDown((prev) => {\n          if (!prev) resetStickyGap('top')\n          return true\n        })\n      }\n      previousScrollY = scrollY\n    }\n\n    window.addEventListener('scroll', handleScroll)\n    window.addEventListener('resize', handleScroll)\n\n    return () => {\n      window.removeEventListener('scroll', handleScroll)\n      window.removeEventListener('resize', handleScroll)\n    }\n  }, [])\n\n  const sidebarStyle = useMemo<CSSProperties>(() => {\n    if (!sidebarScrollable)\n      return { alignSelf: 'start', top: 'var(--header-height)' }\n\n    return {\n      alignSelf: isScrollDown ? 'end' : 'start',\n      top: !isScrollDown ? `var(--header-height)` : '',\n      bottom: isScrollDown ? `0px` : '',\n      marginBottom: stickyGap < 0 ? `${-stickyGap}px` : 0,\n      marginTop: stickyGap >= 0 ? `${stickyGap}px` : 0,\n    }\n  }, [isScrollDown, sidebarScrollable, stickyGap])\n\n  return (\n    <>\n      <div\n        ref={headerHeightDetecterRef}\n        className=\"fixed top-0 left-0 -z-10 h-[var(--header-height)] w-px opacity-0\"\n      />\n      <div id=\"docs-container\" className=\"text-sm xl:text-base\">\n        <div ref={sidebarRef} id=\"docs-sidebar\" style={sidebarStyle}>\n          <div ref={sidebarContentRef} className=\"sidebar-nav-content\">\n            <Navigation manifest={manifest} slug={slug} />\n          </div>\n        </div>\n        <div className=\"my-6 w-px bg-gray-400\" style={{ gridArea: 'border' }} />\n        <div className=\"[grid-area:contents]\">\n          <div className=\"px-8 py-10\">\n            {breadcrumbs?.length && (\n              <div className=\"mb-6 rounded bg-gray-300 p-2\">\n                <Breadcrumb breadcrumbs={breadcrumbs} />\n              </div>\n            )}\n            <article id=\"docs-article\" className=\"container\">\n              {children}\n            </article>\n          </div>\n        </div>\n      </div>\n      {/* <div ref={docsClearfixRef} /> */}\n      <style jsx>{`\n        #docs-container {\n          @apply grid;\n\n          min-height: inherit;\n          grid-template:\n            'sidebar border contents' auto\n            / minmax(16rem, 20%) 1px minmax(0, 1fr);\n        }\n\n        #docs-sidebar {\n          @apply sticky [grid-area:sidebar];\n        }\n\n        #docs-article {\n          @apply mx-auto px-6;\n\n          --root-font-size: 0.9rem;\n        }\n\n        .sidebar-nav-content {\n          @apply mx-auto w-64 px-8 py-10;\n\n          min-width: 16rem;\n        }\n\n        @screen xl {\n          #docs-container {\n            grid-template:\n              'sidebar border contents nav' auto\n              / minmax(16rem, 20%) 1px minmax(0, 1fr) minmax(8rem, 15%);\n          }\n\n          #docs-article {\n            --root-font-size: 1rem;\n          }\n\n          .sidebar-nav-content {\n            @apply w-5/6;\n          }\n        }\n      `}</style>\n    </>\n  )\n}\n"
  },
  {
    "path": "website/components/docs/layouts/Mobile.tsx",
    "content": "import { ThreeBarsIcon, XIcon } from '@primer/octicons-react'\nimport { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock'\nimport classNames from 'classnames'\nimport FocusTrap from 'focus-trap-react'\nimport { useRouter } from 'next/router'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { Breadcrumb } from 'components/docs/Breadcrumb'\nimport { LayoutProps } from 'components/docs/Layout'\nimport { Navigation } from 'components/docs/Navigation'\n\nconst useOnPageLoad = (callback: () => void, immediate = false) => {\n  const router = useRouter()\n\n  useEffect(() => {\n    if (immediate) callback()\n  }, [callback]) // eslint-disable-line react-hooks/exhaustive-deps\n\n  useEffect(() => {\n    router.events.on('routeChangeComplete', callback)\n    return () => router.events.off('routeChangeComplete', callback)\n  }, [callback, router.events])\n}\n\nconst useDrawer = (drawer?: HTMLElement) => {\n  const [open, setOpen] = useState(false)\n  const [active, setActive] = useState(false)\n  const activeTimer = useRef<number>()\n  const lastFocusedElement = useRef<HTMLElement | undefined>(undefined)\n\n  const handleOpen = useCallback((e?: React.SyntheticEvent<HTMLElement>) => {\n    setActive(true)\n    setOpen(true)\n\n    lastFocusedElement.current = e?.currentTarget\n  }, [])\n\n  const handleClose = useCallback(() => {\n    setActive(true)\n    setOpen(false)\n  }, [])\n\n  const toggle = useCallback(\n    (e?: React.SyntheticEvent<HTMLElement>) => {\n      open ? handleClose() : handleOpen(e)\n    },\n    [open, handleOpen, handleClose]\n  )\n\n  useOnPageLoad(handleClose)\n\n  useEffect(() => {\n    if (drawer && open) {\n      disableBodyScroll(drawer)\n      return () => enableBodyScroll(drawer)\n    }\n  }, [drawer, open])\n\n  useEffect(() => {\n    if (open) {\n      const escKeyListener = ({ key }: KeyboardEvent) => {\n        if (key === 'Escape') handleClose()\n      }\n\n      document.addEventListener('keydown', escKeyListener)\n      return () => document.removeEventListener('keydown', escKeyListener)\n    }\n  }, [handleClose, open])\n\n  useEffect(() => {\n    if (!open && lastFocusedElement.current) {\n      lastFocusedElement.current.focus()\n    }\n  }, [open])\n\n  useEffect(() => {\n    if (active) {\n      if (activeTimer.current !== undefined)\n        window.clearTimeout(activeTimer.current)\n\n      activeTimer.current = window.setTimeout(() => setActive(false), 300)\n    }\n  }, [active])\n\n  return { active, handleClose, handleOpen, toggle, open }\n}\n\nexport const Mobile: React.FC<LayoutProps> = ({\n  children,\n  breadcrumbs,\n  manifest,\n  slug,\n}) => {\n  const [drawer, setDrawer] = useState<HTMLElement | null>(null)\n  const { active, handleClose, toggle, open } = useDrawer(drawer ?? undefined)\n\n  const breadcrumbsContainer = useRef<HTMLDivElement | null>(null)\n\n  useOnPageLoad(\n    useCallback(() => {\n      breadcrumbsContainer.current?.scrollTo({\n        left: breadcrumbsContainer.current.scrollWidth,\n        behavior: 'instant' as any,\n      })\n    }, []),\n    true\n  )\n\n  return (\n    <>\n      <div\n        className={classNames('docs-backdrop', { active, open })}\n        onClick={handleClose}\n        aria-hidden\n      />\n      <FocusTrap\n        active={open}\n        focusTrapOptions={{\n          allowOutsideClick: () => true,\n          escapeDeactivates: false,\n          initialFocus: '#docs-nav',\n          fallbackFocus: '#docs-nav-toggle',\n        }}\n      >\n        <nav\n          id=\"docs-nav\"\n          className={classNames({ active, open })}\n          ref={setDrawer}\n          tabIndex={-1}\n          inert={open ? undefined : ''}\n        >\n          <div className=\"p-8\">\n            <p className=\"mb-6\">\n              <button\n                className=\"docs-btn h-8 w-8\"\n                onClick={handleClose}\n                aria-expanded={open}\n              >\n                <XIcon className=\"docs-btn-close-icon\" />\n                <span className=\"sr-only\">Close navigation</span>\n              </button>\n            </p>\n            <Navigation manifest={manifest} slug={slug} />\n          </div>\n        </nav>\n      </FocusTrap>\n      <nav className=\"docs-topbar\">\n        <button\n          className=\"docs-btn relative z-20 m-1 h-8 w-8\"\n          id=\"docs-nav-toggle\"\n          type=\"button\"\n          onClick={toggle}\n          aria-controls=\"docs-nav\"\n          aria-expanded={open}\n        >\n          <ThreeBarsIcon className=\"docs-btn-open-drawer-icon\" />\n          <span className=\"sr-only\">Toggle navigation</span>\n        </button>\n        {breadcrumbs?.length && (\n          <div ref={breadcrumbsContainer} className=\"docs-breadcrumb-container\">\n            <div className=\"docs-breadcrumb\">\n              <Breadcrumb breadcrumbs={breadcrumbs} />\n            </div>\n          </div>\n        )}\n      </nav>\n      <article id=\"docs-article\" className=\"container\">\n        {children}\n      </article>\n      <style jsx global>{`\n        :root {\n          --anchor-margin: calc(var(--header-height) + 2.5rem);\n        }\n      `}</style>\n      <style jsx>{`\n        .docs-backdrop {\n          @apply pointer-events-none fixed inset-0 cursor-pointer opacity-0 transition-opacity;\n\n          -webkit-tap-highlight-color: transparent;\n          backdrop-filter: blur(2px);\n          background: rgba(255, 255, 255, 0.75);\n          z-index: 60;\n        }\n        .docs-backdrop.active {\n          @apply duration-300;\n        }\n        .docs-backdrop.open {\n          @apply pointer-events-auto opacity-100;\n        }\n\n        .docs-btn {\n          @apply appearance-none rounded text-gray-700;\n        }\n        .docs-btn:hover,\n        .docs-btn:focus {\n          @apply bg-gray-200 outline-none;\n        }\n        .docs-btn:hover:active {\n          @apply bg-gray-300 outline-none;\n        }\n        .docs-btn:focus-visible {\n          @apply ring-1 ring-white ring-offset-2;\n        }\n\n        .docs-btn :global(.docs-btn-close-icon) {\n          @apply h-8 w-8;\n        }\n        .docs-btn :global(.docs-btn-open-drawer-icon) {\n          @apply h-8 w-8 p-1;\n        }\n\n        #docs-nav {\n          @apply bg-background fixed inset-0 w-64 -translate-x-full transform overflow-hidden border-r outline-none;\n\n          transition-property: box-shadow, transform;\n          z-index: 60;\n        }\n        #docs-nav.active {\n          @apply duration-300;\n        }\n        #docs-nav.open {\n          @apply transform-none overflow-auto shadow-2xl;\n        }\n\n        .docs-topbar {\n          @apply fixed inset-0 top-16 z-50 flex h-10 items-stretch bg-white shadow-sm;\n        }\n        .docs-breadcrumb-container {\n          @apply flex flex-1 snap-x snap-proximity scroll-px-2 items-center overflow-x-auto;\n\n          mask: linear-gradient(to right, transparent, #000 0.5rem, #000)\n            no-repeat left top;\n          -ms-overflow-style: none;\n          scrollbar-width: none;\n        }\n        .docs-breadcrumb-container::-webkit-scrollbar {\n          display: none;\n        }\n        .docs-breadcrumb {\n          @apply relative mr-auto px-2;\n          @apply after:pointer-events-none after:absolute after:inset-0 after:mx-2 after:snap-end;\n        }\n        .docs-breadcrumb :global(li) {\n          @apply snap-start;\n        }\n\n        #docs-article {\n          @apply mx-auto p-6 pt-16;\n\n          --root-font-size: 0.9rem;\n        }\n      `}</style>\n    </>\n  )\n}\n"
  },
  {
    "path": "website/components/markdown/Anchor.tsx",
    "content": "import Link from 'next/link'\n\nexport const Anchor: React.FC<{ href?: string }> = ({ href, ...rest }) => {\n  if (!href) return <a {...rest} />\n\n  if (href && (href.startsWith('http://') || href.startsWith('https://'))) {\n    return <a href={href} {...rest} target=\"_blank\" rel=\"noreferrer noopener\" />\n  }\n\n  return <Link href={href} {...rest} />\n}\n"
  },
  {
    "path": "website/components/markdown/Heading.tsx",
    "content": "import { createContext, useContext } from 'react'\n\n// eslint-disable-next-line @typescript-eslint/ban-types\ntype HOCProps<P extends {} = Record<string, any>> = React.PropsWithChildren<P>\n\nconst anchorLinkContext = createContext(true)\n\nconst Heading: React.FC<HOCProps<{ level: number; id?: string }>> = ({\n  children,\n  level,\n  id,\n  ...rest\n}) => {\n  const anchorLink = useContext(anchorLinkContext)\n  const HeadingTag: any = 'h' + level\n\n  return (\n    <HeadingTag id={id} {...rest}>\n      {id && anchorLink && (\n        <a\n          aria-hidden\n          className=\"anchor-link\"\n          href={`#${id}`}\n          tabIndex={-1}\n        ></a>\n      )}\n      {children}\n    </HeadingTag>\n  )\n}\n\nexport const H1: React.FC<HOCProps> = ({ children, ...rest }) => (\n  <Heading level={1} {...rest}>\n    <span>\n      {children}\n      <style jsx>{`\n        & {\n          box-shadow: inset 0 -0.2em theme('colors.marp.light');\n        }\n      `}</style>\n    </span>\n  </Heading>\n)\n\nexport const H2: React.FC<HOCProps> = ({ children, ...rest }) => (\n  <Heading level={2} {...rest}>\n    <span className=\"headingLv2\">\n      <span className=\"content\">{children}</span>\n      <span className=\"divider\"></span>\n    </span>\n    <style jsx>{`\n      .headingLv2 {\n        @apply flex items-center;\n      }\n\n      .content {\n        @apply flex-initial;\n      }\n\n      .divider {\n        @apply ml-6 h-0 flex-1 border-t border-gray-400;\n      }\n    `}</style>\n  </Heading>\n)\n\n// export const H2: React.FC = (props) => <Heading level={2} {...props} />\nexport const H3: React.FC<HOCProps> = (props) => (\n  <Heading level={3} {...props} />\n)\nexport const H4: React.FC<HOCProps> = (props) => (\n  <Heading level={4} {...props} />\n)\nexport const H5: React.FC<HOCProps> = (props) => (\n  <Heading level={5} {...props} />\n)\nexport const H6: React.FC<HOCProps> = (props) => (\n  <Heading level={6} {...props} />\n)\n\nexport const AnchorLinkProvider = anchorLinkContext.Provider\n"
  },
  {
    "path": "website/components/markdown/Image.tsx",
    "content": "export type ImageProps = {\n  src: string\n  alt: string\n  [attr: string]: string\n}\n\nexport const Image = ({ src, alt, ...rest }: ImageProps) => {\n  const isVideo = src.endsWith('.mp4')\n\n  if (isVideo) {\n    let autoplay: boolean | undefined\n    let controls: boolean | undefined\n    let poster: string | undefined\n\n    const normalizedAlt = (alt || '')\n      .replace(\n        /\\b(?:autoplay|controls|poster=([^\\s]+))\\s*\\b/g,\n        (matched, value) => {\n          if (matched.startsWith('autoplay')) autoplay = true\n          if (matched.startsWith('controls')) controls = true\n          if (matched.startsWith('poster')) poster = value\n\n          return ''\n        }\n      )\n      .trim()\n\n    return (\n      <video\n        className=\"markdown-video\"\n        src={src}\n        playsInline\n        controls={controls}\n        loop\n        preload=\"metadata\"\n        poster={poster}\n        autoPlay={autoplay}\n        muted={autoplay}\n        {...rest}\n      >\n        <a href={src} target=\"_blank\" rel=\"noopener noreferrer\">\n          {normalizedAlt}\n        </a>\n        <style jsx>{`\n          .markdown-video {\n            @apply mx-auto block w-full max-w-xl shadow-md;\n            @apply my-6 !important;\n          }\n        `}</style>\n      </video>\n    )\n  }\n\n  return <img src={src} alt={alt} {...rest} />\n}\n"
  },
  {
    "path": "website/components/markdown/Pre.tsx",
    "content": "import { CodeBlock } from '../CodeBlock'\n\nexport const Pre: React.FC = (props) => {\n  if (props['data-code'] === undefined) return <pre {...props} />\n\n  return (\n    <CodeBlock\n      className=\"sm:mx-auto sm:w-11/12 lg:w-5/6\"\n      language={props['data-language']}\n      copyButton\n    >\n      {props['data-code']}\n    </CodeBlock>\n  )\n}\n\nexport const toHastCodeHandler = (h, { position, lang, value, marp }) => {\n  if (marp) {\n    return h(position, 'marp-slides', {\n      'data-comments': JSON.stringify(marp.comments),\n      'data-css': marp.css,\n      'data-html': JSON.stringify(marp.html),\n      'data-fonts': JSON.stringify(marp.fonts),\n    })\n  }\n\n  return h(\n    position,\n    'pre',\n    { 'data-code': value, 'data-language': lang?.trim() },\n    []\n  )\n}\n"
  },
  {
    "path": "website/components/top/Description.tsx",
    "content": "import { ChevronDownIcon } from '@primer/octicons-react'\nimport classNames from 'classnames'\nimport { useState } from 'react'\nimport { Button } from 'components/Button'\nimport { CodeBlock } from 'components/CodeBlock'\nimport { Marp, RenderedMarp } from 'components/Marp'\n\nexport type DescriptionProps = {\n  example: RenderedMarp\n}\n\nexport const Description = ({ example }: DescriptionProps) => {\n  const [showExample, setShowExample] = useState(false)\n\n  return (\n    <section className=\"container mx-auto py-16\">\n      <h2 className=\"text-gradient mx-auto w-5/6 text-center text-3xl font-bold md:text-4xl\">\n        Create beautiful slide decks using an intuitive Markdown experience\n      </h2>\n      <p className=\"mx-auto mt-8 w-5/6 md:text-lg lg:w-2/3\">\n        Marp (also known as the Markdown Presentation Ecosystem) provides an\n        intuitive experience for creating beautiful slide decks. You only have\n        to focus on writing your story in a Markdown document.\n      </p>\n      <figure className=\"m-8 mb-0 text-center\">\n        <Marp\n          rendered={example}\n          page={1}\n          className=\"inline-block w-full max-w-sm\"\n        />\n        <Marp\n          rendered={example}\n          page={2}\n          className=\"mt-5 inline-block w-full max-w-sm lg:ml-5 lg:mt-0\"\n        />\n        <figcaption className=\"mt-5 text-sm text-gray-700\">\n          The slides above are from generated directly from{' '}\n          <a href=\"https://github.com/marp-team/marp-core\">Marp Core</a>\n        </figcaption>\n      </figure>\n      <p className=\"show-example-section\">\n        <Button\n          className=\"show-example-btn\"\n          onClick={() => setShowExample((v) => !v)}\n          aria-expanded={showExample}\n        >\n          {showExample ? 'Hide' : 'Show'} Markdown example...\n          <ChevronDownIcon\n            className={classNames(\n              'show-example-btn-chevron',\n              showExample && 'show'\n            )}\n          />\n        </Button>\n      </p>\n      <div\n        aria-hidden={!showExample}\n        className=\"overflow-hidden transition-all duration-300\"\n        style={{ maxHeight: showExample ? '1000px' : '0' }}\n      >\n        <CodeBlock\n          language=\"markdown\"\n          lineNumber\n          className=\"mx-auto mt-5 w-5/6 xl:w-2/3\"\n          copyButton={showExample}\n        >\n          {example.markdown}\n        </CodeBlock>\n      </div>\n      <style jsx>{`\n        .show-example-section {\n          @apply mx-auto mt-8 w-5/6 text-center;\n        }\n        .show-example-section :global(.show-example-btn) {\n          @apply text-sm;\n        }\n        .show-example-section :global(.show-example-btn-chevron) {\n          @apply ml-1 h-4 w-4 transform transition-transform duration-300 md:-my-1 md:h-6 md:w-6;\n        }\n        .show-example-section :global(.show-example-btn-chevron:not(.show)) {\n          @apply relative;\n\n          top: -1px;\n        }\n        .show-example-section :global(.show-example-btn-chevron.show) {\n          @apply -rotate-180;\n        }\n\n        @screen md {\n          .show-example-section :global(.show-example-btn-chevron:not(.show)) {\n            top: -2px;\n          }\n        }\n      `}</style>\n    </section>\n  )\n}\n"
  },
  {
    "path": "website/components/top/Features.tsx",
    "content": "import {\n  CodeSquareIcon,\n  FileIcon,\n  HeartFillIcon,\n  MarkdownIcon,\n  PackageIcon,\n  PaintbrushIcon,\n  PlugIcon,\n} from '@primer/octicons-react'\nimport type { ReactElement } from 'react'\n\ntype CardProps = React.PropsWithChildren<{\n  name: string\n  icon: string | ReactElement\n  index: number\n}>\n\nconst Card: React.FC<CardProps> = ({ children, name, icon, index }) => {\n  let cardIcon = icon\n\n  if (typeof icon === 'string') {\n    cardIcon = <img src={icon} alt={name} width={48} height={48} />\n  }\n\n  return (\n    <section className=\"card\">\n      <div>\n        <div className=\"card-icon\">{cardIcon}</div>\n        <h2 className=\"text-gradient my-4 text-center text-2xl font-semibold\">\n          {name}\n        </h2>\n        <p className=\"text-sm lg:text-base\">{children}</p>\n      </div>\n      <style jsx>{`\n        .card {\n          @apply relative z-10 mx-4 my-8 mb-0 flex items-center justify-center rounded-lg bg-white p-6 shadow-lg;\n\n          grid-column: 1;\n        }\n\n        .card-icon {\n          @apply my-2 text-center text-gray-700;\n        }\n\n        .card-icon :global(svg),\n        .card-icon :global(img) {\n          @apply inline h-12 w-12 lg:h-16 lg:w-16;\n        }\n\n        @screen md {\n          .card {\n            grid-row: ${index + 1} / span 2;\n          }\n\n          .card:first-child {\n            @apply mt-0;\n          }\n\n          .card:nth-of-type(even) {\n            grid-column: 2;\n          }\n        }\n      `}</style>\n    </section>\n  )\n}\n\nconst cards = [\n  ({ index }) => (\n    <Card\n      index={index}\n      name=\"Based on CommonMark\"\n      icon={<MarkdownIcon verticalAlign=\"top\" />}\n    >\n      If you know how to write a document with Markdown, you already know how to\n      write a Marp slide deck. Marp&apos;s format is based on{' '}\n      <a\n        href=\"https://commonmark.org/\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n      >\n        CommonMark\n      </a>\n      , a consistent Markdown specification. The only important difference is{' '}\n      <a\n        href=\"https://marpit.marp.app/markdown\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        a ruler <code>---</code> for splitting pages.\n      </a>\n    </Card>\n  ),\n  ({ index }) => (\n    <Card\n      index={index}\n      name=\"Directives and extended syntax\"\n      icon={<CodeSquareIcon verticalAlign=\"top\" />}\n    >\n      Sometimes simple text content isn&apos;t enough to emphasize your voice,\n      so Marp supports a variety of{' '}\n      <a\n        href=\"https://marpit.marp.app/directives\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        directives\n      </a>{' '}\n      and extended syntax (\n      <a\n        href=\"https://marpit.marp.app/image-syntax\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        image syntax\n      </a>\n      ,{' '}\n      <a\n        href=\"https://github.com/marp-team/marp-core#math-typesetting\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        math typesetting\n      </a>\n      ,{' '}\n      <a\n        href=\"https://github.com/marp-team/marp-core#auto-scaling-features\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        auto-scaling\n      </a>\n      , etc...) to create beautiful slides.\n    </Card>\n  ),\n  ({ index }) => (\n    <Card\n      index={index}\n      name=\"Built-in themes and CSS theming\"\n      icon={<PaintbrushIcon verticalAlign=\"top\" />}\n    >\n      <a\n        href=\"https://github.com/marp-team/marp-core/\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        Our core engine\n      </a>{' '}\n      has{' '}\n      <a\n        href=\"https://github.com/marp-team/marp-core/tree/main/themes\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        3 built-in themes called <code>default</code>, <code>gaia</code>, and{' '}\n        <code>uncover</code>\n      </a>\n      , to tell your story beautifully. If you&apos;d rather customize your\n      design, you can use Marp to{' '}\n      <a\n        href=\"https://marpit.marp.app/theme-css?id=tweak-style-through-markdown\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        tweak styles with Markdown\n      </a>\n      , or{' '}\n      <a\n        href=\"https://marpit.marp.app/theme-css\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        create your own Marp theme with plain CSS\n      </a>\n      .\n    </Card>\n  ),\n  ({ index }) => (\n    <Card\n      index={index}\n      name=\"Export to HTML, PDF, and PowerPoint\"\n      icon={<FileIcon verticalAlign=\"top\" />}\n    >\n      Have you finished writing? It&apos;s time to share your deck! Marp can\n      convert Markdown into presentation-ready HTML, PDF and PowerPoint files\n      directly! (Powered by{' '}\n      <a\n        href=\"https://www.google.com/chrome/\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        Google Chrome\n      </a>{' '}\n      /{' '}\n      <a\n        href=\"https://www.chromium.org/Home\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        Chromium\n      </a>\n      )\n    </Card>\n  ),\n  ({ index }) => (\n    <Card\n      index={index}\n      name=\"Marp family: The official toolset\"\n      icon={<PackageIcon verticalAlign=\"top\" />}\n    >\n      The Marp ecosystem contains a rich toolset to assist your work.{' '}\n      <a\n        href=\"https://marketplace.visualstudio.com/items?itemName=marp-team.marp-vscode\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        <b>Marp for VS Code</b>\n      </a>{' '}\n      is an extension that allows you to edit and preview slide Markdown and\n      custom theming within VS Code.{' '}\n      <a\n        href=\"https://github.com/marp-team/marp-cli/\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        <b>Marp CLI</b>\n      </a>{' '}\n      is a command line tool allows you to convert Markdown with a simple CLI\n      interface.{' '}\n      <a\n        href=\"https://github.com/marp-team/marp/\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        ... and much more!\n      </a>\n    </Card>\n  ),\n  ({ index }) => (\n    <Card\n      index={index}\n      name=\"Pluggable architecture\"\n      icon={<PlugIcon verticalAlign=\"top\" />}\n    >\n      As a matter of fact,{' '}\n      <em>Marp is essentially just a converter for Markdown.</em> The Marp\n      ecosystem is built on{' '}\n      <a\n        href=\"https://marpit.marp.app\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        <b>the Marpit framework</b>\n      </a>\n      , a skinny framework for creating HTML/CSS slide decks. It has a pluggable\n      architecture and any developer can{' '}\n      <a\n        href=\"https://marpit.marp.app/usage?id=extend-marpit-by-plugins\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        extend features via plugins\n      </a>\n      .\n    </Card>\n  ),\n  ({ index }) => (\n    <Card\n      index={index}\n      name=\"Fully open-source\"\n      icon={<HeartFillIcon verticalAlign=\"top\" />}\n    >\n      The Marp team loves open source! All tools and related libraries are built\n      by{' '}\n      <a\n        href=\"https://github.com/marp-team\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n      >\n        the Marp team\n      </a>{' '}\n      and are MIT-licensed.\n    </Card>\n  ),\n]\n\nexport const Features = () => (\n  <div className=\"features\">\n    <div className=\"features-grid container\">\n      {cards.map((Card, i) => (\n        <Card index={i} key={i} />\n      ))}\n    </div>\n    <style jsx>{`\n      .features {\n        @apply relative py-5;\n      }\n\n      .features::before {\n        @apply absolute inset-0 block;\n\n        background-image: var(--noise-image),\n          linear-gradient(\n            -8deg,\n            rgba(120, 197, 233, 0),\n            rgba(120, 197, 233, 0) 50%,\n            rgba(120, 197, 233, 0.5)\n          );\n        clip-path: polygon(0 15vw, 100% 0, 100% 100%, 0 100%);\n        content: '';\n      }\n\n      .features-grid {\n        @apply mx-auto grid px-4;\n\n        grid-template-columns: 1fr;\n        grid-template-rows: repeat(${cards.length + 1}, auto);\n      }\n\n      @screen md {\n        .features-grid {\n          grid-template-columns: 1fr 1fr;\n        }\n      }\n    `}</style>\n  </div>\n)\n"
  },
  {
    "path": "website/components/top/GetStarted.tsx",
    "content": "import classNames from 'classnames'\nimport { Button } from 'components/Button'\n\ntype CardProps = React.PropsWithChildren<{\n  badge?: string\n  className?: string\n  description: string\n  href: string\n  name: string\n  screenShot?: string\n  ssWidth?: number\n  ssHeight?: number\n  summary: string\n}>\n\nconst Card: React.FC<CardProps> = ({\n  badge,\n  children,\n  className,\n  description,\n  href,\n  name,\n  screenShot: screenshot,\n  ssWidth,\n  ssHeight,\n  summary,\n}) => (\n  <section className={classNames('card', className, { screenshot })}>\n    <a\n      href={href}\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n      className=\"custom-anchor card-link\"\n    >\n      <h4 className=\"text-gradient inline-block pr-3 pb-1 text-xl font-bold sm:text-2xl md:text-3xl\">\n        {name}\n      </h4>\n      {badge && (\n        <img\n          src={badge}\n          alt=\"\"\n          className=\"inline rounded-sm align-text-top sm:align-baseline\"\n          loading=\"lazy\"\n        />\n      )}\n      <p className=\"pt-1 text-sm leading-tight text-gray-700\">{summary}</p>\n    </a>\n    {screenshot && (\n      <figure>\n        <img\n          src={screenshot}\n          alt={name}\n          loading=\"lazy\"\n          width={ssWidth}\n          height={ssHeight}\n        />\n      </figure>\n    )}\n    <p className=\"mx-5 lg:my-3\">{description}</p>\n    <p className=\"mx-5 my-4 text-sm\">{children}</p>\n    <style jsx>{`\n      .card {\n        @apply text-foreground relative my-8 grid overflow-hidden rounded-lg bg-white p-2 shadow-xl;\n\n        grid-template-columns: 1fr;\n      }\n      .card::before {\n        @apply absolute right-0 h-40 w-40 transform bg-contain bg-center bg-no-repeat opacity-25;\n\n        content: '';\n        top: -2rem;\n        transform: rotate(-15deg);\n      }\n      .card.vscode::before {\n        background-image: url('https://icongr.am/simple/visualstudiocode.svg?color=67b8e3');\n      }\n      .card.cli::before {\n        background-image: url('https://icongr.am/octicons/terminal.svg?color=67b8e3');\n      }\n      .card.core::before {\n        background-image: url('/assets/marp-logo.svg');\n      }\n      .card.marpit::before {\n        background-image: url('/assets/marpit.svg');\n      }\n      .card > * {\n        @apply relative col-start-1 col-end-1;\n      }\n      .card > figure {\n        @apply mx-auto flex items-center justify-center p-4;\n      }\n      .card > figure > img {\n        @apply max-w-full;\n\n        width: 28rem;\n      }\n\n      .card-link {\n        @apply relative z-10 block rounded p-5 transition-all duration-150;\n      }\n      .card-link:hover,\n      .card-link:focus {\n        @apply shadow;\n\n        background-color: rgba(255, 255, 255, 0.5);\n      }\n      .card-link:hover:active,\n      .card-link:focus {\n        @apply duration-0 outline-none ring-1 ring-white ring-offset-2;\n      }\n\n      @screen lg {\n        .card.screenshot {\n          grid-template-columns: 3fr 2fr;\n        }\n        .card > figure {\n          @apply col-start-2 col-end-2 h-full w-full object-contain px-6 py-0;\n\n          grid-row: 1 / span 9999;\n        }\n        .card::before {\n          @apply h-64 w-64;\n\n          top: -4rem;\n        }\n      }\n\n      @screen xl {\n        .card {\n          @apply mx-auto w-5/6;\n        }\n      }\n    `}</style>\n  </section>\n)\n\nexport const GetStarted = () => (\n  <>\n    <div id=\"get-started\" className=\"get-started flow-root\">\n      <section className=\"container mx-auto py-10 px-8 lg:px-16\">\n        <h3 className=\"text-center text-2xl font-bold sm:text-3xl\">\n          <mark>Tools and integrations</mark>\n        </h3>\n        <Card\n          description=\"Enhance VS Code's Markdown preview pane to support writing your beautiful presentations. You can preview the slide deck output as soon as you edit its Markdown.\"\n          name=\"Marp for VS Code\"\n          summary=\"Create slide decks written in Marp Markdown right in VS Code\"\n          badge=\"https://img.shields.io/visual-studio-marketplace/v/marp-team.marp-vscode.svg?style=flat-square&amp;label=&amp;colorB=0288d1\"\n          href=\"https://marketplace.visualstudio.com/items?itemName=marp-team.marp-vscode\"\n          screenShot=\"/assets/marp-for-vs-code.png\"\n          ssWidth={1946}\n          ssHeight={1424}\n          className=\"vscode\"\n        >\n          <Button\n            color=\"primary\"\n            className=\"mr-2 mb-2\"\n            href=\"https://marketplace.visualstudio.com/items?itemName=marp-team.marp-vscode\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            VS Marketplace\n          </Button>\n          <Button\n            outline\n            className=\"mr-2 mb-2\"\n            href=\"https://github.com/marp-team/marp-vscode\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            GitHub\n          </Button>\n        </Card>\n        <Card\n          description=\"The Marp CLI is the swiss army knife of the Marp ecosystem. Convert your Markdown into various formats, watch changes, launch server for on-demand conversion, and customize the core engine.\"\n          name=\"Marp CLI\"\n          summary=\"A CLI interface for Marp and Marpit based converters\"\n          badge=\"https://img.shields.io/npm/v/@marp-team/marp-cli.svg?style=flat-square&amp;label=&amp;colorB=0288d1\"\n          href=\"https://github.com/marp-team/marp-cli\"\n          screenShot=\"/assets/marp-cli.png\"\n          ssWidth={1400}\n          ssHeight={800}\n          className=\"cli\"\n        >\n          <Button\n            color=\"primary\"\n            className=\"mr-2 mb-2\"\n            href=\"https://github.com/marp-team/marp-cli/releases\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            Releases\n          </Button>\n          <Button\n            outline\n            color=\"primary\"\n            className=\"mr-2 mb-2\"\n            href=\"https://www.npmjs.com/package/@marp-team/marp-cli\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            npm\n          </Button>\n          <Button\n            outline\n            className=\"mr-2 mb-2\"\n            href=\"https://github.com/marp-team/marp-cli\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            GitHub\n          </Button>\n        </Card>\n        <h3 className=\"text-center text-2xl font-bold sm:text-3xl\">\n          <mark>For developers</mark>\n        </h3>\n        <Card\n          description=\"All official Marp tooling uses this core as the engine. It is based on the Marpit framework and includes some extra features to help create beautiful slide decks.\"\n          name=\"Marp Core\"\n          summary=\"The core of the Marp converter\"\n          badge=\"https://img.shields.io/npm/v/@marp-team/marp-core.svg?style=flat-square&amp;label=&amp;colorB=0288d1\"\n          href=\"https://github.com/marp-team/marp-core\"\n          className=\"core\"\n        >\n          <Button\n            outline\n            color=\"primary\"\n            className=\"mr-2 mb-2\"\n            href=\"https://www.npmjs.com/package/@marp-team/marp-core\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            npm\n          </Button>\n          <Button\n            outline\n            className=\"mr-2 mb-2\"\n            href=\"https://github.com/marp-team/marp-core\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            GitHub\n          </Button>\n        </Card>\n        <Card\n          description=\"Marpit (independent from Marp) is the framework that transforms Markdown and CSS themes to slide decks composed of HTML/CSS. It is optimized to output only the minimum set of assets required.\"\n          name=\"Marpit framework\"\n          summary=\"The skinny framework for creating slide decks from Markdown\"\n          badge=\"https://img.shields.io/npm/v/@marp-team/marpit.svg?style=flat-square&amp;label=&amp;colorB=0288d1\"\n          href=\"https://marpit.marp.app/\"\n          className=\"marpit\"\n        >\n          <Button\n            color=\"primary\"\n            className=\"mr-2 mb-2\"\n            href=\"https://marpit.marp.app/\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            Documentation\n          </Button>\n          <Button\n            outline\n            color=\"primary\"\n            className=\"mr-2 mb-2\"\n            href=\"https://www.npmjs.com/package/@marp-team/marpit\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            npm\n          </Button>\n          <Button\n            outline\n            className=\"mr-2 mb-2\"\n            href=\"https://github.com/marp-team/marpit\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            GitHub\n          </Button>\n        </Card>\n        <p className=\"mt-4 text-center\">\n          Find all of the Marp tools, integrations, and examples in the GitHub\n          repository!\n        </p>\n        <p className=\"text-foreground mt-4 text-center text-sm\">\n          <Button\n            href=\"https://github.com/marp-team/marp/\"\n            rel=\"noopener\"\n            target=\"_blank\"\n          >\n            Check out Marp GitHub repository...\n          </Button>\n        </p>\n      </section>\n    </div>\n    <style jsx>{`\n      .get-started {\n        @apply bg-marp-brand relative text-white;\n\n        background-image: var(--noise-image),\n          linear-gradient(\n            -2deg,\n            theme('colors.marp.darken'),\n            theme('colors.marp.brand') 500px\n          );\n      }\n\n      .get-started::before,\n      .get-started::after {\n        @apply absolute inset-x-0 block;\n\n        background-image: var(--noise-image),\n          linear-gradient(to bottom, rgba(255, 255, 255, 0.4), transparent 95%);\n        bottom: calc(100% - 5px);\n        content: '';\n        transform: translateZ(0);\n        z-index: -1;\n      }\n\n      .get-started::before {\n        @apply bg-marp-light;\n\n        clip-path: polygon(0 0, 100% 90%, 100% 100%, 0 100%);\n        height: calc(120px + 5vw);\n      }\n\n      .get-started::after {\n        @apply bg-marp-brand;\n\n        clip-path: polygon(0 0, 100% 95%, 100% 100%, 0 100%);\n        height: calc(60px + 5vw);\n      }\n    `}</style>\n  </>\n)\n"
  },
  {
    "path": "website/components/top/Hero.tsx",
    "content": "import Head from 'next/head'\nimport { Button } from 'components/Button'\nimport Marp from 'public/assets/marp.svg'\n\nconst heroBg = '/assets/hero-background.svg' as const\n\nexport const Hero = () => (\n  <>\n    <Head>\n      <link rel=\"preload\" href={heroBg} as=\"image\" />\n    </Head>\n    <section className=\"border-b py-16 px-4 md:py-24 md:tracking-wider\">\n      <h1 className=\"font-rounded text-center font-bold sm:text-xl md:text-2xl\">\n        <Marp className=\"mx-auto mb-5 h-auto w-4/5 max-w-xl p-3\" />\n        <span className=\"sr-only\">Marp:</span>\n        Markdown Presentation Ecosystem\n      </h1>\n      <p className=\"mt-10 text-center\">\n        <Button\n          href=\"#get-started\"\n          color=\"primary\"\n          className=\"text-xl md:text-2xl\"\n        >\n          Get started!\n        </Button>\n      </p>\n      <p className=\"mt-5 text-center\">\n        <Button\n          href=\"https://github.com/marp-team/marp\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n          className=\"text-sm md:text-base\"\n          color=\"primary\"\n          outline\n        >\n          Find Marp tools on GitHub!\n        </Button>\n      </p>\n      <style jsx>{`\n        section {\n          background: #fcfcfc url('${heroBg}') no-repeat right center;\n          background-size: cover;\n        }\n      `}</style>\n    </section>\n  </>\n)\n"
  },
  {
    "path": "website/css/index.css",
    "content": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n:root {\n  --noise-image: url('/assets/noise.svg');\n  --header-height: 4rem;\n  --anchor-margin: var(--header-height);\n\n  scroll-padding-top: var(--anchor-margin);\n}\n\n@screen md {\n  :root {\n    --header-height: 5rem;\n  }\n}\n\n* {\n  scrollbar-color: theme('colors.gray.500') theme('colors.gray.300');\n  scrollbar-width: thin;\n}\n*::-webkit-scrollbar {\n  width: 8px;\n  height: 8px;\n}\n*::-webkit-scrollbar-track {\n  @apply bg-gray-300;\n}\n*::-webkit-scrollbar-thumb {\n  @apply rounded-full bg-gray-500 bg-clip-padding;\n\n  border: 1px solid transparent;\n}\n*::-webkit-scrollbar-thumb:hover {\n  @apply bg-gray-600;\n}\n*::-webkit-scrollbar-thumb:hover:active {\n  @apply bg-gray-700;\n}\n\nhtml:not(.translating) {\n  scroll-behavior: smooth;\n}\n\nbody {\n  @apply text-foreground bg-background relative min-h-full;\n}\n\nbody::before {\n  @apply bg-background fixed inset-0 block;\n\n  background-image: var(--noise-image),\n    linear-gradient(\n      to bottom,\n      theme('colors.gray.100'),\n      theme('colors.background') 50%\n    );\n  content: '';\n  z-index: -1;\n}\n\na:not(.custom-anchor) {\n  @apply text-marp-darken;\n}\n\na:not(.custom-anchor):hover {\n  @apply text-marp-dark underline transition-colors duration-300;\n}\n\na:not(.custom-anchor):hover:active {\n  @apply text-marp-darkest duration-0;\n}\n\nmark {\n  background: none;\n  color: inherit;\n  box-shadow: inset 0 -0.2em theme('colors.marp.light');\n}\n\n/* NProgress */\n#nprogress .bar {\n  @apply bg-marp-brand;\n}\n#nprogress .peg {\n  @apply shadow-none;\n}\n\n/* Helper classes */\n.text-gradient {\n  @apply text-marp-brand leading-tight;\n}\n\n@supports (background-clip: text) {\n  .text-gradient {\n    @apply bg-marp-brand bg-clip-text text-transparent;\n\n    background-image: linear-gradient(\n      -1deg,\n      theme('colors.marp.light'),\n      theme('colors.marp.brand'),\n      theme('colors.marp.dark')\n    );\n  }\n}\n"
  },
  {
    "path": "website/css/plugin-rem.js",
    "content": "// Based on Marpit PostCSS rem plugin\n// https://github.com/marp-team/marpit/blob/main/src/postcss/root/rem.js\n\nconst rootFontSizeCustomProp = '--root-font-size'\nconst skipParsingMatcher = /(\"[^\"]*\"|'[^']*'|(?:attr|url|var)\\([^)]*\\))/g\n\nmodule.exports = () => ({\n  postcssPlugin: 'marp-rem',\n  Once: (css) =>\n    css.walkDecls((decl) => {\n      if (decl.prop === rootFontSizeCustomProp) return\n\n      decl.value = decl.value\n        .split(skipParsingMatcher)\n        .map((v, i) => {\n          if (i % 2) return v\n\n          return v.replace(\n            /(-?\\d*\\.?\\d+)rem\\b/g,\n            (_, num) => `calc(var(${rootFontSizeCustomProp}, 1rem) * ${num})`\n          )\n        })\n        .join('')\n    }),\n})\n\nmodule.exports.postcss = true\n"
  },
  {
    "path": "website/docs/guide/directives.md",
    "content": "# Directives\n\n### This is a stub page!\n\nMarp has an extended syntax called **\"Directives\"** to control theme, page number, header, footer, and other slide elements.\n\n> The syntax of directives is inherited from [Marpit framework](https://marpit.marp.app/directives). Please note that different directives are used by each Marp tool.\n\n## Usage\n\nMarp parses directives as [YAML](https://yaml.org/).\n\n### HTML comment\n\n```markdown\n<!--\ntheme: default\npaginate: true\n-->\n```\n\n### Front matter\n\nLike many tools (e.g. [Jekyll site generator](https://jekyllrb.com/docs/front-matter/)), Marp uses **YAML front matter**. Directives can be defined in front matter.\n\nYAML front matter must be at the beginning of a Markdown document and enclosed by dashed rulers.\n\n```markdown\n---\ntheme: default\npaginate: true\n---\n```\n\nNote that the dashed ruler is also used to indicate where Marp should [ split slides](/docs/guide/how-to-write-slides#slides). Marp uses the first two dashed rulers to indicate YAML front matter. Subsequent dashed rulers indicate slide breaks.\n\n> TIP: Defining directives in the front matter is equivalent to setting the directives using an HTML comment on the first page. Suppose your favorite Markdown editor does not support the front matter syntax. In that case, you can safely define the directive in an HTML comment instead.\n\n## Type of directives\n\nThere are two types of Marp directives:\n\n- **[Global directives](#global-directives)** - Controlling settings for the all slides (e.g. `theme`, `size`)\n- **[Local directives](#local-directives)** - Controlling setting values for one slide (e.g. `paginate`, `header`, `footer`)\n\nYou can define both directives in the same way. You can mix definitions too. The only difference is that some settings apply to all slides, and some apply to only one slide.\n\n### Global directives\n\n**Global directives** are settings for the entire slide deck.\n\n| Name             | Description                                                                    |\n| ---------------- | ------------------------------------------------------------------------------ |\n| `theme`          | [Set a theme name for the slide deck ▶️](/docs/guide/theme)                    |\n| `style`          | Specify CSS for tweaking theme                                                 |\n| `headingDivider` | [Specify heading divider option ▶️](/docs/guide/heading-divider)               |\n| `size`           | Choose the slide size preset provided by theme                                 |\n| `math`           | [Choose a library to render math typesetting ▶️](/docs/guide/math-typesetting) |\n| `title`          | Set a title of the slide deck                                                  |\n| `author`         | Set an author of the slide deck                                                |\n| `description`    | Set a description of the slide deck                                            |\n| `keywords`       | Set comma-separated keywords for the slide deck                                |\n| `url`            | Set canonical URL for the slide deck (for HTML export)                         |\n| `image`          | Set Open Graph image URL (for HTML export)                                     |\n| `marp`           | Set whether or not enable Marp feature in VS Code                              |\n\nIf you set the same global directive multiple times, Marp will use the last defined value.\n\n### Local directives\n\n**Local directives** are settings for a specific slide.\n\n| Name                 | Description                                                                                                                               |\n| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |\n| `paginate`           | [Show page number on the slide if set to `true` ▶️](#page-number)                                                                         |\n| `header`             | [Specify the content of the slide header ▶️](#header-and-footer)                                                                          |\n| `footer`             | [Specify the content of the slide footer ▶️](#header-and-footer)                                                                          |\n| `class`              | Set [HTML `class` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class) for the slide element `<section>` |\n| `backgroundColor`    | Set [`background-color` style](https://developer.mozilla.org/en-US/docs/Web/CSS/background-color) of the slide                            |\n| `backgroundImage`    | Set [`background-image` style](https://developer.mozilla.org/en-US/docs/Web/CSS/background-image) of the slide                            |\n| `backgroundPosition` | Set [`background-position` style](https://developer.mozilla.org/en-US/docs/Web/CSS/background-position) of the slide                      |\n| `backgroundRepeat`   | Set [`background-repeat` style](https://developer.mozilla.org/en-US/docs/Web/CSS/background-repeat) of the slide                          |\n| `backgroundSize`     | Set [`background-size` style](https://developer.mozilla.org/en-US/docs/Web/CSS/background-size) of the slide                              |\n| `color`              | Set [`color` style](https://developer.mozilla.org/en-US/docs/Web/CSS/color) of the slide                                                  |\n\n#### Inheritance\n\nSlides will inherit setting values of local directives from the immediately previous slide **unless** a local directive is explicitly set for the current slide. In other words, defined local directives will apply to both the defined page and subsequent pages.\n\nFor example, the Markdown for this set of slides defines the `backgroundColor` directive on the second page. Because subsequent pages inherit local directives, the third page will also have the same color.\n\n```markdown\n# Page 1\n\nGo to next page :arrow_right:\n\n---\n\n<!-- backgroundColor: lightblue -->\n\n# Page 2\n\n## This page has a light blue background.\n\n---\n\n# Page 3\n\n## This page also has the same light blue background.\n```\n\n```markdown:marp\n# Page 1\n\nGo to next page :arrow_right:\n\n---\n\n<!-- backgroundColor: lightblue -->\n\n# Page 2\n\n## This page has a light blue background.\n\n---\n\n# Page 3\n\n## This page also has the same light blue background.\n```\n\n#### Scoped local directives\n\nIf you want a local directive to apply only to the current page, add the underscore prefix `_` to the name of directives.\n\nThe value of a scoped directive will be given priority over an inherited value, and subsequent pages will not inherit the value of the scoped directive.\n\n```markdown\n<!-- color: red -->\n\n# Page 1\n\nThis page has red text.\n\n---\n\n<!-- _color: blue -->\n\n# Page 2\n\nThis page has blue text, specified by a scoped local directive.\n\n---\n\n# Page 3\n\nGo back to red text.\n```\n\n```markdown:marp\n<!-- color: red -->\n\n# Page 1\n\nThis page has red text.\n\n---\n\n<!-- _color: blue -->\n\n# Page 2\n\nThis page has blue text, specified by a scoped local directive.\n\n---\n\n# Page 3\n\nGo back to red text.\n```\n\nThe underscore prefix can be added to any local directives.\n\n#### Diagram\n\n![The diagram of local directives and scoped directives](/assets/docs/directives.png 'The diagram of local directives and scoped directives')\n\n## Theme\n\n<!-- TODO: Link to \"Theme\" section -->\n\n## Page number\n\nTo add page number to the slide, set the **`paginate`** local directive to `true`.\n\n```markdown\n<!-- paginate: true -->\n\nYou can see the slide number in the lower right.\n```\n\n```markdown:marp\n<!-- paginate: true -->\n\nYou can see the slide number in the lower right.\n\n<style>\n  @keyframes point {\n    from { background-position: bottom 55px right 55px; }\n    to { background-position: bottom 40px right 40px; }\n  }\n  section {\n    animation: 0.5s ease-in-out alternate infinite point;\n    background: #fff url('https://icongr.am/feather/arrow-down-right.svg?color=0288d1') no-repeat bottom 40px right 40px / 100px;\n  }\n  @media (prefers-reduced-motion) {\n    section {\n      animation: none;\n    }\n  }\n</style>\n```\n\nRefer to [theme guide](/docs/guide/theme) for details on how to style a slide number.\n\n### Skip pagination in the title slide\n\nJust move the definition of the `paginate` directive to the second slide.\n\n```markdown\n# Title slide\n\n---\n\n<!-- paginate: true --->\n\n## Start pagination from this slide.\n```\n\n```markdown:marp\n# Title slide\n\n---\n\n<!-- paginate: true --->\n\n## Start pagination from this slide.\n\n<style scoped>\n  @keyframes point {\n    from { background-position: bottom 55px right 55px; }\n    to { background-position: bottom 40px right 40px; }\n  }\n  section {\n    animation: 0.5s ease-in-out alternate infinite point;\n    background: #fff url('https://icongr.am/feather/arrow-down-right.svg?color=0288d1') no-repeat bottom 40px right 40px / 100px;\n  }\n  @media (prefers-reduced-motion) {\n    section {\n      animation: none;\n    }\n  }\n</style>\n```\n\nYou can also use [scoped directive](#scoped-local-directives) to disable pagination in the title slide.\n\n```markdown\n---\npaginate: true\n_paginate: false\n---\n\n# Title slide\n\n---\n\n## Start pagination from this slide.\n```\n\n## Header and footer\n\nUse **`header`** and **`footer`** local directives to add headers and footers to slides.\n\n```markdown\n<!--\nheader: Header content\nfooter: Footer content\n-->\n\n# Header and footer\n```\n\n```markdown:marp\n<!--\nheader: Header content\nfooter: Footer content\n-->\n\n# Header and footer\n<style>\n  @keyframes point-up {\n    from { background-position: 50px 50px; }\n    to { background-position: 50px 70px; }\n  }\n  @keyframes point-down {\n    from { background-position: left 50px bottom 50px; }\n    to { background-position: left 50px bottom 70px; }\n  }\n  section {\n    animation: 0.5s ease-in-out alternate infinite point-up;\n    background: #fff url('https://icongr.am/feather/arrow-up.svg?color=0288d1') no-repeat 50px 50px / 80px;\n  }\n  section::before {\n    content: '';\n    display: block;\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    pointer-events: none;\n    animation: 0.5s ease-in-out alternate infinite point-down;\n    background: transparent url('https://icongr.am/feather/arrow-down.svg?color=0288d1') no-repeat left 50px bottom 50px / 80px;\n  }\n  @media (prefers-reduced-motion) {\n    section, section::before {\n      animation: none;\n    }\n  }\n</style>\n```\n\nRefer to [theme guide](/docs/guide/theme) for details on how to style header and footer.\n\n### Markdown formatting\n\nYou can use inline Markdown formatting (italic, bold, inline image, etc) in header and footer like this:\n\n```markdown\n---\nheader: '**bold** _italic_'\nfooter: '![image](https://example.com/image.jpg)'\n---\n```\n\nTo make directives parsable as valid YAML, you can wrap content with (double-)quotes.\n\n### Reset header and footer\n\nSet the value of a directive to an empty string value to reset the header and footer in the middle of the slide deck.\n\n```markdown\n---\nheader: '**Header**'\nfooter: '_Footer_'\n---\n\n# Example\n\n---\n\n<!--\nheader: ''\nfooter: ''\n-->\n\n## Reset header and footer\n```\n\n```markdown:marp\n---\nheader: '**Header**'\nfooter: '_Footer_'\n---\n\n# Example\n\n---\n\n<!--\nheader: ''\nfooter: ''\n-->\n\n## Reset header and footer\n```\n\n## Styling slide\n\n### Shorthand\n\n## Editor integration\n\n<!-- By using **Marp for VS Code**, you can preview -->\n"
  },
  {
    "path": "website/docs/guide/fitting-header.md",
    "content": "# Fitting header\n\nWhen the `<!--fit-->` comment is placed in a heading, the heading will be scaled to fit onto a single line.\n\n```markdown\n# <!-- fit --> Fitting header\n```\n\n```markdown:marp\n# <!-- fit --> Fitting header\n```\n\nThe syntax is similar to [Deckset's `[fit]` keyword](https://docs.decksetapp.com/English.lproj/Formatting/01-headings.html), but Marp uses an HTML comment to hide the keyword when the Markdown is rendered.\n\n> This feature is inherited from [Marp Core](https://github.com/marp-team/marp-core).\n\n## Examples\n\n### Takahashi-style\n\nYou can efficiently make [Takahashi-style](https://en.wikipedia.org/wiki/Takahashi_method) slides like the [Big](https://github.com/tmcw/big) presentation system by using the fitting header. Combining fitting headers with the [heading divider](/docs/guide/heading-divider) directive will allow you to write one slide per line.\n\n```markdown\n---\ntheme: uncover\nheadingDivider: 1\n---\n\n# <!--fit--> Takahashi-style<br />presentation\n\n# <!--fit--> Feature\n\n# <!--fit--> Huge text\n\n# <!--fit--> A few words\n```\n\n```markdown:marp\n---\ntheme: uncover\nheadingDivider: 1\n---\n\n# <!--fit--> Takahashi-style<br />presentation\n\n# <!--fit--> Feature\n\n# <!--fit--> Huge text\n\n# <!--fit--> A few words\n```\n"
  },
  {
    "path": "website/docs/guide/fragmented-list.md",
    "content": "# Fragmented list\n\nMarp uses some uncommon list markers to denote a **fragmented list** (also known as an incremental list or builds), which allows list content to appear incrementally.\n\nFragmented lists are _only available if you export to HTML_. If you export to PDF and PPTX, the fragmented list will be rendered as a normal list.\n\n> Be careful when using fragmented lists. While fragmented lists can help focus the audience's attention on the last displayed item, they may also create confusion about hidden items. Some articles recommend never using builds (e.g. [Presentation Rules](http://www.jilles.net/perma/2020/06/05/presentation-rules.html)).\n\n## For bullet lists\n\nCommonMark's bullet list markers are `-`, `+`, and `*` (https://spec.commonmark.org/0.29/#bullet-list-marker). If you use `*` as the marker, Marp will parse the list as a fragmented list.\n\n<!-- prettier-ignore-start -->\n\n```markdown\n# Bullet list\n\n- One\n- Two\n- Three\n\n---\n\n# Fragmented list\n\n* One\n* Two\n* Three\n```\n\n<!-- prettier-ignore-end -->\n\n## For ordered list\n\nCommonMark's [ordered list marker](https://spec.commonmark.org/0.29/#ordered-list-marker) must have `.` or `)` after digits. If you use `)` as the following character, then Marp will parse the ordered list as a fragmented list.\n\n<!-- prettier-ignore-start -->\n\n```markdown\n# Ordered list\n\n1. One\n2. Two\n3. Three\n\n---\n\n# Fragmented list\n\n1) One\n2) Two\n3) Three\n```\n\n<!-- prettier-ignore-end -->\n\n> These are inherited from [Marpit framework](https://marpit.marp.app/fragmented-list).\n>\n> [This syntax only indicates that the list _should_ be fragmented](https://marpit.marp.app/fragmented-list?id=rendering). If the tools integrated with Marp do nothing with the syntax, this list would be rendered as a normal list. In the official toolset, [Marp CLI](https://github.com/marp-team/marp-cli)'s default HTML template `bespoke` can reproduce a fragmented list as a build animation.\n"
  },
  {
    "path": "website/docs/guide/heading-divider.md",
    "content": "# Heading divider\n\nThe heading divider directive tells Marp to automatically add a slide break before a heading of the specified level. This directive is particularly useful when converting an existing Markdown document to slides.\n\nHeading dividers is similar to [Pandoc](https://pandoc.org/)'s [`--slide-level` option](https://pandoc.org/MANUAL.html#structuring-the-slide-show) and [Deckset 2](https://www.deckset.com/2/)'s \"Slide Dividers\" option.\n\n> This feature is inherited from the [Marpit framework](https://marpit.marp.app/directives?id=heading-divider).\n\n## Example\n\nLet’s say you have a Markdown document like this:\n\n```markdown\n# Markdown document\n\nThe article of Markdown\n\n## What is Markdown?\n\n> Markdown is a lightweight markup language for creating formatted text using a plain-text editor.\n>\n> _-- https://en.wikipedia.org/wiki/Markdown_\n\n## History\n\n### Origin\n\nMarkdown has created by John Gruber in 2004.\n\nhttps://daringfireball.net/projects/markdown/\n\n### Standardization\n\nCommonMark is a project for a standardization of Markdown launched in 2012.\n```\n\nAdd the [`headingDivider` global directive](/docs/guide/directives#global-directives).\n\n```markdown\n<!-- headingDivider: 2 -->\n```\n\nOnce you have specified the directive, Marp will automatically split the document into slides by starting a new slide whenever a section has a heading level of 2.\n\n```markdown:marp\n<!-- headingDivider: 2 -->\n\n# Markdown document\n\nThe article of Markdown\n\n## What is Markdown?\n\n> Markdown is a lightweight markup language for creating formatted text using a plain-text editor.\n>\n> _-- https://en.wikipedia.org/wiki/Markdown_\n\n## History\n\n### Origin\n\nMarkdown was created by John Gruber in 2004.\n\nhttps://daringfireball.net/projects/markdown/\n\n### Standardization\n\nCommonMark is a project for a standardization of Markdown launched in 2012.\n```\n\nThe `headingDivider` global directive accepts heading levels from 1 to 6. When the heading level is set as a number, Marp will split slides at headings that are _at the specified level and at all parent levels_. So, `headingDivider: 2` will actually make new slides at headings of levels 1 and 2.\n\nIf a section has so much content that it overflows the slide, it might be better to split it by subsection. To do that, just change the base level for `headingDivider` to `3`. Check out the difference from the previous example after the 3rd page:\n\n```markdown:marp\n<!-- headingDivider: 3 -->\n\n# Markdown document\n\nThe article of Markdown\n\n## What is Markdown?\n\n> Markdown is a lightweight markup language for creating formatted text using a plain-text editor.\n>\n> _-- https://en.wikipedia.org/wiki/Markdown_\n\n## History\n\n### Origin\n\nMarkdown was created by John Gruber in 2004.\n\nhttps://daringfireball.net/projects/markdown/\n\n### Standardization\n\nCommonMark is a project for a standardization of Markdown launched in 2012.\n```\n\n> [Rulers to split pages](/docs/guide/how-to-write-slides#slides) still work normally even if enabled `headingDivider`.\n\n## Advanced\n\nAuto split in parent heading levels is reasonable behavior in most cases, but sometimes you may require finer control of splitting levels. If you set the directive value to an array, you also instruct Marp to split at only the specified levels.\n\n```markdown\n<!-- headingDivider: [1, 3] -->\n```\n\nThis setting will instruct Marp to split slides at heading levels 1 and 3.\n"
  },
  {
    "path": "website/docs/guide/how-to-write-slides.md",
    "content": "# How to write slides\n\n## Markdown\n\nTo write slides using Marp, you have to know basic Markdown syntax. It doesn't take long to learn the basics, and there are many Markdown tutorials on the internet, so this guide will focus on the additional syntax used by Marp that allows you to write slides.\n\n### Resources for learning Markdown\n\n- **[Markdown Guide](https://www.markdownguide.org/)** - A simple guide on how to use Markdown\n- **[Markdown Tutorial](https://www.markdowntutorial.com/)** - Step-by-step Markdown tutorials with interactive exercises\n\n## Slides\n\nOK, let's write presentation slides. Marp splits slides in the deck using the horizontal ruler (e.g. `---`).\n\n```markdown\n# Slide 1\n\nHello, world!\n\n---\n\n# Slide 2\n\nMarp splits slides in the deck by horizontal ruler.\n```\n\n```markdown:marp\n# Slide 1\n\nHello, world!\n\n---\n\n# Slide 2\n\nMarp splits slides in the deck by horizontal ruler.\n```\n\nIf you use the `---` ruler, an empty line may be required before the ruler by [the spec of CommonMark](https://spec.commonmark.org/0.29/#example-28). If you do not want to add empty lines around the ruler, you can also use the underline ruler `___`, asterisk ruler `***`, or space-included ruler `- - -` to split slides.\n\n> This feature is inherited from [Marpit framework](https://marpit.marp.app/markdown).\n\n## Syntaxes\n\nMarp's Markdown syntax is based on [CommonMark](https://commonmark.org/). In addition, Marp uses some extended syntax:\n\n- Line breaks in a paragraph will convert to `<br />` tag automatically.\n  - You also can use `<br />` tag directly (Useful if you need a line break within a [fitting header](/docs/guide/fitting-header)).\n- There is special meaning in some (uncommon) list markers `*` and `1)`. [▶️ Fragmented list](/docs/guide/fragmented-list).\n- Some extended syntaxes that came from [GitHub Flavored Markdown (GFM)](https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown) are enabled:\n  - [Automatic linking for URLs](https://github.github.com/gfm/#autolinks-extension-)\n  - Emoji shortcode (provided by [markdown-it-emoji](https://github.com/markdown-it/markdown-it-emoji) and [twemoji](https://github.com/twitter/twemoji))\n  - [Strikethrough](https://github.github.com/gfm/#strikethrough-extension-) (`~~strike~~`)\n  - Syntax highlighting for code blocks (via [highlight.js](https://highlightjs.org/))\n  - [Tables](https://github.github.com/gfm/#tables-extension-)\n- Most HTML tags are _disabled_ by default for security reasons. Marp only allows users to use two tags by default: the `<style>` tag for tweaking the theme and the `<br />` tag mentioned earlier.\n  - To enable all HTML tags, you need to opt-in for the Marp tool you are using.\n\n> Many extended syntaxes are inherited from [Marp Core](https://github.com/marp-team/marp-core).\n"
  },
  {
    "path": "website/docs/guide/image-syntax.md",
    "content": "# Image syntax\n\n### This is a stub page!\n\n> This feature is inherited from [Marpit framework](https://marpit.marp.app/image-syntax).\n"
  },
  {
    "path": "website/docs/guide/math-typesetting.md",
    "content": "# Math typesetting\n\n[Many Markdown tools support math rendering](https://github.com/cben/mathdown/wiki/math-in-markdown). We have [Pandoc's Markdown style](https://pandoc.org/MANUAL.html#math) math typesetting support. Marp renders math using [MathJax] (or, alternatively, [KaTeX]).\n\n[katex]: https://katex.org/\n[mathjax]: https://www.mathjax.org/\n\n### Inline math\n\nSurround your formula with a single dollar character `$...$`.\n\n```markdown\nRender inline math such as $ax^2+bc+c$.\n```\n\n### Math block\n\nSurround the formula with double dollar characters `$$...$$`. Math in the block element will render with centering. The math in the block element will also scale down automatically if it is sticking out from the horizontal border of the slide (only in supported themes).\n\n<!-- prettier-ignore-start -->\n\n```markdown\n$$ I_{xx}=\\int\\int_Ry^2f(x,y)\\cdot{}dydx $$\n\n$$\nf(x) =\n  \\int_{-\\infty}^\\infty\n  \\hat f(\\xi)\\,e^{2 \\pi i \\xi x}\n  \\,d\\xi\n$$\n```\n<!-- prettier-ignore-end -->\n\n```markdown:marp\n## Inline math\n\nRender inline math such as $ax^2+bc+c$.\n\n## Math block\n\n$$ I_{xx}=\\int\\int_Ry^2f(x,y)\\cdot{}dydx $$\n\n$$\nf(x) =\n  \\int_{-\\infty}^\\infty\n  \\hat f(\\xi)\\,e^{2 \\pi i \\xi x}\n  \\,d\\xi\n$$\n```\n\n> This feature is inherited from [Marp Core](https://github.com/marp-team/marp-core).\n\n## [MathJax]\n\nBy default, Marp uses **[MathJax]** to render math typesetting.\n\n### Declare to use MathJax\n\nSet [`math` global directive](/docs/guide/directives#global-directives) as `mathjax`.\n\n```markdown\n---\nmath: mathjax\n---\n\nRender inline math such as $ax^2+bc+c$.\n```\n\nFor the determined rendering of slide, we recommend always to declare math library to use in the slide. No definition of math directive may bring inconsistent rendering result depending on the version of Marp Core.\n\n## [KaTeX]\n\n**[KaTeX]** is an alternative library to render math typesettings in Marp, and it was former default.\n\nBy defining `math` global directive as `katex`, you can continue to render math with KaTeX.\n\n### Enable KaTeX\n\nSet [`math` global directive](/docs/guide/directives#global-directives) as `katex`.\n\n```markdown\n---\nmath: katex\n---\n\nRender inline math such as $ax^2+bc+c$.\n```\n\n### Define global macro\n\nIn KaTeX rendering, macros defined by `\\def` will persist only in a local math environment. To persist defined macro for subsequent math environments in Markdown, use `\\gdef` (`\\global\\def`) instead.\n\n```markdown\n$$\n% macroA can use only in this math block.\n\\def\\macroA{{\\color{red}A}}\n\n% macroB has defined globally so you can use it after here.\n\\gdef\\macroB{{\\color{blue}B}}\n\n\\macroA + \\macroB\n$$\n\n---\n\n$$\n% macroA cannot use, but macroB can.\n\\macroA + \\macroB\n$$\n```\n\n[See the detail of supported macro functions in KaTeX documentation](https://katex.org/docs/supported.html#macros).\n\n### Configuration\n\nKaTeX options can be configured in [Marp Core's constructor option](https://github.com/marp-team/marp-core#constructor-options). You should use [Marp CLI](https://github.com/marp-team/marp-cli) if you need to set a custom configuration in Marp conversion.\n\n```javascript\n// marp.config.js\nmodule.exports = {\n  options: {\n    math: {\n      lib: 'katex',\n      katexFontPath: 'https://example.com/assets/katex-fonts/'\n      katexOption: {\n        errorColor: '#ff0000',\n        macros: {\n          '\\\\RR': '\\\\mathbb{R}',\n        },\n      },\n    },\n  },\n}\n```\n\n```bash\nmarp -c marp.config.js marp-math.md\n```\n\n[See the details of KaTeX option in the documentation.](https://katex.org/docs/options.html)\n\n### mhchem extension\n\n[mhchem](https://mhchem.github.io/MathJax-mhchem/) is an extension for writing chemical equations. To enable mhchem in Marp, you should use a Marp CLI configuration file and follow [a guide of KaTeX for Node.js](https://katex.org/docs/node.html#using-mhchem-extension).\n\n```javascript\n// marp.config.js\nconst katex = require('katex')\nrequire('katex/dist/contrib/mhchem.js') // modify katex module\n```\n\n```bash\nmarp -c marp.config.js marp-mhchem.md\n```\n\nA common mistake is [using a client-side `<script>` to load the extension](https://github.com/KaTeX/KaTeX/tree/master/contrib/mhchem#usage). _This will not work because Marp's rendering will be completed within Node.js, not the browser._ See also: [marp-team/marp#99](https://github.com/marp-team/marp/discussions/99)\n\n### Known issues for KaTeX rendering\n\n- KaTeX rendering requires fetching Web Fonts from [jsDelivr](https://www.jsdelivr.com/) CDN. If you are in offline or the limited network by proxy, the slide may not render math.\n- Safari does not shrink down the big math block rendered by KaTeX. ([marp-team/marp-core#159](https://github.com/marp-team/marp-core/issues/159))\n- Rendering of `\\tag{}` is incompatible with the math block. ([marp-team/marp-core#236](https://github.com/marp-team/marp-core/issues/236))\n"
  },
  {
    "path": "website/docs/guide/theme.md",
    "content": "# Theme\n\n### This is a stub page!\n"
  },
  {
    "path": "website/docs/introduction/install.md",
    "content": "# Install\n\n### This is a stub page!\n\nThere are two ways to use Marp, through a command-line interface (**[Marp CLI][marp cli]**) or through a graphical user interface (**[VS Code extension][marp for vs code]**). To start authoring presentations, you must install either the CLI or the VS Code extension.\n\n## Should I use the Marp CLI or Marp for VS Code?\n\n### Basic Comparison\n\n|                   | Marp for VS Code |   Marp CLI   |\n| ----------------: | :--------------: | :----------: |\n|            Editor |     VS Code      |  Any editor  |\n|      Live Preview |       Yes        |     Yes      |\n|     Export Method | Click to export  | Command Line |\n| Use Marp plugins? |        No        |     Yes      |\n\n### Marp for VS Code\n\nIf you are not familiar with the command line, use the VS Code extension without hesitation! All of the basic Marp features are available in Marp for VS Code.\n\nEven if you are CLI savvy, you may prefer to author presentations through Marp for VS Code. VS Code has many convenient features for authoring a slide deck, including Marp syntax completion and live preview.\n\n### Marp CLI\n\nUsing Marp CLI is suited for following:\n\n- Authoring Markdown and theme CSS with your favorite editor (such as vim)\n- Batch processing\n- Combination with other tools (through piping and redirection)\n- Continuous Integration (CI)\n- Server-side conversion\n- Set advanced configuration of Marp\n- Use Marp in Node.js project\n- Use Marp / Marpit / markdown-it plugins\n- Use the other Marpit flavored engine\n\n## Installing [Marp for VS Code]\n\n1. Install [Visual Studio Code].\n2. Install the [Marp for VS Code] extension.\n3. Create and open a new Markdown file (with `.md` extension).\n4. Select the `Toggle Marp feature for current Markdown` command from the Marp icon in editor actions (toolbar). This command will add Marp to the front-matter of your Markdown file:\n   ```markdown\n   ---\n   marp: true\n   ---\n   ```\n5. Open VS Code Markdown preview, and start writing your presentation!\n\n[visual studio code]: https://code.visualstudio.com/\n[marp for vs code]: https://marketplace.visualstudio.com/items?itemName=marp-team.marp-vscode\n\n## Installing [Marp CLI]\n\n[marp cli]: https://github.com/marp-team/marp-cli\n\n### [Homebrew](https://brew.sh/) (macOS)\n\n```bash\nbrew install marp-cli\n```\n\n### [Scoop](https://scoop.sh/) (Windows)\n\n```bash\nscoop install marp\n```\n\n### [Node.js](https://nodejs.org/)\n\nIf you have installed Node.js >= 12, you can try one-shot conversion without installing powered by `npx` (`npm exec`).\n\n```bash\nnpx @marp-team/marp-cli@latest markdown.md\n```\n\n#### Install to Node project\n\n```bash\nnpm install --save-dev @marp-team/marp-cli\nnpx marp markdown.md\n```\n\n```bash\nyarn add --dev @marp-team/marp-cli\nyarn exec markdown.md\n```\n\n[You can also install the `marp` command globally](https://github.com/marp-team/marp-cli#global-installation), but it is _not recommended_.\n\n#### Standalone binary\n\n[➡️ Download the latest standalone binary from the GitHub release page...][standalone binary]\n\n[standalone binary]: https://github.com/marp-team/marp-cli/releases\n\n#### Docker\n\n[➡️ Check out the overview of an official container in Docker Hub...][docker]\n\n[docker]: https://hub.docker.com/r/marpteam/marp-cli/\n"
  },
  {
    "path": "website/docs/introduction/whats-marp.md",
    "content": "# What's Marp?\n\n### This is a stub page!\n\n**Marp** (**Mar**kdown **P**resentation Ecosystem) provides a great experience for _writing_ presentations with Markdown.\n\n````markdown:marp\n---\nmarp: true\ntheme: uncover\n---\n\n![Marp w:240](/assets/marp-logo.svg)\n\n# **Marp**\n\nMarkdown Presentation Ecosystem\n\nhttps://marp.app/\n\n---\n\n<!-- paginate: true -->\n\n## What's Marp?\n\nMarp provides a great experience for _writing_ presentations with Markdown. :pencil:\n\n```markdown\n# Slide 1\n\nfoo\n\n---\n\n# Slide 2\n\nbar\n```\n````\n\n## Concepts\n\n### Markdown\n\n[Markdown] is one of the most popular lightweight markup languages. Markdown allows the author to write presentations quickly and focus on the logical structure of the presentation (rather than the code needed to generate the presentation).\n\nThe Marp ecosystem is based on [CommonMark], a consistent spec of Markdown. Marp uses CommonMark to ensure maximum compatibility across Markdown editors and with other Markdown files. Marp only adds a few additional features on top of CommonMark, so your Marp document will look good regardless of what software you used to edit or render Markdown.\n\n[markdown]: https://en.wikipedia.org/wiki/Markdown\n[commonmark]: https://commonmark.org/\n\n### Theme CSS\n\nThe Marp ecosystem is designed to be intuitive to anyone who has made a webpage. As long as you know HTML and CSS, you should be able to style your presentation easily. Our theming system allows you to use plain CSS to style your slides.\n\nMarp is designed with the \"[Separation of content and style](https://en.wikipedia.org/wiki/Separation_of_content_and_presentation)\" in mind. The goal is to make it easy for users to apply designs made by the community to the user's content.\n\n### Export to PDF, PPTX, HTML\n\nMarp has first-class support for conversion into other file formats. We prioritize reproducible rendering across formats so that users do not have to worry about different formats breaking layouts. Our goal is to make sure the PDF, PPTX, and HTML versions of your slides look exactly the same.\n\nNote that Marp is not designed to be stand-alone presentation software. The simplest and recommended way to present is to export to PDF, which allows you to present in any environment that supports PDFs. The PDF format is particularly useful if you are presenting without access to the internet. The HTML format allows you to serve your slide deck on the internet, show interactive content, and use features like fragmented lists. If you want to add additional content manually in PowerPoint, Marp also allows you to export to the PowerPoint (PPTX) format.\n\n### Easy to get started\n\nOur ecosystem provides both a CLI and a GUI (as an VS Code extension) for authoring a Marp slide deck. To create a slide deck, all you need to do is install Marp and write a Markdown file in the Marp format. If you want to export to PDF/PPTX, you will also need to have Chrome, Edge, or some other Chromium-flavored browser installed locally.\n\nThe Marp CLI can convert Markdown into HTML/PDF/PPTX easily. VS Code extension gives real-time slide preview, Marp Markdown language features, and export commands.\n\n### Pluggable architecture\n\nMarp is based on **[Marpit framework]**, the skinny framework for creating a slide deck from Markdown. It has a pluggable architecture, and developers can add features via plugin.\n\nEnd users can customize the conversion engine by using Marp CLI and plugins: Add new Markdown syntax (compatible with markdown-it plugins), add custom directives, provide custom theme set, and so on. Push the limits of Marp as you like!\n\n[marpit framework]: https://marpit.marp.app\n\n## Author\n\nWe're [Marp team](https://github.com/marp-team). (Having said that, currently, Marp is a solo project by maintainer. The best way to join us is many contributions into Marp!)\n\n- **Yuki Hattori ([@yhatt](https://github.com/yhatt))** - Project owner / maintainer\n\n## License\n\nAll tools and related libraries by Marp team are licensed by [MIT License](https://github.com/marp-team/marp/blob/main/LICENSE).\n"
  },
  {
    "path": "website/docs/manifest.yaml",
    "content": "introduction:\n  title: Introduction\n  pages:\n    whats-marp:\n      title: What's Marp?\n    install:\n      title: Install\nguide:\n  title: Guide\n  pages:\n    how-to-write-slides:\n      title: How to write slides\n    directives:\n      title: Directives\n    theme:\n      title: Theme\n    heading-divider:\n      title: Heading divider\n    image-syntax:\n      title: Image syntax\n    fragmented-list:\n      title: Fragmented list\n    fitting-header:\n      title: Fitting header\n    math-typesetting:\n      title: Math typesetting\ntools:\n  title: Tools\n  pages:\n    marp-cli:\n      title: Marp CLI\n    marp-for-vs-code:\n      title: Marp for VS Code\n"
  },
  {
    "path": "website/docs/tools/marp-cli.md",
    "content": "# Marp CLI\n\n### This is a stub page!\n"
  },
  {
    "path": "website/docs/tools/marp-for-vs-code.md",
    "content": "# Marp for VS Code\n\n### This is a stub page!\n"
  },
  {
    "path": "website/global.d.ts",
    "content": "import {} from 'react'\n\ndeclare module 'react' {\n  interface HTMLAttributes {\n    inert?: ''\n  }\n}\n"
  },
  {
    "path": "website/next-env.d.ts",
    "content": "/// <reference types=\"next\" />\n/// <reference types=\"next/image-types/global\" />\n\n// NOTE: This file should not be edited\n// see https://nextjs.org/docs/basic-features/typescript for more information.\n"
  },
  {
    "path": "website/next.config.js",
    "content": "const path = require('path')\nconst withBundleAnalyzer = require('@next/bundle-analyzer')({\n  enabled: !!process.env.ANALYZE,\n})\nconst { devDependencies } = require('./package.json')\n\n// Build test function to ignore devDependencies in client build\nconst ignoreIncludedPaths = Object.keys(devDependencies).map(\n  (m) => path.join(path.resolve(__dirname, '../node_modules'), m) + path.sep\n)\nconst ignoreExcludedPaths = [require.resolve('@marp-team/marp-core/browser')]\n\nconst testToignoreDevDependenciesInClient = (id) =>\n  !ignoreExcludedPaths.some((p) => id.startsWith(p)) &&\n  ignoreIncludedPaths.some((p) => id.startsWith(p))\n\n// Environments\nconst env = { BUILD_YEAR: new Date().getFullYear().toString() }\nif (process.env.URL) env.NEXT_PUBLIC_HOST = process.env.URL // for Netlify's deploy preview\n\nmodule.exports = withBundleAnalyzer({\n  env,\n  transpilePackages: [\n    'hast-util-sanitize',\n    'hast-util-whitespace',\n    'unist-util-is',\n    'unist-util-remove-position',\n    'unist-util-visit',\n  ],\n  webpack: (config, { isServer }) => {\n    config.module.rules.push({ test: /\\.md$/, type: 'asset/source' })\n    config.module.rules.push({\n      test: /\\.ya?ml$/,\n      type: 'json',\n      use: {\n        loader: 'yaml-loader',\n        options: { asJSON: true },\n      },\n    })\n    config.module.rules.push({\n      test: /\\.svg$/,\n      use: '@svgr/webpack',\n    })\n\n    if (!isServer) {\n      config.module.rules.push({\n        test: testToignoreDevDependenciesInClient,\n        issuer: [__dirname],\n        use: 'null-loader',\n      })\n    }\n\n    return config\n  },\n})\n"
  },
  {
    "path": "website/package.json",
    "content": "{\n  \"name\": \"@marp-team/marp-website\",\n  \"version\": \"0.0.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"check:ts\": \"tsc --noEmit\",\n    \"export\": \"next build && next export\",\n    \"dev\": \"next dev\",\n    \"build\": \"next build\",\n    \"start\": \"next start\"\n  },\n  \"dependencies\": {\n    \"@primer/octicons-react\": \"^17.10.0\",\n    \"body-scroll-lock\": \"^4.0.0-beta.0\",\n    \"classnames\": \"^2.3.2\",\n    \"focus-trap-react\": \"^10.0.2\",\n    \"focus-visible\": \"^5.2.0\",\n    \"hast-util-sanitize\": \"^4.0.0\",\n    \"next\": \"^13.1.1\",\n    \"nprogress\": \"^0.2.0\",\n    \"prism-react-renderer\": \"^1.3.5\",\n    \"react\": \"^18.2.0\",\n    \"react-dom\": \"^18.2.0\",\n    \"remark-react\": \"^9.0.1\",\n    \"swiper\": \"^8.4.5\",\n    \"use-media\": \"^1.4.0\",\n    \"wicg-inert\": \"^3.1.2\"\n  },\n  \"devDependencies\": {\n    \"@marp-team/marp-core\": \"^3.6.0\",\n    \"@next/bundle-analyzer\": \"^13.1.1\",\n    \"@svgr/webpack\": \"^6.5.1\",\n    \"@types/classnames\": \"^2.3.1\",\n    \"@types/react\": \"^18.0.26\",\n    \"@types/resize-observer-browser\": \"^0.1.7\",\n    \"@types/webpack-env\": \"^1.18.0\",\n    \"autoprefixer\": \"^10.4.13\",\n    \"dot-prop\": \"^7.2.0\",\n    \"eslint-config-next\": \"^13.1.1\",\n    \"gray-matter\": \"^4.0.3\",\n    \"hast-util-whitespace\": \"^2.0.0\",\n    \"node-fetch\": \"^3.3.0\",\n    \"null-loader\": \"^4.0.1\",\n    \"postcss\": \"^8.4.20\",\n    \"postcss-flexbugs-fixes\": \"^5.0.2\",\n    \"postcss-import-url\": \"^7.2.0\",\n    \"postcss-preset-env\": \"^7.8.3\",\n    \"postcss-url\": \"^10.1.3\",\n    \"prettier-plugin-tailwindcss\": \"^0.2.1\",\n    \"remark-gfm\": \"^3.0.0\",\n    \"remark-parse\": \"^10.0.0\",\n    \"remark-slug\": \"^7.0.0\",\n    \"styled-jsx-plugin-postcss\": \"^4.0.1\",\n    \"tailwindcss\": \"^3.2.4\",\n    \"unified\": \"^10.1.2\",\n    \"unist-util-remove-position\": \"^4.0.1\",\n    \"unist-util-visit\": \"^4.1.1\",\n    \"yaml-loader\": \"^0.8.0\"\n  }\n}\n"
  },
  {
    "path": "website/pages/404.tsx",
    "content": "import { ArrowLeftIcon } from '@primer/octicons-react'\nimport { Button } from 'components/Button'\nimport { Layout } from 'components/Layout'\n\nconst error404 = () => (\n  <Layout title={['404 Not Found']} noIndex>\n    <section className=\"text-center\">\n      <div className=\"m-8 w-screen max-w-2xl sm:m-16\">\n        <h1 className=\"font-rounded text-4xl font-bold tracking-tighter text-gray-700\">\n          404 Not Found\n        </h1>\n        <hr className=\"my-6\" />\n        <p className=\"text-lg\">Oops! The requested page could not be found.</p>\n        <p className=\"mt-10\">\n          <Button\n            className=\"w-full max-w-xs text-xs\"\n            onClick={() => window.history.back()}\n            outline\n            style={{ color: '#4a5568' }}\n          >\n            <span className=\"flex items-center justify-center text-lg\">\n              <ArrowLeftIcon className=\"mr-2 h-8 w-8\" />\n              Back to previous\n            </span>\n          </Button>\n        </p>\n      </div>\n      <style jsx>{`\n        section {\n          @apply flex w-full items-center justify-center;\n\n          background-image: url(\"data:image/svg+xml,%3csvg width='40' height='40' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M0 40L40 0H20L0 20m40 20V20L20 40' fill='%23f0f0f0' fill-opacity='.2' fill-rule='evenodd'/%3e%3c/svg%3e\");\n          min-height: inherit;\n        }\n      `}</style>\n    </section>\n  </Layout>\n)\n\nexport default error404\n"
  },
  {
    "path": "website/pages/_app.tsx",
    "content": "import { Router } from 'next/router'\nimport NProgress from 'nprogress'\nimport { FontFaceProvider, FontFaceRenderer } from 'utils/hooks/useFontFace'\nimport 'focus-visible'\nimport 'wicg-inert'\nimport 'nprogress/nprogress.css'\nimport 'swiper/css/bundle'\nimport 'css/index.css'\n\n// NProgress\nconst translating = () => {\n  NProgress.start()\n  document.documentElement.classList.add('translating')\n}\n\nconst translated = () => {\n  NProgress.done()\n  setTimeout(\n    () => document.documentElement.classList.remove('translating'),\n    250\n  )\n}\n\nRouter.events.on('routeChangeStart', translating)\nRouter.events.on('routeChangeComplete', translated)\nRouter.events.on('routeChangeError', translated)\n\nNProgress.configure({ showSpinner: false, trickleSpeed: 350 })\n\n// Make resilience from manipulating DOM by Google translator\n// https://github.com/facebook/react/issues/11538\nif (typeof Node === 'function' && Node.prototype) {\n  const { removeChild, insertBefore } = Node.prototype\n\n  Node.prototype.removeChild = function <T extends Node>(child: T): T {\n    if (child.parentNode !== this) {\n      if (console) {\n        console.error(\n          'Cannot remove a child from a different parent',\n          child,\n          this\n        )\n      }\n      return child\n    }\n    return removeChild.call(this, child) as T\n  }\n  Node.prototype.insertBefore = function <T extends Node>(\n    newNode: T,\n    referenceNode: Node | null\n  ): T {\n    if (referenceNode && referenceNode.parentNode !== this) {\n      if (console) {\n        console.error(\n          'Cannot insert before a reference node from a different parent',\n          referenceNode,\n          this\n        )\n      }\n      return newNode\n    }\n    return insertBefore.call(this, newNode, referenceNode) as T\n  }\n}\n\nconst App = ({ Component, pageProps }) => (\n  <FontFaceProvider>\n    <FontFaceRenderer />\n    <Component {...pageProps} />\n  </FontFaceProvider>\n)\n\nexport default App\n"
  },
  {
    "path": "website/pages/_document.tsx",
    "content": "import Document, { Html, Head, Main, NextScript } from 'next/document'\n\nclass MyDocument extends Document {\n  render = () => (\n    <Html lang=\"en\">\n      <Head>\n        <link rel=\"icon\" href=\"/favicon.png\" type=\"image/png\" />\n        <link\n          rel=\"apple-touch-icon\"\n          sizes=\"180x180\"\n          href=\"/apple-touch-icon-180x180.png\"\n        />\n        <link\n          href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&amp;family=Quicksand:wght@500;700&amp;display=swap\"\n          rel=\"stylesheet\"\n        />\n      </Head>\n      <body>\n        <Main />\n        <NextScript />\n      </body>\n    </Html>\n  )\n}\n\nexport default MyDocument\n"
  },
  {
    "path": "website/pages/blog/[slug].tsx",
    "content": "import { basename } from 'path'\nimport {\n  GetStaticPaths,\n  GetStaticPropsContext,\n  InferGetStaticPropsType,\n} from 'next'\nimport Link from 'next/link'\nimport { Layout } from 'components/Layout'\nimport { Title } from 'components/Title'\nimport { Typography } from 'components/Typography'\nimport { BlogHeader } from 'components/blog/BlogHeader'\nimport { parse, renderToReact } from 'utils/markdown'\n\nexport const getStaticPaths: GetStaticPaths = async () => ({\n  paths: require\n    .context('blog', false, /\\.md$/)\n    .keys()\n    .map((id) => `/blog/${basename(id, '.md')}`),\n  fallback: false,\n})\n\nexport const getStaticProps = async ({ params }: GetStaticPropsContext) => {\n  const slug = params?.slug as string\n  const { default: md } = await import(`blog/${slug}.md`)\n  const parsed = await parse(md)\n\n  return {\n    props: { markdown: { data: parsed.data, mdast: parsed.mdast }, slug },\n  }\n}\n\nconst Blog = ({\n  markdown: { data, mdast },\n  slug,\n}: InferGetStaticPropsType<typeof getStaticProps>) => (\n  <Layout\n    activeItem=\"blog\"\n    description={data.description || ''}\n    image={data.image}\n    noIndex={!data.date}\n    title={[data.title || slug, 'Blog']}\n  >\n    <Title>\n      <Link href=\"/blog\">Blog</Link>\n    </Title>\n    <div className=\"container mx-auto px-6 py-12\">\n      <BlogHeader\n        title={data.title}\n        date={data.date ? new Date(data.date) : undefined}\n        author={data.author}\n        github={data.github}\n        slug={slug}\n      />\n      <article className=\"mx-auto mt-8 max-w-screen-lg\">\n        {data.image && (\n          <figure className=\"my-12\">\n            <img\n              src={data.image}\n              alt={data.title}\n              className=\"mx-auto block w-full max-w-screen-md bg-white shadow-xl\"\n            />\n          </figure>\n        )}\n        <Typography>{renderToReact(mdast)}</Typography>\n      </article>\n    </div>\n  </Layout>\n)\n\nexport default Blog\n"
  },
  {
    "path": "website/pages/blog.tsx",
    "content": "import fs from 'fs'\nimport { basename } from 'path'\nimport { ArrowRightIcon } from '@primer/octicons-react'\nimport { InferGetStaticPropsType } from 'next'\nimport Head from 'next/head'\nimport Link from 'next/link'\nimport { Layout } from 'components/Layout'\nimport { Title } from 'components/Title'\nimport { Typography } from 'components/Typography'\nimport { formatDate, formatDateShort } from 'utils/date'\nimport { parse, parseMatter, renderToReact } from 'utils/markdown'\nimport { absoluteUrl } from 'utils/url'\n\nconst toJSON = (obj: any) => JSON.parse(JSON.stringify(obj))\n\nconst escapeEntities = (raw: string) =>\n  raw.replace(/[&<>]/g, (matched) => `&#${matched.charCodeAt(0)};`)\n\nexport const getStaticProps = async () => {\n  const ctx = require.context('blog', false, /^.[\\\\/][^\\\\/]*\\.md$/)\n  const mdMetas = await Promise.all(\n    ctx.keys().map((id) => {\n      const md = ctx(id)\n      const { data, excerpt } = parseMatter(md)\n\n      return (async () => ({\n        data,\n        excerpt: excerpt ? await parse(excerpt) : undefined,\n        slug: basename(id, '.md'),\n      }))()\n    })\n  )\n\n  const articles = mdMetas.filter(({ data }) => data.date)\n  articles.sort((a, b) => b.data.date.getTime() - a.data.date.getTime())\n\n  // Generate RSS\n  const rss = `\n<rss version=\"2.0\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n  <channel>\n    <title>Blog | Marp</title>\n    <link>${escapeEntities(absoluteUrl('/blog').toString())}</link>\n    <description>Marp, Markdown Presentation Ecosystem, provides the great experience to create beautiful slide deck. You only have to focus writing your story in Markdown document.</description>\n    <language>en</language>\n    <lastBuildDate>${articles[0].data.date.toUTCString()}</lastBuildDate>\n    <atom:link href=\"${absoluteUrl(\n      '/blog/feed.xml'\n    )}\" rel=\"self\" type=\"application/rss+xml\"/>\n    ${articles\n      .map((article) =>\n        `\n      <item>\n        <guid>${escapeEntities(\n          absoluteUrl(`/blog/${article.slug}`).toString()\n        )}</guid>\n        <title>${escapeEntities(article.data.title)}</title>\n        <link>${escapeEntities(\n          absoluteUrl(`/blog/${article.slug}`).toString()\n        )}</link>\n        <description>${escapeEntities(article.data.description)}</description>\n        <pubDate>${article.data.date.toUTCString()}</pubDate>\n      </item>\n    `.trim()\n      )\n      .join('')}\n  </channel>\n</rss>\n  `.trim()\n\n  await fs.promises.writeFile('./public/blog/feed.xml', rss)\n\n  return {\n    props: {\n      articles: articles.map((article) =>\n        toJSON({\n          data: article.data,\n          excerpt: article.excerpt?.mdast,\n          slug: article.slug,\n        })\n      ),\n    },\n  }\n}\n\nconst Blog = ({ articles }: InferGetStaticPropsType<typeof getStaticProps>) => (\n  <Layout activeItem=\"blog\" title={['Blog']}>\n    <Title>\n      <Link href=\"/blog\">Blog</Link>\n    </Title>\n    <Head>\n      <link\n        rel=\"alternate\"\n        type=\"application/rss+xml\"\n        title=\"Blog | Marp\"\n        href={absoluteUrl(`/blog/feed.xml`).toString()}\n      />\n    </Head>\n    <div className=\"container mx-auto max-w-screen-lg px-3 py-1\">\n      {articles.map((article) => {\n        let summary: JSX.Element | string | undefined\n\n        if (article.excerpt) {\n          summary = (\n            <Typography>\n              {renderToReact(article.excerpt, { anchorLink: false })}\n            </Typography>\n          )\n        } else if (article.data.description) {\n          summary = article.data.description\n        }\n\n        const date = new Date(article.data.date)\n\n        return (\n          <div key={article.slug} className=\"article-container\">\n            <Link href={`/blog/${article.slug}`} legacyBehavior>\n              <a className=\"article-container-link\">\n                <h1 className=\"sr-only\">{article.data.title}</h1>\n              </a>\n            </Link>\n            <div className=\"pointer-events-none relative\">\n              <h1 className=\"text-gradient text-3xl font-bold\" aria-hidden>\n                {article.data.title}\n              </h1>\n              <p className=\"mt-2 mb-4 border-b-2 pb-4 text-sm text-gray-600\">\n                <time dateTime={formatDateShort(date)}>{formatDate(date)}</time>\n                {article.data.author && ` by ${article.data.author}`}\n              </p>\n              {summary && (\n                <>\n                  <div\n                    className=\"article-summary flex flex-col lg:flex-row\"\n                    inert=\"\"\n                  >\n                    {article.data.image && (\n                      <figure className=\"mx-auto mb-6 lg:order-1 lg:mb-0 lg:ml-6 lg:w-full lg:max-w-[20rem]\">\n                        <img\n                          src={article.data.image}\n                          alt={article.data.title}\n                          className=\"w-full max-w-[20rem] bg-white shadow-md lg:w-[100vw]\"\n                        />\n                      </figure>\n                    )}\n                    <article className=\"flex-grow\">{summary}</article>\n                  </div>\n                </>\n              )}\n              <p className=\"read-more\">\n                <ArrowRightIcon className=\"read-more-icon\" />\n                Read more...\n              </p>\n            </div>\n          </div>\n        )\n      })}\n      <style jsx>{`\n        .article-container {\n          @apply relative my-6 p-6;\n        }\n        .article-container-link {\n          @apply absolute inset-0 rounded-lg transition-all duration-300;\n        }\n\n        @media not all and (hover: none) {\n          .article-container-link:hover {\n            @apply bg-white shadow-lg;\n          }\n          .article-container-link:hover:active {\n            @apply duration-0 bg-white outline-none ring-1 ring-white ring-offset-2;\n          }\n          .article-container-link:hover + * .read-more {\n            @apply text-marp-brand;\n          }\n        }\n\n        .article-container-link:focus {\n          @apply duration-0 bg-white outline-none ring-1 ring-white ring-offset-2;\n        }\n\n        .article-summary :global(a) {\n          color: inherit;\n        }\n\n        .read-more {\n          @apply mt-6 flex items-center justify-end text-right font-bold uppercase transition-colors duration-300;\n        }\n\n        .read-more :global(.read-more-icon) {\n          @apply h-8 w-8;\n        }\n\n        @screen md {\n          .article-container {\n            @apply relative p-8;\n          }\n        }\n      `}</style>\n    </div>\n  </Layout>\n)\n\nexport default Blog\n"
  },
  {
    "path": "website/pages/docs/[[...slug]].tsx",
    "content": "import path from 'path'\nimport { getProperty } from 'dot-prop'\nimport {\n  GetStaticPaths,\n  GetStaticPropsContext,\n  InferGetStaticPropsType,\n} from 'next'\nimport { Typography } from 'components/Typography'\nimport { Layout } from 'components/docs/Layout'\nimport { parse, renderToReact } from 'utils/markdown'\n\nconst defaultSlug = ['introduction', 'whats-marp']\nconst docsCtx = () => require.context('docs', true, /\\.md$/)\n\nexport const getStaticPaths: GetStaticPaths = async () => ({\n  paths: [\n    '/docs',\n    ...docsCtx()\n      .keys()\n      .map((id) => path.join('/docs/', id).slice(0, -3)),\n  ],\n  fallback: false,\n})\n\nexport const getStaticProps = async ({ params }: GetStaticPropsContext) => {\n  // Manifest\n  const { default: manifest } = await import('docs/manifest.yaml')\n\n  // Page data\n  const slug = ([] as string[]).concat(params?.slug ?? defaultSlug)\n  if (slug[0] === 'docs') slug.splice(0, 1) // for webpack 5\n\n  const { default: md } = await import(`docs/${path.join(...slug)}.md`)\n  const { data, mdast } = await parse(md)\n\n  // Breadcrumbs\n  const breadcrumbs = slug.map((sl, i) => {\n    const slugs = slug.slice(0, i + 1)\n    const key = slugs.join('/')\n    const data = getProperty(\n      { pages: manifest },\n      slugs.flatMap((s) => ['pages', s]).join('.'),\n      undefined as Record<string, string> | undefined\n    )\n    const hasLink = docsCtx().keys().includes(`./${key}.md`)\n\n    return {\n      key,\n      title: data?.title || sl,\n      ...(hasLink ? { link: `/docs/${key}` } : {}),\n    }\n  })\n\n  return { props: { breadcrumbs, data, manifest, mdast, slug } }\n}\n\nconst Docs = ({\n  breadcrumbs,\n  manifest,\n  mdast,\n  slug,\n}: InferGetStaticPropsType<typeof getStaticProps>) => (\n  <Layout breadcrumbs={breadcrumbs} manifest={manifest} slug={slug}>\n    {/* key is required to fix broken Google Translator built in Chrome */}\n    <Typography key={slug.join('/')}>{renderToReact(mdast)}</Typography>\n  </Layout>\n)\n\nexport default Docs\n"
  },
  {
    "path": "website/pages/index.tsx",
    "content": "import { InferGetStaticPropsType } from 'next'\nimport { Layout } from 'components/Layout'\nimport { generateRenderedMarp } from 'components/Marp'\nimport { Description } from 'components/top/Description'\nimport { Features } from 'components/top/Features'\nimport { GetStarted } from 'components/top/GetStarted'\nimport { Hero } from 'components/top/Hero'\nimport { absoluteUrl } from 'utils/url'\n\nconst exampleMarkdown = `\n---\ntheme: gaia\n_class: lead\npaginate: true\nbackgroundColor: #fff\nbackgroundImage: url('${absoluteUrl('/assets/hero-background.svg')}')\n---\n\n![bg left:40% 80%](${absoluteUrl('/assets/marp.svg')})\n\n# **Marp**\n\nMarkdown Presentation Ecosystem\n\nhttps://marp.app/\n\n---\n\n# How to write slides\n\nSplit pages by horizontal ruler (\\`---\\`). It's very simple! :satisfied:\n\n\\`\\`\\`markdown\n# Slide 1\n\nfoobar\n\n---\n\n# Slide 2\n\nfoobar\n\\`\\`\\`\n`.trim()\n\nexport const getStaticProps = async () => ({\n  props: { example: await generateRenderedMarp(exampleMarkdown) },\n})\n\nconst Index = (props: InferGetStaticPropsType<typeof getStaticProps>) => (\n  <Layout type=\"website\">\n    <Hero />\n    <Description example={props.example} />\n    <Features />\n    <GetStarted />\n  </Layout>\n)\n\nexport default Index\n"
  },
  {
    "path": "website/postcss.config.js",
    "content": "const path = require('path')\nconst remoteInlineCache = new Map()\n\nconst encodeForInlining = (buffer) =>\n  encodeURIComponent(buffer.toString('utf8').replace(/\\n+/g, ''))\n    .replace(/%20/g, ' ')\n    .replace(/#/g, '%23')\n\nmodule.exports = {\n  plugins: {\n    'postcss-flexbugs-fixes': {},\n    tailwindcss: {},\n    'postcss-preset-env': {\n      autoprefixer: { flexbox: 'no-2009' },\n      stage: 3,\n      features: {\n        'custom-properties': false,\n        'focus-visible-pseudo-class': true,\n      },\n    },\n    'postcss-url': [\n      {\n        filter: '**/assets/**/*.svg',\n        basePath: path.resolve(__dirname, './public'),\n        url: 'inline',\n        maxSize: 1,\n      },\n      {\n        filter: ({ url }) => url.startsWith('https://icongr.am/'),\n        url: async ({ url }) => {\n          if (remoteInlineCache.has(url)) return remoteInlineCache.get(url)\n\n          const { default: fetch } = await import('node-fetch')\n          const response = await fetch(url)\n\n          if (!response.ok) {\n            console.error(`Failed to make inline the remote URL: ${url}`)\n            return url\n          }\n\n          const buffer = await response.buffer()\n          const mimeType =\n            response.headers.get('Content-Type') || 'application/octet-stream'\n\n          const svg = [\n            `data:${mimeType};base64,${buffer.toString('base64')}`,\n            `data:${mimeType},${encodeForInlining(buffer)}`,\n          ].sort((a, b) => a.length - b.length)[0]\n\n          remoteInlineCache.set(url, svg)\n          return svg\n        },\n      },\n    ],\n    [require.resolve('./css/plugin-rem')]: {},\n  },\n}\n"
  },
  {
    "path": "website/public/blog/.gitignore",
    "content": "feed.xml\n"
  },
  {
    "path": "website/tailwind.config.js",
    "content": "const { fontFamily } = require('tailwindcss/defaultTheme')\n\nconst marp = {\n  // Brand colors\n  brand: '#0288d1',\n  light: '#67b8e3',\n  dark: '#02669d',\n\n  // Color variations\n  darken: '#0277b7',\n  darkest: '#1b4d68',\n}\n\nconst gray = {\n  100: '#f7fafc',\n  200: '#edf2f7',\n  300: '#e2e8f0',\n  400: '#cbd5e0',\n  500: '#a0aec0',\n  600: '#718096',\n  700: '#4a5568',\n  800: '#2d3748',\n  900: '#1a202c',\n}\n\nmodule.exports = {\n  content: ['@(components|pages|utils)/**/*.[jt]s?(x)'],\n  theme: {\n    borderColor: (theme) => ({ ...theme('colors'), DEFAULT: gray[300] }),\n    colors: {\n      black: '#000',\n      current: 'currentColor',\n      gray,\n      transparent: 'transparent',\n      white: '#fff',\n      background: '#f8f8f8',\n      foreground: gray[800],\n      marp,\n    },\n    ringColor: (theme) => ({ ...theme('colors'), DEFAULT: marp.light }),\n    ringOffsetColor: (theme) => ({ ...theme('colors'), DEFAULT: marp.light }),\n    fontFamily: {\n      ...fontFamily,\n      sans: ['Inter', ...fontFamily.sans],\n      rounded: ['Quicksand', 'Avenir', 'Century Gothic', ...fontFamily.sans],\n    },\n    screens: {\n      sm: '640px',\n      md: '768px',\n      lg: '1024px',\n      xl: '1280px',\n    },\n    extend: { transitionDuration: { 0: '0s' } },\n  },\n}\n"
  },
  {
    "path": "website/tsconfig.json",
    "content": "{\n  \"extends\": \"../tsconfig.json\",\n  \"compilerOptions\": {\n    \"allowJs\": true,\n    \"baseUrl\": \".\",\n    \"downlevelIteration\": true,\n    \"isolatedModules\": true,\n    \"jsx\": \"preserve\",\n    \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"noEmit\": true,\n    \"target\": \"es5\",\n    \"incremental\": true\n  },\n  \"include\": [\n    \"next-env.d.ts\",\n    \"global.d.ts\",\n    \"assets.d.ts\",\n    \"**/*.ts\",\n    \"**/*.tsx\"\n  ],\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "website/utils/date.ts",
    "content": "const monthNames = [\n  'January',\n  'February',\n  'March',\n  'April',\n  'May',\n  'June',\n  'July',\n  'August',\n  'September',\n  'October',\n  'November',\n  'December',\n] as const\n\nconst nth = (day) => {\n  if (day > 3 && day < 21) return `${day}th`\n\n  const firstPlace = day % 10\n  if (firstPlace === 1) return `${day}st`\n  if (firstPlace === 2) return `${day}nd`\n  if (firstPlace === 3) return `${day}rd`\n\n  return `${day}th`\n}\n\nexport const formatDate = (date: Date) =>\n  `${monthNames[date.getMonth()]} ${nth(date.getDate())}, ${date.getFullYear()}`\n\nexport const formatDateShort = (date: Date) =>\n  `${date.getFullYear()}-${`${date.getMonth() + 1}`.padStart(\n    2,\n    '0'\n  )}-${`${date.getDate()}`.padStart(2, '0')}`\n"
  },
  {
    "path": "website/utils/hooks/useFontFace.tsx",
    "content": "import { createContext, useContext, useEffect, useMemo, useState } from 'react'\n\ninterface FontFaceContextInterface {\n  styles: readonly string[]\n  setStyles: (styles: string[] | ((styles: string[]) => string[])) => void\n}\n\nconst FontFaceContext = createContext<FontFaceContextInterface>({\n  styles: [],\n  setStyles: () => {\n    throw new Error('Required wrapping by <FontFaceProvider>.')\n  },\n})\n\nexport const useFontFace = (fonts: string | string[]) => {\n  const fnts = useMemo(() => ([] as string[]).concat(fonts), [fonts])\n  const { setStyles } = useContext(FontFaceContext)\n\n  useEffect(() => {\n    setStyles((styles) => [...styles, ...fnts])\n\n    return () => {\n      const _fnts = [...fnts]\n\n      setStyles((styles) =>\n        styles.filter((existingStyle) => {\n          const fntIdx = _fnts.indexOf(existingStyle)\n          if (fntIdx >= 0) _fnts.splice(fntIdx, 1)\n\n          return fntIdx !== -1\n        })\n      )\n    }\n  }, [fnts, setStyles])\n}\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const FontFaceProvider: React.FC<React.PropsWithChildren<{}>> = ({\n  children,\n}) => {\n  const [styles, setStyles] = useState<string[]>([])\n\n  return (\n    <FontFaceContext.Provider value={{ styles, setStyles }}>\n      {children}\n    </FontFaceContext.Provider>\n  )\n}\n\nexport const FontFaceRenderer = () => {\n  const { styles } = useContext(FontFaceContext)\n\n  return (\n    <>\n      {[...new Set(styles)]\n        .filter((style) => !!style)\n        .map((style) => (\n          <style data-type=\"marp-font-face\" key={style}>\n            {style}\n          </style>\n        ))}\n    </>\n  )\n}\n"
  },
  {
    "path": "website/utils/markdown/index.tsx",
    "content": "import matter from 'gray-matter'\nimport { parse as mdParse } from './parse'\nimport { renderer } from './renderer'\nimport { AnchorLinkProvider } from 'components/markdown/Heading'\n\nconst toJSON = (value: any) => JSON.parse(JSON.stringify(value))\n\nexport const parseMatter = (md: string) =>\n  matter(md, { excerpt_separator: '<!-- more -->' })\n\nexport const parse = async (markdown: string) => {\n  const md = parseMatter(markdown)\n  const mdast = toJSON(await mdParse(md.content))\n\n  return { markdown, mdast, data: toJSON(md.data) }\n}\n\nexport const renderToReact = (\n  mdast: any,\n  { anchorLink = true }: { anchorLink?: boolean } = {}\n) => (\n  <AnchorLinkProvider value={anchorLink}>{renderer(mdast)}</AnchorLinkProvider>\n)\n"
  },
  {
    "path": "website/utils/markdown/parse/image-paragraph-to-figure.ts",
    "content": "import { whitespace } from 'hast-util-whitespace'\nimport { visit } from 'unist-util-visit'\n\n// Based on remark-unwrap-images\n// https://github.com/remarkjs/remark-unwrap-images/blob/main/index.js\nconst applicable = (node, inLink = false): string | false | null => {\n  const { children } = node\n  const { length } = children\n\n  let image: string | false | null = null\n  let index = -1\n\n  while (++index < length) {\n    const child = children[index]\n\n    if (whitespace(child)) {\n      // No ops\n    } else if (child.type === 'image' && typeof child.title === 'string') {\n      image = child.title.trim()\n      child.title = image || null\n    } else if (\n      !inLink &&\n      (child.type === 'link' || child.type === 'linkReference')\n    ) {\n      const linkResult = applicable(child, true)\n\n      if (linkResult === false) return false\n      if (typeof linkResult === 'string') image = linkResult\n    } else {\n      return false\n    }\n  }\n\n  return image\n}\n\n// Transform wrapping paragraph for images with title to <figure>.\nexport const imageParagraphToFigure = () => (tree) => {\n  visit(tree, 'paragraph', (node) => {\n    const figureCaption = applicable(node)\n\n    if (typeof figureCaption === 'string') {\n      node.data = node.data ?? {}\n      node.data.hName = 'figure'\n\n      if (figureCaption.trim()) {\n        ;(node.children as any[]).push({\n          type: 'strong',\n          data: { hName: 'figcaption' },\n          children: [{ type: 'text', value: figureCaption }],\n        })\n      }\n    }\n  })\n}\n"
  },
  {
    "path": "website/utils/markdown/parse/index.ts",
    "content": "import remarkGfm from 'remark-gfm'\nimport remarkParse from 'remark-parse'\nimport remarkSlug from 'remark-slug'\nimport { unified, Processor } from 'unified'\nimport { removePosition } from 'unist-util-remove-position'\nimport { imageParagraphToFigure } from './image-paragraph-to-figure'\nimport { marpCodeBlock } from './marp-code-block'\n\nlet parser: Processor | undefined\n\nexport const parse = async (md: string) => {\n  parser =\n    parser ||\n    unified()\n      .use(remarkParse)\n      .use(remarkGfm)\n      .use(remarkSlug)\n      .use(imageParagraphToFigure)\n      .use([marpCodeBlock])\n\n  return removePosition(await parser.run(parser.parse(md)), true)\n}\n"
  },
  {
    "path": "website/utils/markdown/parse/marp-code-block.ts",
    "content": "import type { Literal } from 'unist'\nimport { visit } from 'unist-util-visit'\nimport { RenderedMarp, generateRenderedMarp } from 'components/Marp'\n\nexport const marpCodeBlock = () => async (tree) => {\n  const marpNodes = new Set<Literal<string> & { marp?: RenderedMarp }>()\n\n  visit(tree, 'code', (node) => {\n    const lang = node.lang as string\n    const langSub = lang.split(':').pop() as string\n\n    if (langSub === 'marp') marpNodes.add(node)\n  })\n\n  await Promise.all(\n    [...marpNodes].map((node) =>\n      (async () => {\n        node.marp = await generateRenderedMarp(node.value)\n      })()\n    )\n  )\n}\n"
  },
  {
    "path": "website/utils/markdown/renderer/index.ts",
    "content": "import { createElement, FunctionComponent } from 'react'\nimport RemarkReact, { Options } from 'remark-react'\nimport { sanitize } from './sanitize'\nimport { MarpSlides } from 'components/Marp'\nimport { Anchor } from 'components/markdown/Anchor'\nimport * as Heading from 'components/markdown/Heading'\nimport { Image } from 'components/markdown/Image'\nimport { Pre, toHastCodeHandler } from 'components/markdown/Pre'\n\nconst remarkReactComponents: Record<string, FunctionComponent<any>> = {\n  a: Anchor,\n  h1: Heading.H1,\n  h2: Heading.H2,\n  h3: Heading.H3,\n  h4: Heading.H4,\n  h5: Heading.H5,\n  h6: Heading.H6,\n  'marp-slides': MarpSlides,\n  pre: Pre,\n  img: Image,\n}\n\nexport const { Compiler: renderer } = new RemarkReact({\n  createElement: createElement as Options['createElement'],\n  remarkReactComponents,\n  sanitize,\n  toHast: { handlers: { code: toHastCodeHandler } },\n})\n"
  },
  {
    "path": "website/utils/markdown/renderer/sanitize.ts",
    "content": "import { defaultSchema } from 'hast-util-sanitize'\n\nexport const sanitize = {\n  ...defaultSchema,\n  attributes: {\n    ...defaultSchema.attributes,\n    '*': [...(defaultSchema.attributes?.['*'] ?? []), 'data*'],\n  },\n  clobberPrefix: '',\n  tagNames: [...(defaultSchema.tagNames ?? []), 'marp-slides'],\n}\n"
  },
  {
    "path": "website/utils/title.ts",
    "content": "export const generateTitle = (breadcrumbs: string[] = []) =>\n  [\n    ...breadcrumbs,\n    `Marp${\n      breadcrumbs.length === 0 ? ': Markdown Presentation Ecosystem' : ''\n    }`,\n  ].join(' | ')\n"
  },
  {
    "path": "website/utils/url.ts",
    "content": "export const absoluteUrl = (path: string) =>\n  new URL(path, process.env.NEXT_PUBLIC_HOST)\n"
  }
]