🗒️ mdBook Journal
Workflow tool that allows you to generate templated documentation, notes, measurements... or really anything. At it's core is the concept of a journal "topic". You specify what core data is tracked for each topic and then get to work!
NOTE: Plugin project for the mdBook
documentation system. It's
not very complex; however, you will need to understand how it works in
order to take advantage of some of the functionality of this tool.
🔩 Demo Example
Let's say that you want to document every major architectural decision
your team makes.
From your book.toml
you can define such a topic:
# Example "book.toml" that demonstrates how to setup
# setup a simple Architectural Decision Record
#
[book]
authors = ["Crazy Dev"]
language = "en"
multilingual = false
src = "src"
title = "roflcopterz"
# You'll need `mdbook-journal` in your path
# make sure the following command works:
#
# `mdbook-journal -V`
#
[preprocessor.journal]
command = "mdbook-journal"
# Setting Up A Journal Topic
#
# This is how you would create a topic of "ADR".
#
# The key immediately after `topics` is the name
# of the topic. --------------+
# |
[preprocessor.journal.topics.ADR]
# The `path_mapping` drives the strategy for generating
# the path location of each entry. It supports a mixture
# of handlebars for any topic data and also is formatted
# against the `CREATED_AT` time.
#
# In this example the directory structure will be the
# year of the title as the root directory, followed by
# a directory for the category, and then lastly the title
# as the filename. It should be pointed out that a `.md`
# extension is automatically appended to the path.
#
# Date Interpolation Docs:
# <https://docs.rs/chrono/latest/chrono/format/strftime/index.html>
#
# default = "%Y/%B/%d-%H-%M-%S-{{kebabCase title}}"
#
path_mapping = "%Y/{{kebabCase category}}/{{kebabCase title}}"
# Entry Template
#
# String template value that is used when generating
# a new "Entry" for this topic. This template is
# interpolated with the data provided from the required
# variables.
#
# default = ""
#
template = """
## Category: **{{category}}**
## ADR: **{{titleCase title}}**
### Problem Statement
What are we solving for?
"""
# Leaf Template
#
# String template value that is used when generating
# index pages for leaf directory nodes. Leafs are
# any directory that only contain `entries` and not
# additional directories.
#
# You have available `entries`; which is a collection
# of each entry in the leaf as well as `path`; which
# is the virtual directory of the leaf itself.
#
leaf_template = """
# {{path}}
{{#each entries}}
- [{{this.meta.title}}](/{{this.virtual_path}})
{{/each}}
"""
# This is how you specify a topic's meta data.
#
# Each key maps to the front-matter which is pinned
# to all journal entries. Currently `title` is
# required to generate file names. Feel free to add
# as many more fields that you want.
#
# Field Options
#
# - required = false
#
# If a field is required this means it's creation
# and updates must have a valid representation of
# the data. Presently that just means it cannot
# be empty.
#
# - default = ""
#
# Value to provide if the field has failed the
# validation phase. It should be noted that a
# default is also provided even if the field is
# not required. ** This is likely to change **
#
# This is the topic name ---+
# |
[preprocessor.journal.topics.ADR.variables]
title = { required = true }
category = { required = true }
priority = { required = true, default = "low" }
In this example the topic name is ADR
and has three
defined data points of title
, category
, and priority
.
This ensures that each record created will collect
those three following data points.
Once a topic is setup an "entry" can be created for it. Here is an example command to create a decision record:
markdown-journal new ADR
This will produce a prompt that collects these data points:
(category)❯ rust
(priority)❯ high
(title)❯ panic for pleasure
Assuming the above was entered it will produce the following file in your project:
src/ADR/2024/rust/panic-for-pleasure.md
---
CREATED_AT: 2024-07-25T00:46:13.541231172+00:00
TOPIC: ADR
category: rust
priority: high
title: panic for pleasure
---
## Category: **rust**
## ADR: **Panic For Pleasure**
### Problem Statement
What are we solving for?
This top part of a markdown spec called front matter
. It
allows for assigning specific data and is at the forefront
of how the journal operates. All entries added this way
are automatically included in the generated HTML documents
without needing to include them in the SUMMARY.md
file.
⚙️ Install Locally
Currently to install you'll need to clone this repo and install with cargo:
git clone https://github.com/benfalk/mdbook-journal.git
cargo install --path mdbook-journal
Verify that it's installed correctly:
mdbook-journal -V
mdbook-journal 0.2.0
Development Setup
Getting Started
-
Setting Up Rust
In order to work with this project you'll need to setup a working Rust development environment that includes
rustc
andcargo
.-
For
OSX
andLinux
:curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-
For
Windows
:Download the installer and follow the onscreen instructions.
-
-
Install
cargo-binstall
Most of the workflows in this project lean heavily upon cargo binary packages. While we could simply
cargo install <package>
, this allows you to install a pre-compiled binary for your environment and avoids a possible lengthy compile time.- For
OSX
andLinux
:
curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
- For
Windows
:
Set-ExecutionPolicy Unrestricted -Scope Process; iex (iwr "https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.ps1").Content
- For
-
Install
just
Build Tooljust
is the preferred build tool for this project, and that includes bootstrapping the remainder of your local environment. It can be installed with the following command:cargo binstall just
-
Finish Bootstrapping Environment
Once you have a working rust environment you can finish setting up the remainder of this project locally with the following command:
just init
-
Install
mdbook-journal
LocallyCreate a production build of the binary and install it to your crate local binary location:
just install
Leaf Templates Are Here
With the release of 0.3.0
comes an experimental new feature of leaf
templates. This new template will power virtual directories in your
markdown book that contain only entries.
New Topic Setting
-
leaf_template
This is very similar to the
template
setting for templates; however, instead of working with a single entry it uses a collection ofentries
. These can be iterated through. Below is an example leaf template:# {{path}} {{#each entries}} - [{{this.meta.title}}](/{{this.virtual_path}}) {{/each}}
This demonstrates the data available for this template. It is provided a
path
which is the virtual path for the README index being generated. It also receivesentries
which can be iterated over. Any of the variables collected can be accessed under themeta
keyword. Here is a full list of the current available data points as of0.3.0
:topic
: The string name of the topic this entry belongs tocreated_at
: string serialized to a string in rfc3339 formatfile_loc
: full file path of the entry on diskvirtual_path
: relative path from the root of the markdown bookmeta
: hash of all variables for the entrycontent
: full string content of the entry
Initial Release v0.2.0
I'm proud to announce the first release of mdbook-journal
@ v0.2.0
.
There is still more to come; however, I believe this project has
enough to get started with. In this post I'll outline what is
currently available and what is yet to come!
What's in v0.2.0
?
Presently your journal can define any number of "topics". A topic in this case represents a collection of similar items that share a common data set. To create a new "entry" for a topic use the following command:
mdbook-journal new <TOPIC_NAME>
This will use the settings for TOPIC_NAME
to generate a new entry.
Topic Settings
A topic presently defines three major concepts:
-
path_mapping
A handlebars template which describes what file structure to use when creating a new instance of a topic. This template can refer to data defined by the topic AND also has access to the time in which it was created.
To reference any user defined topic data simply wrap it in handlebars. It should also be noted that there is a number of string modifiers built in you can can take advantage of, such as
titleCase
andkebabCase
.The entire string is also interpolate with date-time formatting tokens. For instance if your template had the
%Y
token it would be replaced with theYYYY
four digit calendar year. -
template
This is very similar to the handlebars template based path mapping, but it is used to populate a newly created topic entry. Use it as a starter for a new entry with the high level structure of subjects you want to address, etc.
-
variables
A hash definition describing all of the data you want every entry to collect for a topic. Each key translates to a data-point key that is collected and the value is hash of settings. Here is the following settings each key can have:
-
required
(boolean) (default false)If true a "non-empty" value is expected.
-
default
(string) (default "")If a value is not provided this is the default used
-
Rendering Output
The rendering is very minimal. All topics are added to the summary at render time and are displayed in a directory structure format that follows the entries path on disk.
What's Coming Next?
-
Templated Topic Layout
A feature that allows you to define how entries are displayed for a topic. There are many different formats for representing entry data. I want topics to be able to dynamically update where and how they display data as the information on it is updated.
-
Programatic Entry Interface
Ultimately I envision this cli tool being driven by a neovim plugin. Aside from that, I believe it would be extremely handy to support entry like this:
mdbook-journal new TOPIC --json '{"title":"Test Title"}'
-
SQL Structured Searching
The idea is still loose; but I want to support something like the following:
mdbook-journal query TOPIC / "SELECT filename FROM entry WHERE category = 'rust'"