Skip to content

Commit

Permalink
feat(gatsby-remark-prismjs): load languages when referred to by an al…
Browse files Browse the repository at this point in the history
…ias (gatsbyjs#13127)

Currently, referring to a language by an alias (defined in https://github.com/PrismJS/prism/tree/master/components) doesn't work unless the language is already loaded. 

This PR adds first class support for aliases so that languages are loaded when they are referred to by their aliases as well. 

Fixes gatsbyjs#13119
  • Loading branch information
sidharthachatterjee authored and DSchau committed Apr 4, 2019
1 parent 30070ec commit de8f99b
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const loadPrismLanguage = require(`../load-prism-language`)

const { getBaseLanguageName } = loadPrismLanguage

describe(`load prism language`, () => {
afterEach(() => {
jest.resetModules()
Expand Down Expand Up @@ -41,4 +43,58 @@ describe(`load prism language`, () => {
expect(Prism.languages).toHaveProperty(requiredLanguage)
expect(languagesAfterLoaded.length).toBe(languagesBeforeLoaded.length + 2)
})

describe(`aliasing`, () => {
it(`returns undefined if language does not exist`, () => {
const baseLanguage = getBaseLanguageName(`suhdude`, {
languages: {
python: {},
},
})

expect(baseLanguage).toBe(undefined)
})

it(`defaults to language, if exists in lookup`, () => {
const language = `python`

const baseLanguage = getBaseLanguageName(language, {
languages: {
[language]: {},
},
})

expect(baseLanguage).toBe(language)
})

it(`loads language that has a single alias`, () => {
const language = `python`
const alias = `py`

const baseLanguage = getBaseLanguageName(alias, {
languages: {
[language]: {
alias,
},
},
})

expect(baseLanguage).toBe(language)
})

it(`loads language that has an array of aliases`, () => {
const language = `lisp`
const alias = `emacs-lisp`

const baseLanguage = getBaseLanguageName(alias, {
languages: {
[language]: {
alias: [alias],
},
},
})

expect(baseLanguage).toBe(language)
})
})
})
36 changes: 29 additions & 7 deletions packages/gatsby-remark-prismjs/src/load-prism-language.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
const Prism = require(`prismjs`)
const components = require(`prismjs/components`)
const prismComponents = require(`prismjs/components`)

// Get the real name of a language given it or an alias
const getBaseLanguageName = (nameOrAlias, components = prismComponents) => {
if (components.languages[nameOrAlias]) {
return nameOrAlias
}
return Object.keys(components.languages).find(language => {
const { alias } = components.languages[language]
if (!alias) return false
if (Array.isArray(alias)) {
return alias.includes(nameOrAlias)
} else {
return alias === nameOrAlias
}
})
}

module.exports = function loadPrismLanguage(language) {
if (Prism.languages[language]) {
const baseLanguage = getBaseLanguageName(language)

if (!baseLanguage) {
throw new Error(`Prism doesn't support language '${language}'.`)
}

if (Prism.languages[baseLanguage]) {
// Don't load already loaded language
return
}

const languageData = components.languages[language]
if (!languageData) {
throw new Error(`Prism doesn't support language '${language}'.`)
}
const languageData = prismComponents.languages[baseLanguage]

if (languageData.option === `default`) {
// Default language has already been loaded by Prism
Expand All @@ -26,5 +45,8 @@ module.exports = function loadPrismLanguage(language) {
}
}

require(`prismjs/components/prism-${language}.js`)
require(`prismjs/components/prism-${baseLanguage}.js`)
}

/* Exposed for unit testing */
module.exports.getBaseLanguageName = getBaseLanguageName

0 comments on commit de8f99b

Please sign in to comment.