Skip to content

Commit 5dd941c

Browse files
committed
Add meta field to GRVSCCodeBlock
1 parent 7a3a243 commit 5dd941c

File tree

7 files changed

+82
-9
lines changed

7 files changed

+82
-9
lines changed

examples/example-site/content/blog/graphql-based/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
title: GraphQL Support
33
date: "2015-05-01T22:12:03.284Z"
44
description: GraphQL Support
5-
useReact: true
5+
template: react-blog-post
66
---
77

88
This post has its `pre` blocks replaced by interactive React components whose data is sourced from GraphQL nodes generated by gatsby-remark-vscode.
99

1010
The example React component looks like this. Click a token to interact with it:
1111

12-
```jsx
12+
```jsx { startLine: 52 }
1313
function CoolCodeBlock(props) {
1414
const [isRotating, setIsRotating] = useState({})
1515
const codeBlock = (useContext(CodeBlockContext) || [])[+props["data-index"]]
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
title: Rendering line numbers from GraphQL data
3+
date: "2015-05-01T22:12:03.284Z"
4+
template: react-blog-post
5+
codeComponent: CodeBlockWithLineNumbers
6+
---
7+
8+
```js {startLine: 52}
9+
/**
10+
* @template T
11+
* @template U
12+
* @param {T[]} arr
13+
* @param {(element: T) => U | U[]} mapper
14+
* @returns {U[]}
15+
*/
16+
function flatMap(arr, mapper) {
17+
/** @type {U[]} */
18+
const flattened = [];
19+
for (const input of arr) {
20+
const mapped = mapper(input);
21+
if (Array.isArray(mapped)) {
22+
for (const output of mapped) {
23+
flattened.push(output);
24+
}
25+
} else {
26+
flattened.push(mapped);
27+
}
28+
}
29+
return flattened;
30+
}
31+
```

examples/example-site/gatsby-node.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ exports.createPages = async ({ graphql, actions }) => {
2020
}
2121
frontmatter {
2222
title
23-
useReact
23+
template
2424
}
2525
}
2626
}
@@ -42,7 +42,9 @@ exports.createPages = async ({ graphql, actions }) => {
4242

4343
createPage({
4444
path: post.node.fields.slug,
45-
component: post.node.frontmatter.useReact ? reactBlogPost : blogPost,
45+
component: post.node.frontmatter.template
46+
? path.resolve(`./src/templates/${post.node.frontmatter.template}.js`)
47+
: blogPost,
4648
context: {
4749
slug: post.node.fields.slug,
4850
previous,

examples/example-site/src/templates/react-blog-post.js

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,35 @@ function CoolCodeBlock(props) {
4444
) : null
4545
}
4646

47-
const renderAst = new RehypeReact({
48-
createElement: React.createElement,
49-
components: { pre: CoolCodeBlock },
50-
}).Compiler
47+
function CodeBlockWithLineNumbers(props) {
48+
const codeBlock = (useContext(CodeBlockContext) || [])[+props["data-index"]]
49+
return codeBlock ? (
50+
<div className={codeBlock.preClassName}>
51+
<code className={codeBlock.codeClassName}>
52+
{codeBlock.tokenizedLines.map(({ html }, i) => (
53+
<div className="line-wrapper">
54+
<div className="line-number">{(codeBlock.meta ? codeBlock.meta.startLine : 1) + i}</div>
55+
<div className="line-contents" dangerouslySetInnerHTML={{ __html: html }} />
56+
</div>
57+
))}
58+
</code>
59+
</div>
60+
) : null
61+
}
62+
63+
const codeComponents = {
64+
CoolCodeBlock,
65+
CodeBlockWithLineNumbers
66+
};
5167

5268
class BlogPostTemplate extends React.Component {
69+
renderAst = new RehypeReact({
70+
createElement: React.createElement,
71+
components: {
72+
pre: codeComponents[this.props.data.markdownRemark.frontmatter.codeComponent] || CoolCodeBlock
73+
},
74+
}).Compiler;
75+
5376
render() {
5477
window.props = this.props
5578
const post = this.props.data.markdownRemark
@@ -72,6 +95,17 @@ class BlogPostTemplate extends React.Component {
7295
display: inline-block;
7396
animation: rotating 500ms linear infinite;
7497
}
98+
.line-wrapper { display: flex; }
99+
.line-number {
100+
background: rgba(255, 255, 255, 0.1);
101+
flex: 0 0 40px;
102+
text-align: right;
103+
padding: 0 20px;
104+
}
105+
.line-contents {
106+
flex: 1 0 auto;
107+
white-space: pre;
108+
}
75109
`}</style>
76110
<header>
77111
<h1
@@ -93,7 +127,7 @@ class BlogPostTemplate extends React.Component {
93127
</p>
94128
</header>
95129
<CodeBlockContext.Provider value={post.grvscCodeBlocks}>
96-
{renderAst(post.htmlAst)}
130+
{this.renderAst(post.htmlAst)}
97131
</CodeBlockContext.Provider>
98132
<hr
99133
style={{
@@ -151,14 +185,17 @@ export const pageQuery = graphql`
151185
excerpt(pruneLength: 160)
152186
htmlAst
153187
frontmatter {
188+
codeComponent
154189
title
155190
date(formatString: "MMMM DD, YYYY")
156191
description
157192
}
158193
grvscCodeBlocks {
194+
meta
159195
preClassName
160196
codeClassName
161197
tokenizedLines {
198+
html
162199
className
163200
tokens {
164201
startIndex

src/graphql/getCodeBlockDataFromRegistry.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ function getCodeBlockDataFromRegistry(registry, key, codeBlock, getWrapperClassN
6161
return {
6262
index,
6363
text,
64+
meta,
6465
html: renderHTML(createCodeBlockElement(preClassName, codeClassName, languageName, index, lineElements)),
6566
preClassName,
6667
codeClassName,

src/graphql/schema.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ declare namespace grvsc {
4343
preClassName: string;
4444
codeClassName: string;
4545
language?: string;
46+
meta?: any;
4647
defaultTheme: GRVSCTheme;
4748
additionalThemes: GRVSCTheme[];
4849
tokenizedLines?: GRVSCTokenizedLine[];

src/graphql/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type GRVSCCodeBlock implements Node {
4646
preClassName: String!
4747
codeClassName: String!
4848
language: String
49+
meta: JSON
4950
defaultTheme: GRVSCTheme!
5051
additionalThemes: [GRVSCTheme!]!
5152
tokenizedLines: [GRVSCTokenizedLine!]

0 commit comments

Comments
 (0)