|
1 | | - |
2 | 1 | <div align="center"> |
3 | | - <h1 align="center"><b>mdbook-gitinfo</b></h1> |
| 2 | + <h1 align="center"><b>mdbook-gitinfo</b></h1> |
4 | 3 | </div> |
5 | 4 |
|
6 | 5 | <p align="center"> |
|
19 | 18 | <img src="https://img.shields.io/badge/Built%20with-Rust-orange?logo=rust&style=for-the-badge" alt="Built with Rust" /> |
20 | 19 | </p> |
21 | 20 |
|
| 21 | +An <a href="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/rust-lang/mdBook">mdBook</a> preprocessor that injects Git metadata (commit hash, full hash, tag, date/time, branch) into each chapter — as a header, a footer, or both — with flexible templates, alignment, and CSS-style margins. |
22 | 22 |
|
23 | | -An [mdBook](https://github.com/rust-lang/mdBook) preprocessor that injects Git metadata (e.g., commit hash, date, tag) into your rendered book. This is useful for displaying build provenance or version information. |
| 23 | +--- |
24 | 24 |
|
25 | 25 | ## Features |
26 | 26 |
|
27 | | -- Injects the latest Git commit information for each/per chapter/subchapter. |
28 | | -- Fully configurable output format using template variables. |
29 | | -- Supports date and time formatting. |
30 | | -- Renders a styled footer below each chapter with Git metadata. |
31 | | -- Supports the `html` renderer. |
| 27 | +- Injects the latest Git commit information **per chapter** (and subchapters). |
| 28 | +- **Header and/or footer** placement with independent configuration. |
| 29 | +- Message templating via `message.header` / `message.footer` / `message.both`. |
| 30 | +- Split **alignment** for header/footer or a single legacy value. |
| 31 | +- **CSS-style margins (TRBL)** with per-placement overrides and shorthand. |
| 32 | +- Date/time formatting (via `date-format`, `time-format`). |
| 33 | +- Optional **hyperlinks** for commit and branch to your remote provider. |
| 34 | +- Branch verification with graceful fallback to `"main"`. |
| 35 | +- Only the `html` renderer is supported. |
| 36 | + |
| 37 | +--- |
32 | 38 |
|
33 | 39 | ## Installation |
34 | 40 |
|
35 | | -From package manager: |
| 41 | +From crates.io: |
36 | 42 |
|
37 | 43 | ```sh |
38 | 44 | cargo install mdbook-gitinfo |
39 | 45 | ``` |
40 | 46 |
|
41 | | -Clone this repository and install it using Cargo: |
| 47 | +From source (in this repo): |
42 | 48 |
|
43 | 49 | ```sh |
44 | 50 | cargo install --path . |
45 | 51 | ``` |
46 | 52 |
|
47 | | -Make sure the binary (`mdbook-gitinfo`) is in your `PATH`. |
| 53 | +Ensure the `mdbook-gitinfo` binary is on your `PATH`. |
48 | 54 |
|
49 | | -## Configuration |
| 55 | +--- |
50 | 56 |
|
51 | | -Add the following to your book.toml: |
| 57 | +## Quick start |
| 58 | + |
| 59 | +Add to `book.toml`: |
52 | 60 |
|
53 | 61 | ```toml |
54 | 62 | [preprocessor.gitinfo] |
55 | 63 | enable = true |
56 | | -template = "Date: {{date}}{{sep}}branch: {{branch}}{{sep}}commit: {{hash}}" |
57 | | -separator = " • " |
58 | | -font-size = "0.8em" |
| 64 | + |
| 65 | +# choose placement(s) |
| 66 | +header = false # default: false |
| 67 | +footer = true # default: true |
| 68 | + |
| 69 | +# common formatting |
| 70 | +font-size = "0.9em" |
| 71 | +separator = " • " |
59 | 72 | date-format = "%Y-%m-%d" |
60 | | -time-format = "%H:%M:%S" |
61 | | -branch = "main" # default is main, therefore optional |
| 73 | +time-format = "%H:%M" |
| 74 | +branch = "main" |
| 75 | +hyperlink = true # make hash/branch clickable when possible |
| 76 | + |
| 77 | +[preprocessor.gitinfo.message] |
| 78 | +footer = "Built {{date}}{{sep}}commit: {{hash}}" |
| 79 | +``` |
| 80 | + |
| 81 | +--- |
| 82 | + |
| 83 | +## Configuration via **dotted keys** (with table equivalents) |
| 84 | + |
| 85 | +You can configure options either with **dotted keys** under `[preprocessor.gitinfo]` or with nested **tables** like `[preprocessor.gitinfo.message]`. Use **one style consistently** for readability; both work and merge as expected. |
| 86 | + |
| 87 | +### Message templates |
| 88 | + |
| 89 | +**Placeholders:** `{{hash}}`, `{{long}}`, `{{tag}}`, `{{date}}`, `{{sep}}`, `{{branch}}` |
| 90 | +**Precedence (per placement):** `message.header/footer` ➝ `message.both` ➝ legacy `header_message/footer_message` ➝ legacy `template`. |
| 91 | + |
| 92 | +> If a placement-specific template is set (`message.header` or `message.footer`), `message.both` is ignored <em>for that placement</em>. |
| 93 | +
|
| 94 | +**Dotted keys:** |
| 95 | +```toml |
| 96 | +[preprocessor.gitinfo] |
| 97 | +message.header = "Last updated: <em>{{date}}</em>" |
| 98 | +message.footer = "branch: {{branch}}{{sep}}commit: {{hash}}" |
| 99 | +message.both = "<em>{{date}}</em>{{sep}}branch: {{branch}}" |
| 100 | +``` |
| 101 | + |
| 102 | +**Table form (equivalent):** |
| 103 | +```toml |
| 104 | +[preprocessor.gitinfo.message] |
| 105 | +header = "Last updated: <em>{{date}}</em>" |
| 106 | +footer = "branch: {{branch}}{{sep}}commit: {{hash}}" |
| 107 | +both = "<em>{{date}}</em>{{sep}}branch: {{branch}}" |
| 108 | +``` |
| 109 | + |
| 110 | +--- |
| 111 | + |
| 112 | +### Align |
| 113 | + |
| 114 | +Values: `"left" | "center" | "right"` (default **center** for both). |
| 115 | + |
| 116 | +**Resolution:** `align.header` and/or `align.footer` override `align.both`. |
| 117 | +If neither is set, both default to `"center"`. |
| 118 | + |
| 119 | +**Dotted keys:** |
| 120 | +```toml |
| 121 | +[preprocessor.gitinfo] |
| 122 | +align.header = "left" |
| 123 | +align.footer = "right" |
| 124 | +align.both = "center" # used only for any placement not explicitly set |
62 | 125 | ``` |
63 | 126 |
|
64 | | -### Example Output |
| 127 | +**Table form (equivalent):** |
| 128 | +```toml |
| 129 | +[preprocessor.gitinfo.align] |
| 130 | +both = "center" |
| 131 | +header = "left" |
| 132 | +footer = "right" |
| 133 | +``` |
| 134 | + |
| 135 | +--- |
| 136 | + |
| 137 | +### Margin (TRBL) |
| 138 | + |
| 139 | +Margins accept CSS-style **T**op **R**ight **B**ottom **L**eft values. Units can be `px`, `em`, etc., or unitless (`0`). |
| 140 | +You can provide: |
| 141 | +- a **single value** (applies to all sides), |
| 142 | +- an **array** with 1–4 items (CSS shorthand), |
| 143 | +- or **named sides** (`top/right/bottom/left`). |
| 144 | + |
| 145 | +**Resolution:** `margin.header` / `margin.footer` override `margin.both` per placement. |
| 146 | + |
| 147 | +**Defaults (when unset):** |
| 148 | +- **Header:** `["0", "0", "2em", "0"]` (space **below** the header block) |
| 149 | +- **Footer:** `["2em", "0", "0", "0"]` (space **above** the footer block) |
| 150 | +- Legacy `margin-top` (if present) is treated as **footer top** spacing. |
65 | 151 |
|
66 | | -With the above configuration, this footer will be injected: |
| 152 | +**Dotted keys (array shorthand):** |
| 153 | +```toml |
| 154 | +[preprocessor.gitinfo] |
| 155 | +margin.header = ["0", "0", "1.25em", "0"] # T R B L |
| 156 | +margin.footer = ["2em", "0", "0", "0"] # T R B L |
| 157 | +margin.both = "1em" # all sides = 1em unless overridden |
| 158 | +``` |
| 159 | + |
| 160 | +**Dotted keys (named sides):** |
| 161 | +```toml |
| 162 | +[preprocessor.gitinfo] |
| 163 | +margin.header.top = "5em" |
| 164 | +margin.footer.bottom = "2em" |
| 165 | +margin.both.left = "0.5em" |
| 166 | +``` |
| 167 | + |
| 168 | +**Table form (equivalent):** |
| 169 | +```toml |
| 170 | +[preprocessor.gitinfo.margin] |
| 171 | +both = ["1em"] # all sides = 1em |
| 172 | +header = ["0", "0", "1.25em", "0"] # T R B L |
| 173 | +footer = { top = "2em" } # named sides form |
| 174 | +``` |
| 175 | + |
| 176 | +--- |
| 177 | + |
| 178 | +## Placeholders |
| 179 | + |
| 180 | +Use these tokens inside your message templates: |
| 181 | + |
| 182 | +- `{{hash}}` — short commit hash |
| 183 | +- `{{long}}` — full commit hash |
| 184 | +- `{{tag}}` — nearest tag |
| 185 | +- `{{date}}` — commit date and time (combined using your `date-format` and `time-format`) |
| 186 | +- `{{sep}}` — the configured separator (e.g., `" • "`) |
| 187 | +- `{{branch}}` — branch name |
| 188 | + |
| 189 | +--- |
| 190 | + |
| 191 | +## Example output |
| 192 | + |
| 193 | +With the configuration above, a footer will be injected similar to: |
67 | 194 |
|
68 | 195 | ```html |
69 | | -<footer> |
70 | | - <span class="gitinfo-footer" style="font-size:0.8em;..."> |
71 | | - Date: 2025-06-23 16:19:28 • branch: main • commit: 2160ec5 |
72 | | - </span> |
| 196 | +<footer class="gitinfo-footer" style="font-size:0.8em;padding:4px;margin:2em 0 0 0;text-align:center;display:block;"> |
| 197 | + branch: <b><a href="somelinktosomeawesomerepo">main</a></b> • commit: <a href="somelinktosomeawesomerepo">9296b47</a> |
73 | 198 | </footer> |
74 | 199 | ``` |
75 | 200 |
|
76 | | -> [!NOTE] |
77 | | -> date and time formatting use chrono format specifiers |
78 | | -> | Format | Meaning | Example | |Format | Meaning | Example | |
79 | | -> | ------ | ---------------------------- | -------- |-| ------ | ------------------------------ | -------- | |
80 | | -> | `%Y` | Year with century | `2025` | | `%H` | Hour (00-23) | `14` | |
81 | | -> | `%y` | Year without century (00-99) | `25` | | `%I` | Hour (01-12) | `02` | |
82 | | -> | `%m` | Month number (01-12) | `06` | | `%p` | AM/PM | `PM` | |
83 | | -> | `%b` | Abbreviated month name | `Jun` | | `%M` | Minute (00-59) | `05` | |
84 | | -> | `%B` | Full month name | `June` | | `%S` | Second (00-60, leap-sec aware) | `09` | |
85 | | -> | `%d` | Day of month (01-31) | `24` | | `%f` | Microseconds (000000-999999) | `123456` | |
86 | | -> | `%e` | Day of month, space-padded | `24` | | `%z` | +hhmm timezone offset | `+0100` | |
87 | | -> | `%a` | Abbreviated weekday | `Mon` | | `%:z` | +hh\:mm timezone offset | `+01:00` | |
88 | | -> | `%A` | Full weekday name | `Monday` | | `%Z` | Time zone name | `BST` | |
89 | | -> | `%j` | Day of year (001–366) | `176` | |||| |
| 201 | +> The preprocessor inserts blank lines around injected blocks so Markdown headings/paragraphs render correctly. |
90 | 202 |
|
| 203 | +--- |
91 | 204 |
|
92 | | -## Template Variables |
93 | | -You can use the following placeholders in the template string: |
| 205 | +## Formatting & Git options |
94 | 206 |
|
95 | | -- `{{hash}}`: Short commit hash (`git rev-parse --short HEAD`) |
| 207 | +- `font-size` — e.g., `"0.8em"` |
| 208 | +- `separator` — string used by `{{sep}}` |
| 209 | +- `date-format`, `time-format` — chrono formatting strings (examples below) |
| 210 | +- `branch` — default `"main"`. If the branch isn’t found, the preprocessor falls back to `"main"` with a warning. |
| 211 | +- `hyperlink` — when `true`, `{{hash}}` and `{{branch}}` are linked to your provider (derived from CI env vars like `GITHUB_SERVER_URL`/`GITHUB_REPOSITORY`, `CI_SERVER_URL`/`CI_PROJECT_PATH`, Bitbucket vars, or `remote.origin.url`). |
96 | 212 |
|
97 | | -- `{{long}}`: Full commit hash |
| 213 | +### Common chrono format specifiers |
98 | 214 |
|
99 | | -- `{{tag}}`: Git tag (from `git describe`) |
| 215 | +For DateTime format specifiers refer to `chrono`::`format`: |
| 216 | +- [https://docs.rs/chrono/latest/chrono/format/strftime/index.html](https://docs.rs/chrono/latest/chrono/format/strftime/index.html) |
100 | 217 |
|
101 | | -- `{{date}}`: Timestamp of the latest commit, formatted |
| 218 | +--- |
102 | 219 |
|
103 | | -- `{{sep}}`: Separator (defaults to " • ") |
| 220 | +## CI note (GitHub Actions) |
104 | 221 |
|
105 | | -## .github/workflow/... |
106 | | - |
107 | | -In order for mdbook-gitinfo to reference the correct commit whilst using `actions/checkout@v4`, set `fetch-depth` as `0`: |
| 222 | +When using `actions/checkout@v4`, set `fetch-depth: 0` so the plugin can access commit history: |
108 | 223 |
|
109 | 224 | ```yml |
110 | | -... |
111 | 225 | jobs: |
112 | 226 | deploy: |
113 | 227 | runs-on: ubuntu-22.04 |
114 | | - concurrency: |
115 | | - group: ${{ github.workflow }}-${{ github.ref }} |
116 | 228 | steps: |
117 | 229 | - uses: actions/checkout@v4 |
118 | 230 | with: |
119 | 231 | fetch-depth: 0 |
120 | | -... |
| 232 | + # … your build & deploy steps |
121 | 233 | ``` |
122 | 234 |
|
| 235 | +--- |
| 236 | + |
123 | 237 | ## Compatibility |
124 | 238 |
|
125 | | -- `mdbook-gitinfo` is tested with mdbook 0.4.x. |
| 239 | +- Tested with **mdBook 0.4.x**. |
| 240 | +- Renderer support: **html** only. |
126 | 241 |
|
127 | | -- Only the html renderer is supported. |
| 242 | +--- |
128 | 243 |
|
129 | 244 | ## License |
130 | 245 |
|
131 | 246 | [Apache-2.0](LICENSE.md) |
132 | 247 |
|
| 248 | +--- |
| 249 | + |
133 | 250 | ## Author |
134 | 251 |
|
135 | | -[CompEng0001](https://github.com/CompEng0001) |
| 252 | +[CompEng0001](https://github.com/CompEng0001) |
0 commit comments