From 13b30dcd6ac7289a62fcb9a7c7a7b5f6da4229ab Mon Sep 17 00:00:00 2001 From: Chris Pymm Date: Thu, 3 Aug 2023 14:23:47 +0100 Subject: [PATCH] Add option to generate govspeak gem compatible classes --- lib/class-generator.js | 8 ++ lib/class-names.js | 31 ++++++++ lib/extensions/address.js | 3 +- lib/extensions/button.js | 6 +- lib/extensions/call-to-action.js | 3 +- lib/extensions/contact.js | 3 +- lib/extensions/example.js | 3 +- lib/extensions/form-download.js | 3 +- lib/extensions/information-callout.js | 4 +- lib/extensions/information.js | 3 +- lib/extensions/place.js | 3 +- lib/extensions/stat-headline.js | 3 +- lib/extensions/steps.js | 4 +- lib/extensions/warning-callout.js | 4 +- tests/compatibility.mjs | 103 ++++++++++++++++++++++++++ 15 files changed, 171 insertions(+), 13 deletions(-) create mode 100644 lib/class-generator.js create mode 100644 lib/class-names.js create mode 100644 tests/compatibility.mjs diff --git a/lib/class-generator.js b/lib/class-generator.js new file mode 100644 index 0000000..3e616e7 --- /dev/null +++ b/lib/class-generator.js @@ -0,0 +1,8 @@ +const defaultClassNames = require('./class-names').default +const gemCompatibleClassNames = require('./class-names').compatible + +module.exports = function (component) { + const classNames = this.parser.options.govspeakGemCompatibility ? gemCompatibleClassNames : defaultClassNames + + return classNames[component] ?? '' +} diff --git a/lib/class-names.js b/lib/class-names.js new file mode 100644 index 0000000..f6c9f7e --- /dev/null +++ b/lib/class-names.js @@ -0,0 +1,31 @@ +module.exports.default = { + address: 'govspeak-address h-adr', + button: 'govuk-button', + 'button--start': 'govuk-button govuk-button--start', + 'call-to-action': 'govspeak-call-to-action', + contact: 'govspeak-contact', + example: 'govspeak-example', + 'form-download': 'govspeak-form-download', + 'information-callout': 'govspeak-information-callout', + information: 'govspeak-information', + place: 'govspeak-place', + 'stat-headline': 'govspeak-stat-headline', + steps: 'govspeak-steps', + 'warning-callout': 'govspeak-warning-callout' +} + +module.exports.compatible = { + address: 'address', + button: 'gem-c-button govuk-button', + 'button--start': 'gem-c-button govuk-button govuk-button--start', + 'call-to-action': 'call-to-action', + contact: 'contact', + example: 'example', + 'form-download': 'form-download', + 'information-callout': 'application-notice info-notice', + information: 'information', + place: 'place', + 'stat-headline': 'stat-headline', + steps: 'steps', + 'warning-callout': 'application-notice help-notice' +} diff --git a/lib/extensions/address.js b/lib/extensions/address.js index f704719..b9a4cef 100644 --- a/lib/extensions/address.js +++ b/lib/extensions/address.js @@ -1,4 +1,5 @@ const blockTokenizer = require('../block-tokenizer') +const classGenerator = require('../class-generator.js') module.exports = { name: 'govspeak-address', @@ -10,7 +11,7 @@ module.exports = { return blockTokenizer.bind(this)(src, 'govspeak-address', '$A') }, renderer (token) { - return `
+ return `
${this.parser.parse(token.tokens)}
` } diff --git a/lib/extensions/button.js b/lib/extensions/button.js index 3b57265..5b77f03 100644 --- a/lib/extensions/button.js +++ b/lib/extensions/button.js @@ -1,3 +1,5 @@ +const classGenerator = require('../class-generator.js') + module.exports = { name: 'govspeak-button', level: 'inline', @@ -33,9 +35,9 @@ module.exports = { }, renderer (token) { if (token.isStartButton) { - return `${token.tokens[0].text}` + return `${token.tokens[0].text}` } - return `${token.tokens[0].text}` + return `${token.tokens[0].text}` } } diff --git a/lib/extensions/call-to-action.js b/lib/extensions/call-to-action.js index 7a4466e..1eaf771 100644 --- a/lib/extensions/call-to-action.js +++ b/lib/extensions/call-to-action.js @@ -1,4 +1,5 @@ const blockTokenizer = require('../block-tokenizer') +const classGenerator = require('../class-generator.js') module.exports = { name: 'govspeak-call-to-action', @@ -10,7 +11,7 @@ module.exports = { return blockTokenizer.bind(this)(src, 'govspeak-call-to-action', '$CTA') }, renderer (token) { - return `
+ return `
${this.parser.parse(token.tokens)}
` } diff --git a/lib/extensions/contact.js b/lib/extensions/contact.js index 8fc4317..fc32459 100644 --- a/lib/extensions/contact.js +++ b/lib/extensions/contact.js @@ -1,4 +1,5 @@ const blockTokenizer = require('../block-tokenizer') +const classGenerator = require('../class-generator.js') module.exports = { name: 'govspeak-contact', @@ -10,7 +11,7 @@ module.exports = { return blockTokenizer.bind(this)(src, 'govspeak-contact', '$C') }, renderer (token) { - return `
+ return `
${this.parser.parse(token.tokens)}
` } diff --git a/lib/extensions/example.js b/lib/extensions/example.js index ad04e05..842faf0 100644 --- a/lib/extensions/example.js +++ b/lib/extensions/example.js @@ -1,4 +1,5 @@ const blockTokenizer = require('../block-tokenizer') +const classGenerator = require('../class-generator.js') module.exports = { name: 'govspeak-example', @@ -10,7 +11,7 @@ module.exports = { return blockTokenizer.bind(this)(src, 'govspeak-example', '$E') }, renderer (token) { - return `
+ return `
${this.parser.parse(token.tokens)}
` } diff --git a/lib/extensions/form-download.js b/lib/extensions/form-download.js index 04d3057..d25ff39 100644 --- a/lib/extensions/form-download.js +++ b/lib/extensions/form-download.js @@ -1,4 +1,5 @@ const blockTokenizer = require('../block-tokenizer') +const classGenerator = require('../class-generator.js') module.exports = { name: 'govspeak-form-download', @@ -10,7 +11,7 @@ module.exports = { return blockTokenizer.bind(this)(src, 'govspeak-form-download', '$D') }, renderer (token) { - return `
+ return `
${this.parser.parse(token.tokens)}
` } diff --git a/lib/extensions/information-callout.js b/lib/extensions/information-callout.js index 0122c2c..32be3f2 100644 --- a/lib/extensions/information-callout.js +++ b/lib/extensions/information-callout.js @@ -1,3 +1,5 @@ +const classGenerator = require('../class-generator.js') + module.exports = { name: 'govspeak-information-callout', level: 'block', @@ -19,7 +21,7 @@ module.exports = { } }, renderer (token) { - return `
+ return `

${this.parser.parseInline(token.text)}

` } diff --git a/lib/extensions/information.js b/lib/extensions/information.js index 9204039..e21886c 100644 --- a/lib/extensions/information.js +++ b/lib/extensions/information.js @@ -1,4 +1,5 @@ const blockTokenizer = require('../block-tokenizer') +const classGenerator = require('../class-generator.js') module.exports = { name: 'govspeak-information', @@ -10,7 +11,7 @@ module.exports = { return blockTokenizer.bind(this)(src, 'govspeak-information', '$I') }, renderer (token) { - return `
+ return `
${this.parser.parse(token.tokens)}
` } diff --git a/lib/extensions/place.js b/lib/extensions/place.js index 6c5238a..ed71346 100644 --- a/lib/extensions/place.js +++ b/lib/extensions/place.js @@ -1,4 +1,5 @@ const blockTokenizer = require('../block-tokenizer') +const classGenerator = require('../class-generator.js') module.exports = { name: 'govspeak-place', @@ -10,7 +11,7 @@ module.exports = { return blockTokenizer.bind(this)(src, 'govspeak-place', '$P') }, renderer (token) { - return `
+ return `
${this.parser.parse(token.tokens)}
` } diff --git a/lib/extensions/stat-headline.js b/lib/extensions/stat-headline.js index dab819a..c85b47a 100644 --- a/lib/extensions/stat-headline.js +++ b/lib/extensions/stat-headline.js @@ -1,4 +1,5 @@ const blockTokenizer = require('../block-tokenizer') +const classGenerator = require('../class-generator.js') module.exports = { name: 'govspeak-stat-headline', @@ -10,7 +11,7 @@ module.exports = { return blockTokenizer.bind(this)(src, 'govspeak-stat-headline', '{stat-headline}', '{/stat-headline}') }, renderer (token) { - return `
+ return `
${this.parser.parse(token.tokens)}
` } diff --git a/lib/extensions/steps.js b/lib/extensions/steps.js index 9b5654a..f145421 100644 --- a/lib/extensions/steps.js +++ b/lib/extensions/steps.js @@ -1,3 +1,5 @@ +const classGenerator = require('../class-generator.js') + module.exports.steps = { name: 'govspeak-steps', level: 'block', @@ -20,7 +22,7 @@ module.exports.steps = { } }, renderer (token) { - return `
    ${this.parser.parseInline(token.tokens)}\n
` + return `
    ${this.parser.parseInline(token.tokens)}\n
` } } diff --git a/lib/extensions/warning-callout.js b/lib/extensions/warning-callout.js index ce48167..30a6097 100644 --- a/lib/extensions/warning-callout.js +++ b/lib/extensions/warning-callout.js @@ -1,3 +1,5 @@ +const classGenerator = require('../class-generator.js') + module.exports = { name: 'govspeak-warning-callout', level: 'block', @@ -19,7 +21,7 @@ module.exports = { } }, renderer (token) { - return `
+ return `

${this.parser.parseInline(token.text)}

` } diff --git a/tests/compatibility.mjs b/tests/compatibility.mjs new file mode 100644 index 0000000..aa8766a --- /dev/null +++ b/tests/compatibility.mjs @@ -0,0 +1,103 @@ +import test from 'ava' +import { marked } from 'marked' +import govspeak from '../index.js' + +marked.setOptions({ govspeakGemCompatibility: true }) +marked.use({ extensions: govspeak }) + +test('Renders address', t => { + const result = marked('$A\nLine 1 \nLine 2\n$A') + t.is(result, `
+

Line 1
Line 2

+ +
`) +}) + +test('Renders button', t => { + const result = marked('{button}[Click me](https://gov.uk){/button}') + t.is(result, '

Click me

\n') +}) + +test('Renders start button', t => { + const result = marked('{button start}[Click me](https://gov.uk){/button}') + t.is(result, '

Click me

\n') +}) + +test('Renders call to action', t => { + const result = marked('$CTA\nCall to action\n$CTA') + t.is(result, `
+

Call to action

+ +
`) +}) + +test('Renders contact', t => { + const result = marked('$C\nPhone \nEmail\n$C') + t.is(result, `
+

Phone
Email

+ +
`) +}) + +test('Renders form download', t => { + const result = marked('$D\n[Download (PDF, 14KB)](https://example.com/file.pdf)\n$D') + t.is(result, ``) +}) + +test('Renders example', t => { + const result = marked('$E\nExample\n$E') + t.is(result, `
+

Example

+ +
`) +}) + +test('Renders information callout', t => { + const result = marked('^information^') + t.is(result, `
+

information

+
`) +}) + +test('Renders information', t => { + const result = marked('$I\ninformation\n$I') + t.is(result, `
+

information

+ +
`) +}) + +test('Renders place', t => { + const result = marked('$P\nThis is a place\n$P') + t.is(result, `
+

This is a place

+ +
`) +}) + +test('Renders stat headline', t => { + const result = marked('{stat-headline}\n*13.8bn* years since the big bang{/stat-headline}') + t.is(result, `
+

13.8bn years since the big bang

+ +
`) +}) + +test('Renders steps', t => { + const result = marked('s1. Add numbers.\ns2. Check numbers.\ns3. Love numbers.') + t.is(result, `
    +
  1. Add numbers.
  2. +
  3. Check numbers.
  4. +
  5. Love numbers.
  6. +
`) +}) + +test('Renders warning callout', t => { + const result = marked('%warning%') + t.is(result, `
+

warning

+
`) +})