Last active
June 24, 2023 10:40
-
-
Save i-am-the-slime/35f212988e306c58b63fd423d48b09a0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module BuildTime.GetMDXFiles where | |
import Prelude | |
import Node.FS.Aff (readTextFile, readdir) | |
import Data.Foldable (for_) | |
import Node.Glob.Basic (expandGlobsCwd) | |
import BuildTime.MDXBundler (EsbuildOptions, Extension(Extension), RehypePlugin, RemarkPlugin, addLoader, addRehypePlugins, addRemarkPlugins, bundleMDX, setPlatform) | |
import Node.Encoding (Encoding(..)) | |
import Debug (spy) | |
import Effect.Aff (launchAff_) | |
import Effect.Uncurried (EffectFn1, EffectFn2, mkEffectFn1, mkEffectFn2) | |
import Effect (Effect) | |
import Record.Unsafe (unsafeSet) | |
import Unsafe.Coerce (unsafeCoerce) | |
import Data.Traversable (for) | |
import Control.Promise (fromAff) as Promise | |
import Control.Promise (Promise) | |
import Data.Set (Set) | |
import Data.Set (toUnfoldable) as Set | |
type Frontmatter = {} | |
getMdxFiles :: EffectFn2 { remarkPlugins :: Array RemarkPlugin, rehypePlugins :: Array RehypePlugin } (Array String) (Promise (Array _)) | |
getMdxFiles = mkEffectFn2 \plugins globs -> Promise.fromAff do | |
filePaths <- expandGlobsCwd globs <#> Set.toUnfoldable | |
parsed <- for filePaths \filePath -> do | |
source <- readTextFile UTF8 filePath | |
{ code, frontmatter } <- bundleMDX @Frontmatter | |
{ source | |
, mdxOptions: mkEffectFn2 \opts (_ :: Frontmatter) -> do | |
opts # addRehypePlugins plugins.rehypePlugins | |
opts # addRemarkPlugins plugins.remarkPlugins | |
pure opts | |
, esbuildOptions: mkEffectFn2 | |
\(opts :: EsbuildOptions) (_ :: Frontmatter) -> do | |
opts # setPlatform "node" | |
opts # addLoader (Extension ".purs") "text" | |
pure opts | |
} | |
let _ = spy "path" filePath | |
pure { path: filePath, code, frontmatter } | |
pure parsed |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {bundleMDX} from 'mdx-bundler' | |
export const bundleMDXImpl = bundleMDX | |
export const addRehypePluginsImpl = (plugins, config) => config.rehypePlugins = [...(config.rehypePlugins ?? []), ...plugins] | |
export const addRemarkPluginsImpl = (plugins, config) => config.remarkPlugins = [...(config.remarkPlugins ?? []), ...plugins] | |
export const setPlatformImpl = (value, config) => config.platform = value | |
export const addLoaderImpl = (filetype, loader, config) => config.loader = {...config.loader, [filetype]: loader } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module BuildTime.MDXBundler where | |
import Prelude | |
import Effect.Uncurried (EffectFn1, EffectFn2, EffectFn3, runEffectFn1, runEffectFn2, runEffectFn3) | |
import Data.Undefined.NoProblem (Opt, SNil) | |
import Control.Promise (Promise, toAffE) | |
import Data.Undefined.NoProblem.Open (class Coerce, class CoerceProp, coerce) as Open | |
import Effect.Aff (Aff) | |
import Effect (Effect) | |
import Unsafe.Coerce (unsafeCoerce) | |
foreign import data MdxOptions :: Type | |
foreign import data Frontmatter :: Type | |
foreign import data EsbuildOptions :: Type | |
foreign import data RemarkPlugin :: Type | |
foreign import data RehypePlugin :: Type | |
type BundleMdxOptions frontmatter = | |
{ source :: String | |
, mdxOptions :: Opt (EffectFn2 MdxOptions frontmatter MdxOptions) | |
, esbuildOptions :: Opt (EffectFn2 EsbuildOptions frontmatter EsbuildOptions) | |
} | |
foreign import bundleMDXImpl :: forall frontmatter. EffectFn1 | |
(BundleMdxOptions frontmatter) | |
(Promise { code :: String, frontmatter :: frontmatter }) | |
bundleMDX :: forall @frontmatter given. | |
Open.Coerce given (BundleMdxOptions frontmatter) | |
=> given -> Aff { code :: String , frontmatter :: frontmatter } | |
bundleMDX opts = toAffE (runEffectFn1 bundleMDXImpl (Open.coerce opts)) | |
foreign import addRehypePluginsImpl :: EffectFn2 (Array RehypePlugin) MdxOptions Unit | |
foreign import addRemarkPluginsImpl :: EffectFn2 (Array RemarkPlugin) MdxOptions Unit | |
addRehypePlugins :: (Array RehypePlugin) -> MdxOptions -> Effect Unit | |
addRehypePlugins = runEffectFn2 addRehypePluginsImpl | |
addRemarkPlugins :: (Array RemarkPlugin) -> MdxOptions -> Effect Unit | |
addRemarkPlugins = runEffectFn2 addRemarkPluginsImpl | |
foreign import setPlatformImpl :: EffectFn2 String EsbuildOptions Unit | |
setPlatform :: String -> EsbuildOptions -> Effect Unit | |
setPlatform = runEffectFn2 setPlatformImpl | |
newtype Extension = Extension String | |
foreign import addLoaderImpl :: EffectFn3 Extension String EsbuildOptions Unit | |
addLoader :: Extension -> String -> EsbuildOptions -> Effect Unit | |
addLoader = runEffectFn3 addLoaderImpl |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {allPosts} from 'contentlayer/generated' | |
import {default as Page} from "@/output/Alethic.Page.View" | |
import {notFound} from "next/navigation"; | |
import {getMdxFiles} from "@/output/BuildTime.GetMDXFiles" | |
import remarkGfm from "remark-gfm"; | |
import rehypeSlug from "rehype-slug"; | |
import rehypeAutolinkHeadings from "rehype-autolink-headings"; | |
import {h, s} from "hastscript"; | |
import rehypePrettyCode from "rehype-pretty-code"; | |
import {getHighlighter} from "@/contentlayer/shiki"; | |
const mdx = { | |
remarkPlugins: [[remarkGfm]], | |
rehypePlugins: [ | |
[rehypeSlug], | |
[ | |
rehypeAutolinkHeadings, | |
{ | |
behavior: "prepend", | |
properties: { | |
properties: { | |
className: 'autolink', | |
ariaHidden: true, | |
tabIndex: -1, | |
}, | |
}, | |
content: [ | |
h('span.autolink-info', {className: "sr-only"}, ' permalink'), | |
s( | |
'svg.autolink-svg', | |
{ | |
xmlns: 'http://www.w3.org/2000/svg', | |
width: 20, | |
height: 20, | |
fill: 'currentColor', | |
viewBox: '0 0 24 24', | |
className: "opacity-0 group-hover:opacity-100" | |
}, | |
s('path', { | |
d: 'M9.199 13.599a5.99 5.99 0 0 0 3.949 2.345 5.987 5.987 0 0 0 5.105-1.702l2.995-2.994a5.992 5.992 0 0 0 1.695-4.285 5.976 5.976 0 0 0-1.831-4.211 5.99 5.99 0 0 0-6.431-1.242 6.003 6.003 0 0 0-1.905 1.24l-1.731 1.721a.999.999 0 1 0 1.41 1.418l1.709-1.699a3.985 3.985 0 0 1 2.761-1.123 3.975 3.975 0 0 1 2.799 1.122 3.997 3.997 0 0 1 .111 5.644l-3.005 3.006a3.982 3.982 0 0 1-3.395 1.126 3.987 3.987 0 0 1-2.632-1.563A1 1 0 0 0 9.201 13.6zm5.602-3.198a5.99 5.99 0 0 0-3.949-2.345 5.987 5.987 0 0 0-5.105 1.702l-2.995 2.994a5.992 5.992 0 0 0-1.695 4.285 5.976 5.976 0 0 0 1.831 4.211 5.99 5.99 0 0 0 6.431 1.242 6.003 6.003 0 0 0 1.905-1.24l1.723-1.723a.999.999 0 1 0-1.414-1.414L9.836 19.81a3.985 3.985 0 0 1-2.761 1.123 3.975 3.975 0 0 1-2.799-1.122 3.997 3.997 0 0 1-.111-5.644l3.005-3.006a3.982 3.982 0 0 1 3.395-1.126 3.987 3.987 0 0 1 2.632 1.563 1 1 0 0 0 1.602-1.198z', | |
}) | |
), | |
], | |
}, | |
], | |
[rehypePrettyCode, { | |
keepBackground: true, | |
getHighlighter, | |
onVisitLine: node => { | |
if (node.children && node.children[0] && node.children[0].children[0] && node.children[0].children[0].value == 'import') { | |
if (node.properties) | |
if (node.properties.className) { | |
node.properties.className.push(" import-line") | |
} else { | |
node.properties.className = ["import-line"] | |
} | |
} | |
}, | |
onVisitHighlightedWord: (element) => { | |
// Each word element has no className by default. | |
element.properties.className = ['highlighted-word']; | |
element.style = "color:#000" | |
}, | |
}] | |
] | |
} | |
export const generateStaticParams = async () => { | |
const mdxFiles = await getMdxFiles(mdx, ['./content/**/*.mdx']) | |
console.log(mdxFiles) | |
return [] // allPosts.filter(post => post.docType == 'page').map((post) => ({slug: post._raw.flattenedPath})) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is for building your own: find some mdx files at build time on the server-side and parse them etc.