feat: add custom code tag to markdown

This commit is contained in:
Stevan Freeborn
2023-04-09 14:50:50 -05:00
parent ae44fe7e07
commit 4c6257012d
12 changed files with 189 additions and 115 deletions
View File
+15
View File
@@ -0,0 +1,15 @@
import styles from './Code.module.css';
export default function Code({
children,
language,
}: {
children: string;
language: string;
}) {
return (
<pre className={styles.pre}>
<code className={styles.code}>{children}</code>
</pre>
);
}
+5
View File
@@ -18,3 +18,8 @@
.container>article {
flex: 1;
}
.container>article>p {
margin-top: 20px;
color: #c1c9d2
}
+6 -10
View File
@@ -1,18 +1,14 @@
import { ReactNode } from 'react';
import styles from './Section.module.css';
export default function Section({
copy,
example,
children,
}: {
copy: string;
example: string;
children: ReactNode;
}) {
return (
<section
className={styles.container}
dangerouslySetInnerHTML={{
__html: `${copy}${example}`,
}}
></section>
<section className={styles.container}>
{children}
</section>
);
}
+6 -6
View File
@@ -1,10 +1,10 @@
'use client';
import { useState } from 'react';
import { DocsStructure } from '../types/types.js';
import { Doc, DocsStructure } from '../types/types.js';
import styles from './SideBar.module.css';
function TreeNode({ doc }: { doc: DocsStructure }) {
function TreeNode({ doc }: { doc: Doc }) {
const [isExpanded, setIsExpanded] =
useState<boolean>(true);
@@ -62,7 +62,7 @@ function TreeNode({ doc }: { doc: DocsStructure }) {
);
}
function ListTree({ docs }: { docs: DocsStructure[] }) {
function ListTree({ docs }: { docs: Doc[] }) {
return (
<ul className={styles.list}>
{docs.map(d => (
@@ -76,8 +76,8 @@ export default function SideBar({
versionOne,
versionTwo,
}: {
versionOne: DocsStructure[];
versionTwo: DocsStructure[];
versionOne: DocsStructure;
versionTwo: DocsStructure;
}) {
return (
<div className={styles.container}>
@@ -85,7 +85,7 @@ export default function SideBar({
<span className={styles.onspring}>Onspring</span>{' '}
<span className={styles.api}>API</span>
</h1>
<ListTree docs={versionTwo} />
<ListTree docs={versionTwo.docs} />
</div>
);
}
+93
View File
@@ -0,0 +1,93 @@
import Markdoc from '@markdoc/markdoc';
import fs from 'fs';
import path from 'path';
import React, { ReactNode } from 'react';
import Code from '../components/Code';
import { Doc, Section } from './../types/types';
const DOCS_PATH = path.join(process.cwd(), 'src/docs');
function getCopyPath(version: string, doc: Doc): string {
if (doc.copy === undefined) {
return '';
}
return path.join(
DOCS_PATH,
version,
doc.folder,
doc.copy
);
}
function getExamplePath(version: string, doc: Doc): string {
if (doc.example === undefined) {
return '';
}
return path.join(
DOCS_PATH,
version,
doc.folder,
doc.example
);
}
const markDocConfig = {
tags: {
code: {
render: 'Code',
children: ['text'],
attributes: {
language: {
type: 'string',
},
},
},
},
};
function parseMarkdown(sourcePath: string): ReactNode {
const source = fs.readFileSync(sourcePath, 'utf8');
const ast = Markdoc.parse(source);
const content = Markdoc.transform(
ast,
markDocConfig as any
);
const children = Markdoc.renderers.react(content, React, {
components: {
Code: Code,
},
});
return children;
}
function getCopyChild(version: string, doc: Doc) {
const copyPath = getCopyPath(version, doc);
return parseMarkdown(copyPath);
}
function getExampleChild(version: string, doc: Doc) {
const examplePath = getExamplePath(version, doc);
return parseMarkdown(examplePath);
}
export function loadSections(
version: string,
docs: Doc[],
sections: Section[] = []
): Section[] {
for (const doc of docs) {
sections.push({
title: doc.title,
copy: getCopyChild(version, doc),
example: getExampleChild(version, doc),
});
if (doc.children && doc.children.length > 0) {
loadSections(version, doc.children, sections);
}
}
return sections;
}
+11 -72
View File
@@ -1,82 +1,21 @@
import { versionTwo } from '@/docs/version_002/docsStructure';
import Markdoc from '@markdoc/markdoc';
import fs from 'fs';
import path from 'path';
import Section from './components/Section';
import { loadSections } from './lib/markdoc';
import styles from './page.module.css';
import { DocsStructure } from './types/types';
type Section = {
title: string;
copy: string;
example: string;
};
function loadSections(
docs: DocsStructure[],
sections: Section[] = []
): Section[] {
for (const doc of docs) {
try {
const copyPath = path.join(
process.cwd(),
'src/docs',
'version_002',
doc.folder,
doc.copy!
);
const examplePath = path.join(
process.cwd(),
'src/docs',
'version_002',
doc.folder,
doc.example!
);
const copySource = fs.readFileSync(copyPath, 'utf8');
const exampleSource = fs.readFileSync(
examplePath,
'utf8'
);
const copyAst = Markdoc.parse(copySource);
const exampleAst = Markdoc.parse(exampleSource);
const copyContent = Markdoc.transform(copyAst);
const exampleContent = Markdoc.transform(exampleAst);
const copyHtml = Markdoc.renderers.html(copyContent);
const exampleHtml =
Markdoc.renderers.html(exampleContent);
sections.push({
title: doc.title,
copy: copyHtml,
example: exampleHtml,
});
if (doc.children && doc.children.length > 0) {
loadSections(doc.children, sections);
}
} catch (error) {
console.log(error);
continue;
}
}
return sections;
}
export default function Home() {
const versionTwoSections = loadSections(versionTwo);
console.log(versionTwoSections);
const versionTwoSections = loadSections(
versionTwo.version,
versionTwo.docs
);
return (
<main className={styles.container}>
{versionTwoSections.map(article => (
<Section
key={article.title}
copy={article.copy}
example={article.example}
/>
{versionTwoSections.map(section => (
<Section key={section.title}>
{section.copy}
{section.example}
</Section>
))}
</main>
);
+13 -1
View File
@@ -1,7 +1,19 @@
import { ReactNode } from 'react';
export type DocsStructure = {
version: string;
docs: Doc[];
};
export type Doc = {
title: string;
folder: string;
copy?: string;
example?: string;
children?: DocsStructure[];
children?: Doc[];
};
export type Section = {
title: string;
copy: ReactNode;
example: ReactNode;
};
+5 -2
View File
@@ -1,6 +1,8 @@
import { DocsStructure } from '@/app/types/types';
export const versionOne: DocsStructure[] = [
export const versionOne: DocsStructure = {
version: 'version_001',
docs: [
{
title: 'Introduction',
folder: 'introduction',
@@ -8,4 +10,5 @@ export const versionOne: DocsStructure[] = [
example: 'example.md',
children: [],
},
];
],
};
+5 -2
View File
@@ -1,6 +1,8 @@
import { DocsStructure } from '@/app/types/types';
export const versionTwo: DocsStructure[] = [
export const versionTwo: DocsStructure = {
version: 'version_002',
docs: [
{
title: 'Introduction',
folder: 'introduction',
@@ -15,4 +17,5 @@ export const versionTwo: DocsStructure[] = [
example: 'example.md',
children: [],
},
];
],
};
+5 -1
View File
@@ -1,3 +1,7 @@
# Introduction
This is the copy for the introduction page.
The Onspring API is organized around REST. It enables external programs to retrieve, save, and delete data within your Onspring instance. The Onspring API implements version 3 of the Open API Specification (OAS).
The Onspring API does support bulk operation for some, but not all endpoints. Bulk operations are not supported for endpoints that create, update, or delete data. The one exception is the bulk delete endpoint, which is used to delete multiple records at once.
The Onspring API is used to interact with any Onspring instance regardless of whether it is a development, test, or production instance.
@@ -1,3 +1,7 @@
# Example
This is the example for the introduction page.
{% code language="javascript" %}
console.log('hello world');
{% /code %}