From b70e36a6ec963bb5e1c7b35e910d49bca53636a7 Mon Sep 17 00:00:00 2001 From: Brent M Clark Date: Wed, 20 Jan 2021 00:23:30 -0600 Subject: [PATCH] external links and autolinked headers --- content/blog/stateful-provider-pattern.mdx | 6 +- package.json | 3 + src/pages/blog/[slug].js | 11 +++- src/styles/global.css | 10 ++++ yarn.lock | 64 ++++++++++++++++++++++ 5 files changed, 90 insertions(+), 4 deletions(-) diff --git a/content/blog/stateful-provider-pattern.mdx b/content/blog/stateful-provider-pattern.mdx index 1ed0f46..5e1257d 100644 --- a/content/blog/stateful-provider-pattern.mdx +++ b/content/blog/stateful-provider-pattern.mdx @@ -18,10 +18,10 @@ be used together to create something powerful. ## The Context API -The most recent iteration of the [Context API](<[https://reactjs.org/docs/context.html](https://reactjs.org/docs/context.html)>) (introduced +The most recent iteration of the [Context API](https://reactjs.org/docs/context.html) (introduced in 16.3) is one of those things that can be very confusing if you're new to the concept. It helps me to think of it as a variant of the -[Observer Pattern]() popularized by the -classic [Gang of Four](<[https://martinfowler.com/bliki/GangOfFour.html](https://martinfowler.com/bliki/GangOfFour.html)>) book. Don't +[Observer Pattern](https://en.wikipedia.org/wiki/Observer_pattern) popularized by the +classic [Gang of Four](https://martinfowler.com/bliki/GangOfFour.html) book. Don't feel like you need to know those things before mastering the `Stateful Provider Pattern` though. The links are purely for reference. Don't worry if you're unfamiliar with the Observer Pattern, you can think about the Context API like this: diff --git a/package.json b/package.json index 74917d7..6dceab4 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,9 @@ "react": "^16.12.0", "react-dom": "^16.12.0", "react-typography": "^0.16.19", + "rehype-autolink-headings": "^5.0.1", + "rehype-slug": "^4.0.1", + "remark-external-links": "^8.0.0", "typeface-merriweather": "0.0.72", "typeface-montserrat": "0.0.75", "typography": "^0.16.19", diff --git a/src/pages/blog/[slug].js b/src/pages/blog/[slug].js index 9d729d8..7c2c85c 100644 --- a/src/pages/blog/[slug].js +++ b/src/pages/blog/[slug].js @@ -13,6 +13,10 @@ import PageWrapper from "components/PageWrapper" import SEO from "components/seo" import SyntaxHighlighter from "components/SyntaxHighlighter" +import externalLinks from 'remark-external-links' +import autolinkHeadings from 'rehype-autolink-headings' +import autoslugHeadings from 'rehype-slug' + const components = { pre: props =>
, code: SyntaxHighlighter, @@ -108,7 +112,12 @@ async function getStaticProps(context) { const postPath = path.join(process.cwd(), `content/blog/${params.slug}.mdx`) const post = fs.readFileSync(postPath) const { content, data } = matter(post) - const mdxSource = await renderToString(content) + const mdxSource = await renderToString(content, { + mdxOptions: { + remarkPlugins: [externalLinks], + rehypePlugins: [autoslugHeadings, [autolinkHeadings, {behavior: 'wrap'}]] + } + }) return { props: { body: mdxSource, frontMatter: data }, } diff --git a/src/styles/global.css b/src/styles/global.css index 61aea58..5b637eb 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -162,6 +162,16 @@ small { border-color: var(--color-5); } +#blog-container h2 a, +#blog-container h2 a:hover, +#blog-container h3 a, +#blog-container h3 a:hover, +#blog-container h4 a, +#blog-container h4 a:hover +{ + color: var(--color-4); +} + @tailwind components; diff --git a/yarn.lock b/yarn.lock index c2f6343..4a4724f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2607,6 +2607,11 @@ emailjs-com@^2.4.1: resolved "https://registry.yarnpkg.com/emailjs-com/-/emailjs-com-2.6.4.tgz#c3bac8f7ee58d536ab34923e73013ad39f299f46" integrity sha512-4G8rxq+1mbL4rGntMa9tqNJ4N9BhuCl8lFJASDHxZVXeC82ivwL6qw+Zu48cAWHpNK2/F3vScaAZk8zoTAfiAA== +"emoji-regex@>=6.0.0 <=6.1.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.1.1.tgz#c6cd0ec1b0642e2a3c67a1137efc5e796da4f88e" + integrity sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4= + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -2991,6 +2996,13 @@ github-from-package@0.0.0: resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= +github-slugger@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.3.0.tgz#9bd0a95c5efdfc46005e82a906ef8e2a059124c9" + integrity sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q== + dependencies: + emoji-regex ">=6.0.0 <=6.1.1" + glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -3155,6 +3167,16 @@ hast-util-from-parse5@^6.0.0: vfile-location "^3.2.0" web-namespaces "^1.0.0" +hast-util-has-property@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/hast-util-has-property/-/hast-util-has-property-1.0.4.tgz#9f137565fad6082524b382c1e7d7d33ca5059f36" + integrity sha512-ghHup2voGfgFoHMGnaLHOjbYFACKrRh9KFttdCzMCbFoBMJXiNi2+XTrPP8+q6cDJM/RSqlCfVWrjp1H201rZg== + +hast-util-heading-rank@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hast-util-heading-rank/-/hast-util-heading-rank-1.0.1.tgz#28dfd8b0724cfb0da48308e2a794b1d9f24fd80d" + integrity sha512-P6Hq7RCky9syMevlrN90QWpqWDXCxwIVOfQR2rK6P4GpY4bqjKEuCzoWSRORZ7vz+VgRpLnXimh+mkwvVFjbyQ== + hast-util-parse-selector@^2.0.0: version "2.2.5" resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" @@ -3187,6 +3209,11 @@ hast-util-to-parse5@^6.0.0: xtend "^4.0.0" zwitch "^1.0.0" +hast-util-to-string@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/hast-util-to-string/-/hast-util-to-string-1.0.4.tgz#9b24c114866bdb9478927d7e9c36a485ac728378" + integrity sha512-eK0MxRX47AV2eZ+Lyr18DCpQgodvaS3fAQO2+b9Two9F5HEoRPhiUMNzoXArMJfZi2yieFzUBMRl3HNJ3Jus3w== + hastscript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" @@ -3328,6 +3355,11 @@ inline-style-parser@0.1.1: resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== +is-absolute-url@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== + is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" @@ -5171,6 +5203,38 @@ regjsparser@^0.6.4: dependencies: jsesc "~0.5.0" +rehype-autolink-headings@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/rehype-autolink-headings/-/rehype-autolink-headings-5.0.1.tgz#7482bd8ffdae522a1295d8df598028ff89f9111d" + integrity sha512-B6dmUVhtGdXLxJr3qynjRR10+f/iPJbSOtW5YyWieMvcwAm1XW5/yIYaW/9Qqr/Sd5h/Jym3dDCLJ4y6rPluWg== + dependencies: + extend "^3.0.0" + hast-util-has-property "^1.0.0" + hast-util-heading-rank "^1.0.0" + unist-util-visit "^2.0.0" + +rehype-slug@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/rehype-slug/-/rehype-slug-4.0.1.tgz#313274501cffa997bd52dd57bf2da5851959747a" + integrity sha512-KIlJALf9WfHFF21icwTd2yI2IP+RQRweaxH9ChVGQwRYy36+hiomG4ZSe0yQRyCt+D/vE39LbAcOI/h4O4GPhA== + dependencies: + github-slugger "^1.1.1" + hast-util-has-property "^1.0.0" + hast-util-heading-rank "^1.0.0" + hast-util-to-string "^1.0.0" + unist-util-visit "^2.0.0" + +remark-external-links@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/remark-external-links/-/remark-external-links-8.0.0.tgz#308de69482958b5d1cd3692bc9b725ce0240f345" + integrity sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA== + dependencies: + extend "^3.0.0" + is-absolute-url "^3.0.0" + mdast-util-definitions "^4.0.0" + space-separated-tokens "^1.0.0" + unist-util-visit "^2.0.0" + remark-footnotes@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-2.0.0.tgz#9001c4c2ffebba55695d2dd80ffb8b82f7e6303f"