Notedown 0.1.0

dotnet add package Notedown --version 0.1.0
NuGet\Install-Package Notedown -Version 0.1.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Notedown" Version="0.1.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Notedown --version 0.1.0
#r "nuget: Notedown, 0.1.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Notedown as a Cake Addin
#addin nuget:?package=Notedown&version=0.1.0

// Install Notedown as a Cake Tool
#tool nuget:?package=Notedown&version=0.1.0

Notedown

Build

Notedown is a set of conventions for notes in markdown and tools that operate on the conventions. These conventions aim to

  • be intuitive as plain text
  • not interrupt flow while taking notes
  • make notes easy to skim for reference
  • easily back into existing notes
  • treat notes as a data source

This repository contains tools for programmatically leveraging Notedown conventions: a CLI tool and an .NET library.

Library / Code Model

Nuget (with prereleases)

The code model is written in F# and follows F# design practices, but it can be used from any .NET language

The code model creates a hierarchy of sections in a markdown document each with metadata and contents.

For example, it would parse a Notedown-based document like this.

---
some-config: "I'm root-level meta" 
date: 20xx-MM-dd
tags: [tag1, tag2]
---

Root level content

# I'm a section

Content 

## I'm a child Section
```yml
some-config: "I'm child section meta"
rating: 5
\```
Child Content

The parsed data comes in this form

type Section = {
    Level: SectionLevel
    Meta: MetadataValue
    ExclusiveText: string
    Children: Section list
    // There is also a FullText() method
}

To create the note model

open Notedown

let noteModel = NoteModel.parse markdownText

There are also several optional rules for metadata inheritance. For example

let notesWithMetaInheritance = noteModel |> NoteModel.Inheritance.parentChild

You can crawl the note hierarchy to create your own inheritance rules or otherwise transform the model using Section.mapFold.

Metadata

Metadata is shaped like

type MetadataValue =
    | SingleValue of string
    | Vector of MetadataValue list
    | Complex of EquatableDictionary<string, MetadataValue>

List-like values become Vector. Key-value maps become Complex. And values become SingleValue. Note that Vectors can be hetrogeneous. In other words, they could contain a mix of any meta kinds (SingleValue, Vector, Complex).

All meta is read as a string and interpretation is left to the consumer. Yaml is currently the only supported meta format.

There are a few helpers for setting specific meta values. Suppose we have meta as follows

---
date: 0000-00-00
config: 
  sub-group:
    rating: 5
    tags: ["tag", "other tag"]
---

We can get specific values with path selectors

MetadataValue.trySelect "config.sub-group.rating" // returns Some SingleValue "5"
MetadataValue.trySelect "config.sub-group.tags" // returns Some Vector ["tag", "other tag"]

MetadataValue.trySelectSingle "config.sub-group.rating" // returns Some "5"
MetadataValue.trySelectSingle "config.sub-group.nope" // returns None
MetadataValue.trySelectSingle "config.sub-group.tags" // returns None because tags is an array, not a single value

There are two options for setting values by path clobber and trySet. Clobber will create the desired path, even if it overwrites intermediate values. TrySet will only write if it doesn't overwrite intermediate values. If it detects an overwrite, it'll return and error with the location and conflicting value.

Tag Extraction

The other main feature is tag extraction

let extract (tags: string list) (markdownDocument: string) : string list

It takes any list of tags to extract and any markdown text, then returns the markdown text of any sections, paragraphs, or list items marked by those tags

let extracted = TagExtraction.extract ["tag:"; "otherTag:"] markdown

Here's a sample of how tagging could work

## TAGGED: I'm a tagged heading

Content of tagged sections is extracted with the heading

- PRO: This list item is tagged pro
- CON: this list item is tagged con
  - child list items are included with tagged parent

TAGGED: This paragraph is tagged
- List items following the paragraph without space between are included in extraction

Notedown CLI

alternate text is missing from this package README image Nuget (with prereleases)

Tag Extraction

notedown extract-tags file-here.md -t "TAG:" -o output-file.md

Extract all content with the given tag by the following rules

  • Paragraph: Extracts the full paragraph if the tag appears anywhere in the paragraph
  • Paragraph+list: Extracts the paragraph and following list if there is no space between the paragraph and list
  • List items: Extracts any list items containing the tag along with any sub-items (but not parent items)
  • Headings/Sections: Extracts any heading containing the tag along with all content in the heading's section

Installation

If you have the dotnet sdk installed, you can just run

dotnet tool install -g notedown.cli

Otherwise, download the zip for your platform from releases. Unzip and either

  • put the exe in your path
  • or create an alias to the exe in your shell profile
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.1.0 125 5/8/2023
0.1.0-alpha1 85 5/8/2023