Skip to content

Commit

Permalink
Disable automatic conversion of Markdown to HTML (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
mtsknn authored Jul 31, 2021
1 parent 717239b commit 2c1ea0d
Show file tree
Hide file tree
Showing 13 changed files with 136 additions and 1,362 deletions.
7 changes: 5 additions & 2 deletions .eleventy.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const md = require('./data/md')
const setupBrowserSync = require('./eleventy/browserSync')
const setupCollections = require('./eleventy/collections')

Expand All @@ -14,7 +13,11 @@ module.exports = (config) => {
// https://www.11ty.dev/docs/data-deep-merge/
config.setDataDeepMerge(true)

config.setLibrary('md', md)
// Disable automatic conversion of Markdown to HTML;
// we'll call `md.render(content)` manually in layouts.
// This way we can access pages' raw Markdown (via `content`)
// which wouldn't otherwise be possible (https://github.com/11ty/eleventy/issues/1206).
config.setLibrary('md', { render: (markdown) => markdown })

return {
dir: {
Expand Down
4 changes: 3 additions & 1 deletion _sample-content/feeds/feeds.11tydata.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ module.exports = {
getFullContent(item) {
return (
md.render(item.data.intro) +
item.templateContent.replace(/<a class="link link-permalink".+<\/a>/g, '')
md
.render(item.templateContent)
.replace(/<a class="link link-permalink".+<\/a>/g, '')
)
},
getFeedUpdatedDate(items) {
Expand Down
131 changes: 82 additions & 49 deletions data/getTocItems.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,93 @@
const { JSDOM } = require('jsdom')

const { slugify } = require('./slugify')
const md = require('./md')

// "If you return a `function`, we'll use the return value from that function."
// Source: https://www.11ty.dev/docs/data-js/
module.exports = () =>
function getTocItems(html) {
const uniqueSlugs = new Set()
const dom = new JSDOM(html)

return [...dom.window.document.body.querySelectorAll('h2, h3')].reduce(
(result, heading) => {
const item = createItem(heading)
const prevH3 = result[result.length - 1]

if (heading.tagName === 'H2') {
result.push(item)
} else if (heading.tagName === 'H3') {
prevH3.subItems.push(item)
}

return result
},
[]
)
module.exports = () => (markdown) => {
const tokens = md.parse(markdown, {})

function createItem(heading) {
const nodes = [...heading.childNodes[0].childNodes]

const itemHtml = nodes.reduce(
(result, node) => result + (node.outerHTML || node.textContent),
''
)

const text = nodes.reduce((result, node) => result + node.textContent, '')
const slug = getUniqueSlug(text)
/*
Example `tokens` for `## Heading text with `inline code`;
the `link_open` and `link_close` tokens are generated by `markdown-it-anchor`:
[
// ...
{
type: 'heading_open',
tag: 'h2',
content: '',
// ...
},
{
type: 'inline',
tag: '',
content: '',
children: [
{
type: 'link_open',
tag: 'a',
content: '',
// ...
},
{
type: 'text',
tag: '',
content: 'Heading text with ',
// ...
},
{
type: 'code_inline',
tag: 'code',
content: 'inline code',
// ...
},
{
type: 'link_close',
tag: 'a',
content: '',
// ...
}
],
// ...
},
{
type: 'heading_close',
tag: 'h2',
content: '',
// ...
},
// ...
]
*/

return {
content: itemHtml,
href: `#${slug}`,
subItems: [],
}
const headingIndexes = tokens.reduce((indexes, token, index) => {
if (token.type === 'heading_open' && ['h2', 'h3'].includes(token.tag)) {
indexes.push(index)
}
return indexes
}, [])

function getUniqueSlug(text) {
const slug = slugify(text)
return headingIndexes.reduce((items, index) => {
const headingOpenToken = tokens[index]
const headingContentTokens = tokens[index + 1].children
const linkOpenToken = headingContentTokens[0]

let uniqueSlug = slug
let i = 1
const content = md.renderer.render(
// Omit `link_open` and `link_close`
headingContentTokens.slice(1, -1)
)

while (uniqueSlugs.has(uniqueSlug)) {
uniqueSlug = `${slug}-${i}`
i += 1
}
const item = {
content,
href: linkOpenToken.attrGet('href'),
subItems: [],
}

uniqueSlugs.add(uniqueSlug)
return uniqueSlug
if (headingOpenToken.tag === 'h2') {
items.push(item)
} else {
const prevH2 = items[items.length - 1]
prevH2.subItems.push(item)
}
}

return items
}, [])
}
2 changes: 1 addition & 1 deletion layouts/_layout.pug
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ html(lang="en")
+breadcrumb

block content
.prose(class="xl:prose-lg")!= content
.prose(class="xl:prose-lg")!= md.render(content)
footer.border-t.border-gray-300.flex.items-baseline.justify-between.pt-6.text-gray-700.text-sm(
class="xl:text-base"
)
Expand Down
4 changes: 2 additions & 2 deletions layouts/_mixins.pug
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ mixin skipLink(text, href, classes = '')
href=href
)= text

mixin toc(html)
mixin toc(markdown)
mixin list(items)
ol
each item in items
Expand All @@ -69,7 +69,7 @@ mixin toc(html)
if item.subItems.length > 0
+list(item.subItems)

- const items = getTocItems(html)
- const items = getTocItems(markdown)
if items.length >= 2
h2.tracking-widest.uppercase(class="!text-base !text-gray-700 xl:!text-lg")
| Table of contents
Expand Down
2 changes: 1 addition & 1 deletion layouts/blog-post.pug
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ block content
#continue-reading.mb-12

+toc(content)
!= content
!= md.render(content)
2 changes: 1 addition & 1 deletion layouts/blog.pug
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ block content
h1.text-center= title

p.lead!= md.renderInline(intro)
!= content
!= md.render(content)

h2 Coolest blog posts, hot off the press
each post, i in collections.blogPosts
Expand Down
2 changes: 1 addition & 1 deletion layouts/feeds.pug
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ block content
.prose(class="xl:prose-lg")
h1.text-center= title
p.lead!= md.renderInline(intro)
!= content
!= md.render(content)
2 changes: 1 addition & 1 deletion layouts/home.pug
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ block content
| #{' '}a full-stack web developer

.lead!= md.render(intro)
!= content
!= md.render(content)

ul(class="sm:space-x-8")
-
Expand Down
2 changes: 1 addition & 1 deletion layouts/weekly-log-entry.pug
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ block content
hr(aria-hidden="true")

+toc(content)
!= content
!= md.render(content)

hr(aria-hidden="true")

Expand Down
2 changes: 1 addition & 1 deletion layouts/weekly-log.pug
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ block content
h1.text-center= title
p.lead!= md.renderInline(intro)

!= content
!= md.render(content)

//- TODO: Replace the hardcoded year with dynamic years
h2#2021 2021
Expand Down
Loading

0 comments on commit 2c1ea0d

Please sign in to comment.