Giter Site home page Giter Site logo

hubdown's Introduction

hubdown

CircleCI build status

Convert markdown to GitHub-style HTML using a common set of remark and rehype plugins

Used by electron/i18n and electronjs.org.

unified processes content with syntax trees and transforms between different formats. remark and rehype are its markdown and HTML ecosystems. We use this because its performant and has a large collection of plugins. Primarily, unlike some other node markdown parsers that provide syntax highlighting capabilities, unified does not have any native C++ dependencies. This makes it easier to install and reduces the likelihood of system-dependent installation failures.

Plugins

The following remark and rehype plugins are used by hubdown:

Installation

npm install hubdown --save

Usage

hubdown exports a single function that returns a promise:

const hubdown = require('hubdown')

hubdown('I am markdown').then(doc => {
  console.log(doc)
})

The resolved promise yields an object with a content property containing the parsed HTML:

{
  content: '<p>I am markdown</p>'
}

Usage with Cache

hubdown's remark markdown parser is pretty fast, but things can start to slow down when you're processing hundreds or thousands of files. To make life easier in these situations you can use hubdown's optional cache, which stores preprocessed markdown for fast retrieval on subsequent runs.

To use the cache, bring your own level instance and supply it as an option to hubdown. This helps keep hubdown lean on (native) dependencies for users who don't need the cache.

const hubdown = require('hubdown')
const cache = require('level')('./my-hubdown-cache')

hubdown('I will be cached.', { cache }).then(doc => {
  console.log(doc)
})

API

hubdown(markdownString[, options])

Arguments:

  • markdownString String - (required)
  • options Object - (optional)
    • runBefore Array of remark plugins - Custom plugins to be run before the commonly used plugins listed above.
    • frontmatter Boolean - Whether or not to try to parse YML frontmatter in the file. Defaults to false.
    • cache LevelDB - An optional level instance in which to store preprocessed content. See Usage with Cache.
    • highlight - Object of rehype-highlight options.

Returns a promise. The resolved object looks like this:

{
  content: 'HTML goes here'
}

If YML frontmatter is parsed, those properties will be present on the object too:

{
  title: 'The Feminine Mystique',
  author: 'Betty Friedan',
  content: '<p>The Feminine Mystique is a book written by Betty Friedan which is widely credited with sparking the  beginning of second-wave feminism in the United States.</p>'
}

Tests

npm install
npm test

License

MIT

hubdown's People

Contributors

ckerr avatar dependabot[bot] avatar dsanders11 avatar erickzhao avatar marshallofsound avatar sarahs avatar sofianguy avatar vhashimotoo avatar wooorm avatar zeke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hubdown's Issues

Add copy button & language name to code blocks

Hello! I'm opening this on behalf of the GitHub Docs team πŸ‘‹ We'd like to add a copy-to-clipboard button to code fences, automatically as part of the rendering pipeline. One way that we've done this in the past is with a custom Unified plugin

I yoinked this out of another project, but here's some code
import { Node } from 'hast'
import h from 'hastscript'
import octicons from '@primer/octicons'
import parse5 from 'parse5'
import fromParse5 from 'hast-util-from-parse5'

const LANGUAGE_MAP = {
  'asp': 'ASP',
  // ...
}

interface CodeNode extends Node {
  lang: string
  value: string
}

/**
 * Adds a bar above code blocks that shows the language and a copy button
 */
export default function addCodeHeader (node: CodeNode) {
  const language = LANGUAGE_MAP[node.lang] || node.lang || 'Code'

  const btnIconHtml = octicons.clippy.toSVG()
  const btnIconAst = parse5.parse(String(btnIconHtml))
  const btnIcon = fromParse5(btnIconAst, btnIconHtml)

  const header = h('header', 
    {
      class: [
        'd-flex',
        'flex-items-center',
        'flex-justify-between',
        'p-2',
        'text-small',
        'rounded-top-1',
        'border'
      ]
    }, [
    h('span', language),
    h(
      'button',
      {
        class: ['js-btn-copy', 'btn', 'btn-sm', 'tooltipped', 'tooltipped-nw'],
        ['data-clipboard-text']: node.value,
        ['aria-label']: 'Copy code to clipboard'
      },
      btnIcon
    )
  ])

  return {
    before: [header]
  }
}

That generates a <header> that looks like this:

The actual copy-to-clipboard functionality is handled by some delegated events, but it doesn't have to be.

I'd love to add this kind of functionality here in hubdown, but there are a couple of decisions to be made, all of which are pretty specific to our use-case. So for us to add this to the render pipeline for github/docs, we have to:

  • Add this plugin to hubdown's createProcessor, which may cause unwanted changes to other consumers like Electron's docs
  • Fork (and maintain our fork of) hubdown, which is also not ideal
  • Export createProcessor from hubdown, and inject this one plugin at a particular point to it

Wondering if y'all have any thoughts on the right approach here. Is this feature something you've wanted in the past? I'm happy to work with y'all to make it useful for both Electron and docs.github.com!

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Missing CFA_HOST environment variable

Unfortunatly this error doesn't have any additionnal information. Feel free to kindly ask the author of the @continuous-auth/semantic-release-npm plugin to add more helpful informations.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

remark-heading-id extension not used when run before remark processor

@wooorm Zeke forwarded me to you as the maintainer of remark and the Unified.js ecosystem. The docs provided for Unified.js are excellent! πŸ™Œ I'm testing out adding an extension and also looking at writing a new extension, and I'm running into some issues. Can you confirm if this is a bug in the extension or hubdown?

I'm testing out the remark-heading-id extension and it seems that the placement of the extension in the runBefore list determines whether it works or not.

When the remark-heading-id extension is listed first in this pull request, the extension works:

Screen Shot 2021-01-11 at 9 17 52 PM

When it's not listed first, the custom id is rendered as part of the heading:

Screen Shot 2021-01-11 at 9 18 12 PM

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.