├── .gitattributes
├── .gitignore
├── start.sh
├── freeze.json
├── LICENSE
├── flake.lock
├── flake.nix
├── README-ja.md
├── README.md
└── gallery
├── npm-install.svg
├── npm-run-dev.svg
└── tree.svg
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.svg -diff
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /*.svg
2 | result*
3 |
--------------------------------------------------------------------------------
/start.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | exec tmux new-session 'fish --init-command="function fish_prompt; echo '"'"'\$'" '"'; end"'
--------------------------------------------------------------------------------
/freeze.json:
--------------------------------------------------------------------------------
1 | {
2 | "theme": "catppuccin-mocha",
3 | "window": false,
4 | "border": {
5 | "radius": 0,
6 | "width": 0,
7 | "color": "#515151"
8 | },
9 | "shadow": false,
10 | "padding": [20, 40, 20, 20],
11 | "margin": "0",
12 | "font": {
13 | "family": "JetBrainsMono Nerd Font Mono",
14 | "size": 12
15 | },
16 | "line_height": 1.2
17 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 suin
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 |
--------------------------------------------------------------------------------
/flake.lock:
--------------------------------------------------------------------------------
1 | {
2 | "nodes": {
3 | "flake-utils": {
4 | "inputs": {
5 | "systems": "systems"
6 | },
7 | "locked": {
8 | "lastModified": 1731533236,
9 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
10 | "owner": "numtide",
11 | "repo": "flake-utils",
12 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
13 | "type": "github"
14 | },
15 | "original": {
16 | "owner": "numtide",
17 | "repo": "flake-utils",
18 | "type": "github"
19 | }
20 | },
21 | "nixpkgs": {
22 | "locked": {
23 | "lastModified": 1750365781,
24 | "narHash": "sha256-XE/lFNhz5lsriMm/yjXkvSZz5DfvKJLUjsS6pP8EC50=",
25 | "owner": "NixOS",
26 | "repo": "nixpkgs",
27 | "rev": "08f22084e6085d19bcfb4be30d1ca76ecb96fe54",
28 | "type": "github"
29 | },
30 | "original": {
31 | "owner": "NixOS",
32 | "ref": "nixos-unstable",
33 | "repo": "nixpkgs",
34 | "type": "github"
35 | }
36 | },
37 | "root": {
38 | "inputs": {
39 | "flake-utils": "flake-utils",
40 | "nixpkgs": "nixpkgs"
41 | }
42 | },
43 | "systems": {
44 | "locked": {
45 | "lastModified": 1681028828,
46 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
47 | "owner": "nix-systems",
48 | "repo": "default",
49 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
50 | "type": "github"
51 | },
52 | "original": {
53 | "owner": "nix-systems",
54 | "repo": "default",
55 | "type": "github"
56 | }
57 | }
58 | },
59 | "root": "root",
60 | "version": 7
61 | }
62 |
--------------------------------------------------------------------------------
/flake.nix:
--------------------------------------------------------------------------------
1 | {
2 | inputs = {
3 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
4 | flake-utils.url = "github:numtide/flake-utils";
5 | };
6 |
7 | outputs =
8 | {
9 | self,
10 | nixpkgs,
11 | flake-utils,
12 | }:
13 | flake-utils.lib.eachDefaultSystem (
14 | system:
15 | let
16 | pkgs = import nixpkgs {
17 | inherit system;
18 | };
19 |
20 | tools = with pkgs; [
21 | tmux
22 | charm-freeze
23 | fishMinimal
24 | fontconfig
25 | nerd-fonts.jetbrains-mono
26 | ];
27 | in
28 | {
29 | devShells = {
30 | default = pkgs.mkShell {
31 | packages = tools ++ [ pkgs.inkscape ];
32 | FONTCONFIG_PATH = "${pkgs.fontconfig.out}/etc/fonts";
33 | };
34 | start = pkgs.mkShell {
35 | packages = tools;
36 | shellHook = ''
37 | ./start.sh
38 | '';
39 | };
40 | };
41 | packages = {
42 | terminal = pkgs.writeShellApplication {
43 | name = "terminal";
44 | runtimeInputs = with pkgs; [
45 | fishMinimal
46 | tmux
47 | ];
48 | text = ''
49 | tmux new-session 'fish --init-command="function fish_prompt; echo '"'"'\$'" '"'; end"'
50 | '';
51 | };
52 | # Takes screenshots of the terminal instance
53 | # usage: capture -o output.svg
54 | # TODO: make excluded prompt lines configurable here
55 | capture = pkgs.writeShellApplication {
56 | name = "capture";
57 | runtimeInputs = tools;
58 | runtimeEnv.FONTCONFIG_PATH = "${pkgs.fontconfig}/etc/fonts";
59 | text = ''
60 | tmux capture-pane -pet 0 | freeze -c ${self}/freeze.json "$@"
61 | '';
62 | };
63 | };
64 | }
65 | );
66 | }
67 |
--------------------------------------------------------------------------------
/README-ja.md:
--------------------------------------------------------------------------------
1 | # terminal-svg-screenshot
2 |
3 | きれいなSVGスクリーンショットを作成するためのツールです。ターミナルの出力をSVG形式で保存することで、高品質かつ編集可能なスクリーンショットを簡単に作成できます。ドキュメントやブログ記事の作成に最適です。
4 |
5 | ## 必要なもの
6 |
7 | - nix(flakeが使える環境)
8 | - ウィンドウサイズを調整できるターミナルアプリ
9 | - バイザー設定などで幅が固定されていないものを使用してください
10 | - 推奨:Ghostty、Hyper
11 | - `brew install --cask ghostty`
12 | - `brew install --cask hyper`
13 |
14 | ## 使い方
15 |
16 | ### 1. リポジトリのセットアップ
17 |
18 | 以下のコマンドでリポジトリをクローンします:
19 |
20 | ```zsh
21 | git clone https://github.com/suin/terminal-svg-screenshot.git
22 | cd terminal-svg-screenshot
23 | ```
24 |
25 | ### 2. スクリーンショットの作成
26 |
27 | 2つのターミナルを使用します:
28 |
29 | 1. モデルターミナル:撮影したいコマンドを実行するターミナル
30 | 2. カメラマンターミナル:SVGファイルを出力するターミナル
31 |
32 | #### モデルターミナルの準備
33 |
34 | 1. ターミナルアプリを開きます(iTerm2ではなく、ウインドウサイズが調整できるアプリを使用してください)
35 | 2. 以下のコマンドを実行します:
36 | ```zsh
37 | nix develop .#start
38 | ```
39 | 3. 撮影したいコマンドを実行します
40 | 4. ターミナルウィンドウにちょうど収まるようにウインドウサイズと文字サイズを調整します
41 | 5. 画面構成が決まったら、そのままの状態にしておきます
42 |
43 | #### スクリーンショットの撮影
44 |
45 | カメラマンターミナルで以下の手順を実行します:
46 |
47 | 1. 新しいターミナルを開き、以下のコマンドを実行します:
48 | ```zsh
49 | nix develop
50 | ```
51 |
52 | 2. SVGファイルを生成します:
53 | ```zsh
54 | tmux capture-pane -pet 0 | freeze -c ./freeze.json -o output.svg
55 | ```
56 |
57 | プロンプト行の調整が必要な場合は、以下のコマンドを使用します:
58 |
59 | - 最後の行のプロンプトを除外:
60 | ```zsh
61 | tmux capture-pane -pet 0 | head -n -1 | freeze -c ./freeze.json -o output.svg
62 | ```
63 |
64 | - 末尾行数の微調整(出力を確認しながら行数を調整):
65 | ```zsh
66 | tmux capture-pane -pet 0 | head -n -10
67 | ```
68 |
69 | #### SVGの後処理
70 |
71 | 環境によってフォントの問題が発生することを防ぐため、テキストをアウトライン化することをお勧めします:
72 |
73 | ```zsh
74 | inkscape --export-text-to-path output.svg -o output-outlined.svg
75 | ```
76 |
77 | 必要に応じて、FigmaやIllustratorで追加の編集を行うことができます。
78 |
79 | ## カスタマイズ
80 |
81 | ### テーマの設定
82 |
83 | `freeze.json`でターミナルの見た目を設定できます:
84 |
85 | - 背景色
86 | - 文字色
87 | - 文字サイズ
88 | - その他の設定
89 |
90 | 詳細は[freezeのドキュメント](https://github.com/charmbracelet/freeze)を参照してください。
91 | 利用可能なテーマは[こちら](https://xyproto.github.io/splash/docs/all.html)で確認できます。
92 |
93 | ### フォントの変更
94 |
95 | デフォルトではJetBrainsMono Nerd Font Monoを使用しています。フォントを変更する場合は:
96 |
97 | 1. `freeze.json`の`font`設定を変更します
98 | 2. `flake.nix`に使用したいフォントを追加します:
99 |
100 | ```nix
101 | tools = with pkgs; [
102 | tmux
103 | charm-freeze
104 | fish
105 | inkscape
106 | fontconfig
107 | nerd-fonts.jetbrains-mono
108 | # ここに新しいフォントを追加
109 | ];
110 | ```
111 |
112 | ## ギャラリー
113 |
114 | 以下のスクリーンショットは、このリポジトリのサンプルコマンドを使用して作成されました:
115 |
116 | 
117 |
118 | 
119 |
120 | 
121 |
122 | 
123 |
124 | 
125 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # terminal-svg-screenshot
2 |
3 | A tool for creating beautiful SVG screenshots. Easily capture terminal output in SVG format to create high-quality, editable screenshots perfect for documentation and blog posts.
4 |
5 | [日本語版のREADME](README-ja.md)
6 |
7 | ## Requirements
8 |
9 | - nix (with flakes enabled)
10 | - Terminal app with adjustable window size
11 | - Use a terminal that doesn't have fixed width settings (like visor mode)
12 | - Recommended: Ghostty, Hyper
13 | - `brew install --cask ghostty`
14 | - `brew install --cask hyper`
15 |
16 | ## Usage
17 |
18 | ### 1. Repository Setup
19 |
20 | Clone the repository with the following commands:
21 |
22 | ```zsh
23 | git clone https://github.com/suin/terminal-svg-screenshot.git
24 | cd terminal-svg-screenshot
25 | ```
26 |
27 | ### 2. Creating Screenshots
28 |
29 | You'll need two terminal windows:
30 |
31 | 1. Model Terminal: The terminal where you'll execute the commands you want to capture
32 | 2. Photographer Terminal: The terminal that will output the SVG file
33 |
34 | #### Preparing the Model Terminal
35 |
36 | 1. Open your terminal app (avoid iTerm2; use an app that allows window size adjustment)
37 | 2. Run the following command:
38 | ```zsh
39 | nix develop .#start
40 | ```
41 | 3. Execute the commands you want to capture
42 | 4. Adjust the window size and font size to fit your content perfectly
43 | 5. Keep the window configuration as is once you're satisfied
44 |
45 | #### Taking the Screenshot
46 |
47 | In the Photographer Terminal, follow these steps:
48 |
49 | 1. Open a new terminal and run:
50 | ```zsh
51 | nix develop
52 | ```
53 |
54 | 2. Generate the SVG file:
55 | ```zsh
56 | tmux capture-pane -pet 0 | freeze -c ./freeze.json -o output.svg
57 | ```
58 |
59 | For prompt line adjustments, use these commands:
60 |
61 | - To exclude the last prompt line:
62 | ```zsh
63 | tmux capture-pane -pet 0 | head -n -1 | freeze -c ./freeze.json -o output.svg
64 | ```
65 |
66 | - To fine-tune the number of trailing lines (adjust while checking output):
67 | ```zsh
68 | tmux capture-pane -pet 0 | head -n -10
69 | ```
70 |
71 | #### SVG Post-processing
72 |
73 | To prevent font issues across different environments, it's recommended to convert text to outlines:
74 |
75 | ```zsh
76 | inkscape --export-text-to-path output.svg -o output-outlined.svg
77 | ```
78 |
79 | You can perform additional editing in Figma or Illustrator if needed.
80 |
81 | ## Customization
82 |
83 | ### Theme Configuration
84 |
85 | Customize the terminal appearance in `freeze.json`:
86 |
87 | - Background color
88 | - Text color
89 | - Font size
90 | - Other settings
91 |
92 | For more details, refer to the [freeze documentation](https://github.com/charmbracelet/freeze).
93 | Available themes can be found [here](https://xyproto.github.io/splash/docs/all.html).
94 |
95 | ### Changing Fonts
96 |
97 | The default font is JetBrainsMono Nerd Font Mono. To change the font:
98 |
99 | 1. Modify the `font` setting in `freeze.json`
100 | 2. Add your desired font to `flake.nix`:
101 |
102 | ```nix
103 | tools = with pkgs; [
104 | tmux
105 | charm-freeze
106 | fish
107 | inkscape
108 | fontconfig
109 | nerd-fonts.jetbrains-mono
110 | # Add your new font here
111 | ];
112 | ```
113 |
114 | ## Gallery
115 |
116 | The following screenshots were created using sample commands from this repository:
117 |
118 | 
119 |
120 | 
121 |
122 | 
123 |
124 | 
125 |
126 | 
127 |
--------------------------------------------------------------------------------
/gallery/npm-install.svg:
--------------------------------------------------------------------------------
1 |
2 |
94 |
--------------------------------------------------------------------------------
/gallery/npm-run-dev.svg:
--------------------------------------------------------------------------------
1 |
2 |
126 |
--------------------------------------------------------------------------------
/gallery/tree.svg:
--------------------------------------------------------------------------------
1 |
2 |
348 |
--------------------------------------------------------------------------------