journing robot

🗒️ 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:

Panic for Pleasure

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

  1. Setting Up Rust

    In order to work with this project you'll need to setup a working Rust development environment that includes rustc and cargo.

    • For OSX and Linux:

      curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
      
    • For Windows:

      Download the installer and follow the onscreen instructions.

  2. 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 and Linux:
    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
    
  3. Install just Build Tool

    just 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
    
  4. 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
    
  5. Install mdbook-journal Locally

    Create 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 of entries. 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 receives entries which can be iterated over. Any of the variables collected can be accessed under the meta keyword. Here is a full list of the current available data points as of 0.3.0:

    • topic : The string name of the topic this entry belongs to
    • created_at : string serialized to a string in rfc3339 format
    • file_loc : full file path of the entry on disk
    • virtual_path : relative path from the root of the markdown book
    • meta : hash of all variables for the entry
    • content : 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 and kebabCase.

    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 the YYYY 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'"