Skip to content

Repository files navigation

m2slide - Markdown Presentation & E-book Generator

🌏 English: this document · 한국어: README_kr.md

A tool that automatically converts Markdown files into Reveal.js presentations and EPUB e-books. An independent per-project folder structure lets you manage many lecture decks and e-books in an organized way.

🌐 Live demo: https://finfra.github.io/m2slide/

View the actually generated presentations directly in your web browser.

📊 m2slide intro decks:

📋 Public project list: Projects_org.md

The list of example projects included in this repository. It is auto-generated by ./m2slide.sh --sync-projects, so do not edit it by hand.

Key Features

1. Reveal.js HTML presentation generation

  • Markdown → HTML conversion: slides are split automatically by the --- separator
  • Markmap table of contents: a clickable, interactive mind map
  • Hierarchical navigation: automatic linking of main/sub chapters, parent-page button
  • Responsive design: optimized for desktop and mobile
  • Full Markdown support: headers, lists, tables, code blocks, images, blockquotes, and more

2. EPUB e-book generation

  • EPUB 3.0 standard: works with all readers such as iBooks, Calibre, Google Play Books
  • Automatic table of contents: hierarchical structure based on AGENDA.md
  • Mermaid diagrams: auto-converted to SVG images (when mmdc is installed)
  • Automatic image embedding: Markdown images are embedded inside the EPUB

3. Independent per-project management

  • Independent folder structure: each project is managed in its own folder
  • Consistent workflow: the same commands apply to every project
  • Git-friendly: optional per-project version control

4. Multiple output formats

  • HTML: Reveal.js presentation (default)
  • EPUB: e-book (--epub)
  • PDF: per-chapter combined PDF (--pdf, uses decktape)
  • PPTX: PowerPoint-compatible (--pptx, uses pandoc)
  • Automatic GitHub Pages deploy: deploy_formats in _config.yml + the /deploy-docs command auto-syncs artifacts and cards (see the GitHub Pages deployment section)

Project Structure

m2slide/
├── Projects/
│   ├── ProjectA/                  # Independent project 1
│   │   ├── markdown/              # Markdown source
│   │   │   ├── AGENDA.md
│   │   │   ├── 01-section.md
│   │   │   └── ...
│   │   ├── slide/                 # HTML output (auto-generated)
│   │   └── ProjectA.epub          # EPUB output (auto-generated)
│   ├── ProjectB/                  # Independent project 2
│   │   ├── markdown/
│   │   ├── slide/
│   │   └── ProjectB.epub
│   └── LlmAndVibeCoding/          # Example project (see below)
├── config.yml                     # Current working project setting
├── m2slide.sh                     # One-click conversion (HTML/EPUB)
├── lib/                           # Script collection
│   ├── generate-slides.js         # HTML conversion script
│   ├── generate-epub.js           # EPUB conversion script
│   ├── deploy.sh                  # GitHub Pages deploy
│   └── debug_yaml.js              # YAML parsing debug util
├── theme/                         # Themes (default·default_lec tracked in git, others gitignored)
│   ├── default/                   # General-purpose base theme
│   │   ├── slide.css              # Global styles
│   │   └── layouts/_toc.html      # System layout (auto-applied TOC)
│   └── default_lec/               # Official lecture theme
│       ├── slide.css
│       └── layouts/*.html         # cover, contents, split-image-text, etc.
└── README.md

Operating Modes

Mode detection

If AGENDA.md exists inside the markdown/ folder → chapter mode; if it is absentsingle-page mode.

Single-page mode

One Markdown file → one HTML slide deck. For short talks.

  1. Create the Projects/{name}/ folder
  2. Write a Markdown file inside it (split slides with ---)
  3. Run ./m2slide.sh Projects/{name}
  4. Open Projects/{name}/slide/{name}.html to check

Markdown file selection priority (when there are multiple .md files):

  1. {project-folder-name}.md (ex: MarkdownGraph/MarkdownGraph.md)
  2. README.md
  3. If there is only one .md file, that file
  4. If there is only one .md file starting with a normal character (letter/digit/Korean), that file
  • If there are multiple candidates → error → rename to match the folder name

Chapter mode

Multiple Markdown files → per-chapter HTML + a mind-map table of contents. For long lectures and e-books.

  1. Create the Projects/{name}/markdown/ folder
  2. Write chapter files — main: 01-opening.md, sub: 02.1-chat.md
  3. Write the table of contents in markdown/AGENDA.md (this file is the signal that enables chapter mode)
  4. Run ./m2slide.sh Projects/{name}
  5. Open Projects/{name}/slide/index.html (mind-map TOC)

Usage

1. Generate an HTML presentation

Simple way (recommended):

# Use the current project from config.yml
./m2slide.sh

# Specify a particular project
./m2slide.sh Projects/ProjectA

Detailed control (running Node.js directly):

# Use the default project
node generate-slides.js

# Specify a project folder
node generate-slides.js Projects/ProjectA

# Specify the markdown folder directly (../slide/ is created automatically)
node generate-slides.js Projects/ProjectA/markdown

# Specify input/output folders directly (advanced)
node generate-slides.js Projects/ProjectA/markdown Projects/ProjectA/slide

Output:

  • slide/*.html: per-chapter Reveal.js presentations
  • slide/index.html: full table of contents based on Markmap (mind map)
  • slide/img/: images copied automatically

2. Generate an EPUB e-book

Generate HTML + EPUB at once:

# Current project from config.yml
./m2slide.sh --epub

# A particular project
./m2slide.sh Projects/ProjectA --epub

EPUB only (skip HTML):

node generate-epub.js Projects/ProjectA

Mermaid diagram rendering (optional):

# Install the Mermaid CLI (mmdc)
npm install -g @mermaid-js/mermaid-cli

# Google Chrome is required (auto-detected)
# - macOS: /Applications/Google Chrome.app/
# - Linux: /usr/bin/google-chrome
# - Windows: C:\Program Files\Google\Chrome\Application\chrome.exe

# If mmdc is missing, a placeholder SVG is used instead

Output:

  • Projects/ProjectA/ProjectA.epub: EPUB 3.0 e-book
  • slide/ProjectA.epub: copied automatically alongside the presentation
  • index.html: EPUB download link shown automatically

3. View the presentation

# Open in the browser
open Projects/ProjectA/slide/index.html      # Mind-map navigation
open Projects/ProjectA/slide/01-section.html # Individual section

Navigation:

  • ← / →: previous/next slide
  • : chapter mode — go to the parent page (sub chapter → main chapter → TOC) / single-page mode — go to the first slide
  • → twice on the last slide: move to the next chapter (chapter mode only)
  • ESC: slide overview
  • S: speaker-notes mode
  • Bottom-right button: click the "↑ up" button to move to the parent page
  • First slide: clickable Markmap TOC (includes sub-chapter links)

4. Add a new project

# 1. Create the project folder
mkdir -p Projects/NewProject/markdown

# 2. Write AGENDA.md and Markdown files
# In the markdown folder, use the following format:
# - AGENDA.md: ## [title](./filename.md) format
# - XX-title.md: main section (ex: 01-intro.md)
# - XX.Y-title.md: sub section (ex: 02.1-detail.md)
# - Split slides with the --- separator in each file

# 3. Add Git tracking (optional)
echo "!/NewProject/" >> Projects/.gitignore

# 4. Generate HTML/EPUB
./m2slide.sh Projects/NewProject --epub

# 5. Check
open Projects/NewProject/slide/index.html

5. PowerPoint conversion (optional)

# Pandoc must be installed (brew install pandoc)

# Convert a single file
pandoc Projects/ProjectA/markdown/01-section.md -o presentation.pptx

# Combine all material
pandoc Projects/ProjectA/markdown/*.md -o complete.pptx

Highlights

Reveal.js presentation system

  • Automatic slide splitting: slide boundaries are detected automatically by the --- separator
  • Markmap TOC: visualizes the AGENDA.md structure as an interactive mind map
  • Hierarchical navigation:
    • main chapter TOC automatically shows sub-chapter links
    • parent-page button (bottom-right "↑ up")
    • keyboard ↑ moves to the parent page
  • Complete Markdown parser:
    • headers, Bold, Italic, inline code
    • ordered/unordered lists, nested lists
    • tables, code blocks, blockquotes
    • images (auto size limit 400x300px)
  • Responsive design: optimized for desktop and mobile
  • Slide numbers: current/total display
  • Automatic index.html generation: mind-map navigation based on the AGENDA.md structure

EPUB e-book system

  • EPUB 3.0 standard: mimetype, META-INF/container.xml, OEBPS/content.opf, toc.ncx
  • Automatic TOC generation: extracts book title and chapter structure from AGENDA.md
  • Mermaid diagram conversion:
    • auto-converted to SVG images when the Mermaid CLI is installed
    • uses the system Chrome (PUPPETEER_EXECUTABLE_PATH)
    • generates a placeholder SVG on conversion failure
  • Image embedding: images in markdown/img/ are embedded inside the EPUB
  • Pure Node.js implementation: no external dependencies (mmdc is optional)
  • Universal compatibility: all EPUB readers such as iBooks, Calibre, Google Play Books

Automatic conversion scripts

  • One-click conversion: the ./m2slide.sh script generates HTML/EPUB at once
  • config.yml support: automatically detects the current working project
  • Automatic image copy: markdown/img/ → slide/img/, and inside the EPUB
  • Automatic parent-page detection: derives the hierarchy from AGENDA.md
  • Error resilience: generates placeholders on conversion failure

Theme & Layout

Each project specifies its theme and default layout in _config.yml.

theme: default_lec              # applies theme/{name}/slide.css
theme_default_layout: contents  # auto-applies theme/{name}/layouts/contents.html

To use a different layout for a specific slide only, add this at the start of the Markdown slide:

---
#cover

# First page

For layouts that need slots such as left/right split, use a fenced div:

---
#split-image-text

# Slide title

::: left
![image](./img/x.png)
:::

::: right
* Right-side text
:::

System layout: the first slide (TOC) automatically gets the _toc layout. In theme/{name}/layouts/_toc.html, the markmap slot is marked by the {{markmap}} variable.

Folder structure (single CSS, only HTML templates per layout):

lib/css/base.css            # Common skeleton shared by all themes (Issue64, ~1050 lines)
                            # @import + :root defaults + common layout + components + responsive
                            # injected automatically as an inline <style> by html-builder.js
theme/
├── default/                # Base theme (tracked in git, general-purpose ~400 lines)
│   ├── slide.css           # Theme-specific: colors, background images, visual language
│   └── layouts/
│       └── _toc.html       # System layout (TOC)
└── default_lec/            # Official lecture theme (tracked in git)
    ├── slide.css           # Theme-specific selectors
    └── layouts/            # HTML templates only (CSS is merged into slide.css)
        ├── _toc.html
        ├── _cover.html
        ├── _contents.html
        ├── split-image-text.html
        └── ...

CSS priority (low → high): CDN (reset/reveal/highlight/open-props) → lib/css/base.css (inline) → theme/{name}/slide.css (link) → <body style> (config variables). Details: _doc_arch/css.md.

Guide for writing a new theme:

  • Minimum requirement: create theme/{name}/slide.css (an empty file is fine). base.css provides the cover/contents/chapter/exercise/blank/closing/toc skeletons plus :root variable defaults.
  • Optional: :root --kn-* branding colors, theme/{name}/img/ background images, theme/{name}/layouts/*.html templates (falls back to default when absent).
  • In the _config.yml style section, specify only the values that deviate from the defaults (Issue64 1.b policy). Omitted keys use the lib/config.js defaults, guaranteeing the same result as the base.css :root.

Standard variables: {{title}}, {{content}}, {{slotName}}, {{markmap}} (system-reserved, _toc only)

Backward compatibility: the slide_css: key still works. When theme: and theme_default_layout: are unset, the existing behavior is preserved. When style.global.font_import[] is specified, a <link> is added after the base.css @import position (legacy append).

Markdown Authoring Rules

AGENDA.md format

# Project title

## [Main section 1](./01-section.md)
### [Sub section 1.1](./01.1-detail.md)
### [Sub section 1.2](./01.2-detail.md)

## [Main section 2](./02-section.md)

Important:

  • Only the inline link format ([title](filename)) is recognized
  • ##: main section, ###: sub section
  • File naming: XX-title.md (main), XX.Y-title.md (sub)

Slide separation

# First slide

content...

---

# Second slide

content...

Editing Workflow

  1. Edit the Markdown files in the Projects/[Project]/markdown/ folder
  2. Run ./m2slide.sh --epub (generates HTML + EPUB at once)
  3. Check Projects/[Project]/slide/index.html in the browser
  4. Check Projects/[Project]/[Project].epub in an EPUB reader

Auto-generated files:

  • slide/*.html: all per-chapter Reveal.js presentations
  • slide/index.html: mind-map navigation based on AGENDA.md
  • [Project].epub: EPUB 3.0 e-book
  • slide/[Project].epub: provided alongside the presentation

GitHub Pages Deployment

The root docs/ folder is the GitHub Pages source (main branch + /docs). It gathers many projects into one place and deploys them as cards (https://finfra.github.io/m2slide/).

Method 1: /deploy-docs command (Claude Code, recommended)

A slash command defined in .claude/commands/deploy-docs.md. It supports automatic new/update/delete branching across many projects + an artifact-format option list + automatic main index card updates.

/deploy-docs <project>          # update if docs/<project>/ exists, otherwise new
/deploy-docs <project> delete   # remove the folder + main index card (user approval required)
/deploy-docs                    # print usage + current docs/ deployment list

Automatic artifact-format inclusion (EPUB/PDF/PPTX): add one line, deploy_formats, to the project's _config.yml:

deploy_formats: [epub, pdf, pptx]   # all formats
deploy_formats: [epub]               # EPUB only
## Omit the key or use [] → HTML only (default)

Then a single /deploy-docs <project> call builds (auto-passing m2slide.sh options such as --epub) → syncs to docs/ → automatically shows download badges (📚 EPUB · 📄 PDF · 📊 PPTX) on the main index card.

Method 2: lib/deploy.sh script (single project)

## Automatically deploy the current project from _config.yml
./lib/deploy.sh

## Custom commit message
./lib/deploy.sh "Add new slides"
  • Automatically reads the current project from _config.yml
  • Automatically copies the slide/ folder into the docs/ folder
  • Automatically runs Git add, commit, push
  • Exits automatically when there are no changes

Method 3: Manual deployment

## 1. Regenerate HTML (+ optional artifacts)
./m2slide.sh <project> --epub --pdf --pptx

## 2. Copy into the docs/ folder
mkdir -p docs/<project>
cp -R Projects/<project>/slide/. docs/<project>/

## 3. Git commit and push
git add docs && git commit -m "Update slides" && git push

Verifying the deployment

Reflected within about 1–2 minutes after pushing. Check status:

gh api repos/<owner>/<repo>/pages/builds --jq '.[0] | {status, commit, updated_at}'
gh run list --repo <owner>/<repo> --limit 3

GitHub Pages setup (one time)

  1. Open the GitHub repository
  2. SettingsPages menu
  3. Source: Branch main, Folder /docs
  4. Click Save

Tech Stack

HTML presentation

  • Reveal.js 5.0.4: HTML presentation framework
  • Markmap.js: mind-map visualization (TOC)
  • Mermaid.js 10.9.0: diagram rendering
  • D3.js: data visualization
  • Node.js: Markdown conversion scripts (pure standard library)

EPUB e-book

  • Node.js: EPUB 3.0 generation (pure standard library)
  • Mermaid CLI (optional): diagram SVG conversion (@mermaid-js/mermaid-cli)
  • Google Chrome (optional): Mermaid rendering engine

Others

  • Pandoc (optional): PowerPoint conversion
  • GitHub Pages: web hosting

Example project: LlmAndVibeCoding

Topic: LLM tooling evolution and the generational classification of vibe coding (30-minute lecture material)

Live demo: https://finfra.github.io/m2slide/

Content overview:

  1. Opening: the paradigm shift of AI coding
  2. LLM tooling evolution: chat → IDE → CLI progression
  3. Vibe coding: concept and philosophy
  4. Generational classification: based on the user interface (Gen 0: chat, Gen 1: IDE, Gen 2: CLI)
  5. Generational comparison: a selection guide
  6. Real-world cases: how to use them
  7. Adoption roadmap: a practical strategy
  8. Q&A and closing

File structure:

  • Markdown source: Projects/LlmAndVibeCoding/markdown/ (16 files)
  • HTML presentation: Projects/LlmAndVibeCoding/slide/
  • EPUB e-book: Projects/LlmAndVibeCoding/LlmAndVibeCoding.epub

Highlights:

  • Markmap-based interactive navigation
  • Hierarchical chapter structure (7 main, 9 sub)
  • Mermaid diagrams (LLM tooling evolution timeline, etc.)

This project is a reference example that demonstrates all of m2slide's features.

Specifying the Project

./m2slide.sh determines the project in the following priority order:

  1. CLI argument: ./m2slide.sh MarkdownGraph or ./m2slide.sh Projects/MyProj
  2. _config.yml in the CWD: cd into the project folder, then run ../../m2slide.sh
  3. current_project in the root _config.yml: (used only when present)

_config.org.yml is used only as the defaults SSOT, and current_project is intentionally commented out. If the project cannot be determined, the usage is printed.

To set a default via the root _config.yml:

# _config.yml (root, for local user settings — can be tracked in git)
current_project: LlmAndVibeCoding

./lib/deploy.sh reads current_project the same way.

Check the help:

./m2slide.sh --help

License

Dual license — see LICENSE.md for full terms.

  • Free (CC BY 4.0): Presentations generated with m2slide must keep the attribution line "Powered by finfra.kr, Made by m2slide" on the first and last slides.
  • Paid (Commercial license): Generating presentations with that attribution removed requires a paid commercial license. Contact: finfra@gmail.com / https://finfra.kr

About

Markdown을 SlideShow로 보여주는

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages