@ainame/tuzuru 0.0.20 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +250 -26
- package/{scripts → npm/scripts}/install.js +1 -1
- package/package.json +6 -6
- /package/{bin → npm/bin}/tuzuru.js +0 -0
package/README.md
CHANGED
|
@@ -1,34 +1,258 @@
|
|
|
1
|
-
|
|
1
|
+
# Tuzuru
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+

|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- Installs prebuilt Tuzuru binary for your platform (macOS universal or Linux x64/aarch64) during npm install.
|
|
7
|
-
- Exposes a `tuzuru` executable on your PATH.
|
|
8
|
-
- Sets `TUZURU_RESOURCES` automatically so Tuzuru can locate its resource bundle.
|
|
5
|
+
Tuzuru (綴る) is dead-simple static **blog** generator CLI that uses Git to manage your blog's metadata.
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
- Latest published: `npm i -g @ainame/tuzuru`
|
|
12
|
-
- Or as a dev dependency: `npm i -D @ainame/tuzuru`
|
|
7
|
+
Instead of writing YAML front matter, you just write and save your plain Markdown files to Git. Tuzuru automatically pulls metadata like the publication date and author information from the Git commit history.
|
|
13
8
|
|
|
14
|
-
|
|
15
|
-
- `tuzuru --help`
|
|
16
|
-
- `tuzuru generate`
|
|
17
|
-
- `tuzuru init`
|
|
9
|
+
This means you can focus on what you're writing, not on remembering syntax. It's a simpler, more lightweight way to manage your blog.
|
|
18
10
|
|
|
19
|
-
|
|
20
|
-
- The npm package version should match the Tuzuru GitHub release tag (no `v` prefix). The installer fetches the asset for that tag.
|
|
21
|
-
- If the package version is `0.0.0`, the installer falls back to the latest release via the GitHub API.
|
|
11
|
+
## Motivation
|
|
22
12
|
|
|
23
|
-
|
|
24
|
-
1) Create a Tuzuru release and note the version (e.g. `1.2.3`). Ensure assets exist named:
|
|
25
|
-
- `tuzuru-1.2.3-macos-universal.tar.gz`
|
|
26
|
-
- `tuzuru-1.2.3-linux-x86_64.tar.gz`
|
|
27
|
-
- `tuzuru-1.2.3-linux-aarch64.tar.gz`
|
|
28
|
-
2) Update `npm/package.json` version to the same `1.2.3`.
|
|
29
|
-
3) From the `npm/` directory, run:
|
|
30
|
-
- `npm publish --access public`
|
|
13
|
+
Years ago, I built a blog with Hugo, but eventually stopped updating it. When I recently wanted to start again, I found it tough to remember and re-learn how to use it.
|
|
31
14
|
|
|
32
|
-
|
|
33
|
-
- This package uses the GitHub REST API unauthenticated during installation to resolve the asset URL. On heavily parallelized CI, consider setting `GITHUB_TOKEN` in the environment to increase rate limits.
|
|
15
|
+
I wanted a simple, intuitive blogging tool, but none I tried felt quite right. So, I decided to build my own.
|
|
34
16
|
|
|
17
|
+
Tuzuru is designed with these core principles:
|
|
18
|
+
|
|
19
|
+
* Plain Markdown: No YAML front matter.
|
|
20
|
+
* Simple Routing: A routing system built specifically for blogs.
|
|
21
|
+
* No JavaScript Framework: Lightweight and fast.
|
|
22
|
+
* Single Binary Installation: Avoids environment setup for tools that you may not use day-to-day
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
### Homebrew (macOS)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
brew tap ainame/tuzuru https://github.com/ainame/Tuzuru
|
|
30
|
+
brew install tuzuru
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Manual Build
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
swift build -c release
|
|
37
|
+
cp .build/release/tuzuru /path/to/bin
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Getting started
|
|
41
|
+
|
|
42
|
+
You first need to set up a Git repo locally.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
mkdir new-blog
|
|
46
|
+
cd new-blog
|
|
47
|
+
git init
|
|
48
|
+
|
|
49
|
+
# Initialize a blog project
|
|
50
|
+
# This adds `assets`, `contents`, `templates` directories and `tuzuru.json`
|
|
51
|
+
tuzuru init
|
|
52
|
+
|
|
53
|
+
git add .
|
|
54
|
+
git commit -m "init commit"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Then create a markdown file under the `contents` directory and do `git commit`.
|
|
58
|
+
|
|
59
|
+
``` bash
|
|
60
|
+
emacs contents/first-blog-post.md
|
|
61
|
+
git add contents/first-blog-post.md
|
|
62
|
+
git commit -m "First post"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
When you make `git commit` becomes your post's published date.
|
|
66
|
+
Specifically, the first commit's Author Date for a markdown file under `contents` is the published date and also, author name will be taken from Git's config.
|
|
67
|
+
|
|
68
|
+
Now it's time to build your blog.
|
|
69
|
+
|
|
70
|
+
``` bash
|
|
71
|
+
tuzuru generate
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
You can now see the `blog` directory that can be deployed to GitHub Pages or your favorite HTTP server.
|
|
75
|
+
|
|
76
|
+
For local development, use the built-in serve command:
|
|
77
|
+
|
|
78
|
+
``` bash
|
|
79
|
+
tuzuru serve
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
This starts a local HTTP server at `http://localhost:8000` with auto-regeneration enabled. When you modify source files, the blog will be automatically rebuilt on the next request.
|
|
83
|
+
|
|
84
|
+
### Built-in layout
|
|
85
|
+
|
|
86
|
+
The built-in layout is a great starting point and is easy to customize. It already includes [github-markdown-css](https://github.com/sindresorhus/github-markdown-css) and [highlight.js](https://highlightjs.org/) to make writing tech blog posts a breeze.
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+

|
|
90
|
+
|
|
91
|
+
### Example project structure
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
my-blog/
|
|
95
|
+
├── contents/
|
|
96
|
+
│ ├── hello-world.md # → /hello-world
|
|
97
|
+
│ ├── tech/
|
|
98
|
+
│ │ └── swift-tips.md # → /tech/swift-tips (listed on /tech)
|
|
99
|
+
│ └── unlisted/
|
|
100
|
+
│ └── about.md # → /about (not listed anywhere. You can link to /about from layout.mustache manually)
|
|
101
|
+
├── templates/
|
|
102
|
+
│ ├── layout.mustache
|
|
103
|
+
│ ├── post.mustache
|
|
104
|
+
│ └── list.mustache
|
|
105
|
+
├── assets/
|
|
106
|
+
│ └── main.css
|
|
107
|
+
└── tuzuru.json
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Demo
|
|
111
|
+
|
|
112
|
+
You can see Tuzuru in action with this demo blog hosted on GitHub Pages:
|
|
113
|
+
|
|
114
|
+
- **Live Demo**: [https://ainame.tokyo/tuzuru-demo/](https://ainame.github.io/tuzuru-demo/)
|
|
115
|
+
- **Source Repository**: [https://github.com/ainame/tuzuru-demo](https://github.com/ainame/tuzuru-demo)
|
|
116
|
+
|
|
117
|
+
This demo showcases the built-in layout and demonstrates how Tuzuru generates clean, lightweight blog pages from plain Markdown files.
|
|
118
|
+
|
|
119
|
+
## How it works
|
|
120
|
+
|
|
121
|
+
### Layout and customization
|
|
122
|
+
|
|
123
|
+
Tuzuru supports two types of pages.
|
|
124
|
+
|
|
125
|
+
1. Post - a blog article
|
|
126
|
+
2. List - a listing page generated automatically
|
|
127
|
+
|
|
128
|
+
You can customize these layouts using three Mustache files:
|
|
129
|
+
|
|
130
|
+
* templates/layout.mustache - Base layout
|
|
131
|
+
* templates/post.mustache - main part of post page
|
|
132
|
+
* templates/list.mustache - main part of list page
|
|
133
|
+
|
|
134
|
+
For more on syntax, see the documentation.
|
|
135
|
+
https://docs.hummingbird.codes/2.0/documentation/hummingbird/mustachesyntax/
|
|
136
|
+
|
|
137
|
+
### Listing and Unlisted Pages
|
|
138
|
+
|
|
139
|
+
By default, any Markdown file in the `contents` directory is automatically listed on:
|
|
140
|
+
|
|
141
|
+
* The home page (`/`) based on your configuration.
|
|
142
|
+
* Yearly archive pages (e.g., `/2025`, `/2024`).
|
|
143
|
+
* Category pages for files in subdirectories (e.g., `contents/tech/swift.md` is listed on `/tech`).
|
|
144
|
+
|
|
145
|
+
You can add an unlisted page by placing it in `contents/unlisted/`. These pages won't be listed anywhere automatically, but you can link to them manually from your templates.
|
|
146
|
+
|
|
147
|
+
### Assets
|
|
148
|
+
|
|
149
|
+
The `tuzuru init` command creates an assets directory containing `main.css`. The tuzuru generate command copies all files from this directory to `blog/assets`.
|
|
150
|
+
|
|
151
|
+
To prevent browser cache issues, use the `{{buildVersion}}` variable in your templates.
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
```mustache
|
|
155
|
+
<link rel="stylesheet" href="{{assetsUrl}}main.css?{{buildVersion}}">
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### tuzuru.json
|
|
159
|
+
|
|
160
|
+
`tuzuru.json` is the main configuration file, though you can omit most settings if you stick to the defaults.
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
{
|
|
165
|
+
// `metadata` is the only mandatory section.
|
|
166
|
+
"metadata" : {
|
|
167
|
+
"blogName" : "My Blog",
|
|
168
|
+
"copyright" : "My Blog",
|
|
169
|
+
"description" : "My personal blog", // Meta description for SEO
|
|
170
|
+
"baseUrl" : "https://example.com/", // Production URL
|
|
171
|
+
"locale" : "en_GB" // Affects the published date format
|
|
172
|
+
},
|
|
173
|
+
// `output` for configuring output options
|
|
174
|
+
"output" : {
|
|
175
|
+
"directory" : "blog", // The output directory
|
|
176
|
+
"homePageStyle" : "all", // "all", "pastYear", or a number (last X posts)
|
|
177
|
+
"routingStyle" : "subdirectory" // "subdirectory" (e.g., /hello-world) or "direct" (e.g., /hello-world.html)
|
|
178
|
+
},
|
|
179
|
+
// `sourceLayout` to customize the default directory structure (typically not needed)
|
|
180
|
+
"sourceLayout" : {
|
|
181
|
+
"assets" : "assets",
|
|
182
|
+
"contents" : "contents",
|
|
183
|
+
"imported" : "contents/imported",
|
|
184
|
+
"templates" : {
|
|
185
|
+
"layout" : "templates/layout.mustache",
|
|
186
|
+
"list" : "templates/list.mustache",
|
|
187
|
+
"post" : "templates/post.mustache"
|
|
188
|
+
},
|
|
189
|
+
"unlisted" : "contents/unlisted"
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Import posts from Hugo project
|
|
195
|
+
|
|
196
|
+
You can import Markdown files from a Hugo project. Tuzuru will parse the YAML front matter to get the title, author, and date, then remove it. Each imported Markdown file will be added as an individual Git commit.
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
tuzuru import /path/to/import-target-dir # import them to ./contents/imported by default
|
|
200
|
+
tuzuru import /path/to/import-target-dir --destination /path/to/import
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Amend published date or author
|
|
204
|
+
|
|
205
|
+
Need to change a post's published date or author without rewriting your Git history? Use the amend command.
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# Update published date
|
|
209
|
+
tuzuru amend contents/my-post.md --published-at "2023-12-01"
|
|
210
|
+
|
|
211
|
+
# Update author
|
|
212
|
+
tuzuru amend contents/my-post.md --author "New Author"
|
|
213
|
+
|
|
214
|
+
# Update both
|
|
215
|
+
tuzuru amend contents/my-post.md --published-at "2023-12-01 10:30:00 +0900" --author "New Author"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
The command supports flexible date formats:
|
|
219
|
+
|
|
220
|
+
- `2023-12-01` (date only)
|
|
221
|
+
- `2023-12-01 10:30:00` (date and time)
|
|
222
|
+
- `2023-12-01T10:30:00Z` (ISO 8601 UTC)
|
|
223
|
+
- `2023-12-01 10:30:00 +0900` (with timezone)
|
|
224
|
+
|
|
225
|
+
This command creates a special marker commit that Tuzuru recognizes for post metadata, leaving your history clean.
|
|
226
|
+
|
|
227
|
+
## Local Development Server
|
|
228
|
+
|
|
229
|
+
Tuzuru includes a built-in HTTP server for local development:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
# Basic usage (serves on port 8000)
|
|
233
|
+
tuzuru serve
|
|
234
|
+
|
|
235
|
+
# Custom port
|
|
236
|
+
tuzuru serve --port 3000
|
|
237
|
+
|
|
238
|
+
# Custom directory (default is 'blog')
|
|
239
|
+
tuzuru serve --directory my-output
|
|
240
|
+
|
|
241
|
+
# Custom config file
|
|
242
|
+
tuzuru serve --config my-config.json
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Auto-regeneration
|
|
246
|
+
|
|
247
|
+
The serve command automatically watches for changes in your source files and regenerates the blog when needed:
|
|
248
|
+
|
|
249
|
+
- **Content files**: Watches `contents/` and `contents/unlisted/` directories
|
|
250
|
+
- **Asset files**: Watches the `assets/` directory
|
|
251
|
+
- **Templates**: Watches template files for changes
|
|
252
|
+
|
|
253
|
+
When files are modified, the blog is regenerated on the next HTTP request, providing a seamless development experience without manual rebuilds.
|
|
254
|
+
|
|
255
|
+
## Build Requirements
|
|
256
|
+
|
|
257
|
+
- Swift 6.1+
|
|
258
|
+
- macOS v15+
|
|
@@ -27,7 +27,7 @@ function fail(msg) {
|
|
|
27
27
|
process.exit(1);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
const pkg = require('
|
|
30
|
+
const pkg = require('../../package.json');
|
|
31
31
|
const version = (pkg.version || '').trim();
|
|
32
32
|
if (!version || version === '0.0.0') {
|
|
33
33
|
log('Package version is 0.0.0; attempting to install latest release via GitHub API');
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainame/tuzuru",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Tuzuru static blog generator (npm wrapper around prebuilt binaries)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
7
7
|
"bin": {
|
|
8
|
-
"tuzuru": "bin/tuzuru.js"
|
|
8
|
+
"tuzuru": "npm/bin/tuzuru.js"
|
|
9
9
|
},
|
|
10
10
|
"os": [
|
|
11
11
|
"darwin",
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
"url": "https://github.com/ainame/Tuzuru/issues"
|
|
28
28
|
},
|
|
29
29
|
"scripts": {
|
|
30
|
-
"postinstall": "node scripts/install.js"
|
|
30
|
+
"postinstall": "node npm/scripts/install.js"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
|
-
"bin/",
|
|
34
|
-
"scripts/",
|
|
35
|
-
"vendor/",
|
|
33
|
+
"npm/bin/",
|
|
34
|
+
"npm/scripts/",
|
|
35
|
+
"npm/vendor/",
|
|
36
36
|
"README.md"
|
|
37
37
|
]
|
|
38
38
|
}
|
|
File without changes
|