Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
MoSattler committed Sep 21, 2022
1 parent 1caa1b9 commit 4d13af0
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 14 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,12 @@
"rehype-autolink-headings": "^6.1.1",
"rehype-sanitize": "^5.0.1",
"rehype-slug": "^5.0.1",
"remark-comment": "^1.0.0",
"remark-external-links": "^9.0.1",
"remark-gfm": "^3.0.1",
"remark-heading-id": "^1.0.0",
"remark-inline-links": "^6.0.1",
"remark-parse": "^10.0.1",
"strip-indent": "^4.0.0",
"unist-util-visit": "^4.1.1",
"vfile": "^5.3.5"
Expand Down
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions src/index.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable react/display-name */
import React from 'react'
import { MDXRemote } from 'next-mdx-remote'
// import { State, Observe } from 'mdx-observable'
import { State, Observe } from 'mdx-observable'
// import Tabs, { Tab } from './components/Tabs.jsx'
// import Interpolate from './components/Interpolate.jsx'
import CodeBlock from './components/CodeBlock.jsx'
Expand All @@ -20,7 +20,9 @@ export function Documentation({ source, theme, additionalComponents = {} }) {
)
},
pre: (props) => <CodeBlock {...props} theme={theme} />,
code: (props) => <InlineCode {...props} theme={theme} />
code: (props) => <InlineCode {...props} theme={theme} />,
State,
Observe,
},
additionalComponents
)
Expand Down
23 changes: 17 additions & 6 deletions src/lib/remark-plugins/state/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
const COMMENT_LABEL = 'export-to-input'

const isClosingComment = (child) => {
return (
child.type === 'comment' && child.commentValue.trim().includes(`/${COMMENT_LABEL}`)
)
}

const isOpeningComment = (child) => {

return (
child.type === 'comment' && child.commentValue.trim().includes(COMMENT_LABEL)
)
}

function findVarsToSub(children) {
const varsToSub = []

const updatedChildren = children.reduce((arr, child) => {
const isClosingInputComment =
child.type === 'comment' &&
child.value.trim().includes('/export-to-input')
const isClosingInputComment = isClosingComment(child)

if (isClosingInputComment) {
// find opening comment
const numberOfElementsToRemove = [...arr].reverse().findIndex((c) => {
return (
c.type === 'comment' && c.value.trim().includes('export-to-input')
)
return isOpeningComment(c)
})

const arrWithoutComment = arr.slice(0, -numberOfElementsToRemove)
Expand Down
4 changes: 2 additions & 2 deletions src/serialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import remarkInlineLinks from 'remark-inline-links'
import remarkHeadingId from './lib/remark-plugins/heading-ids'
// TODO: plugins require some refactoring, see https://github.com/storybookjs/storybook/issues/9602 for inspiration/guidance
// import remarkTabs from './lib/remark-plugins/tabs'
// import remarkState from './lib/remark-plugins/state'
import remarkState from './lib/remark-plugins/state'
// import remarkSections from './lib/remark-plugins/sections'
import remarkGfm from 'remark-gfm'
import remarkExternalLinks from 'remark-external-links'
Expand Down Expand Up @@ -124,7 +124,7 @@ export async function pageProps(context, args) {
remarkHeadingId,
// remarkSections,
// remarkTabs,
// remarkState,
remarkState,
remarkGfm,
[
remarkCodeImport,
Expand Down
File renamed without changes.
28 changes: 28 additions & 0 deletions test/__snapshots__/Documentation.test.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

exports[`Document > should render 1`] = `
<div>
&lt;State initialstate={
{
}
}&gt;
{({setState: setSubstitutionState, ...substitutionState}) =&gt; (
&lt;&gt;
&lt;Interpolate substitutions={substitutionState}&gt;
<hr />
Expand Down Expand Up @@ -117,5 +133,17 @@ exports[`Document > should render 1`] = `
<p>
Second Paragraph.
</p>
&lt;/Interpolate&gt;
&lt;/&gt;
)}
&lt;/State&gt;
</div>
`;
File renamed without changes.
File renamed without changes.
136 changes: 132 additions & 4 deletions test/remark-plugins/state.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,17 @@ import { State, Observe } from 'mdx-observable'
import Interpolate from '../../src/components/Interpolate'
import userEvent from '@testing-library/user-event'
import MDX from '@mdx-js/runtime'
import { describe, it, expect } from 'vitest'
import { describe, it, expect, afterAll } from 'vitest'
import { serialize } from 'next-mdx-remote/serialize'
import { MDXRemote } from 'next-mdx-remote'
import remarkParse from 'remark-parse'
import remarkComment from 'remark-comment'

const md = `
# Hi folks!
Here is some text for you. How are you doing today?
const markdown = `
<!--export-to-input-->
~~~bash
Expand All @@ -21,8 +29,96 @@ export OPSTRACE_CLUSTER_NAME=<choose_a_name>
~~~
`

const mdx = `
# Hi folks!
Here is some text for you. How are you doing today?
{/* export-to-input */}
~~~bash
export OPSTRACE_CLUSTER_NAME=<choose_a_name>
~~~
{/* /export-to-input */}
~~~bash
./opstrace destroy aws $OPSTRACE_CLUSTER_NAME
~~~
`

const { ...originalEnv } = process.env

afterAll(async () => {
process.env = originalEnv
})

describe('remarkState', () => {
it('test parsing', async () => {
it.only('test parsing MD', async () => {
const mdxSource = await serialize(md, { format: 'mdx',
mdxOptions: {
remarkPlugins: [remarkState, remarkParse, [remarkComment, { ast: true }]]
}
})
const testComponent = render(
<MDXRemote
{...mdxSource}
components={{
Interpolate,
State,
Observe
}}
/>
)

// // the commented export statement is not rendered
// expect(
// testComponent.queryByText('export OPSTRACE_CLUSTER_NAME=<choose_a_name>')
// ).not.toBeInTheDocument()

// // default value is shown
// expect(
// testComponent.getByText('./opstrace destroy aws $OPSTRACE_CLUSTER_NAME')
// ).toBeInTheDocument()

// // typing my custon name
// const value = 'MyService'
// const input = testComponent.getByRole('textbox')
// await userEvent.type(input, value)

// // custom name is shown
// expect(
// await testComponent.findByText(`./opstrace destroy aws ${value}`)
// ).toBeInTheDocument()

expect(testComponent.container).toMatchInlineSnapshot(`
<div>
<h1>
Hi folks!
</h1>
<p>
Here is some text for you. How are you doing today?
</p>
<input
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md mb-5"
placeholder="$OPSTRACE_CLUSTER_NAME"
type="text"
value="MyService"
/>
<pre>
<code
class="language-bash"
>
./opstrace destroy aws MyService
</code>
</pre>
</div>
`)
})

it.skip('test parsing MDX', async () => {
process.env.DOCS_USE_MDX = 'true'
const testComponent = render(
<MDX
components={{
Expand All @@ -32,7 +128,7 @@ describe('remarkState', () => {
}}
remarkPlugins={[remarkState]}
>
{markdown}
{mdx}
</MDX>
)

Expand All @@ -55,5 +151,37 @@ describe('remarkState', () => {
expect(
await testComponent.findByText(`./opstrace destroy aws ${value}`)
).toBeInTheDocument()

expect(testComponent.container).toMatchInlineSnapshot(`
<div>
<h1>
Hi folks!
</h1>
<p>
Here is some text for you. How are you doing today?
</p>
<p>
{/
<em>
export-to-input
</em>
/}
</p>
<input
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md mb-5"
placeholder="$OPSTRACE_CLUSTER_NAME"
type="text"
value="MyService"
/>
<pre>
<code
class="language-bash"
>
./opstrace destroy aws MyService
</code>
</pre>
</div>
`)
})
})

0 comments on commit 4d13af0

Please sign in to comment.