🚀 DAY 5 OF LAUNCH WEEK: Introducing Socket Firewall Enterprise.Learn more
Socket
Book a DemoInstallSign in
Socket

@vivliostyle/vfm

Package Overview
Dependencies
Maintainers
7
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vivliostyle/vfm

Custom Markdown syntax specialized in book authoring.

latest
Source
npmnpm
Version
2.4.0
Version published
Weekly downloads
801
42.02%
Maintainers
7
Weekly downloads
 
Created
Source

Vivliostyle Flavored Markdown

Actions Status: test npm-badge npm: total downloads npm: license

Vivliostyle Flavored Markdown (VFM), a Markdown syntax optimized for book authoring. It is standardized and published for Vivliostyle and its sibling projects.

Table of contents

Install

npm install -g @vivliostyle/vfm

Use

vfm --help
vfm README.md
echo "# Hello" | vfm

Usage with vivliostyle command

npm i -g @vivliostyle/cli
vfm README.md --style https://raw.githubusercontent.com/jagat-xpub/cosmology/gh-pages/css/scholarly.css > book.html
vivliostyle build book.html -s A4

API

npm install --save @vivliostyle/vfm
import { stringify } from '@vivliostyle/vfm';

console.log(
  stringify(`
# はじめに

{Vivliostyle|ビブリオスタイル}の世界へようこそ。
`),
);

This snippet will generates:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>はじめに</title>
  </head>
  <body>
    <h1>はじめに</h1>
    <p>
      <ruby>Vivliostyle<rt>ビブリオスタイル</rt></ruby
      >の世界へようこそ。
    </p>
  </body>
</html>

Options

style (default: undefined)

Set the specified value as the href attribute of <link rel="stylesheet">.

stringify('# Hello', { style: 'https://example.com/book.css' });

will generates:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" href="https://example.com/book.css" />
  </head>
  <body>
    <p><h1>Hello</h1></p>
  </body>
</html>

style can be an array of styles.

stringify('# Hello', {
  style: ['https://example.com/book.css', 'https://example.com/extra.css'],
});

will generates:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" href="https://example.com/book.css" />
    <link rel="stylesheet" href="https://example.com/extra.css" />
  </head>
  <body>
    <p><h1>Hello</h1></p>
  </body>
</html>

partial (default: false)

If true is specified, only the HTML defined in <body> is output.

stringify('# Hello', { partial: true });

will generates:

<p><h1>Hello</h1></p>

title (default: undefined)

Set the specified value as the text of <title>.

stringify('# Hello', { title: 'Hello' });

will generates:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Hello</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <p><h1>Hello</h1></p>
  </body>
</html>

language (default: undefined)

Set the specified value as the lang attribute of <html>.

stringify('# Hello', { language: 'ja' });

will generates:

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <p><h1>Hello</h1></p>
  </body>
</html>

hardLineBreaks (default: false)

Converts line breaks to <br>.

stringify(
  `
new
line
`,
  { hardLineBreaks: true },
);

will generates:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <p>
      new<br />
      line
    </p>
  </body>
</html>

disableFormatHtml (default: false)

Disable automatic HTML format. Explicitly specify true if want unformatted HTML during development or debug.

stringify(
  `text`,
  { disableFormatHtml: true },
);

will generates:

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<p>text</p>
</body>
</html>

math (default: true)

Handles math syntax. The default value is true, which is valid.

stringify(
  `$x = y$`
);

will generates:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.9/MathJax.js?config=TeX-MML-AM_CHTML"></script>
  </head>
  <body data-math-typeset="true">
    <p><span class="math inline">\(x = y\)</span></p>
  </body>
</html>

To explicitly disable it, specify false for this option or math: false for Markdown's Frontmatter.

stringify(
  `$x = y$`,
  { math: false }
);

will generates:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body>
    <p>$x = y$</p>
  </body>
</html>

Advanced usage

Unified processor

import { VFM } from '@vivliostyle/vfm';

const processor = VFM({ partial: true });
const html = processor.processSync('# Hello').toString();

Unified plugin

import unified from 'unified';
import vfm from '@vivliostyle/vfm/lib/revive-parse';
import html from '@vivliostyle/vfm/lib/revive-rehype';

function main() {
  unified()
    .use(vfm)
    .use(customRemarkPlugin)
    .use(html)
    .use(customRehypePlugin)
    .processSync('# Hello');
}

readMetadata

Read metadata from Markdown frontmatter.

Useful if just want to get the metadata, Markdown parse and metadata typing (for TypeScript) are handled by the VFM side.

readMetadata(md: string, customKeys: string[]): Metadata

  • params:
    • md: String Markdown text.
    • customKeys: String[] A collection of key names to be ignored by meta processing.
  • returns:
    • metadata: Metadata Metadata.
import { readMetadata } from '@vivliostyle/vfm'

const md = `---
id: 'my-page'
lang: 'en'
dir: 'ltr'
class: 'my-class'
title: 'Title'
vfm:
  math: false
  theme: 'sample.css'
---
`;

const metadata = readMetadata(md);
console.log(metadata);

About Metadata details, refer to VFM's "Frontmatter" or type information of TypeScript.

About customKeys

Use this if want to add custom metadata with a third party tool.

Keys that are not defined as VFM are treated as meta. If you specify a key name in customKeys, the key and its data type will be preserved and stored in custom instead of meta.

import { readMetadata } from '@vivliostyle/vfm'

const md = `---
title: 'Title'
tags: ['foo', 'bar']
---
`;

const metadata = readMetadata(md, ['tags']);
console.log(metadata);

Results:

{
  title: 'title',
  custom: {
    tags: ['foo', 'bar']
  }
}

tags is stored and retained structure in custom instead of meta.

If specify a default key such as title, it will be processed as custom.

User-specified metadata

Metadata can be specified for stringify, this specification takes precedence over Frontmatter.

The following usage is assumed.

  • Use metadata other than Frontmatter
  • Process Frontmatter metadata obtained by readMetadata
stringify(
  '# Title',
  {},
  { title: 'My Page', body: [{ name: 'id', value: 'page' }] },
);

HTML:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>My Page</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body id="page">
    <section id="title" class="level1">
      <h1>Title</h1>
    </section>
  </body>
</html>

Spec

Current Status

Principles

  • Open: steadily improving through open discussion and feedback from the vast community.
  • Consistent: Provides reference implementation for parsing and converting VFM to HTML, allowing other non Vivliostyle projects to use this syntax for their purposes.

Contribution

We want you to:

Maintainers

Keywords

markdown

FAQs

Package last updated on 05 Oct 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts