1.3.5 • Published 5 months ago

marklow v1.3.5

Weekly downloads
-
License
ISC
Repository
-
Last release
5 months ago

marklow

marklow is a library and npx script for defining custom markdown-like syntax and compiling your custom markdown into JSON to be rendered however you please in your application.

Installation

npm i marklow

Why?

Geez, I gotta have a reason for everything? Jokes aside, consider the following scenario:

  1. You have some writing in the form of .txt or .md files that you'd like to turn into a blog.
  2. Sounds like a job for Jekyll (or equivalent).
  3. But, in addition to the basic markdown stuff, you'd also like to add a bit of extra functionality to your writing. For example, suppose you'd like some words to have a "definition" feature, where you can click on it and a pop-up will appear in the corner with the definition.
  4. Realizing that you'll need a custom framework, you switch to writing your content directly in your jsx/tsx files.

Inlining content in your JSX files is terrible in every way; not only will duplicate JSX be unavoidable, but your writing will also be practically unreadable, resulting in the worst of both worlds. With marklow, you can instead define custom syntax for your specific use-case e.g. %term%((definition)) and then write markdown as usual. Then, your markdown files get compiled into JSON which your application can read and display exactly in the way you want.

Usage

Example

After installing marklow, we need to define a configuration file called marklow.json at the package level. An example with all options set is shown below:

// marklow.json
{
  "defaultsConfig": {
    // If this value is true, all others are ignored. True by default.
    "useAllDefaults": false,
    // See the table below for a description of each default pattern.
    "useDefaultHeaders": false,
    "useDefaultBold": false,
    "useDefaultItalic": false,
    "useDefaultCode": false,
    "useDefaultLink": false,
    "useDefaultImage": false,
    "useDefaultBreaks": false,
    "useDefaultCodeBlock": false,
    "useDefaultQuotation": false
  },
  // The directory containing your input files.
  "inputDir": "./posts",
  // The output JSON directory.
  "outputDir": "./src/posts",
  // Custom syntax.
  "matchers": [
    {
      // A regex pattern. Note that escaped regex characters need to be double escaped.
      // Named groups (besides "body") will be used as attributes of the "color" element.
      // "body" is a special group name used for text meant to be displayed inline.
      "pattern": ";;(?<body>.+?);;\\((?<colorName>.+?)\\)",
      // The "tag name" for this element
      "tag": "color",
    },
    {
      "pattern": "%(?<body>.+?)%\\(\\((?<definition>.+?)\\)\\)",
      "tag": "def",
      // An optional list of named groups in the regex pattern to treat as children rather than attributes.
      // These are essentially like additional "body"s.
      "subgroups": ["definition"]
    }
  ],
  // Which file extensions in the input directory to compile / watch for changes.
  "ext": ["md", "txt"]
}

Then, you just need to run npx marklow and marklow will compile your md or txt files into JSON using the patterns you defined, watching for changes and re-compiling as needed. Say we have the following markdown file:

This page is about ;;red ants;;(red).

Red ants are %terrestrial%((This means they live on ;;land;;(green))) critters.

Marklow will convert this markdown to the following JSON (some fields removed for brevity):

{
  "type": "marklow",
  "children": [
    {
      "text": "This page is about "
    },
    {
      "attributes": { "colorName": "red" },
      "type": "color",
      "children": [
        {
          "children": [{ "text": "red ants" }]
        }
      ]
    },
    {
      "text": ".\n\nRed ants are "
    },
    {
      "type": "def",
      "children": [
        {
          "children": [
            {
              "text": "terrestrial"
            }
          ]
        },
        {
          "type": "definition",
          "children": [
            {
              "text": "This means they live on "
            },
            {
              "attributes": { "colorName": "green" },
              "type": "color",
              "children": [
                {
                  "children": [
                    {
                      "id": "3dea1cd2-19ac-43a8-868b-fca59a20c7fb",
                      "text": "land"
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    },
    { "text": " critters.\n" }
  ]
}

The JSON implements the MarklowNode interface, which can be imported in your application via:

import { MarklowNode } from "marklow";

Default matchers

Below is a list of currently supported default matchers.

nametagsupported?syntaxattributessubgroups
boldbyes**example**--
italiciyes_example_--
codecodeyes`example`--
headersh1, h2, etc.yes# title, ## title, etc.--
code blockcodeblockyes``` multiline ``` | - | -
quotequotyes""" multiline """--
linkayes[example](link)href-
imageimgyes![example](link)src, alt-
paragraph breakpbyes\n\n--
line breakbryes\n--
listsul & liunordered- example--
tables-no---

Rendering example

For an example of how marklow can be rendered in an application, check out my blog (live link to be added) and the React rendering logic on GitHub.

CLI usage

tsx marklow [-c | --config] [-i | --initial]
  • config (string): If not using the default marklow.json, where to look for the configuration file.
  • initial (boolean): If set, compiles immediately upon execution instead of first waiting for changes (default: true).

Bugs & feature requests

This library is new and was initially developed just so that I could add definitions and footnotes to my blog without moving away from markdown. If you have a bug or feature request, please feel free to leave an Issue on GitHub.

1.3.5

5 months ago

1.3.4

5 months ago

1.3.3

5 months ago

1.3.2

6 months ago

1.3.1

6 months ago

1.3.0

6 months ago

1.2.7

6 months ago

1.2.6

6 months ago

1.2.5

6 months ago

1.2.4

6 months ago

1.2.3

6 months ago

1.2.2

6 months ago

1.2.1

6 months ago

1.2.0

6 months ago

1.1.0

6 months ago

1.0.0

6 months ago