npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

jsdotmd

v0.0.4

Published

Literate JavaScript within Markdown

Downloads

10

Readme

jsdotmd

What is it?

jsdotmd takes all JavaScript inline code tags from Github Flavored Markdown file and compiles them into JavaScript file.

Why would I use it?

You can use it if you want to write extensive code documentation. See Literate programming

Why did you do that?

I wanted to make a language, whose compiler is written on itself and is also its README. Just for fun.

How to use the CLI?

Install the package globally:

npm install --global jsdotmd
# or
yarn global add jsdotmd

After installing, use the following syntax:

jsdotmd [source file] [destination file]

How to use the parser in my code?

Install the package locally:

npm install --save jsdotmd
# or
yarn add jsdotmd
import {parse} from 'jsdotmd'

const src = []
  .concat('# Hello, Markdown!')
  .concat('```javascript')
  .concat('console.log("Hello, JavaScript!")')
  .concat('```')
  .join('\n')

const result = parse(source)
//=> 'console.log("Hello, JavaScript!")'

Since working with JavaScript code in Markdown code tags in JavaScript strings is a bit messy, you can also use file-to-file compiler:

import path from 'path'
import {compile} from 'jsdotmd'

const sourcePath = path.join(__dirname, 'index.js.md')
const destinationPath = path.join(__dirname, 'index.js')

compile(sourcePath, destinationPath)
  .catch((err) => console.log('Something went wrong!', err))

How does the parser work?

The code is very simple.

It uses only two dependencies:

  • marked for parsing Markdown source file. We don't need the HTML output, so we use only lexer.

    const {lexer} = require('marked')
  • fs-promise to work with the file system easier.

    const fs = require('fs-promise')

By default, jsdotmd compiles into JavaScript code only those Markdown inline code tags, which are marked javascript, js or node.

const defaultLangCodes = ['javascript', 'js', 'node']

From CLI, you can specify tags like this:

jsdotmd [source file] [destination file] -l js,javascript,node,jsx,typescript

parse function

function parse (source, options) {
  options = options || {}

  const langCodes = options.langCodes || defaultLangCodes
  const separator = options.separator || '\n\n'

parse function joins code blocks using separator specified in the second argments options which is two line breaks by default.

  const tokens = lexer(source)

Lexer returns an array of tokens. We are only interested in tokens with type 'code'. They look like this:

{
  type: 'code',
  lang: 'javascript',
  text: '  const tokens = lexer(source)'
}

Next we filter only the tokens we need, retrieve text from them and join them with a separator.

  const code = tokens
    .filter(({type, lang}) => type === 'code' && langCodes.includes(lang))
    .map(({text}) => text)
    .join(separator)

  return code
}

compile function

Compile function is even simpler. It just reads file, specified in the first argument, parses it with parse and writes it to file, specified in the second argument. Done!

function compile (sourcePath, destinationPath, options) {
  options = options || {}

  const encoding = options.encoding || 'utf-8'

  return fs.readFile(sourcePath, {encoding})
    .then((contents) => parse(contents, options))
    .then((code) => fs.writeFile(destinationPath, code, {encoding}))
}

jsdotmd exports both parse and compile functions for you to use.

module.exports = {parse, compile}

How does the CLI work?

It uses commander. Check bin/jsdotmd.js. I haven't written it in jsdotmd for simplicity.

I've made changes to the code. How to recompile the compiler?

Run npm run build. It compiles README.md into lib/index.js.

How to test if the code works?

Run npm test. It runs npm run build two times. If the compiler compiles itself after the recompiling, it probably works. If not, well, no luck.

Should I use it in the real project?

Probably not.

That's super weird.

Thank you.