feat(vecs): transform mkdocs admonition to supabase admonition

This commit is contained in:
Greg Richardson committed 2023-06-02 10:56:12 -06:00
1 parent c1ea51afba
commit 692b33f9fc
3 files changed
+111 -6

No files matched your search

+4 -5
View File
@@ -1,13 +1,12 @@
import { FC } from 'react'
import { IconInfo, IconHelpCircle, IconAlertTriangle } from 'ui'
import { PropsWithChildren } from 'react'
import { IconAlertTriangle, IconHelpCircle, IconInfo } from 'ui'
interface Props {
export interface AdmonitionProps {
type: 'note' | 'tip' | 'info' | 'caution' | 'danger'
label?: string
children: any
}
const Admonition: FC<Props> = ({ type = 'note', label, children }) => {
const Admonition = ({ type = 'note', label, children }: PropsWithChildren<AdmonitionProps>) => {
return (
<div
className={[
@@ -0,0 +1,105 @@
import { Content, Paragraph, Parent } from 'mdast'
import { MdxJsxFlowElement } from 'mdast-util-mdx'
import { Node } from 'unist'
import { visit } from 'unist-util-visit'
import { AdmonitionProps } from '~/components/Admonition'
/**
* Transforms an `mkdocs-material` Admonition to a Supabase Admonition.
*
* https://squidfunk.github.io/mkdocs-material/reference/admonitions/
*/
const remarkMkDocsAdmonition = function () {
return function transformer(root: Parent) {
visit(root, 'paragraph', (paragraph: Paragraph, index: number, parent: Parent) => {
const [firstChild] = paragraph.children
if (firstChild?.type === 'text') {
const match = firstChild.value.match(/^!!! ?(.*?)\n(.*)/s)
if (!match) {
return
}
// Extract the admonition type along with the remaining text
const [, type, value] = match
// Rewrite the node's value to remove the admonition syntax
firstChild.value = value
// Extract sibling nodes that should be linked to this admonition
const siblingsToNest = extractLinkedSiblings(parent, paragraph, index)
const children: any[] = [...paragraph.children, ...siblingsToNest]
// Generate a Supabase Admonition JSX element
const admonitionElement: MdxJsxFlowElement = {
type: 'mdxJsxFlowElement',
name: 'Admonition',
attributes: [
{
type: 'mdxJsxAttribute',
name: 'type',
value: mapAdmonitionType(type),
},
],
children,
}
// Overwrite original node with new element
parent.children.splice(index, 1, admonitionElement)
}
})
}
}
/**
* Identifies sibling nodes that should be linked to this admonition
* based on their indent level (ie. 4 spaces).
*
* Iterates through proceeding siblings until one is found that is
* not indented relative to the original node.
*
* Splices the discovered siblings out of the original parent and returns them.
*/
function extractLinkedSiblings(parent: Parent, node: Node, index: number, indentAmount = 4) {
const { column } = node.position.start
let nextSibling: Content
let i = index
do {
nextSibling = parent.children[++i]
} while (nextSibling?.position && nextSibling.position.start.column === column + indentAmount)
return parent.children.splice(index + 1, i - index - 1)
}
/**
* Maps `mkdocs-material` Admonition types to Supabase Admonition types.
*
* https://squidfunk.github.io/mkdocs-material/reference/admonitions/#supported-types
*/
function mapAdmonitionType(type: string): AdmonitionProps['type'] {
switch (type) {
case 'quote':
case 'example':
case 'note':
return 'note'
case 'tip':
return 'tip'
case 'warning':
return 'caution'
case 'failure':
case 'bug':
case 'danger':
return 'danger'
case 'abstract':
case 'question':
case 'info':
default:
return 'info'
}
}
export default remarkMkDocsAdmonition
+2 -1
View File
@@ -7,6 +7,7 @@ import remarkGfm from 'remark-gfm'
import components from '~/components'
import Layout from '~/layouts/DefaultGuideLayout'
import { UrlTransformFunction, linkTransform } from '~/lib/mdx/plugins/rehypeLinkTransform'
import remarkMkDocsAdmonition from '~/lib/mdx/plugins/remarkAdmonition'
import { removeTitle } from '~/lib/mdx/plugins/remarkRemoveTitle'
// We fetch these docs at build time from an external repo
@@ -117,7 +118,7 @@ export const getStaticProps: GetStaticProps<PythonClientDocsProps> = async ({ pa
const mdxSource = await serialize(source, {
mdxOptions: {
remarkPlugins: [remarkGfm, [removeTitle, meta.title]],
remarkPlugins: [remarkGfm, remarkMkDocsAdmonition, [removeTitle, meta.title]],
rehypePlugins: [[linkTransform, urlTransform], rehypeSlug],
},
})