├── .circleci
└── config.yml
├── .github
├── CONTRIBUTING.md
└── workflows
│ └── github-release.yml
├── .gitignore
├── .jsdoc.json
├── .nvmrc
├── .prettierignore
├── .stylelintrc.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── api.md
├── babel.config.js
├── docs
├── _redirects
├── _sidebar.md
├── assets
│ ├── directives.png
│ ├── hello-marpit-theme.pdf
│ ├── hello-marpit.pdf
│ ├── how-to-use
│ │ ├── example.html
│ │ └── example.pdf
│ ├── image-syntax
│ │ ├── multiple-bg-vertical.png
│ │ ├── multiple-bg.png
│ │ ├── split-background.jpg
│ │ ├── split-bg-with-size.jpg
│ │ └── split-multiple-bg.jpg
│ └── plugin-custom-container.png
├── directives.md
├── favicon.png
├── fragmented-list.md
├── image-syntax.md
├── index.html
├── inline-svg.md
├── introduction.md
├── jsdoc.css
├── markdown.md
├── marpit-dark.png
├── marpit.png
├── theme-css.md
└── usage.md
├── docsify
├── _alert.scss
├── _code.scss
├── _layout.scss
├── build.js
├── docsify.scss
├── modules
│ └── build.js
└── serve.js
├── eslint.config.mjs
├── index.d.ts
├── jest.config.js
├── jest.setup.js
├── package-lock.json
├── package.json
├── plugin.js
├── src
├── element.js
├── helpers
│ ├── inline_style.js
│ ├── postcss_plugin.js
│ ├── split.js
│ ├── wrap_array.js
│ └── wrap_tokens.js
├── index.js
├── markdown
│ ├── background_image.js
│ ├── background_image
│ │ ├── advanced.js
│ │ ├── apply.js
│ │ └── parse.js
│ ├── collect.js
│ ├── comment.js
│ ├── container.js
│ ├── directives
│ │ ├── apply.js
│ │ ├── directives.js
│ │ ├── parse.js
│ │ └── yaml.js
│ ├── fragment.js
│ ├── header_and_footer.js
│ ├── heading_divider.js
│ ├── image.js
│ ├── image
│ │ ├── apply.js
│ │ └── parse.js
│ ├── inline_svg.js
│ ├── slide.js
│ ├── slide_container.js
│ ├── style
│ │ ├── assign.js
│ │ └── parse.js
│ └── sweep.js
├── marpit.js
├── plugin.js
├── postcss
│ ├── advanced_background.js
│ ├── container_query.js
│ ├── import
│ │ ├── hoisting.js
│ │ ├── parse.js
│ │ ├── replace.js
│ │ └── suppress.js
│ ├── meta.js
│ ├── nesting.js
│ ├── pagination.js
│ ├── printable.js
│ ├── pseudo_selector
│ │ ├── prepend.js
│ │ └── replace.js
│ ├── root
│ │ ├── font_size.js
│ │ ├── increasing_specificity.js
│ │ ├── rem.js
│ │ └── replace.js
│ ├── section_size.js
│ └── svg_backdrop.js
├── theme.js
├── theme
│ ├── scaffold.js
│ └── symbol.js
└── theme_set.js
└── test
├── _supports
├── postcss_finder.js
└── selector_normalizer.js
├── element.js
├── helpers
└── inline_style.js
├── markdown
├── background_image.js
├── collect.js
├── comment.js
├── container.js
├── directives
│ ├── apply.js
│ ├── parse.js
│ └── yaml.js
├── fragment.js
├── header_and_footer.js
├── heading_divider.js
├── image.js
├── inline_svg.js
├── slide.js
├── slide_container.js
├── style
│ ├── assign.js
│ └── parse.js
└── sweep.js
├── marpit.js
├── plugin.js
├── postcss
├── advanced_background.js
├── container_query.js
├── import
│ ├── hoisting.js
│ ├── parse.js
│ ├── replace.js
│ └── suppress.js
├── meta.js
├── pagination.js
├── printable.js
├── pseudo_selector
│ ├── prepend.js
│ └── replace.js
├── root
│ ├── font_size.js
│ ├── increasing_specificity.js
│ ├── rem.js
│ └── replace.js
├── section_size.js
└── svg_backdrop.js
├── theme.js
└── theme_set.js
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2.1
2 |
3 | orbs:
4 | codecov: codecov/codecov@5.0.3
5 |
6 | executors:
7 | node:
8 | parameters:
9 | version:
10 | type: string
11 | default: lts
12 | docker:
13 | - image: cimg/node:<< parameters.version >>
14 | working_directory: ~/marpit
15 |
16 | commands:
17 | install:
18 | parameters:
19 | force:
20 | type: boolean
21 | default: false
22 | postinstall:
23 | type: steps
24 | default: []
25 | steps:
26 | - restore_cache:
27 | keys:
28 | - v3-dependencies-{{ .Environment.CIRCLE_JOB }}-{{ checksum "package-lock.json" }}-{{ .Branch }}
29 | - v3-dependencies-{{ .Environment.CIRCLE_JOB }}-{{ checksum "package-lock.json" }}-
30 | - v3-dependencies-{{ .Environment.CIRCLE_JOB }}-
31 |
32 | - run: npm ci <<# parameters.force >>--force< parameters.force >>
33 | - steps: << parameters.postinstall >>
34 |
35 | - save_cache:
36 | key: v2.3-dependencies-{{ .Environment.CIRCLE_JOB }}-{{ checksum "package-lock.json" }}-{{ .Branch }}
37 | paths:
38 | - ~/.npm
39 |
40 | audit:
41 | steps:
42 | - checkout
43 | - install:
44 | postinstall:
45 | - run: npm -s run check:audit
46 |
47 | prepare:
48 | parameters:
49 | force:
50 | type: boolean
51 | default: false
52 | steps:
53 | - run: node --version
54 |
55 | - checkout
56 | - install:
57 | force: << parameters.force >>
58 |
59 | lint:
60 | steps:
61 | - run:
62 | name: Prettier formatting
63 | command: npm run check:format
64 |
65 | - run:
66 | name: ESLint
67 | command: npm run lint:js
68 |
69 | - run:
70 | name: stylelint
71 | command: npm run lint:css
72 |
73 | test:
74 | steps:
75 | - run:
76 | name: Jest
77 | command: npm run test:coverage -- --ci --maxWorkers=2 --reporters=default --reporters=jest-junit
78 | environment:
79 | JEST_JUNIT_OUTPUT_DIR: tmp/test-results
80 |
81 | - codecov/upload
82 |
83 | - store_test_results:
84 | path: tmp/test-results
85 |
86 | - store_artifacts:
87 | path: ./coverage
88 | destination: coverage
89 |
90 | jobs:
91 | audit:
92 | executor: node
93 | steps:
94 | - audit
95 |
96 | test-node18:
97 | executor:
98 | name: node
99 | version: '18.20'
100 | steps:
101 | - prepare:
102 | force: true
103 | - test
104 |
105 | test-node20:
106 | executor:
107 | name: node
108 | version: '20.19'
109 | steps:
110 | - prepare
111 | - lint
112 | - test
113 |
114 | test-node22:
115 | executor:
116 | name: node
117 | version: '22.15.0' # Specify LTS version for development
118 | steps:
119 | - prepare
120 | - lint
121 | - test
122 |
123 | test-node24:
124 | executor:
125 | name: node
126 | version: '24.0'
127 | steps:
128 | - prepare
129 | - lint
130 | - test
131 |
132 | workflows:
133 | test:
134 | jobs:
135 | - audit
136 | - test-node18:
137 | requires:
138 | - audit
139 | - test-node20:
140 | requires:
141 | - audit
142 | - test-node22:
143 | requires:
144 | - audit
145 | - test-node24:
146 | requires:
147 | - audit
148 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Marpit
2 |
3 | Thank you for taking the time to read how to contribute to Marpit! This is the guideline for contributing to Marpit.
4 |
5 | We are following [**the contributing guideline of Marp team projects**](https://github.com/marp-team/.github/blob/master/CONTRIBUTING.md). _You have to read this before starting work._
6 |
7 | ## Development
8 |
9 | ### Pull request
10 |
11 | When sending pull request updated the interface of public class, it's better to mind to these resources.
12 |
13 | - JSDoc (for [API documentation](https://marpit-api.marp.app/))
14 | - [Documents](https://marpit.marp.app/) (at [`/docs/`](../docs/))
15 | - [`/index.d.ts`](../index.d.ts) (Type definition for TypeScript)
16 |
--------------------------------------------------------------------------------
/.github/workflows/github-release.yml:
--------------------------------------------------------------------------------
1 | name: GitHub Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - v*
7 |
8 | jobs:
9 | github-release:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v4
13 | - uses: marp-team/actions@v1
14 | with:
15 | task: release
16 | token: ${{ secrets.GITHUB_TOKEN }}
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | lib
2 | dist
3 | jsdoc
4 | /docs/style/
5 |
6 | ########## gitignore.io ##########
7 | # Created by https://www.gitignore.io/api/node,windows,macos,linux,sublimetext,emacs,vim,visualstudiocode
8 |
9 | ### Emacs ###
10 | # -*- mode: gitignore; -*-
11 | *~
12 | \#*\#
13 | /.emacs.desktop
14 | /.emacs.desktop.lock
15 | *.elc
16 | auto-save-list
17 | tramp
18 | .\#*
19 |
20 | # Org-mode
21 | .org-id-locations
22 | *_archive
23 |
24 | # flymake-mode
25 | *_flymake.*
26 |
27 | # eshell files
28 | /eshell/history
29 | /eshell/lastdir
30 |
31 | # elpa packages
32 | /elpa/
33 |
34 | # reftex files
35 | *.rel
36 |
37 | # AUCTeX auto folder
38 | /auto/
39 |
40 | # cask packages
41 | .cask/
42 | dist/
43 |
44 | # Flycheck
45 | flycheck_*.el
46 |
47 | # server auth directory
48 | /server/
49 |
50 | # projectiles files
51 | .projectile
52 |
53 | # directory configuration
54 | .dir-locals.el
55 |
56 | ### Linux ###
57 |
58 | # temporary files which can be created if a process still has a handle open of a deleted file
59 | .fuse_hidden*
60 |
61 | # KDE directory preferences
62 | .directory
63 |
64 | # Linux trash folder which might appear on any partition or disk
65 | .Trash-*
66 |
67 | # .nfs files are created when an open file is removed but is still being accessed
68 | .nfs*
69 |
70 | ### macOS ###
71 | *.DS_Store
72 | .AppleDouble
73 | .LSOverride
74 |
75 | # Icon must end with two \r
76 | Icon
77 |
78 | # Thumbnails
79 | ._*
80 |
81 | # Files that might appear in the root of a volume
82 | .DocumentRevisions-V100
83 | .fseventsd
84 | .Spotlight-V100
85 | .TemporaryItems
86 | .Trashes
87 | .VolumeIcon.icns
88 | .com.apple.timemachine.donotpresent
89 |
90 | # Directories potentially created on remote AFP share
91 | .AppleDB
92 | .AppleDesktop
93 | Network Trash Folder
94 | Temporary Items
95 | .apdisk
96 |
97 | ### Node ###
98 | # Logs
99 | logs
100 | *.log
101 | npm-debug.log*
102 | yarn-debug.log*
103 | yarn-error.log*
104 |
105 | # Runtime data
106 | pids
107 | *.pid
108 | *.seed
109 | *.pid.lock
110 |
111 | # Directory for instrumented libs generated by jscoverage/JSCover
112 | lib-cov
113 |
114 | # Coverage directory used by tools like istanbul
115 | coverage
116 |
117 | # nyc test coverage
118 | .nyc_output
119 |
120 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
121 | .grunt
122 |
123 | # Bower dependency directory (https://bower.io/)
124 | bower_components
125 |
126 | # node-waf configuration
127 | .lock-wscript
128 |
129 | # Compiled binary addons (http://nodejs.org/api/addons.html)
130 | build/Release
131 |
132 | # Dependency directories
133 | node_modules/
134 | jspm_packages/
135 |
136 | # Typescript v1 declaration files
137 | typings/
138 |
139 | # Optional npm cache directory
140 | .npm
141 |
142 | # Optional eslint cache
143 | .eslintcache
144 |
145 | # Optional REPL history
146 | .node_repl_history
147 |
148 | # Output of 'npm pack'
149 | *.tgz
150 |
151 | # Yarn Integrity file
152 | .yarn-integrity
153 |
154 | # dotenv environment variables file
155 | .env
156 |
157 |
158 | ### SublimeText ###
159 | # cache files for sublime text
160 | *.tmlanguage.cache
161 | *.tmPreferences.cache
162 | *.stTheme.cache
163 |
164 | # workspace files are user-specific
165 | *.sublime-workspace
166 |
167 | # project files should be checked into the repository, unless a significant
168 | # proportion of contributors will probably not be using SublimeText
169 | # *.sublime-project
170 |
171 | # sftp configuration file
172 | sftp-config.json
173 |
174 | # Package control specific files
175 | Package Control.last-run
176 | Package Control.ca-list
177 | Package Control.ca-bundle
178 | Package Control.system-ca-bundle
179 | Package Control.cache/
180 | Package Control.ca-certs/
181 | Package Control.merged-ca-bundle
182 | Package Control.user-ca-bundle
183 | oscrypto-ca-bundle.crt
184 | bh_unicode_properties.cache
185 |
186 | # Sublime-github package stores a github token in this file
187 | # https://packagecontrol.io/packages/sublime-github
188 | GitHub.sublime-settings
189 |
190 | ### Vim ###
191 | # swap
192 | [._]*.s[a-v][a-z]
193 | [._]*.sw[a-p]
194 | [._]s[a-v][a-z]
195 | [._]sw[a-p]
196 | # session
197 | Session.vim
198 | # temporary
199 | .netrwhist
200 | # auto-generated tag files
201 | tags
202 |
203 | ### VisualStudioCode ###
204 | .vscode/*
205 |
206 | ### Windows ###
207 | # Windows thumbnail cache files
208 | Thumbs.db
209 | ehthumbs.db
210 | ehthumbs_vista.db
211 |
212 | # Folder config file
213 | Desktop.ini
214 |
215 | # Recycle Bin used on file shares
216 | $RECYCLE.BIN/
217 |
218 | # Windows Installer files
219 | *.cab
220 | *.msi
221 | *.msm
222 | *.msp
223 |
224 | # Windows shortcuts
225 | *.lnk
226 |
--------------------------------------------------------------------------------
/.jsdoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "opts": {
3 | "destination": "jsdoc",
4 | "readme": "api.md",
5 | "recurse": true,
6 | "template": "node_modules/clean-jsdoc-theme",
7 | "theme_opts": {
8 | "default_theme": "light",
9 | "homepageTitle": "Marpit API",
10 | "title": "Marpit API",
11 | "menu": [
12 | {
13 | "title": "« Marpit docs",
14 | "link": "https://marpit.marp.app/",
15 | "target": "_blank"
16 | }
17 | ],
18 | "sections": ["Classes", "Modules"],
19 | "displayModuleHeader": true,
20 | "include_css": ["./docs/jsdoc.css"]
21 | },
22 | "markdown": {
23 | "idInHeadings": true
24 | }
25 | },
26 | "plugins": ["plugins/markdown"]
27 | }
28 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 22.15.0
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | .git/
2 | .vscode/
3 | coverage/
4 | dist/
5 | jsdoc/
6 | lib/
7 | /docs/style/
8 | node_modules
9 | package.json
10 |
--------------------------------------------------------------------------------
/.stylelintrc.yml:
--------------------------------------------------------------------------------
1 | extends:
2 | - stylelint-config-standard-scss
3 |
4 | ignoreFiles:
5 | - coverage/**/*
6 | - docs/style/**/*
7 | - jsdoc/**/*
8 |
9 | rules:
10 | at-rule-no-unknown:
11 | - null
12 | custom-property-pattern:
13 | - null
14 | scss/at-rule-no-unknown:
15 | - true
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018- Marp team (marp-team@marp.app)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Marpit : Markdown slide deck framework
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ### [🗒 Documentation](https://marpit.marp.app/) | [⚙ API](https://marpit-api.marp.app/)
18 |
19 |
20 |
21 | ---
22 |
23 | **Marpit** /mɑːrpɪt/ is the skinny framework for creating slide deck from Markdown. It can transform Markdown and CSS theme(s) to slide deck composed of static HTML and CSS and create a web page convertible into slide PDF by printing.
24 |
25 | Marpit is designed to _output minimum assets for the slide deck_. You can use the bare assets as a logicless slide deck, but mainly we expect to integrate output with other tools and applications.
26 |
27 | In fact, this framework is created for using as the base of [a core converter][marp-core] in [Marp ecosystem][marp].
28 |
29 | [marp]: https://github.com/marp-team/marp/
30 | [marp-core]: https://github.com/marp-team/marp-core/
31 |
32 | ## Features
33 |
34 | ### [:pencil: **Marpit Markdown**](https://marpit.marp.app/markdown)
35 |
36 | We have extended several features into [markdown-it](https://github.com/markdown-it/markdown-it) parser to support writing awesome slides, such as [_Directives_](https://marpit.marp.app/directives) and [_Slide backgrounds_](https://marpit.marp.app/image-syntax?id=slide-backgrounds). Additional syntaxes place importance on a compatibility with general Markdown documents.
37 |
38 | ### [:art: **Theme CSS by clean markup**](https://marpit.marp.app/theme-css)
39 |
40 | Marpit has the CSS theming system that can design slides everything. Unlike other slide frameworks, there are not any predefined classes and mixins. You have only to focus styling HTML elements by pure CSS. Marpit would take care of the selected theme's necessary conversion.
41 |
42 | ### [:triangular_ruler: **Inline SVG slide**](https://marpit.marp.app/inline-svg) _(Experimental)_
43 |
44 | Optionally `` element can use as the container of each slide page. It can be realized the pixel-perfect scaling of the slide only by CSS, so handling slides in integrated apps become simplified. The isolated layer made by `` can provide [_advanced backgrounds_](https://marpit.marp.app/image-syntax?id=advanced-backgrounds) for the slide with keeping the original Markdown DOM structure.
45 |
46 | > We not provide any themes because Marpit is just a framework. You can use [@marp-team/marp-core][marp-core] if you want. It has the official themes, and practical features extended from Marpit.
47 |
48 | ## Getting started
49 |
50 | See [the documentation of Marpit](https://marpit.marp.app/?id=getting-started) to get started.
51 |
52 | - **[Documentation](https://marpit.marp.app/)**
53 | - [API (JSDoc)](https://marpit-api.marp.app/)
54 |
55 | ## Contributing
56 |
57 | Are you interested in contributing? See [CONTRIBUTING.md](.github/CONTRIBUTING.md) and [the common contributing guideline for Marp team](https://github.com/marp-team/.github/blob/master/CONTRIBUTING.md).
58 |
59 | ### Development
60 |
61 | ```bash
62 | git clone https://github.com/marp-team/marpit
63 | cd marpit
64 |
65 | npm install
66 | npm run build
67 | ```
68 |
69 | ## Sub-projects
70 |
71 | - **[@marp-team/marpit-svg-polyfill](https://github.com/marp-team/marpit-svg-polyfill)** - A polyfill of the inline SVG slide in Safari based browsers.
72 |
73 | ## Author
74 |
75 | Managed by [@marp-team](https://github.com/marp-team).
76 |
77 | - Yuki Hattori ([@yhatt](https://github.com/yhatt))
78 |
79 | ## License
80 |
81 | This framework releases under the [MIT License](LICENSE).
82 |
--------------------------------------------------------------------------------
/api.md:
--------------------------------------------------------------------------------
1 | # [Marpit API](https://marpit-api.marp.app/)
2 |
3 | The documentation of Marpit API (on `main` branch) has been published at **[https://marpit-api.marp.app/](https://marpit-api.marp.app/)**.
4 |
5 | > Please run `npm run jsdoc` if you want to build documentation at local. It would build docs in `jsdoc` directory.
6 |
7 | ## Documentations
8 |
9 | ### Classes
10 |
11 | **Classes** section is documented about public classes.
12 |
13 | We provide **[`Marpit`](Marpit.html)** class by default export.
14 |
15 | ```javascript
16 | import Marpit from '@marp-team/marpit'
17 | ```
18 |
19 | And all classes can use with named export. (Recommend if you are using TypeScript)
20 |
21 | ```javascript
22 | import { Element, Marpit, Theme, ThemeSet } from '@marp-team/marpit'
23 | ```
24 |
25 | ### Modules _(for internal)_
26 |
27 | **Modules** section is documented about internal modules, that includes plugins for markdown-it and PostCSS, for helping to learn Marpit's architecture by contributors and plugin authors.
28 |
29 | ⚠️ **Do not use internal modules directly.** They might be changed the specification without following semantic versioning.
30 |
31 | ---
32 |
33 | ## Create plugin
34 |
35 | Are you interested to develop third-party plugin for Marpit?
36 |
37 | ### [markdown-it](https://github.com/markdown-it/markdown-it) plugin
38 |
39 | Marpit's plugin interface has compatible with [markdown-it](https://github.com/markdown-it/markdown-it). [Please refer to the documentation of markdown-it](https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md) if you want to manipulate the result of Markdown rendering in plugin.
40 |
41 | ### Marpit plugin
42 |
43 | When plugin was used through [`Marpit.use()`](Marpit.html#use), it can access to current Marpit instance via `marpit` member of the passed markdown-it instance.
44 |
45 | `@marp-team/marpit/plugin` provides [a helper for creating Marpit plugin](module-plugin.html). A generated plugin promises an existance of `marpit` member.
46 |
47 | ```javascript
48 | import { marpitPlugin } from '@marp-team/marpit/plugin'
49 |
50 | export default marpitPlugin(({ marpit }) => {
51 | // Add your plugin code here (Add theme, define custom directives, etc...)
52 | /*
53 | marpit.customDirectives.local.yourDirective = (value) => {
54 | return { yourDirective: value }
55 | }
56 | */
57 | })
58 | ```
59 |
60 | If the user tried to use the generated Marpit plugin from this helper as markdown-it plugin wrongly, the plugin throws an error. Thus, you can mark the plugin as dedicated to Marpit.
61 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | ['@babel/preset-env', { targets: { node: '18' }, shippedProposals: true }],
4 | ],
5 | }
6 |
--------------------------------------------------------------------------------
/docs/_redirects:
--------------------------------------------------------------------------------
1 | https://marpit.netlify.com/* https://marpit.marp.app/:splat 301!
2 | /* /index.html 200
3 |
--------------------------------------------------------------------------------
/docs/_sidebar.md:
--------------------------------------------------------------------------------
1 | - [Introduction](/)
2 | - [Usage](/usage)
3 | - [Marpit Markdown](/markdown)
4 | - [Directives](/directives)
5 | - [Image syntax](/image-syntax)
6 | - [Fragmented list](/fragmented-list)
7 | - [Theme CSS](/theme-css)
8 | - [Inline SVG slide](/inline-svg)
9 |
10 | ---
11 |
12 |
13 |
14 | - Marpit API (JSDoc)
15 | - GitHub
16 | - npm 
17 |
--------------------------------------------------------------------------------
/docs/assets/directives.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marp-team/marpit/b4ea3e5ada57da696dab50baa24814344b7dcc0c/docs/assets/directives.png
--------------------------------------------------------------------------------
/docs/assets/hello-marpit-theme.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marp-team/marpit/b4ea3e5ada57da696dab50baa24814344b7dcc0c/docs/assets/hello-marpit-theme.pdf
--------------------------------------------------------------------------------
/docs/assets/hello-marpit.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marp-team/marpit/b4ea3e5ada57da696dab50baa24814344b7dcc0c/docs/assets/hello-marpit.pdf
--------------------------------------------------------------------------------
/docs/assets/how-to-use/example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
77 |
78 |
79 | Hello, Marpit!
80 |
81 | Marpit is the skinny framework for creating slide deck from Markdown.
82 |
83 |
84 |
85 | Ready to convert into PDF!
86 | You can convert into PDF slide deck through Chrome.
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/docs/assets/how-to-use/example.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marp-team/marpit/b4ea3e5ada57da696dab50baa24814344b7dcc0c/docs/assets/how-to-use/example.pdf
--------------------------------------------------------------------------------
/docs/assets/image-syntax/multiple-bg-vertical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marp-team/marpit/b4ea3e5ada57da696dab50baa24814344b7dcc0c/docs/assets/image-syntax/multiple-bg-vertical.png
--------------------------------------------------------------------------------
/docs/assets/image-syntax/multiple-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marp-team/marpit/b4ea3e5ada57da696dab50baa24814344b7dcc0c/docs/assets/image-syntax/multiple-bg.png
--------------------------------------------------------------------------------
/docs/assets/image-syntax/split-background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marp-team/marpit/b4ea3e5ada57da696dab50baa24814344b7dcc0c/docs/assets/image-syntax/split-background.jpg
--------------------------------------------------------------------------------
/docs/assets/image-syntax/split-bg-with-size.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marp-team/marpit/b4ea3e5ada57da696dab50baa24814344b7dcc0c/docs/assets/image-syntax/split-bg-with-size.jpg
--------------------------------------------------------------------------------
/docs/assets/image-syntax/split-multiple-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marp-team/marpit/b4ea3e5ada57da696dab50baa24814344b7dcc0c/docs/assets/image-syntax/split-multiple-bg.jpg
--------------------------------------------------------------------------------
/docs/assets/plugin-custom-container.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marp-team/marpit/b4ea3e5ada57da696dab50baa24814344b7dcc0c/docs/assets/plugin-custom-container.png
--------------------------------------------------------------------------------
/docs/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marp-team/marpit/b4ea3e5ada57da696dab50baa24814344b7dcc0c/docs/favicon.png
--------------------------------------------------------------------------------
/docs/fragmented-list.md:
--------------------------------------------------------------------------------
1 | # Fragmented list
2 |
3 | Since v0.9.0, Marpit will parse lists with specific markers as the **fragmented list** for appearing contents one by one.
4 |
5 | ## For bullet list
6 |
7 | CommonMark allows `-`, `+`, and `*` as the character of [bullet list marker](https://spec.commonmark.org/0.29/#bullet-list-marker). Marpit would parse as fragmented list if you are using `*` as the marker.
8 |
9 |
10 |
11 | ```markdown
12 | # Bullet list
13 |
14 | - One
15 | - Two
16 | - Three
17 |
18 | ---
19 |
20 | # Fragmented list
21 |
22 | * One
23 | * Two
24 | * Three
25 | ```
26 |
27 |
28 |
29 | ## For ordered list
30 |
31 | CommonMark's [ordered list marker](https://spec.commonmark.org/0.29/#ordered-list-marker) must have `.` or `)` after digits. Marpit would parse as fragmented list if you are using `)` as the following character.
32 |
33 |
34 |
35 | ```markdown
36 | # Ordered list
37 |
38 | 1. One
39 | 2. Two
40 | 3. Three
41 |
42 | ---
43 |
44 | # Fragmented list
45 |
46 | 1) One
47 | 2) Two
48 | 3) Three
49 | ```
50 |
51 |
52 |
53 | ## Rendering
54 |
55 | A structure of rendered HTML from the fragmented list is same as the regular list. It just adds `data-marpit-fragment` data attribute to list items. They would be numbered from 1 in order of recognized items.
56 |
57 | In addition, `` element of the slide that has fragmented list would be added `data-marpit-fragments` data attribute. It shows the number of fragmented list items of its slide.
58 |
59 | The below HTML is a rendered result of [bullet list example](#for-bullet-list).
60 |
61 | ```html
62 |
63 | Bullet list
64 |
65 | One
66 | Two
67 | Three
68 |
69 |
70 |
71 | Fragmented list
72 |
73 | One
74 | Two
75 | Three
76 |
77 |
78 | ```
79 |
80 | ?> Fragmented list does not change DOM structure and appearances. It relies on a behavior of the integrated app whether actually treats the rendered list as fragments.
81 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Marpit: The skinny framework for creating slide deck from Markdown
7 |
8 |
9 |
13 |
17 |
18 |
19 |
20 |
21 |
70 |
71 |
72 |
116 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/docs/introduction.md:
--------------------------------------------------------------------------------
1 | [marp]: https://github.com/marp-team/marp/
2 | [marp-core]: https://github.com/marp-team/marp-core
3 |
4 |
5 |
6 | [](/)
7 |
8 |
9 |
10 |
11 | **Marpit**: Markdown slide deck framework
12 |
13 |
14 |
15 | ---
16 |
17 | **Marpit** /mɑːrpɪt/ is the skinny framework for creating slide deck from Markdown. It can transform Markdown and CSS theme(s) to slide deck composed of static HTML and CSS and create a web page convertible into slide PDF by printing.
18 |
19 | Marpit is designed to _output minimum assets for the slide deck_. You can use the bare assets as a logicless slide deck, but mainly we expect to integrate output with other tools and applications.
20 |
21 | In fact, this framework is created for using as the base of [a core converter][marp-core] in [Marp ecosystem][marp].
22 |
23 | ## Features
24 |
25 | ### [📝 Marpit Markdown](/markdown) {docsify-ignore}
26 |
27 | We have extended several features into [markdown-it](https://github.com/markdown-it/markdown-it) parser to support writing awesome slides, such as [_Directives_](/directives) and [_Slide backgrounds_](/image-syntax#slide-backgrounds). Additional syntaxes place importance on a compatibility with general Markdown documents.
28 |
29 | ### [🎨 Theme CSS by clean markup](/theme-css) {docsify-ignore}
30 |
31 | Marpit has the CSS theming system that can design slides everything. Unlike other slide frameworks, there are not any predefined classes and mixins. You have only to focus styling HTML elements by pure CSS. Marpit would take care of the selected theme's necessary conversion.
32 |
33 | ### [📐 Inline SVG slide (Experimental) ](/inline-svg) {docsify-ignore}
34 |
35 | Optionally `` element can use as the container of each slide page. It can be realized the pixel-perfect scaling of the slide only by CSS, so handling slides in integrated apps become simplified. The isolated layer made by `` can provide [_advanced backgrounds_](/image-syntax#advanced-backgrounds) for the slide with keeping the original Markdown DOM structure.
36 |
37 | ?> We not provide any themes because Marpit is just a framework. You can use [@marp-team/marp-core][marp-core] if you want. It has the official themes, and practical features extended from Marpit.
38 |
39 | ## Getting started
40 |
41 | ### Installation
42 |
43 | #### npm
44 |
45 | ```bash
46 | npm install @marp-team/marpit
47 | ```
48 |
49 | #### yarn
50 |
51 | ```bash
52 | yarn add @marp-team/marpit
53 | ```
54 |
55 | #### pnpm
56 |
57 | ```bash
58 | pnpm add @marp-team/marpit
59 | ```
60 |
61 | ### How to use
62 |
63 | ```javascript
64 | import Marpit from '@marp-team/marpit'
65 | import fs from 'fs'
66 |
67 | // 1. Create instance (with options if you want)
68 | const marpit = new Marpit()
69 |
70 | // 2. Add theme CSS
71 | const theme = `
72 | /* @theme example */
73 |
74 | section {
75 | background-color: #369;
76 | color: #fff;
77 | font-size: 30px;
78 | padding: 40px;
79 | }
80 |
81 | h1,
82 | h2 {
83 | text-align: center;
84 | margin: 0;
85 | }
86 |
87 | h1 {
88 | color: #8cf;
89 | }
90 | `
91 | marpit.themeSet.default = marpit.themeSet.add(theme)
92 |
93 | // 3. Render markdown
94 | const markdown = `
95 |
96 | # Hello, Marpit!
97 |
98 | Marpit is the skinny framework for creating slide deck from Markdown.
99 |
100 | ---
101 |
102 | ## Ready to convert into PDF!
103 |
104 | You can convert into PDF slide deck through Chrome.
105 |
106 | `
107 | const { html, css } = marpit.render(markdown)
108 |
109 | // 4. Use output in your HTML
110 | const htmlFile = `
111 |
112 |
113 |
114 | ${html}
115 |
116 | `
117 | fs.writeFileSync('example.html', htmlFile.trim())
118 | ```
119 |
120 | Outputted HTML is [here](/assets/how-to-use/example.html ':ignore'). It can convert into [PDF slide deck](/assets/how-to-use/example.pdf ':ignore') through printing by Chrome.
121 |
122 | We are introducing the basic usage step-by-step in [Usage](usage.md) section.
123 |
124 | ## Author
125 |
126 | Managed by [@marp-team](https://github.com/marp-team).
127 |
128 | -  Yuki Hattori ([@yhatt](https://github.com/yhatt))
129 |
130 | ## License
131 |
132 | This framework releases under the [MIT License](https://github.com/marp-team/marpit/blob/main/LICENSE).
133 |
--------------------------------------------------------------------------------
/docs/jsdoc.css:
--------------------------------------------------------------------------------
1 | .sidebar-container,
2 | .mobile-sidebar-container {
3 | padding: 0 !important;
4 | border-radius: 0 !important;
5 | }
6 |
7 | .sidebar-items-container {
8 | margin-top: 2rem !important;
9 | }
10 |
11 | .sidebar-container *,
12 | .mobile-sidebar-container * {
13 | border-radius: 0 !important;
14 | }
15 |
16 | section th,
17 | section td {
18 | padding: 0.25rem 0.75rem !important;
19 | font-size: 90%;
20 | }
21 |
22 | .attributes,
23 | .default {
24 | overflow-wrap: anywhere;
25 | }
26 |
--------------------------------------------------------------------------------
/docs/markdown.md:
--------------------------------------------------------------------------------
1 | # Marpit Markdown {docsify-ignore-all}
2 |
3 | Marpit Markdown syntax focuses on compatibility with commonly Markdown documents. It means the result of rendering keeps looking nice even if you open the Marpit Markdown in a general Markdown editor.
4 |
5 | ## How to write slides?
6 |
7 | Marpit splits pages of the slide deck by horizontal ruler (e.g. `---`). It's very simple.
8 |
9 | ```markdown
10 | # Slide 1
11 |
12 | foo
13 |
14 | ---
15 |
16 | # Slide 2
17 |
18 | bar
19 | ```
20 |
21 | ?> An empty line may be required before the dash ruler by the spec of [CommonMark](https://spec.commonmark.org/0.29/#example-28). You can use the underline ruler `___`, asterisk ruler `***`, and space-included ruler `- - -` when you do not want to add empty lines.
22 |
23 | ## Extended features
24 |
25 | ### [Directives](/directives)
26 |
27 | Marpit Markdown has extended syntax called **"Directives"** to support writing awesome slides. It can control your slide-deck theme, page number, header, footer, style, and so on.
28 |
29 | ### [Image syntax](/image-syntax)
30 |
31 | Marpit has extended Markdown image syntax `` to be helpful creating beautiful slides.
32 |
33 | ### [Fragmented list](/fragmented-list)
34 |
35 | Since v0.9.0, Marpit will parse lists with specific markers as the **fragmented list** for appearing contents one by one.
36 |
--------------------------------------------------------------------------------
/docs/marpit-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marp-team/marpit/b4ea3e5ada57da696dab50baa24814344b7dcc0c/docs/marpit-dark.png
--------------------------------------------------------------------------------
/docs/marpit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marp-team/marpit/b4ea3e5ada57da696dab50baa24814344b7dcc0c/docs/marpit.png
--------------------------------------------------------------------------------
/docsify/_alert.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:color';
2 |
3 | .alert-for-marp-consumers {
4 | background: var(--notice-important-background);
5 | border: 3px double var(--notice-important-border-color);
6 | margin: 0 0 2rem;
7 | overflow: hidden;
8 | padding: 0 1.5rem;
9 | }
10 |
11 | .alert-for-marp-consumers-content {
12 | grid-area: contents;
13 | }
14 |
15 | .alert-for-marp-consumers-close-container {
16 | float: right;
17 | width: 3rem;
18 | height: 3rem;
19 | padding: 0 0 1rem 1rem;
20 | overflow: hidden;
21 | }
22 |
23 | .alert-for-marp-consumers-close {
24 | background: transparent;
25 | border: 0;
26 | width: 2rem;
27 | height: 2rem;
28 | padding: 0;
29 | cursor: pointer;
30 | opacity: 0.7;
31 |
32 | &:hover {
33 | opacity: 0.8;
34 | }
35 |
36 | &:hover:active {
37 | opacity: 0.5;
38 | }
39 | }
40 |
41 | .alert-for-marp-consumers-close-img {
42 | width: 2rem;
43 | height: 2rem;
44 | }
45 |
46 | .alert-for-marp-consumers-button-container {
47 | text-align: right;
48 | margin-bottom: 1rem;
49 | }
50 |
51 | .alert-for-marp-consumers-button {
52 | background: var(--notice-important-border-color);
53 | border-radius: 0.25rem;
54 | border: 0;
55 | color: #fff;
56 | cursor: pointer;
57 | padding: 0.5rem 2rem;
58 |
59 | &:active {
60 | background: color.mix($important-color, #000, 80%);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/docsify/_code.scss:
--------------------------------------------------------------------------------
1 | :root {
2 | --code-theme-background: #{rgba(#666, 0.05)};
3 | --code-theme-comment: #9ab;
4 | --code-theme-function: #e71;
5 | --code-theme-keyword: #d42;
6 | --code-theme-operator: #a67f59;
7 | --code-theme-punctuation: #5ad;
8 | --code-theme-selection: #b3d4fc;
9 | --code-theme-selector: #458;
10 | --code-theme-tag: #70a;
11 | --code-theme-text: #333;
12 | --code-theme-variable: #e90;
13 |
14 | // Block
15 | --code-block-padding: 1.25em;
16 | --code-block-line-height: 1.4;
17 |
18 | // Inline
19 | --code-inline-color: currentcolor;
20 |
21 | // Copy code plugin
22 | --copycode-background: #aaa;
23 | }
24 |
--------------------------------------------------------------------------------
/docsify/build.js:
--------------------------------------------------------------------------------
1 | require('./modules/build')()
2 |
--------------------------------------------------------------------------------
/docsify/docsify.scss:
--------------------------------------------------------------------------------
1 | @import '../node_modules/docsify-themeable/dist/css/theme-defaults';
2 | @import './layout';
3 | @import './code';
4 | @import './alert';
5 |
--------------------------------------------------------------------------------
/docsify/modules/build.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const { promisify } = require('util')
4 | const autoprefixer = require('autoprefixer')
5 | const cssnano = require('cssnano')
6 | const postcss = require('postcss')
7 | const sass = require('sass')
8 |
9 | const from = path.join(__dirname, '../docsify.scss')
10 | const to = path.join(__dirname, '../../docs/style/docsify.css')
11 |
12 | module.exports = async () => {
13 | const { css: cssBuf } = await promisify(sass.render)({
14 | file: from,
15 | outFile: to,
16 | sourceMap: true,
17 | sourceMapEmbed: true,
18 | })
19 |
20 | const { css } = await postcss([
21 | autoprefixer,
22 | cssnano({ preset: ['default', { mergeLonghand: false }] }),
23 | ]).process(cssBuf, { from, to, map: { annotation: false, inline: false } })
24 |
25 | await promisify(fs.mkdir)(path.dirname(to), { recursive: true })
26 | await promisify(fs.writeFile)(to, css)
27 | }
28 |
--------------------------------------------------------------------------------
/docsify/serve.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const http = require('http')
3 | const path = require('path')
4 | const stream = require('stream')
5 | const chokidar = require('chokidar')
6 | const handler = require('serve-handler')
7 | const WebSocket = require('ws')
8 | const build = require('./modules/build')
9 |
10 | const debounce = (func, wait) => {
11 | let timeout
12 | return (...args) => {
13 | clearTimeout(timeout)
14 | timeout = setTimeout(() => {
15 | timeout = null
16 | func(...args)
17 | }, wait)
18 | }
19 | }
20 |
21 | // Serve WebSocket server for live reload
22 | const wsPort = process.env.WS_PORT || 3001
23 | const wss = new WebSocket.Server({ port: wsPort })
24 | const reload = () => wss.clients.forEach((client) => client.send('reload'))
25 |
26 | const wsScript = `
27 | (function() {
28 | const ws = new WebSocket('ws://' + location.hostname + ':${wsPort}/')
29 |
30 | ws.addEventListener('message', (e) => {
31 | if (e.data === 'reload') location.reload()
32 | })
33 | })()
34 | `
35 |
36 | // Build docisfy style and watch changes
37 | chokidar.watch('**/*.scss', { cwd: __dirname }).on('all', debounce(build, 250))
38 |
39 | // Watch change of docs directory
40 | chokidar
41 | .watch('**/*', { cwd: path.resolve(__dirname, '../docs') })
42 | .on('all', debounce(reload, 250))
43 |
44 | // Serve documentation
45 | const port = process.env.PORT || 3000
46 | const server = http.createServer((req, res) => {
47 | const { writeHead } = res
48 | const overriddenHeaders = { 'Cache-Control': 'no-store' }
49 |
50 | res.writeHead = function overriddenWriteHead(status, headers) {
51 | return writeHead.call(this, status, {
52 | ...(headers || {}),
53 | ...overriddenHeaders,
54 | })
55 | }
56 |
57 | const createReadStream = (absolutePath, opts) =>
58 | new Promise((resolve) => {
59 | const readStream = fs.createReadStream(absolutePath, opts)
60 | if (path.extname(absolutePath) !== '.html') {
61 | resolve(readStream)
62 | } else {
63 | let queue = Buffer.from([])
64 |
65 | readStream.pipe(
66 | new stream.Transform({
67 | transform: (chunk, _, callback) => {
68 | queue = Buffer.concat([queue, chunk])
69 | callback()
70 | },
71 | final(callback) {
72 | let html = queue.toString()
73 | const endBodyIdx = html.lastIndexOf('