Compare commits
10 commits
beb753bd39
...
5c454c0233
Author | SHA1 | Date | |
---|---|---|---|
5c454c0233 | |||
Jan-Erik Rediger | 61c9ab5ee4 | ||
Jan-Erik Rediger | d703e66df1 | ||
Jan-Erik Rediger | febe468843 | ||
Jan-Erik Rediger | 7aaed9865b | ||
Jan-Erik Rediger | 8faae2a1bb | ||
113362a944 | |||
e897dbffcc | |||
a6280bf91f | |||
3f9ceee047 |
|
@ -1,3 +1,12 @@
|
|||
# v0.14.1 (2023-08-05)
|
||||
|
||||
* Upgrade mdbook and downgrade toml
|
||||
|
||||
# v0.14.0 (2023-08-02)
|
||||
|
||||
* Use custom header IDs if present
|
||||
* Upgrade dependencies
|
||||
|
||||
# v0.13.0 (2023-07-18)
|
||||
|
||||
* Upgrade dependencies
|
||||
|
|
649
Cargo.lock
generated
649
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
18
Cargo.toml
18
Cargo.toml
|
@ -1,22 +1,22 @@
|
|||
[package]
|
||||
name = "mdbook-toc"
|
||||
version = "0.13.0"
|
||||
version = "0.14.1"
|
||||
authors = ["Jan-Erik Rediger <janerik@fnordig.de>"]
|
||||
description = "mdbook preprocessor to add Table of Contents"
|
||||
license = "MPL-2.0"
|
||||
homepage = "https://github.com/badboy/mdbook-toc"
|
||||
repository = "https://github.com/badboy/mdbook-toc"
|
||||
edition = "2018"
|
||||
rust-version = "1.58"
|
||||
rust-version = "1.66"
|
||||
|
||||
[dependencies]
|
||||
mdbook = "0.4.32"
|
||||
pulldown-cmark = "0.9.1"
|
||||
log = "0.4.11"
|
||||
clap = { version = "4.0.29", features = ["cargo"] }
|
||||
serde_json = "1.0.57"
|
||||
toml = "0.7.6"
|
||||
mdbook = "0.4.33"
|
||||
pulldown-cmark = "0.9.3"
|
||||
log = "0.4.19"
|
||||
clap = { version = "4.3.19", features = ["cargo", "derive"] }
|
||||
serde_json = "1.0.104"
|
||||
toml = "0.5.11"
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "1.0.0"
|
||||
pretty_assertions = "1.4.0"
|
||||
env_logger = "0.10.0"
|
||||
|
|
94
flake.lock
Normal file
94
flake.lock
Normal file
|
@ -0,0 +1,94 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1692799911,
|
||||
"narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"naersk": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1692351612,
|
||||
"narHash": "sha256-KTGonidcdaLadRnv9KFgwSMh1ZbXoR/OBmPjeNMhFwU=",
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"rev": "78789c30d64dea2396c9da516bbcc8db3a475207",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1692808169,
|
||||
"narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9201b5ff357e781bf014d0330d18555695df7ba8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1692808169,
|
||||
"narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9201b5ff357e781bf014d0330d18555695df7ba8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"naersk": "naersk",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
29
flake.nix
Normal file
29
flake.nix
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
inputs = {
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
naersk.url = "github:nix-community/naersk";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
};
|
||||
|
||||
outputs = { self, flake-utils, naersk, nixpkgs }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = (import nixpkgs) {
|
||||
inherit system;
|
||||
};
|
||||
|
||||
naersk' = pkgs.callPackage naersk {};
|
||||
|
||||
in rec {
|
||||
# For `nix build` & `nix run`:
|
||||
defaultPackage = naersk'.buildPackage {
|
||||
src = ./.;
|
||||
};
|
||||
|
||||
# For `nix develop`:
|
||||
devShell = pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs; [ rustc cargo ];
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
|
@ -3,7 +3,7 @@ extern crate mdbook;
|
|||
extern crate mdbook_toc;
|
||||
extern crate serde_json;
|
||||
|
||||
use clap::{crate_version, Arg, ArgMatches, Command};
|
||||
use clap::{Parser, Subcommand};
|
||||
use mdbook::errors::Error;
|
||||
use mdbook::preprocess::{CmdPreprocessor, Preprocessor};
|
||||
use mdbook_toc::Toc;
|
||||
|
@ -11,22 +11,24 @@ use mdbook_toc::Toc;
|
|||
use std::io;
|
||||
use std::process;
|
||||
|
||||
pub fn make_app() -> Command {
|
||||
Command::new("mdbook-toc")
|
||||
.version(crate_version!())
|
||||
.about("mdbook preprocessor to add Table of Contents")
|
||||
.subcommand(
|
||||
Command::new("supports")
|
||||
.arg(Arg::new("renderer").required(true))
|
||||
.about("Check whether a renderer is supported by this preprocessor"),
|
||||
)
|
||||
#[derive(Parser)]
|
||||
#[command(about, version)]
|
||||
struct App {
|
||||
#[command(subcommand)]
|
||||
cmd: Option<Cmd>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Cmd {
|
||||
/// Check whether a renderer is supported by this preprocessor
|
||||
Supports { renderer: String },
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let matches = make_app().get_matches();
|
||||
let app = App::parse();
|
||||
|
||||
if let Some(sub_args) = matches.subcommand_matches("supports") {
|
||||
handle_supports(sub_args);
|
||||
if let Some(Cmd::Supports { renderer }) = app.cmd {
|
||||
handle_supports(&renderer);
|
||||
} else if let Err(e) = handle_preprocessing() {
|
||||
eprintln!("{e}");
|
||||
process::exit(1);
|
||||
|
@ -51,10 +53,7 @@ fn handle_preprocessing() -> Result<(), Error> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_supports(sub_args: &ArgMatches) -> ! {
|
||||
let renderer = sub_args
|
||||
.get_one::<String>("renderer")
|
||||
.expect("Required argument");
|
||||
fn handle_supports(renderer: &str) -> ! {
|
||||
let supported = Toc.supports_renderer(renderer);
|
||||
|
||||
// Signal whether the renderer is supported by exiting with 1 or 0.
|
||||
|
|
35
src/lib.rs
35
src/lib.rs
|
@ -140,11 +140,11 @@ fn add_toc(content: &str, cfg: &Config) -> Result<String> {
|
|||
let mut current_header_level: Option<u32> = None;
|
||||
let mut id_counter = HashMap::new();
|
||||
|
||||
let mut opts = Options::empty();
|
||||
opts.insert(Options::ENABLE_TABLES);
|
||||
opts.insert(Options::ENABLE_FOOTNOTES);
|
||||
opts.insert(Options::ENABLE_STRIKETHROUGH);
|
||||
opts.insert(Options::ENABLE_TASKLISTS);
|
||||
let opts = Options::ENABLE_TABLES
|
||||
| Options::ENABLE_FOOTNOTES
|
||||
| Options::ENABLE_STRIKETHROUGH
|
||||
| Options::ENABLE_TASKLISTS
|
||||
| Options::ENABLE_HEADING_ATTRIBUTES;
|
||||
|
||||
let mark: Vec<Event> = Parser::new(&cfg.marker).collect();
|
||||
log::trace!("Marker: {mark:?}");
|
||||
|
@ -179,20 +179,27 @@ fn add_toc(content: &str, cfg: &Config) -> Result<String> {
|
|||
current_header_level = Some(lvl as u32);
|
||||
continue;
|
||||
}
|
||||
if let Event::End(Heading(..)) = e {
|
||||
if let Event::End(Heading(_, fragment, _)) = e {
|
||||
// Skip if this header is nested too deeply.
|
||||
if let Some(level) = current_header_level.take() {
|
||||
let header = current_header.clone();
|
||||
let mut slug = mdbook::utils::normalize_id(&header);
|
||||
let id_count = id_counter.entry(slug.clone()).or_insert(0);
|
||||
let slug = if let Some(slug) = fragment {
|
||||
// If a fragment is defined, take it as is, not trying to append an extra ID
|
||||
// in case of duplicates (same behavior as mdBook)
|
||||
slug.to_owned()
|
||||
} else {
|
||||
let mut slug = mdbook::utils::normalize_id(&header);
|
||||
let id_count = id_counter.entry(slug.clone()).or_insert(0);
|
||||
|
||||
// Append unique ID if multiple headers with the same name exist
|
||||
// to follow what mdBook does
|
||||
if *id_count > 0 {
|
||||
write!(slug, "-{id_count}").unwrap();
|
||||
}
|
||||
// Append unique ID if multiple headers with the same name exist
|
||||
// to follow what mdBook does
|
||||
if *id_count > 0 {
|
||||
write!(slug, "-{id_count}").unwrap();
|
||||
}
|
||||
|
||||
*id_count += 1;
|
||||
*id_count += 1;
|
||||
slug
|
||||
};
|
||||
|
||||
if level <= cfg.max_level {
|
||||
toc_content.push((level, header, slug));
|
||||
|
|
11
tests/attributes.in.md
Normal file
11
tests/attributes.in.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Chapter
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
# Header 1
|
||||
|
||||
## Header {#header-1-sub}
|
||||
|
||||
# Header 2
|
||||
|
||||
## Header {#header-2-sub .class1 .class2}
|
14
tests/attributes.out.md
Normal file
14
tests/attributes.out.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Chapter
|
||||
|
||||
* [Header 1](#header-1)
|
||||
* [Header](#header-1-sub)
|
||||
* [Header 2](#header-2)
|
||||
* [Header](#header-2-sub)
|
||||
|
||||
# Header 1
|
||||
|
||||
## Header {#header-1-sub}
|
||||
|
||||
# Header 2
|
||||
|
||||
## Header {#header-2-sub .class1 .class2}
|
19
tests/it.rs
19
tests/it.rs
|
@ -7,15 +7,17 @@ fn default<T: Default>() -> T {
|
|||
}
|
||||
|
||||
fn with_marker<S: Into<String>>(marker: S) -> Config {
|
||||
let mut cfg = Config::default();
|
||||
cfg.marker = marker.into();
|
||||
cfg
|
||||
Config {
|
||||
marker: marker.into(),
|
||||
..Config::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn with_max_level(level: u32) -> Config {
|
||||
let mut cfg = Config::default();
|
||||
cfg.max_level = level;
|
||||
cfg
|
||||
Config {
|
||||
max_level: level,
|
||||
..Config::default()
|
||||
}
|
||||
}
|
||||
|
||||
trait FromContent {
|
||||
|
@ -169,3 +171,8 @@ fn empty_document() {
|
|||
fn crlf() {
|
||||
assert_toc!("crlf");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attributes() {
|
||||
assert_toc!("attributes");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue