mdbook-theme 0.1.1

A preprocessor and a backend to config theme for mdbook, especially making a pagetoc on the right and setting full color themes from the offical ace editor
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
A preprocessor and a backend to config themes for [mdbook](https://github.com/rust-lang/mdBook), 
especially making a pagetoc on the right and setting full color themes from the offical 
[ace](https://github.com/ajaxorg/ace) editor.

# installation

`mdbook-theme` package includes two CLI :
a preprocess `mdbook-theme` and a backend `mdbook-theme-ace` .

What they are actually doing is simply replacing values within files given by mdbook default or user.

You can get these via:

1. `cargo install`

```cmd
cargo install mdbook-theme
```

2. building the latest from source

```cmd
git clone https://github.com/zjp-CN/mdbook-theme.git
cd mdbook-theme
cargo build
```

3. download and unzip a [complied release](https://github.com/zjp-CN/mdbook-theme/releases),
put them in your system path.

Any suggestion or contribution is greatly welcomed.

# mdbook-theme

This preprocessor does a little more work to integrate [mdBook-pagetoc](https://github.com/JorelAli/mdBook-pagetoc) (pure js/css/hbs files) with [mdBook](https://github.com/rust-lang/mdBook) which currently lacks a pagetoc (to jump within titles of the opened page) .

And it makes some modification of css easily done just via a few lines in book.toml ( fine with or without `pagetoc` ), for example, common layout, fontsize and color settings.

* If you just want a pagetoc on the right, use this in `book.timl` :

```toml
[preprocessor.theme]
pagetoc = true

[output.html]
additional-css = ["theme/pagetoc.css"] 
additional-js = ["theme/pagetoc.js"] 
```

* If you want to config more by yourself, refer to the fully supported configs as listed below:

```toml
[preprocessor.theme]
# enable pagetoc (toc on the left)
pagetoc = true

# some variables related (defined in theme/css/variables.css)
# `content-max-width` + `pagetoc-width` = 95% seems the best
pagetoc-width = "13%"
content-max-width = "82%"
pagetoc-fontsize = "14.5px"
sidebar-width = "300px"
menu-bar-height = "40px"  # memu-bar = the bar on the top
page-padding = "15px"
mobile-content-max-width = "98%"

# layout 
content-padding = "0 10px"
content-main-margin-left = "2%"
content-main-margin-right = "2%"
nav-chapters-max-width = "auto"
nav-chapters-min-width = "auto"
chapter-line-height = "2em"
section-line-height = "1.5em"

# modify some fontsizes
root-font-size = "70%"    # control the main font-size
body-font-size = "1.5rem"
code-font-size = "0.9em"
sidebar-font-size = "1em" # sidebar = toc on the left

# modify some colors under ayu/coal/light/navy/rust theme
coal-inline-code-color = "#ffb454"
light-inline-code-color = "#F42C4C"
navy-inline-code-color = "#ffb454"
rust-inline-code-color = "#F42C4C"
light-links = "#1f1fff"
rust-links = "#1f1fff"

# if true, never read and touch the files in theme dir
turn-off = false

# If you set `pagetoc = true`, you need to set the following as well:
[output.html]
theme = "theme" # this is the default if not explicitly set
additional-css = ["theme/pagetoc.css"] # This tool will produce it!
additional-js = ["theme/pagetoc.js"]   # This tool will produce it!
```

Attention: local files in `theme` dir are prior. So if you need or modify a theme based on the
complete default this tool provide, removing the whole `theme` dir is recommended.

# mdbook-theme-ace

This backend mainly deals with the rendered theme files that may not be handled during preprocess, specifically to modify the js/css of the [ace](https://github.com/ajaxorg/ace) editor.

```toml
# here is a must to load ace editor in mdbook
[output.html]
[output.html.playground]
editable = true

[output.theme-ace]
theme-white = "dawn" 
theme-dark = "tomorrow_night"
below-build-dir = true 
```

supported the official [ace theme names](https://github.com/ajaxorg/ace/tree/master/lib/ace/theme) :

```text
               ambiance | chaos          |              chrome | clouds                | clouds_midnight | cobalt    |
         crimson_editor | dawn           |             dracula | dreamweaver           |         eclipse | github    |
                    gob | gruvbox        |        idle_fingers | iplastic              |     katzenmilch | kr_theme  |
                 kuroir | merbivore      |      merbivore_soft | mono_industrial       |         monokai | nord_dark |
               one_dark | pastel_on_dark |      solarized_dark | solarized_light       |       sqlserver | terminal  |
               textmate | tomorrow       | tomorrow_night_blue | tomorrow_night_bright |  tomorrow_night |
tomorrow_night_eighties | twilight       |         vibrant_ink | xcode                 |
```

Note: for simplicity, this tool just directly modify the `cssText` in *theme-dawn.js* and *theme-tomorrow_night.js* . That is to say, if you set `theme-white = "xcode"` , you may find there is **no** *theme-xcode.js* or*theme-xcode.js* in the *build_dir* .

You are allowed to provide the `ace-dark.css` and `ace-white.css` in the `theme` dir which accords with `output.html` table to shadow the default given by the official ace. And the `theme-white/dark` configs beneath `output.theme-ace` are ignored.

Besides, for convenience, if you provide a single `ace.css` , both dark and white themes will use it! This is useful when you try the same ace config on both themes. But you're informed that `ace-dark.css` or `ace-white.css` is firstly used whenever there is `ace.css` or not . For instance, the bundle of `ace-white.css` and `ace.css` actually works as the combination of `ace-white.css` and `ace-dark.css` ; the bundle of `ace-white.css` , `ace-dark.css` and `ace.css` actually works as the combination of `ace-white.css` and `ace-dark.css` .

In short, you can download a css file form [ace theme](https://github.com/ajaxorg/ace/tree/master/lib/ace/theme) , rename it `ace.css` or `ace-dark.css` / `ace-white.css` , do minor modification about colors and put it into the `theme` dir.

`below-build-dir = true`  is the default to make output files in `html` right below `build_dir` in stead of `build_dir/html` , and there is no `build_dir/theme-post` automatically generated by mdbook. If you set `below-build-dir = false` , there will be `html` and `theme-post` dirs under *build_dir* (usually `book/`), and the `theme-post` should be empty for now.

# details about the preprocessor

## when `pagetoc = true`

```toml
[preprocessor.theme]
pagetoc = true
```

### pagetoc css

**Much appreciation for JorelAli's handy [mdBook-pagetoc](https://github.com/JorelAli/mdBook-pagetoc) !**

1. automatically add pagetoc in `index.hbs` :

```html
<!-- before in `index.hbs`                │after in `index.hbs` -->
  <div id="content" class="content">      │  <div id="content" class="content">
      <main>                              │      <main>
                                          │          <!-- Page table of contents -->
                                          │          <div class="sidetoc"><nav class="pagetoc"></nav></div>
                                          │
          {{{ content }}}                 │          {{{ content }}}
      </main>                             │      </main>
```

2. automatically  add `pagetoc.js` and `pagetoc.css` files

### `css/variables.css`

```toml
[preprocessor.theme]
pagetoc = true
# variables
pagetoc-width = "13%"
pagetoc-fontsize = "14.5px"
sidebar-width = "300px"
content-max-width = "82%"
menu-bar-height = "40px" # memu-bar = the bar on the top
page-padding = "15px"
mobile-content-max-width = "98%"
```

| `:root` variables   | default value |
| ------------------- | ------------- |
| --sidebar-width     | 300px         |
| --page-padding      | 15px          |
| --content-max-width | 750px         |
| --menu-bar-height   | 50px          |

by using `mdbook-theme`  , you can particularly specify the pagetoc width and fontsize:

| `:root` variables   | info    | set `pagetoc = true` |
| ------------------- | ------- | -------------------- |
| --sidebar-width     | default | 140px                |
| --page-padding      | default | 15px                 |
| --content-max-width | default | 82%                  |
| --menu-bar-height   | default | 40px                 |
| --pagetoc-width     | added   | 13%                  |
| --pagetoc-fontsize  | added   | 14.5px               |

Besides, this tool automatically makes content width larger if `max-width:1439px` (i.e. on the mobile device screen) when `pagetoc = true` is set in book.toml.

```css
@media only screen and (max-width:1439px) {
  :root{
    --content-max-width: 98%;
  }
}
```

### layout

```toml
[preprocessor.theme]
pagetoc = true
# layout 
content-padding = "0 10px"
content-main-margin-left = "2%"
content-main-margin-right = "2%"
nav-chapters-max-width = "auto"
nav-chapters-min-width = "auto"
chapter-line-height = "2em"
section-line-height = "1.5em"
```

```css
/* before in `css/general.css`               │ after in `css/general.css` */
  .content {                                 │    .content {
      padding: 0 15px;                       │        padding: 0 10px;
      ...                                    │        ...
  }                                          │    }
  .content main {                            │    .content main {
      margin-left: auto;                     │        margin-left: 2%;
      margin-right: auto;                    │        margin-right: 2%;
      ...                                    │        ...
  }                                          │    }
```

```css
/* before in `css/chrome.css`                │ after in `css/chrome.css` */
  .nav-chapters {                            │    .nav-chapters {
      ...                                    │        ...
      max-width: 150px;                      │        max-width: auto;
      min-width: 90px;                       │        min-width: auto;
      ...                                    │        ...
  }                                          │    }
                                             │
  .chapter {                                 │    .chapter {
      ...                                    │        ...
      line-height: 2.2em;                    │        line-height: 2.em;
  }                                          │    }
                                             │
 .section {                                  │    .section {
      ...                                    │        ...
      line-height: 1.9em;                    │        line-height: 1.5em;
  }                                          │    }
```

## set some fontsizes

To modify the fontsize in `css/general.css` :

```css
/* before in `css/general.css`               │ after in `css/general.css` */
    :root {                                  │    :root {
        font-size: 62.5%;                    │        font-size: 70%;
    }                                        │    }
                                             │
    body {                                   │    body {
        font-size: 1.6rem;                   │        font-size: 1.5rem;
      ...                                    │        ...
    }                                        │    }
                                             │
    code {                                   │    code {
        font-size: 0.875em;                  │        font-size: 0.9em;
      ...                                    │        ...
    }                                        │    }
```

and modify the fontsize of `.sidebar` in `css/chrome.css` ,

```css
/* before in `css/chrome.css`                │ after in `css/chrome.css` */
  .sidebar {                                 │    .sidebar {
      ...                                    │        ...
      font-size: 0.875em;                    │        font-size: 1em;
      ...                                    │        ...
  }                                          │    }
```

you can add `*-font-size = "value"` in book.toml:

```toml
[preprocessor.theme]
root-font-size = "70%"
body-font-size = "1.5rem"
code-font-size = "0.9em"
sidebar-font-size = "1em"
```

## set some colors

`--links` and `--inline-code-color` in `light` theme (in `css/variables.css` ) can be simply modified via this preprocessor.

These colors draws little attention to recognition for myself : )

```toml
[preprocessor.theme]
# you'are allowed to change the prefix within ayu/coal/light/navy/rust
light-links = "#1f1fff"
light-inline-code-color = "#F42C4C"
```

## if not set `pagetoc = true`

If a user did *not* set `pagetoc = true` (or equivalently `pagetoc = false`), ` Ready` will get an **empty** default, meaning this tool completely acts with user's configs.

The user can still set anything that only works with pagetoc's presence, though that setting will *not* work (and it will lie in css files).

More likely, a user may actually set `pagetoc = "true"`, then `Ready` will  get a **full** default, meaning he/she don't have to set most of the configs.

Both circumstances are **ready** to go!

## avoid repeating call on this tool when `mdbook watch`

Once `mdbook watch` detects your files changed, freshing leads to invoke `preprocessor.theme`, and `preprocessor.theme` reads from `book.toml` and `Theme` dir. When `preprocessor.theme` finds your css/js files are not consistent with what it computes, it'll cover everything concerned. (Of course, if they are consistent, no file will be rewritten.) The procedure holds back and forth, in the backyard ...

The point is that this tool, unlike the preprocessors aiming to deal with contents in md files and obliged to keep up with revision, produces theme files that are **needless to check (compute and compare) as long as nothing concerned changes**. Sadly, this tool are incapable of doing this kind of check, beacuse I haven't found a solution, causing whether to check is at the user's explicit option (see the following suggestions).

Since all theme configs are written into files under `theme` dir or appended only once, `mdbook build` will **not cause repeating** .

Therefore, if you don't modify the theme when `mdbook watch`, **run once `mdbook build`** and do **one** of the followings to avoid repeating:

1. set `turn-off = true` beneath `[preprocessor.theme]` to let this tool do nothing (such as not comparing local files with computed ones), or equivalently set the [shell env](https://rust-lang.github.io/mdBook/format/configuration/environment-variables.html) :
   ```cmd
   export MDBOOK_preprocessor__theme__turn_off=true
   #export MDBOOK_output__html__additional_css="[]"  # if the theme dir no longer exists, don't forget to tell mdbook about it
   #export MDBOOK_output__html__additional_js="[]"   # if the theme dir no longer exists, don't forget to tell mdbook about it
   mdbook watch
   ```

   and you can restore these values:
   ```cmd
   export MDBOOK_preprocessor__theme__turn_off=false
   #export MDBOOK_output__html__additional_css='["theme/pagetoc.css"]' # if you have set this empty, don't forget to fetch it now
   #export MDBOOK_output__html__additional_js='["theme/pagetoc.js"]'   # if you have set this empty, don't forget to fetch it now
   mdbook watch
   ```

   Remember a env variable always outstrips your configs counterpart in `book.toml` , so prefer to delete the env values to restore configs:
   ```cmd
   unset MDBOOK_preprocessor__theme__turn_off MDBOOK_output__html__additional_css MDBOOK_output__html__additional_js
   ```
2. comment the table header (i.e.`#[preprocessor.theme]`) to skip this preprocessor ( `turn-off = true` actually does not prevent running this preprocessor ); if you are certain that you will never need this tool to generate files agian, it's fine to delete the whole `[preprocessor.theme] ` table and keep the `theme` dir.
3. add `theme` in your `.gitignore` file to skip `mdbook watch`'s check on `theme` dir: this is a simple but useful way if you don't mind the `theme` dir; `mdbook build` will check the `theme` dir no matter whether it's in `.gitignore` or not : )

Fisrt two suggestions also suits more-than-once `mdbook build` in order to reduce/ban computation this tool produces during preprocess.

# examples

## Rust Book

```diff
 [output.html]
-additional-css = ["ferris.css", "theme/2018-edition.css"]
-additional-js = ["ferris.js"]
+additional-css = ["ferris.css", "theme/2018-edition.css", "theme/pagetoc.css"]
+additional-js = ["ferris.js", "theme/pagetoc.js"]
 git-repository-url = "https://github.com/rust-lang/book"
+
+[preprocessor.theme]
+pagetoc = true
+sidebar-width = "280px"
+content-max-width = "75%"
+content-main-margin-left = "5%"
+content-main-margin-right = "5%"
+root-font-size = "80%"
+sidebar-font-size = "0.85em"
```

before : [https://doc.rust-lang.org/book](https://doc.rust-lang.org/book)

![image.png](assets/image-20210623231453-0102ygv.png)

after : [http://129.28.186.100/rust-book](http://129.28.186.100/rust-book)

![image.png](assets/image-20210623231552-iwnqhs0.png)

## Rust Reference

```diff
 [output.html]
-additional-css = ["theme/reference.css"]
+additional-css = ["theme/reference.css", "theme/pagetoc.css"]
+additional-js = ["theme/pagetoc.js"]
...
+[preprocessor.theme]
+pagetoc = true
+sidebar-width = "240px"
```

before : [https://doc.rust-lang.org/nightly/reference](https://doc.rust-lang.org/nightly/reference)

![image.png](assets/image-20210623232913-ex16lxj.png)

after : [http://129.28.186.100/rust-reference](http://129.28.186.100/rust-reference)

![image.png](assets/image-20210623232802-551j8ck.png)

## Rust by Example

```diff
+[preprocessor.theme]
+pagetoc = false
+sidebar-width = "290px"
+content-max-width = "85%"
+root-font-size = "75%"

+[output.html]
+#additional-css = ["theme/pagetoc.css"]
+#additional-js = ["theme/pagetoc.js"]

+[output.theme-ace]
+theme-white = "ambiance"
+theme-dark = "solarized_dark"
```

before : [https://doc.rust-lang.org/stable/rust-by-example](https://doc.rust-lang.org/stable/rust-by-example)

![image.png](assets/image-20210623234530-760uke0.png)

![image.png](assets/image-20210623235115-5t5j2z2.png)

after : [http://129.28.186.100/rust-by-example](http://129.28.186.100/rust-by-example)

![image.png](assets/image-20210623235016-8d4be37.png)

![image.png](assets/image-20210623234953-bs9jgtf.png)

## Others

Rust API Guidelines (Chinese Version): [https://zjp-cn.github.io/api-guidelines](https://zjp-cn.github.io/api-guidelines)

![image.png](assets/image-20210623235339-kqxm3ur.png)

The Little Book of Rust Macros (Updated & Chinese Version): [https://zjp-cn.github.io/tlborm](https://zjp-cn.github.io/tlborm)

![image.png](assets/image-20210623235527-jqu0pto.png)