Skip to content

Commit

Permalink
Update the list indenting to match GOV.UK style
Browse files Browse the repository at this point in the history
Since we now handle the list markdown rather than turndown we have the
opportunity to update the indenting to be more consistent with GOV.UK
style. This sets the lists to have just one space after a marker and 3
spaces before it.

I wrestled for a bit trying to work out what should be the correct level
of indentation. Some places advise 2 characters, others 3 and others 4.
If you are working in monotype fonts it's most readable to have 2 for
ul's and 3 for ol's. As we expect users not to be typing in monotype
fonts this isn't too big a concern and 3 seems to offer a nice balance
of readability and without special cases for each list type.
  • Loading branch information
kevindew committed Apr 4, 2019
1 parent 5e11419 commit 7b9e5d8
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 26 deletions.
26 changes: 14 additions & 12 deletions src/to-govspeak.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import TurndownService from 'turndown'

const service = new TurndownService({
bulletListMarker: '-'
bulletListMarker: '-',
listIndent: ' ' // 3 spaces
})

// As a user may have pasted markdown we rather crudley
Expand Down Expand Up @@ -125,37 +126,38 @@ service.addRule('invalidNestedLists', {
return previousNodeName === 'li'
}
},
replacement: (content, node) => {
replacement: (content, node, options) => {
content = content
.replace(/^\n+/, '') // remove leading newlines
.replace(/\n+$/, '') // replace trailing newlines
.replace(/\n/gm, '\n ') // indent
.replace(/\n/gm, `\n${options.listIndent}`) // indent all nested content in the list

return ' ' + content + '\n'
// indent this list to match sibling
return options.listIndent + content + '\n'
}
})

// This is ported from https://github.com/domchristie/turndown/blob/80297cebeae4b35c8d299b1741b383c74eddc7c1/src/commonmark-rules.js#L61-L80
// It is modified to handle items from the invalidNestedLists as if these
// are ordered lists they will be output with incorrect numbering. It also
// removed handling of start attribute of <ol> elements as this has no effect
// on govspeak.
// It is modified in the following ways:
// - Only determines ol ordering based on li elements
// - Removes handling of ol start attribute as this doesn't affect govspeak output
// - Makes spacing consistent with gov.uk markdown guidance
service.addRule('listItems', {
filter: 'li',
replacement: function (content, node, options) {
content = content
.replace(/^\n+/, '') // remove leading newlines
.replace(/\n+$/, '\n') // replace trailing newlines with just a single one
.replace(/\n/gm, '\n ') // indent
.replace(/\n/gm, `\n${options.listIndent}`) // indent all nested content in the list

let prefix = options.bulletListMarker + ' '
let prefix = options.bulletListMarker + ' '
const parent = node.parentNode
if (parent.nodeName.toLowerCase() === 'ol') {
const listItems = Array.prototype.filter.call(
parent.children, (element) => element.nodeName.toLowerCase() === 'li'
)
const index = Array.prototype.indexOf.call(listItems, node)
prefix = (index + 1).toString() + '. '
prefix = (index + 1).toString() + '. '
}
return (
prefix + content + (node.nextSibling && !/\n$/.test(content) ? '\n' : '')
Expand All @@ -178,7 +180,7 @@ function removeBrParagraphs (govspeak) {
function extractHeadingsFromLists (govspeak) {
// This finds instances of headings within ordered lists and replaces them
// with the headings only. This only applies to H2 and H3.
const headingsInListsRegExp = new RegExp(/\d\.\s{2}(#{2,3})/, 'g')
const headingsInListsRegExp = new RegExp(/\d\.\s(\#{2,3})/, 'g')
return govspeak.replace(headingsInListsRegExp, '$1')
}

Expand Down
28 changes: 14 additions & 14 deletions test/to-govspeak.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ it('converts lists to a dash bullet style', () => {
<li>Item 2</li>
</ul>
`
expect(toGovspeak(html)).toEqual('- Item 1\n- Item 2')
expect(toGovspeak(html)).toEqual('- Item 1\n- Item 2')
})

it('maintains H2 and H3 headers', () => {
Expand Down Expand Up @@ -110,7 +110,7 @@ it('extracts headers from lists', () => {
<li><h3>Item 2</h3></li>
</ol>
`
expect(toGovspeak(html)).toEqual('## Item 1\n \n### Item 2')
expect(toGovspeak(html)).toEqual('## Item 1\n \n### Item 2')
})

it('strips paragraph elements within a list item', () => {
Expand All @@ -120,7 +120,7 @@ it('strips paragraph elements within a list item', () => {
<li><p>Item 2</p></li>
</ul>
`
expect(toGovspeak(html)).toEqual('- Item 1\n- Item 2')
expect(toGovspeak(html)).toEqual('- Item 1\n- Item 2')
})

it('removes nested links when link markdown text is wrapped in an element', () => {
Expand Down Expand Up @@ -151,10 +151,10 @@ it('fixes an invalid nested unordered list that Google Docs produces', () => {
</ul>
`
expect(toGovspeak(html)).toEqual(
'- Parent\n' +
' - Child\n' +
' - Grand child\n' +
'- Parent sibling'
'- Parent\n' +
' - Child\n' +
' - Grand child\n' +
'- Parent sibling'
)
})

Expand All @@ -175,12 +175,12 @@ it('fixes an invalid nested ordered list that Google Docs produces', () => {
</ol>
`
expect(toGovspeak(html)).toEqual(
'1. Parent\n' +
' 1. Child 1\n' +
' 1. Grand child 1\n' +
' 2. Grand child 2\n' +
' 2. Child 2\n' +
' 3. Child 3\n' +
'2. Parent sibling'
'1. Parent\n' +
' 1. Child 1\n' +
' 1. Grand child 1\n' +
' 2. Grand child 2\n' +
' 2. Child 2\n' +
' 3. Child 3\n' +
'2. Parent sibling'
)
})

0 comments on commit 7b9e5d8

Please sign in to comment.