  # <zero-md> > Ridiculously simple zero-config markdown displayer A native markdown-to-html web component based on [Custom Elements V1 specs](https://www.w3.org/TR/custom-elements/) to load and display an external MD file. Under the hood, it uses [Marked](https://github.com/markedjs/marked) for super-fast markdown transformation, and [Prism](https://github.com/PrismJS/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](https://github.com/zerodevx/zero-md/tree/v1).** Featuring: - [x] Automated hash-link scrolls - [x] Built-in FOUC prevention - [x] Automatically rewrite URLs relative to `src` - [x] Automatically re-render when `src` changes - [x] Automatically re-render when inline markdown or style template changes - [x] Support for >200 code languages with detection for unhinted code blocks - [x] Easy styling mechanism - [x] 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](https://developer.mozilla.org/en-US/docs/Web/HTTP/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. ```html <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](https://nodejs.org/) installed. ``` $ npm install --save zero-md ``` Import the class, register the element, and use anywhere. ```js // 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. ```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 ```html <!-- 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: ```html <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. ```html <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 ```html <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 ```html <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. ```html <!-- 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 ```html <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. ```html <!-- 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> ``` 2. Markdown source behaviour has changed. Think of `<script type="text/markdown">` as a "fallback". ```html <!-- 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> ``` 3. The `css-urls` attribute is deprecated. Use `<link rel="stylesheet">` instead. ```html <!-- 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> ``` 4. 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`. ```html <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> ``` 5. The global config object has been renamed from `ZeroMd.config` to `ZeroMdConfig`. ```html <!-- 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> ``` 6. 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](https://github.com/zerodevx/zero-md/issues) in the Github repo, or raise a [PR](https://github.com/zerodevx/zero-md/pulls)! I'd be stoked to accept any contributions! ### Develop locally #### Install Fork and clone the project, then install dependencies. ```bash $ cd zero-md $ npm install ``` #### Run the dev server ```bash $ 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](https://mochajs.org/) with [Chai](https://www.chaijs.com/) 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](https://standardjs.com/) format. Run the linter with: ```bash $ 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](https://pages.github.com/) and based on [`zero-md-docs`](https://github.com/zerodevx/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](https://github.com/EmilePerron), [@bennypowers](https://github.com/bennypowers), [@TheUnlocked](https://github.com/TheUnlocked), [@ernsheong](https://github.com/ernsheong) for your code commits. :thumbsup: ## Version History Check out the [releases](https://github.com/zerodevx/zero-md/releases) page.