@mvarble/markdown-compiler

A cycle.js driver which compiles markdown into Snabbdom streams.

Usage no npm install needed!

<script type="module">
  import mvarbleMarkdownCompiler from 'https://cdn.skypack.dev/@mvarble/markdown-compiler';
</script>

README

Note. This project has been moved to cycle-markdown.

markdown-compiler

This is a Cycle.js component which converts a Markdown stream into that of Snabbdom. The Markdown-to-Snabbdom processing is handled by a unified processor and a collection of user-provided cycle components. As a use case, suppose I had the following Markdown for some page on a website.

# This is a title

Here is some text and a nice little Carousel of images that the user can click through to navigate.

<carousel>
  <img src="/img/1.png">
  <img src="/img/2.png">
  <img src="/img/3.png">
  <img src="/img/4.png">
</carousel>

Here are my most recently read books; showing these amounts to looking at the current state of a database.

<recent-books></recent-books>

Of course, some of this page is vanilla Markdown which can be converted, but the <carousel> and <recent-books> tags are nonstandard. Moreover, these tags may require event callbacks and asynchronous server requests. Writing Cycle.js components that act accordingly will be easy by interfacing with sources.DOM, sources.HTTP, sinks.DOM, sinks.HTTP, and the like; however, I don't want to write new apps for each new page I create on my website. This is particularly the case with a component like <carousel>, which I may repeatedly want to reuse in a blog or something of this form.

The purpose of this package is to allow the user to write a Cycle.js component like carousel of the usual sources => sinks structure and mount said component to the corresponding tag.

Writing Components

A component is able to use any sources the user would like, along with the provided sources.staleDom, which is a Snabbdom stream corresponding to the Snabbdom seralization of the HTML tag provided in the Markdown file. A component currently is only capable of manipulating the DOM and sending HTTP requests. For the former, the component should use @cycle/state functionality; that is, it should return a reducer stream of functions (previousState) => state, where the state is an object with { DOM: <Snabbdom> }. For the latter, the component should return the request to its sink.HTTP. Custom sinks will be provided in the future.

Mounting Components

By using makeMarkdownCompiler, the user may mount the components they'd like:

// no babel
const makeMarkdownCompiler = require('@mvarble/markdown-compiler').makeMarkdownCompiler;

// babel
import { makeMarkdownCompiler } from '@mvarble/markdown-compiler';

// ... create some components
function carousel(sources) {
  ...
  return { 
    state: reducerStream$
  };
}

// mount them
const app = makeMarkdownCompiler({ 'carousel': carousel });

// use withState from @cycle/state and run from @cycle/run to see!
run(withState(app), { markdown: () => someMarkdownStream$ });

As hinted, the app will take sources.markdown as the stream for parsing. Everything else from that point is handled!