zero-md

Ridiculously simple zero-config markdown displayer

Usage no npm install needed!

<script type="module">
  import zeroMd from 'https://cdn.skypack.dev/zero-md';
</script>

README

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
  • Automatically re-render when inline markdown or style template changes
  • Support for >200 code languages with detection for unhinted code blocks
  • Easy styling mechanism
  • Highly extensible

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

NOTE: Your markdown file(s) needs to be hosted! Browsers don't generally allow javascript to access files on the local hard drive because of security concerns. Standard CORS rules apply.

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

Acknowledgements

Big thank you to contributors @EmilePerron, @bennypowers, @TheUnlocked, @ernsheong for your code commits. :thumbsup:

Version History

Check out the releases page.