├── .github └── workflows │ └── build.yaml ├── .gitignore ├── .marprc.yml ├── .vscode ├── honwaka.code-snippets └── settings.json ├── Makefile ├── README.md ├── check_unused_img.py └── slides ├── 0_header.md ├── 1_intro.md ├── 2_main.md ├── 3_outro.md └── img ├── normal_distribution.png └── shibainu.png /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | 2 | name: Build Slide and Deploy 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | timeout-minutes: 5 12 | steps: 13 | - uses: actions/checkout@v3 14 | 15 | - name: Setup 16 | run: | 17 | make setup 18 | 19 | - name: Marp Build 20 | uses: docker://marpteam/marp-cli:v3.4.0 21 | with: 22 | args: build/slide.md --config-file .marprc.yml --output build/index.html 23 | env: 24 | MARP_USER: root:root 25 | 26 | - uses: actions/upload-pages-artifact@v3 27 | with: 28 | path: build 29 | 30 | 31 | 32 | deploy: 33 | needs: build 34 | permissions: 35 | pages: write 36 | id-token: write 37 | 38 | environment: 39 | name: github-pages 40 | url: ${{ steps.deployment.outputs.page_url }} 41 | 42 | runs-on: ubuntu-latest 43 | steps: 44 | - name: Deploy to GitHub Pages 45 | id: deployment 46 | uses: actions/deploy-pages@v4 47 | 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ -------------------------------------------------------------------------------- /.marprc.yml: -------------------------------------------------------------------------------- 1 | allowLocalFiles: true 2 | html: true 3 | theme: build/honwaka-theme/style.css -------------------------------------------------------------------------------- /.vscode/honwaka.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "template": { 3 | "prefix": "honwaka-template", 4 | "body": [ 5 | "---", 6 | "marp: true", 7 | "paginate: true", 8 | "math: mathjax", 9 | "theme: honwaka", 10 | "---", 11 | "$$", 12 | "\\newcommand{\\argmin}{\\mathop{\\rm arg~min}\\limits}", 13 | "$$" 14 | ], 15 | "description": "Honwaka slide template" 16 | }, 17 | "lead": { 18 | "prefix": "leadpage", 19 | "body": [ 20 | "---", 21 | "" 22 | ], 23 | "description": "Lead page" 24 | }, 25 | "newpage": { 26 | "prefix": "newpage", 27 | "body": [ 28 | "---", 29 | "" 30 | ], 31 | "description": "New page with header" 32 | }, 33 | "header": { 34 | "prefix": "header", 35 | "body": [ 36 | "" 37 | ], 38 | "description": "Slide header" 39 | }, 40 | "columns": { 41 | "prefix": "columns", 42 | "body": [ 43 | "
", 44 | "", 45 | "$1", 46 | "", 47 | "
" 48 | ], 49 | "description": "2 columns layout" 50 | }, 51 | "columns3": { 52 | "prefix": "columns3", 53 | "body": [ 54 | "
", 55 | "", 56 | "$1", 57 | "", 58 | "
" 59 | ], 60 | "description": "3 columns layout" 61 | }, 62 | "columns4": { 63 | "prefix": "columns4", 64 | "body": [ 65 | "
", 66 | "", 67 | "$1", 68 | "", 69 | "
" 70 | ], 71 | "description": "4 columns layout" 72 | }, 73 | "def": { 74 | "prefix": "def", 75 | "body": [ 76 | "
", 77 | "", 78 | "$1", 79 | "", 80 | "
" 81 | ], 82 | "description": "Definition box" 83 | }, 84 | "proof": { 85 | "prefix": "proof", 86 | "body": [ 87 | "
", 88 | "", 89 | "$1", 90 | "", 91 | "
" 92 | ], 93 | "description": "Proof box" 94 | }, 95 | "thm": { 96 | "prefix": "thm", 97 | "body": [ 98 | "
", 99 | "", 100 | "$1", 101 | "", 102 | "
" 103 | ], 104 | "description": "Theorem box" 105 | }, 106 | "box": { 107 | "prefix": "box", 108 | "body": [ 109 | "
", 110 | "", 111 | "$1", 112 | "", 113 | "
" 114 | ], 115 | "description": "Generic box" 116 | }, 117 | "center": { 118 | "prefix": "center", 119 | "body": [ 120 | "
", 121 | "", 122 | "$1", 123 | "", 124 | "
" 125 | ], 126 | "description": "Center aligned block" 127 | }, 128 | "dot-text": { 129 | "prefix": "dottext", 130 | "body": [ 131 | "$1" 132 | ], 133 | "description": "Dot emphasis text" 134 | }, 135 | "orangelined": { 136 | "prefix": "orangelined", 137 | "body": [ 138 | "$1" 139 | ], 140 | "description": "Orange underline marker" 141 | }, 142 | "bluelined": { 143 | "prefix": "bluelined", 144 | "body": [ 145 | "$1" 146 | ], 147 | "description": "Blue highlight marker" 148 | }, 149 | "red": { 150 | "prefix": "red", 151 | "body": [ 152 | "$1" 153 | ], 154 | "description": "Red bold text" 155 | }, 156 | "green": { 157 | "prefix": "green", 158 | "body": [ 159 | "$1" 160 | ], 161 | "description": "Green bold text" 162 | }, 163 | "gray": { 164 | "prefix": "gray", 165 | "body": [ 166 | "$1" 167 | ], 168 | "description": "Gray text" 169 | }, 170 | "small": { 171 | "prefix": "small", 172 | "body": [ 173 | "$1" 174 | ], 175 | "description": "Small inline text" 176 | }, 177 | "smalldiv": { 178 | "prefix": "smalldiv", 179 | "body": [ 180 | "
", 181 | "", 182 | "$1", 183 | "", 184 | "
" 185 | ], 186 | "description": "Small text block" 187 | }, 188 | "div": { 189 | "prefix": "div", 190 | "body": [ 191 | "
", 192 | "", 193 | "$2", 194 | "", 195 | "
" 196 | ], 197 | "description": "Generic div" 198 | }, 199 | "emptydiv": { 200 | "prefix": "emptydiv", 201 | "body": [ 202 | "
", 203 | "", 204 | "$2", 205 | "", 206 | "
" 207 | ], 208 | "description": "Empty div for layout" 209 | }, 210 | "toc": { 211 | "prefix": "toc", 212 | "body": [ 213 | "
", 214 | "", 215 | "$1", 216 | "", 217 | "
" 218 | ], 219 | "description": "TOC container" 220 | }, 221 | "toc-sec": { 222 | "prefix": "tocsec", 223 | "body": [ 224 | "
", 225 | "
$1
", 226 | "
", 227 | "", 230 | "
", 231 | "
" 232 | ], 233 | "description": "Section in TOC" 234 | }, 235 | "cite": { 236 | "prefix": "cite", 237 | "body": [ 238 | "
", 239 | "$1", 240 | "
" 241 | ], 242 | "description": "Citation / bottom text" 243 | }, 244 | "mathblock": { 245 | "prefix": "mathblock", 246 | "body": [ 247 | "$$", 248 | "$1", 249 | "$$" 250 | ], 251 | "description": "MathJax block" 252 | }, 253 | "codecaption": { 254 | "prefix": "codecaption", 255 | "body": [ 256 | "
", 257 | "```$1", 258 | "$2", 259 | "```", 260 | "
$3
", 261 | "
" 262 | ], 263 | "description": "Code block with caption" 264 | }, 265 | "img-center": { 266 | "prefix": "imgcenter", 267 | "body": [ 268 | "![center]($1)" 269 | ], 270 | "description": "Centered image" 271 | }, 272 | "section-label": { 273 | "prefix": "sectionlabel", 274 | "body": [ 275 | "
", 276 | "$1", 277 | "
" 278 | ], 279 | "description": "Top-right section label" 280 | }, 281 | "toc-list": { 282 | "prefix": "toclist", 283 | "body": [ 284 | "" 287 | ], 288 | "description": "TOC unordered list" 289 | }, 290 | "label": { 291 | "prefix": "label", 292 | "body": [ 293 | "$1" 294 | ], 295 | "description": "Labeled span" 296 | }, 297 | "badge": { 298 | "prefix": "badge", 299 | "body": [ 300 | "$1" 301 | ], 302 | "description": "Badge-style label" 303 | }, 304 | "bg-lightblue": { 305 | "prefix": "bgblue", 306 | "body": [ 307 | "
", 308 | "$1", 309 | "
" 310 | ], 311 | "description": "Light blue background box" 312 | }, 313 | "bg-orange": { 314 | "prefix": "bgorange", 315 | "body": [ 316 | "
", 317 | "$1", 318 | "
" 319 | ], 320 | "description": "Light orange background box" 321 | } 322 | } 323 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "markdown.copyFiles.destination": { 3 | "slides/*.md": "img/${fileName}" 4 | } 5 | } -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SRC_DIR := slides 2 | BUILD_DIR := build 3 | SRC_FILES := $(wildcard $(SRC_DIR)/*.md) 4 | HEADER_FILE := $(firstword $(SRC_FILES)) 5 | REST_FILES := $(filter-out $(HEADER_FILE), $(SRC_FILES)) 6 | OUTPUT_FILE := $(BUILD_DIR)/slide.md 7 | THEME_NAME := honwaka-theme 8 | THEME_REPO := https://github.com/abap34/honwaka-theme 9 | MARPRC_FILE := .marprc.yml 10 | 11 | .PHONY: all setup pdf html pptx preview clean 12 | 13 | all: clean setup pdf html pptx 14 | 15 | setup: $(OUTPUT_FILE) 16 | @echo "Setup theme and slide file..." 17 | 18 | $(OUTPUT_FILE): $(SRC_FILES) 19 | @mkdir -p $(BUILD_DIR) 20 | @echo "Clone theme..." 21 | @git clone $(THEME_REPO) $(BUILD_DIR)/$(THEME_NAME) 22 | @echo "Creating slide file..." 23 | @echo "N_SECTION = $(words $(SRC_FILES))" 24 | @cp -r $(SRC_DIR)/* $(BUILD_DIR)/ 25 | @echo "HEADER_FILE = $(HEADER_FILE)" 26 | @cat $(HEADER_FILE) > $(OUTPUT_FILE) 27 | @for file in $(REST_FILES); do \ 28 | echo "### section: $$file"; \ 29 | awk 'BEGIN { found = 0; } { if (found >= 2) print; if ($$0 == "---") found++; }' $$file >> $(OUTPUT_FILE); \ 30 | done 31 | 32 | pdf: setup 33 | @echo "Creating PDF..." 34 | @marp $(OUTPUT_FILE) --config-file $(MARPRC_FILE) --output $(BUILD_DIR)/slide.pdf 35 | 36 | html: setup 37 | @echo "Creating HTML..." 38 | @marp $(OUTPUT_FILE) --config-file $(MARPRC_FILE) --output $(BUILD_DIR)/slide.html 39 | 40 | pptx: setup 41 | @echo "Creating PPTX..." 42 | @marp $(OUTPUT_FILE) --config-file $(MARPRC_FILE) --output $(BUILD_DIR)/slide.pptx 43 | 44 | preview: clean setup 45 | @echo "Creating preview..." 46 | @marp $(OUTPUT_FILE) --config-file $(MARPRC_FILE) --preview 47 | 48 | clean: 49 | @echo "Cleaning up..." 50 | @rm -rf $(BUILD_DIR) 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # slide-template 2 | 3 | [![Build Slide and Deploy](https://github.com/abap34/LT-template/actions/workflows/build.yaml/badge.svg)](https://github.com/abap34/LT-template/actions/workflows/build.yaml) 4 | 5 | This is a template repository for creating slides with [Marp](https://marp.app/). 6 | 7 | ## Usage 8 | 9 | 1. Click the "Use this template" button to create a new repository. 10 | 2. Enable GitHub Actions to build and deploy your slide: 11 | - Navigate to `https://github.com/{username}/{repository-name}/settings/pages` and select `GitHub Actions` as the source. 12 | 3. Write your slide content in the `slides` directory: 13 | - To split your slide into multiple files, create `{number}_{title}.md` files in the `slides` directory. 14 | - Files are sorted numerically by number and then concatenated. See the "Warning" section for details. 15 | - Files under the `slides` directory will be copied to the `build` directory. Therefore, please place images and other assets here. 16 | 4. Push changes to the `main` branch. 17 | 5. Your slide will be published at `https://.github.io/` 🤗 18 | 19 | ## Customize Theme 20 | 21 | This template uses the [honwaka-theme](https://github.com/abap34/honwaka-theme) as the default theme. You can customize the theme by editing the `Makefile` and `.marprc.yml` files. 22 | 23 | 1. Edit `Makefile`: 24 | - Modify `THEME_NAME` and `THEME_REPO` to your theme. (`THEME_REPO = https://github.com/{username}/{theme-repository}`. and `THEME_NAME = {theme-repository}`) 25 | 2. Edit `.marprc.yml`: 26 | - Change the `theme` field to your desired theme. 27 | 28 | ## Build Slide Locally 29 | 30 | 1. Install the [Marp CLI](https://github.com/marp-team/marp-cli). 31 | 2. Run `make all` to build the slide in the `build/` directory: 32 | - This command generates `.html`, `.pdf`, and `.pptx` files. Individual targets like `make html`, `make pdf`, and `make pptx` are also available. 33 | 3. `make preview` to start a local server and open your slide in a browser for preview. 34 | 35 | ## Warning 36 | 37 | When splitting slides into multiple files, follow these rules: 38 | 39 | - Files are sorted before concatenation based on their names, so using `{number}_{title}.md` is recommended. 40 | - **YAML front matter is only applied from the first file**: 41 | - The first file retains its YAML front matter. Subsequent files are concatenated without YAML front matter. 42 | -------------------------------------------------------------------------------- /check_unused_img.py: -------------------------------------------------------------------------------- 1 | import os 2 | import glob 3 | import re 4 | 5 | pages = glob.glob("**/*.md", recursive=True) 6 | 7 | 8 | def get_used_imgs(page): 9 | with open(page) as f: 10 | content = f.read() 11 | return re.findall(r"!\[.*\]\(img/([^)]*)\)", content) 12 | 13 | 14 | used_imgs = set() 15 | 16 | for page in pages: 17 | used_imgs.update(get_used_imgs(page)) 18 | 19 | 20 | imgs = glob.glob("slides/img/*", recursive=True) 21 | 22 | unused_imgs = [img for img in imgs if img.split("/")[-1] not in used_imgs] 23 | 24 | print("--- Unused images? ---") 25 | for img in unused_imgs: 26 | print(img) 27 | 28 | print("--- Total unused images ---") 29 | print(len(unused_imgs)) 30 | 31 | remove = input("Remove unused images? (y/n): ") 32 | 33 | 34 | if remove == "y": 35 | for img in unused_imgs: 36 | print(f"rm \"{img}\"") 37 | os.system(f"rm \"{img}\"") 38 | else: 39 | print("No images removed.") 40 | 41 | print("Done.") -------------------------------------------------------------------------------- /slides/0_header.md: -------------------------------------------------------------------------------- 1 | --- 2 | marp: true 3 | paginate: true 4 | math: mathjax 5 | theme: honwaka 6 | --- 7 | 8 | 9 | 10 | # Slide Template 11 | ## For Marp Users 12 | 13 | @name 14 | 2023/12/31 15 | 16 | --- -------------------------------------------------------------------------------- /slides/1_intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | marp: true 3 | paginate: true 4 | math: mathjax 5 | theme: honwaka 6 | --- 7 | 8 | 9 | 10 |
Introduction
11 | 12 | # Write Intoduction Here 13 | 14 | 15 | --- -------------------------------------------------------------------------------- /slides/2_main.md: -------------------------------------------------------------------------------- 1 | --- 2 | marp: true 3 | paginate: true 4 | math: mathjax 5 | theme: honwaka 6 | --- 7 | 8 | 9 | 10 | 11 |
Main Topic
12 | 13 | # Write Main Topic Here 14 | 15 | --- 16 | 17 | 18 | # Shiba Inu is one of the most popular dog breeds in Japan. 19 | 20 | ![bg 30%](img/shibainu.png) 21 | 22 | 23 | --- 24 | 25 | 26 | 27 | 28 | $$ 29 | f(x) = \frac{1}{\sqrt{2\pi\sigma^2}} e^{-\frac{(x-\mu)^2}{2\sigma^2}} 30 | $$ 31 | 32 | 33 | ![bg right 90%](img/normal_distribution.png) 34 | 35 | 36 | 37 | 38 | --- -------------------------------------------------------------------------------- /slides/3_outro.md: -------------------------------------------------------------------------------- 1 | --- 2 | marp: true 3 | paginate: true 4 | math: mathjax 5 | theme: honwaka 6 | --- 7 | 8 | 9 | 10 | 11 |
Appendix
12 | 13 | 18 | 19 | # Outro Here 20 | 21 | -------------------------------------------------------------------------------- /slides/img/normal_distribution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abap34/slide-template/a500e3591c610860018ff00c2709104f1e35d884/slides/img/normal_distribution.png -------------------------------------------------------------------------------- /slides/img/shibainu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abap34/slide-template/a500e3591c610860018ff00c2709104f1e35d884/slides/img/shibainu.png --------------------------------------------------------------------------------