/zero-md

Ridiculously simple zero-config markdown displayer

Primary LanguageJavaScriptISC LicenseISC

GitHub package.json version jsDelivr hits (GitHub)

<zero-md>

Ridiculously simple zero-config markdown displayer

A native markdown-to-html web component based on Custom Elements V1 specs to load and display an external MD file. Under the hood, it uses Marked for super-fast markdown transformation, and Prism for feature-packed syntax highlighting - automagically rendering into its own self-contained shadow DOM container, while encapsulating implementation details into one embarassingly easy-to-use package.

NOTE: This is the V2 branch. If you're looking for the older version, see the V1 branch.

Featuring:

  • Automated hash-link scrolls
  • Built-in FOUC prevention
  • Automatically rewrite URLs relative to src
  • Automatically re-render when src changes
  • Support for >200 code languages with detection for unhinted code blocks
  • Easy styling mechanism
  • Highly extensible

Documentation: https://zerodevx.github.io/zero-md/

Installation

Load via CDN (recommended)

zero-md is designed to be zero-config with good defaults. For most use-cases, just importing the script from CDN and consuming the component directly should suffice.

<head>
  ...
  <!-- Import element definition -->
  <script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@2/dist/zero-md.min.js"></script>
  ...
</head>
<body>
  ...
  <!-- Profit! -->
  <zero-md src="/example.md"></zero-md>
  ...
</body>

Latest stable: https://cdn.jsdelivr.net/gh/zerodevx/zero-md@2/dist/zero-md.min.js

Latest beta: https://cdn.jsdelivr.net/npm/zero-md@next/dist/zero-md.min.js

Install in web projects

Install package with npm or yarn. Note that you'll need Node.js installed.

$ npm install --save zero-md

Import the class, register the element, and use anywhere.

// Import the element definition
import ZeroMd from 'zero-md'

// Register the custom element
customElements.define('zero-md', ZeroMd)

// Render anywhere
app.render(`<zero-md src=${src}></zero-md>`, target)

Or load the distribution directly in HTML.

<script type="module" src="/node_modules/zero-md/dist/zero-md.min.js"></script>
...
<zero-md src="example.md"></zero-md>

Basic Usage

Display an external markdown file

<!-- Simply set the `src` attribute and win -->
<zero-md src="https://example.com/markdown.md"></zero-md>

At its most basic, <zero-md> loads and displays an external MD file with default stylesheets - a Github-themed stylesheet paired with a light-themed one for code blocks, just like what you see in these docs. So internally, the above code block is semantically equivalent to the one below:

<zero-md src="https://example.com/markdown.md">
  <!-- By default, this style template gets loaded -->
  <template>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/sindresorhus/github-markdown-css@4/github-markdown.min.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/PrismJS/prism@1/themes/prism.min.css">
  </template>
</zero-md>

Using your own styles

To override the default theme, supply your own style template.

<zero-md src="https://example.com/markdown.md">
  <!-- Wrap with a <template> tag -->
  <template>
    <!-- Define your own styles inside a `<style>` tag -->
    <style>
      h1 {
        color: red;
      }
      ...
    </style>
  </template>
</zero-md>

Or your own stylesheets

<zero-md src="https://example.com/markdown.md">
  <!-- Wrap with a <template> tag -->
  <template>
    <!-- Load external stylesheets with a `<link rel="stylesheet">` tag -->
    <link rel="stylesheet" href="markdown-styles.css">
    <link rel="stylesheet" href="highlight-styles.css">
  </template>
</zero-md>

Or both

<zero-md src="https://example.com/markdown.md">
  <template>
    <!-- The CSS load order is respected -->
    <link rel="stylesheet" href="markdown-styles.css">
    <style>
      h1 {
        color: red;
      }
    </style>
    <link rel="stylesheet" href="highlight-styles.css">
    <style>
      code {
        background: yellow;
      }
    </style>
  </template>
</zero-md>

Write markdown inline

You can pass in your markdown inline too.

<!-- Do not set the `src` attribute -->
<zero-md>
  <!-- Write your markdown inside a `<script type="text/markdown">` tag -->
  <script type="text/markdown">
# **This** is my [markdown](https://example.com)
  </script>
</zero-md>

By default, <zero-md> first tries to render src. If src is falsy (undefined, file not found, empty file etc), it falls-back to the contents inside the <script type="text/markdown"> tag.

Put it all together

<zero-md src="https://example.com/markdown.md">
  <template>
    <link rel="stylesheet" href="markdown-styles.css">
    <style>
      h1 {
        color: red;
      }
    </style>
    <link rel="stylesheet" href="highlight-styles.css">
    <style>
      code {
        background: yellow;
      }
    </style>
  </template>
  <script type="text/markdown">
This is the fall-back markdown that will **only show** when `src` is falsy.
  </script>
</zero-md>

API

Advanced usage: https://zerodevx.github.io/zero-md/advanced-usage/

Attributes and helpers: https://zerodevx.github.io/zero-md/attributes-and-helpers/

Configuration: https://zerodevx.github.io/zero-md/configuration/

Migrating from V1 to V2

  1. Support for <xmp> tag is removed; use <script type="text/markdown"> instead.
<!-- Previous -->
<zero-md>
  <template>
    <xmp>
# `This` is my [markdown](example.md)
    </xmp>
  </template>
</zero-md>

<!-- Now -->
<zero-md>
  <!-- No need to wrap with <template> tag -->
  <script type="text/markdown">
# `This` is my [markdown](example.md)
  </script>
</zero-md>

<!-- If you need your code to be pretty, -->
<zero-md>
  <!-- Set `data-dedent` to opt-in to dedent the text during render -->
  <script type="text/markdown" data-dedent>
    # It is important to be pretty
    So having spacing makes me happy.
  </script>
</zero-md>
  1. Markdown source behaviour has changed. Think of <script type="text/markdown"> as a "fallback".
<!-- Previous -->
<zero-md src="will-not-render.md">
  <template>
    <xmp>
# This has first priority and will be rendered instead of `will-not-render.md`
    </xmp>
  </template>
<zero-md>

<!-- Now -->
<zero-md src="will-render-unless-falsy.md">
  <script type="text/markdown">
# This will NOT be rendered *unless* `src` resolves to falsy
  </script>
<zero-md>
  1. The css-urls attribute is deprecated. Use <link rel="stylesheet"> instead.
<!-- Previous -->
<zero-md src="example.md" css-urls='["/style1.css", "/style2.css"]'><zero-md>

<!-- Now, this... -->
<zero-md src="example.md"></zero-md>

<!-- ...is actually equivalent to this -->
<zero-md src="example.md">
  <template>
    <!-- These are the default stylesheets -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/sindresorhus/github-markdown-css@4/github-markdown.min.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/PrismJS/prism@1/themes/prism.min.css">
  </template>
</zero-md>

<!-- So, to apply your own external stylesheets... -->
<zero-md src="example.md">
  <!-- ...you overwrite the default template -->
  <template>
    <!-- Use <link> tags to reference your own stylesheets -->
    <link rel="stylesheet" href="/style1.css">
    <link rel="stylesheet" href="/style2.css">
    <!-- You can even apply additional styles -->
    <style>
      p {
        color: red;
      }
    </style>
  </template>
</zero-md>

<!-- If you like the default stylesheets but wish to apply some overrides -->
<zero-md src="example.md">
  <!-- Set `data-merge` to "append" to apply this template AFTER the default template -->
  <!-- Or "prepend" to apply this template BEFORE -->
  <template data-merge="append">
    <style>
      p {
        color: red;
      }
    </style>
  </template>
</zero-md>
  1. The attributes marked-url and prism-url are deprecated. To load marked or prism from another location, simply load their scripts before importing zero-md.
<head>
  ...
  <script defer src="/lib/marked.js"></script>
  <script defer src="/lib/prism.js"></script>
  <script type="module" src="/lib/zero-md.min.js"></script>
</head>
  1. The global config object has been renamed from ZeroMd.config to ZeroMdConfig.
<!-- Previous -->
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
<script>
  window.ZeroMd = {
    config: {
      cssUrls: [
        '/styles/my-markdown-theme.css',
        '/styles/my-highlight-theme.css'
      ]
    }
  };
</script>
<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script>

<!-- Now -->
<script>
  window.ZeroMdConfig = {
    cssUrls: [
      '/styles/my-markdown-theme.css',
      '/styles/my-highlight-theme.css'
    ]
  }
</script>
<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@2/dist/zero-md.min.js"></script>
  1. The convenience events zero-md-marked-ready and zero-md-prism-ready are removed and will no longer fire. Instead, the zero-md-ready event guarantees that everything is ready, and that render can begin.

Contributing

Noticed a bug? Have a feature request?

Open a new issue in the Github repo, or raise a PR! I'd be stoked to accept any contributions!

Develop locally

Install

Fork and clone the project, then install dependencies.

$ cd zero-md
$ npm install

Run the dev server

$ npm run dev

Open your browser to http://localhost:5000. You should see the test suite running.

Testing

Tests are browser-based and run on Mocha with Chai asserts. If you're adding a new feature or bugfixing, please add the corresponding regression test into test/index.spec.js accordingly.

Tests can be run by pointing your browser to http://localhost:5000.

Linting

Code should be in Standardjs format. Run the linter with:

$ npm run lint

Making changes to source

If you're adding a new feature or bugfixing, please commit your changes into a new branch and raise a pull-request into the main branch upstream, and reference the related issues.

Running the docs

The docs (as seen in https://zerodevx.github.io/zero-md/) can be accessed by pointing your browser to http://localhost:5000/docs/ (note the trailing slash).

Making changes to docs

Documentation is stored in the /docs folder, published with Github Pages and based on zero-md-docs. The markdown for each section is located in readme.md in its corresponding pretty URL.

In general, just raising a PR on readme.md files should suffice.

License

ISC

Version History

Check out the releases page.