/amunet

Amunet : markdown metadata hidden

Primary LanguageJavaScriptMIT LicenseMIT

Amunet

Amunet : markdown metadata hidden

Test Github Status Coverage Status version node-version downloads

MIT License PRs Welcome Code of Conduct XO code style

Watch on GitHub Star on GitHub

The goal

The goal is to embed invisible metadata in a Markdown file when this file will be rendered on a web page, for example under Github.

There is a solution that is described on Stackoverflow to add comments that will be invisible when rendering. To summarize, the following syntax allows you to include comments that will not be rendered on an HTML page:

[comment]: # (Hello world)

In general, this approach should work with most Markdown parsers, since it's part of the core specification.

The complementary idea for adding metadata is to produce the metadata as key/value pairs. Just place the key between the brackets, and the value between the parentheses:

[key1]: # (value1)
[key2]: # (value2)
[a]: # (1)
[foo] # (bar)

Amunet is the tool to parse and produce this concept easily in your Markdown files.

Note that this README.md file contains a filename metadata with the value README.md. It is not visible on this web page, but if you see the contents of the file in the second line, you can see this metadata:

[filename]: # (README.md)

Table of Contents

Installation

This module is distributed via npm which is bundled with node and should be installed as one of your project's devDependencies:

npm install --save-dev amunet

Usage

Node.js

const path = require('path');
const amunet = require('amunet');

// ----------------------------
// Read the file synchronously
// ----------------------------
const file = amunet.readSync(path.join(__dirname, 'README.md'));
console.log(file.metadata);
//=> With the 'README.md' file of this package => { filename: 'README.md' }

// -----------------------------
// Read the file asynchronously
// -----------------------------
(async () => {
  const fileSync = await amunet.read(path.join(__dirname, 'README.md'));
  console.log(fileSync.metadata);
  // With the 'README.md' file of this package => { filename: 'README.md' }
})();

Or from a remote location:

const https = require('https');
const amunet = require('amunet');

const getRemoteMetadata = url => new Promise((resolve, reject) => {
  https.get(url, resp => {
    resp.once('data', buffer => {
      resp.destroy();
      resolve(amunet.parse(buffer.toString('utf8')));
    });
  }).on('error', error => {
    reject(error);
  });
});

(async () => {
  console.log(await getRemoteMetadata('https://raw.githubusercontent.com/forresst/amunet/master/README.md'));
  // With the 'README.md' file of this package => { filename: 'README.md' }
})();

API

amunet.parse(input)

Parse the content of the string. Returns a object with the metadata (key/value pairs).

input

Type: string

The string to parse.

return

Type: object

The object with the metadata as key\value pairs.

Note: If the string does not contain metadata, the function returns an empty object.

Example

index.js:

const amunet = require('amunet');

const inputString = `
[a]: # (1)
[b]: # (Hello)

# Doc

Hello world
`;

console.log(amunet.parse(inputString));
//=> { a: '1', b: 'Hello' }

amunet.stringify(input, objectAfter)

Add/change/remove the content of the input string with the object objectAfter. Returns a string with the modified content.

Notes:

  • If a key does not exist in the input string and exists in object objectAfter, the key/value pair is appended to the content with the value of objectAfter.
  • If a key exists in the input string and exists in object objectAfter and the value is changed, the key/value pair is changed in the content with the value of objectAfter.
  • If a key exists in the input string and exists in object objectAfter and the value is not changed, the content is not changed.
  • If a key exists in the input string but does not exist in object objectAfter, the key/value pair is removed.

input

Type: string

The string to stringify.

objectAfter

Type: object

The object with all metadata as key\value pairs.

return

Type: string

The string with the content changed.

Example

index.js:

const amunet = require('amunet');

const inputString = `
[a]: # (1)
[b]: # (Hello)
[c]: # (3)

# Doc

Hello world
`;

console.log(amunet.stringify(inputString, { a: '1', b: 'World', d: '4' }));
//=> `
// [d]: # (4)
// [a]: # (1)
// [b]: # (World)
//
// # Doc
//
// Hello world
// `

amunet.read(filePath)

Read asynchronously a file and parse its content. Returns a Promise<object> with the parsed metadata of the specified file (filePath).

filePath

Type: string

return

Type: Promise<object>

The object contains the metadata as key\value pairs found in the specified file.

Notes:

  • If the file does not exist, the function returns an empty object.
  • If the file does not contain metadata, the function returns an empty object.

Example

README.md:

[a]: # (1)
[b]: # (Hello)

# Doc

Hello world

index.js:

const path = require('path');
const amunet = require('amunet');

(async () => {
  const fileAsync = await amunet.read(path.join(__dirname, 'README.md'));
  console.log(fileAsync);
  //=> { a: '1', b: 'Hello' }
})();

amunet.readSync(filePath)

Read synchronously a file and parse its content. Returns a object with the parsed metadata of the specified file (filePath).

filePath

Type: string

return

Type: object

The object contains the metadata as key\value pairs found in the specified file.

Notes:

  • If the file does not exist, the function returns an empty object.
  • If the file does not contain metadata, the function returns an empty object.

Example

README.md:

[a]: # (1)
[b]: # (Hello)

# Doc

Hello world

index.js:

const path = require('path');
const amunet = require('amunet');

const fileSync = amunet.readSync(path.join(__dirname, 'README.md'));
console.log(fileSync);
//=> { a: '1', b: 'Hello' }

amunet.write(filePath, objectAfter, options?)

Write asynchronously a file (filePath) and change its content with object objectAfter.

filePath

Type: string

objectAfter

Type: object

The object with all metadata as key\value pairs.

options

Type: object

  • createFolderUnknown: create the folder of the file if the folder does not exist
    • Type: boolean
    • Default: true
  • createFileUnknown: create the file if the file does not exist
    • Type: boolean
    • Default: true

return

Type: Promise

Example

README.md:

[a]: # (1)
[b]: # (Hello)
[c]: # (3)

# Doc

Hello world

index.js:

const path = require('path');
const amunet = require('amunet');

(async () => {
  await amunet.write(path.join(__dirname, 'README.md'), { a: '1', b: 'World', d: '4' });
  //=> new content of README.md:
  // [d]: # (4)
  // [a]: # (1)
  // [b]: # (World)
  //
  // # Doc
  //
  // Hello world
})();

amunet.writeSync(filePath, objectAfter, options?)

Write synchronously a file (filePath) and change its content with object objectAfter.

filePath

Type: string

objectAfter

Type: object

The object with all metadata as key\value pairs.

options

Type: object

  • createFolderUnknown: create the folder of the file if the folder does not exist
    • Type: boolean
    • Default: true
  • createFileUnknown: create the file if the file does not exist
    • Type: boolean
    • Default: true

return

Nothing

Example

README.md:

[a]: # (1)
[b]: # (Hello)
[c]: # (3)

# Doc

Hello world

index.js:

const path = require('path');
const amunet = require('amunet');

amunet.writeSync(path.join(__dirname, 'README.md'), { a: '1', b: 'World', d: '4' });
//=> new content of README.md:
// [d]: # (4)
// [a]: # (1)
// [b]: # (World)
//
// # Doc
//
// Hello world

LICENSE

MIT