Pagic
The easiest way to generate static html page from markdown, built with Deno! 🦕
Features
- Markdown + Layout => HTML
- React component as a page
- Copy static files
- Sub pages and layouts
- Front matter
- Configuration
- Plugins and themes
WARNING: This project is under development so api would changes without announce. The stable version will some soon when v1.0.0 finished.
Live demo
- Deno X ranking (GitHub)
- TypeScript 入门教程 (GitHub)
- Deno 钻研之术 (GitHub)
- Deno 中文手册 (GitHub)
- Add my site as a demo 😝
Getting started
Installation
# Install deno https://deno.land/#installation
curl -fsSL https://deno.land/x/install/install.sh | sh
# Install pagic
deno install --unstable --allow-read --allow-write --allow-net --name pagic https://deno.land/x/pagic/mod.ts
Docker
alias pagic='docker run -it --rm -v $PWD:/pagic yardenshoham/pagic'
Markdown + Layout => HTML
Let’s say we have a project like this:
docs/
├── public/
└── src/
├── _layout.tsx
└── index.md
The src/_layout.tsx
is a simple react component:
// @deno-types="https://deno.land/x/pagic/src/types/react/v16.13.1/react.d.ts"
import React from 'https://dev.jspm.io/react@16.13.1';
import { PagicLayout } from 'https://deno.land/x/pagic/mod.ts';
const Layout: PagicLayout = ({ title, content }) => (
<html>
<head>
<title>{title}</title>
<meta charSet="utf-8" />
</head>
<body>{content}</body>
</html>
);
export default Layout;
The src/index.md
is a simple markdown file:
# Pagic
The easiest way to generate static html page from markdown, built with Deno! 🦕
Then run:
pagic build
We’ll get an index.html
file in public
directory:
docs/
├── public/
| └── index.html
└── src/
├── _layout.tsx
└── index.md
The content should be:
<html>
<head>
<title>Pagic</title>
<meta charset="utf-8" />
</head>
<body>
<article>
<h1 id="pagic">Pagic</h1>
<p>The easiest way to generate static html page from markdown, built with Deno! 🦕</p>
</article>
</body>
</html>
React component as a page
A react component can also be built to html:
docs/
├── public/
| ├── index.html
| └── hello.html
└── src/
├── _layout.tsx
├── index.md
└── hello.tsx
Here we build src/hello.tsx
to public/hello.html
, using src/_layout.tsx
as the layout.
src/hello.tsx
is a simple react component:
// @deno-types="https://deno.land/x/pagic/src/types/react/v16.13.1/react.d.ts"
import React from 'https://dev.jspm.io/react@16.13.1';
const Hello = () => <h1>Hello World</h1>;
export default Hello;
And public/hello.html
would be:
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
Copy static files
If there are other static files which are not end with .{md,tsx}
or (start with _
and end with .tsx
), we will simply copy them:
docs/
├── public/
| ├── assets
| | └── index.css
| ├── index.html
| └── hello.html
└── src/
├── assets
| └── index.css
├── _layout.tsx
├── _sidebar.tsx
├── index.md
└── hello.tsx
Sub pages and layouts
We can have sub directory which contains markdown or component.
Sub directory can also have a _layout.tsx
file.
For each markdown or react component, it will walk your file system looking for the nearest _layout.tsx
. It starts from the current directory and then moves to the parent directory until it finds the _layout.tsx
.
docs/
├── public/
| ├── assets
| | └── index.css
| ├── index.html
| └── hello.html
| └── sub
| └── index.html
└── src/
├── assets
| └── index.css
├── _layout.tsx
├── _sidebar.tsx
|── index.md
└── sub
├── _layout.tsx
└── index.md
Front matter
Front matter allows us add extra meta data to markdown:
---
author: xcatliu
published: 2020-05-20
---
# Pagic
The easiest way to generate static html page from markdown, built with Deno! 🦕
Every item in the front matter will pass to the _layout.tsx
as the props:
// @deno-types="https://deno.land/x/pagic/src/types/react/v16.13.1/react.d.ts"
import React from 'https://dev.jspm.io/react@16.13.1';
import { PagicLayout } from 'https://deno.land/x/pagic/mod.ts';
const Layout: PagicLayout = ({ title, content, author, published }) => (
<html>
<head>
<title>{title}</title>
<meta charSet="utf-8" />
</head>
<body>
{content}
<footer>
Author: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>a</mi><mi>u</mi><mi>t</mi><mi>h</mi><mi>o</mi><mi>r</mi></mrow><mo separator="true">,</mo><mi>P</mi><mi>u</mi><mi>b</mi><mi>l</mi><mi>i</mi><mi>s</mi><mi>h</mi><mi>e</mi><mi>d</mi><mo>:</mo></mrow><annotation encoding="application/x-tex">{author}, Published: </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="mord mathnormal">u</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal" style="margin-right:0.02778em;">or</span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mord mathnormal">u</span><span class="mord mathnormal">b</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span></span></span></span>{published}
</footer>
</body>
</html>
);
export default Layout;
Front matter in react component
In react component we can export a frontMatter
variable:
// @deno-types="https://deno.land/x/pagic/src/types/react/v16.13.1/react.d.ts"
import React from 'https://dev.jspm.io/react@16.13.1';
const Hello = () => <h1>Hello World</h1>;
export default Hello;
export const frontMatter = {
title: 'Hello World',
author: 'xcatliu',
published: '2020-05-20'
};
Configuration
It’s able to configurate pagic by adding a pagic.config.ts
file. The default configuration is:
export default {
srcDir: '.',
outDir: 'dist',
include: undefined,
exclude: [
// Dot files
'**/.*',
// Node common files
'**/package.json',
'**/package-lock.json',
'**/node_modules',
'pagic.config.ts',
'pagic.config.tsx',
// https://docs.npmjs.com/using-npm/developers.html#keeping-files-out-of-your-package
'**/config.gypi',
'**/CVS',
'**/npm-debug.log'
// ${config.outDir} will be added later
],
root: '/',
theme: 'default',
plugins: ['clean', 'init', 'md', 'tsx', 'script', 'layout', 'out'],
watch: false,
serve: false,
port: 8000
};
Your pagic.config.ts
will be deep-merge to the default config, that is, your exclude
and plugins
will be appended to default, not replace it.
Plugins and themes
As you see default plugins are set to ['init', 'md', 'tsx', 'script', 'layout', 'write']
.
We can add the optional plugins by setting the plugins
in the pagic.config.ts
file:
export default {
srcDir: 'site',
plugins: ['sidebar']
};
sidebar
plugin will add a sidebar
properity to the props.
We can also add our own plugin like this:
import myPlugin from './myPlugin.tsx';
export default {
srcDir: 'site',
plugins: [myPlugin]
};
To develop a myPlugin
please checkout the built-in plugins.
Themes is under development, please come back later!
Use pagic as cli
pagic build
We can use pagic build
to build static pages, there are some options while using build
command:
pagic build [options]
# --watch watch src dir change
# --serve serve public dir
# --port override default port
LICENSE
Have fun with pagic!