Compare commits

..

13 Commits

Author SHA1 Message Date
Wynd e5a0ccdb53 Very bad take on a list of recently updated chapters 2023-10-03 23:18:55 +03:00
Wynd ea94977ec5 Merge branch 'main' of https://github.com/badboy/mdbook-last-changed 2023-10-02 22:59:12 +03:00
Jan-Erik Rediger 4f5518a1bd chore: Release mdbook-last-changed version 0.1.4 2023-08-05 19:58:06 +02:00
Jan-Erik Rediger 3f1d3ae842 Dependency updates 2023-08-05 19:57:06 +02:00
Jan-Erik Rediger d5b3e2dfb5 Update mdbook and downgrade toml 2023-08-05 19:56:36 +02:00
Sergejs Kostjucenko afd7ddb5dc
Update cargo dependencies (#8) 2023-07-21 17:52:25 +02:00
Jan-Erik Rediger a6e4a45cac Dependency updates 2023-07-11 11:52:04 +02:00
Jan-Erik Rediger 2c302a0ae9 chore: Release mdbook-last-changed version 0.1.3 2023-07-11 11:50:53 +02:00
Jan-Erik Rediger c86ff23f8b Update crossbeam-channel 2023-07-11 11:50:34 +02:00
Wynd bc6e40eede
Optional git-repository-url (#6)
Co-authored-by: Jan-Erik Rediger <janerik@fnordig.de>
2023-07-11 11:49:25 +02:00
Jan-Erik Rediger a8325211b3
Update src/lib.rs 2023-07-11 11:47:22 +02:00
Wynd dac759ceea Updated the README file 2023-07-09 12:41:41 +03:00
Wynd 78606b8e67 Made git-repository-url optional 2023-07-07 18:43:20 +03:00
4 changed files with 742 additions and 503 deletions

1101
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package]
name = "mdbook-last-changed"
version = "0.1.2"
version = "0.1.4"
description = "mdbook preprocessor to add the last modification date per page"
license = "MPL-2.0"
homepage = "https://github.com/badboy/mdbook-last-changed"
@ -8,10 +8,12 @@ repository = "https://github.com/badboy/mdbook-last-changed"
edition = "2021"
[dependencies]
mdbook = "0.4.21"
mdbook = "0.4.33"
env_logger = "0.10.0"
log = "0.4"
clap = { version = "4.0.29", features = ["cargo"] }
serde_json = "1.0"
toml = "0.5.6"
toml = "0.5.11"
xshell = "0.2.2"
chrono = "0.4.31"
concat-string = "1.0.1"

View File

@ -10,7 +10,6 @@ It uses the configured `git-repository-url` as the base.
## Requirements
* The `git` command line tool.
* A configured git repository url in your `book.toml` configuration. See [Configuration](#configuration).
* Access to the git repository checkout while building your book.
## Installation
@ -36,10 +35,22 @@ renderer = ["html"]
```toml
[output.html]
# Required: Your repository URL used in the link.
# Optional: Your repository URL used in the link.
git-repository-url = "https://github.com/$user/$project"
```
If `git-repository-url` is not configured the footer will not contain the commit and a link to it and instead only show the last changed date.
Without `git-repository-url` configured:
```HTML
<footer id="last-change">Last change: 2023-07-09</footer>
```
With `git-repository-url` configured:
```HTML
<footer id="last-change">Last change: 2023-07-09, commit: <a href="https://github.com/$user/$project/commit/$commit">0000000</a></footer>
```
To style the footer add a custom CSS file for your HTML output:
```toml

View File

@ -1,5 +1,9 @@
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use chrono::NaiveDate;
use concat_string::concat_string;
use mdbook::book::{Book, BookItem, Chapter};
use mdbook::errors::Result;
use mdbook::preprocess::{Preprocessor, PreprocessorContext};
@ -7,6 +11,12 @@ use xshell::{cmd, Shell};
pub struct LastChanged;
#[derive(Debug, Eq, PartialEq, Hash)]
struct LiteLink {
name: String,
path: Option<PathBuf>,
}
impl Preprocessor for LastChanged {
fn name(&self) -> &str {
"last-changed"
@ -21,27 +31,29 @@ impl Preprocessor for LastChanged {
log::debug!("Src root: {}", src_root.display());
log::debug!("Git root: {}", git_root.display());
let repository_url = match ctx.config.get("output.html.git-repository-url") {
None => {
log::error!("mdbook-last-changed was called, but no `output.html.git-repository-url` configured. Book is left unchanged.");
return Ok(book);
}
Some(url) => url,
};
let repository_url = match repository_url {
let repository_string: Option<&str> = match ctx.config.get("output.html.git-repository-url")
{
Some(val) => {
let url = match val {
toml::Value::String(s) => s,
_ => {
log::trace!("git-repository-url is not a string: {repository_url:?}");
log::trace!("git-repository-url is not a string: {val:?}");
return Ok(book);
}
};
log::debug!("Repository URL: {}", repository_url);
log::debug!("Repository URL: {}", url);
if !repository_url.contains("github.com") {
log::trace!("git-repository-url is not a GitHub URL: {repository_url:?}");
if !url.contains("github.com") {
log::trace!("git-repository-url is not a GitHub URL: {url:?}");
return Ok(book);
}
Some(&url)
}
None => None,
};
let mut map: HashMap<LiteLink, String> = HashMap::new();
let mut res = None;
book.for_each_mut(|item: &mut BookItem| {
if let Some(Err(_)) = res {
@ -51,13 +63,53 @@ impl Preprocessor for LastChanged {
if let BookItem::Chapter(ref mut chapter) = *item {
res = Some(
last_changed(&git_root, &src_root, repository_url, chapter).map(|md| {
last_changed(&git_root, &src_root, repository_string, chapter, &mut map).map(
|md| {
chapter.content = md;
}),
},
),
);
}
});
let mut vec: Vec<(LiteLink, NaiveDate)> = map
.into_iter()
.map(|e| (e.0, NaiveDate::from_str(&e.1).unwrap()))
.collect();
// Sorting alphabetically and then by date, this means same date entries will be sorted alphabetically, otherwise the end result will be randomized when truncating
vec.sort_by(|a, b| a.0.name.cmp(&b.0.name));
vec.sort_by(|a, b| b.1.cmp(&a.1));
vec.truncate(5);
let text: String = vec
.into_iter()
.map(|f| {
format!(
"<li><a href=\"{}\">{}</a></li>",
f.0.path.unwrap().display(),
f.0.name
)
})
.collect();
let text = concat_string!("## Recently Updated:\n", "<ul>", text, "</ul>");
book.for_each_mut(|item: &mut BookItem| {
if let Some(Err(_)) = res {
log::trace!("Error when changing the book. Last result: {res:?}");
return;
}
if let BookItem::Chapter(ref mut chapter) = *item {
if let Some(ch) = &chapter.number {
if ch.0[0] == 1 {
// let content = &chapter.content;
// chapter.content = format!("{}\n{}", text, content);
chapter.content = chapter.content.replace("⁂⁂⁂", &text);
}
}
}
});
res.unwrap_or(Ok(())).map(|_| book)
}
}
@ -65,8 +117,9 @@ impl Preprocessor for LastChanged {
fn last_changed(
git_root: &Path,
src_root: &Path,
base_url: &str,
base_url: Option<&str>,
chapter: &mut Chapter,
map: &mut HashMap<LiteLink, String>,
) -> Result<String> {
let content = &chapter.content;
@ -95,12 +148,24 @@ fn last_changed(
let modification = get_last_modification(git_root, &path);
let text = match modification {
Ok((date, commit)) => {
let url = format!("{}/commit/{}", base_url, commit);
let lite_link = LiteLink {
name: chapter.name.clone(),
path: chapter.path.clone(),
};
map.insert(lite_link, date.clone());
match base_url {
Some(url) => {
let url = format!("{}/commit/{}", url, commit);
format!(
"Last change: {}, commit: <a href=\"{}\">{}</a>",
date, url, commit
)
}
None => {
format!("Last change: {}", date)
}
}
}
Err(e) => {
log::trace!("No modification found for {path:?}. Error: {e:?}");
return Ok(content.into());