https://github.com/acdh-oeaw/mdx-lib

Utilities for MDX

https://github.com/acdh-oeaw/mdx-lib

Science Score: 26.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (7.9%) to scientific vocabulary

Keywords

frontend
Last synced: 6 months ago · JSON representation

Repository

Utilities for MDX

Basic Info
  • Host: GitHub
  • Owner: acdh-oeaw
  • License: mit
  • Language: TypeScript
  • Default Branch: main
  • Homepage:
  • Size: 359 KB
Statistics
  • Stars: 0
  • Watchers: 5
  • Forks: 0
  • Open Issues: 0
  • Releases: 7
Topics
frontend
Created over 1 year ago · Last pushed 6 months ago
Metadata Files
Readme Changelog License Codeowners

readme.md

mdx lib

utilities and plugins for mdx.

how to install

bash npm i @acdh-oeaw/mdx-lib

how to use

configure types for supported locales and jsx:

```ts // ./types/mdx.d.ts

// import type * as runtime from "astro/jsx-runtime"; import type * as runtime from "react/jsx-runtime";

declare module "mdx/types" { namespace JSX { type Element = runtime.JSX.Element; type ElementClass = runtime.JSX.ElementClass; type IntrinsicElements = runtime.JSX.IntrinsicElements; } }

declare module "@acdh-ch/mdx-lib" { export interface MdxConfig { locales: "de" | "en"; } } ```

provide component mappings (in next.js the file location has to be mdx-components.tsx at the project root):

```ts // ./mdx-components.ts

import { Link } from "@/components/link";

const components = { a: Link, /** ... */ };

declare global { type MDXProvidedComponents = typeof components; }

export function useMDXComponents(): MDXProvidedComponents { return components; } ```

create locale aware mdx compilers:

```ts // ./lib/mdx/compile-mdx.ts

import { createMdxProcessors, run } from "@acdh-ch/mdx-lib"; // import * as runtime from "astro/jsx-runtime"; import * as runtime from "react/jsx-runtime";

const createProcessor = createMdxProcessors((locale) => { return { /** When using astro instead of react. */ // elementAttributeNameCase: "html", // jsxImportSource: "astro",

    remarkPlugins: [],
    remarkRehypeOptions: {},
    rehypePlugins: [],
};

});

export async function compileMdx(content: string, baseUrl: URL, locale: string) { const processor = await createProcessor(locale); const compiled = await processor.process(content); return run(compiled, { ...runtime, baseUrl, useMDXComponents }); } ```

note that in astro projects, you need to use the astro jsx runtime (astro/jsx-runtime), and set elementAttributeNameCase to "html".

plugins

with-custom-heading-ids

rehype plugin which finds <HeadingId id="abc" /> mdx components, and applies the id attribute to a parent heading element.

example:

```mdx

This is a heading

```

when not using any other plugins, this would be transformed to a regular <h2> element. when using the rehype-slug plugin, this would add an auto-generated id attribute: <h2 id="this-is-a-heading">. when using this plugin, you can add custom ids to the heading: <h2 id="my-custom-heading">. the <HeadingId> component will be removed from the generated output.

with-footnotes

remark plugin which finds inline <Footnote> mdx components, and transforms them to markdown footnotes, i.e. footnoteReference and footnoteDefinition mdast nodes (requires remark-gfm).

example:

mdx This is an important sentence.<Footnote>Found it on the internet.</Footnote>

will be transformed to:

html <p> This is an important sentence.<sup ><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref aria-describedby="footnote-label" >1</a ></sup >. </p> <section data-footnotes class="footnotes"> <h2 class="sr-only" id="footnote-label">Footnotes</h2> <ol> <li id="user-content-fn-1"> <p> Found it on the internet. <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref" >↩</a > </p> </li> </ol> </section>

The h2 text content and aria-labels for generated elements can be controlled by setting remarkRehypeOptions.

with-iframe-titles

rehype plugin which applies the text content of a component to its title attribute. this is meant to be used with components which render an <iframe>. accepts a components option listing the names of components to handle.

example:

mdx <Embed src="https://example.com/iframe">This is **the** title.</Embed>

will be transformed to:

html <iframe src="https://example.com/iframe" title="This is the title." />

with-image-imports

rehype plugin which transforms the src attribute of <img> elements and configured mdx components into esm imports, because most javascript frameworks provide image optimisation features which integrate with a bundler and work via import statements.

example:

```mdx

This is the image caption.

```

will be transformed to:

```mdx import image1 from "./first-image.png"; import image2 from "/home/stefan/my-project/public/second-image.png";

This is the image caption.

```

note that paths starting with "/" will be expanded to absolute paths using the publicPath config option (defaults to "/public/"). for relative paths starting with "./" or "../", you need to provide a baseUrl to the mdx compiler.

also note that you need a bundler to handle the image imports, so this requires outputFormat: "program".

don't forget to map img elements to a custom component which can handle objects as src prop, e.g.:

```ts // ./mdx-components.ts

import Image from "next/image";

const components = { img: Image, };

export function useMDXComponents() { return components; } ```

with-table-of-contents

rehype plugin which generates a table of contents, and provides it via vfile.data.tableOfContents, as well as a tableOfContents named export. additionally, it provides the table of contents data to any TableOfContents mdx component.

ts const vfile = await processor.process(content); console.log(vfile.data.tableOfContents); const { default: Content, tableOfContents } = await run(vfile, { ...runtime });

example using all provided plugins

```ts // ./lib/mdx/compile-mdx.ts

import { createMdxCompiler, createMdxProcessors, typographyConfig, withCustomHeadingIds, withFootnotes, withIframeTitles, // withImageImports, withImageSizes, withTableOfContents, } from "@acdh-ch/mdx-lib"; import withHeadingIds from "rehype-slug"; import withGfm from "remark-gfm"; import withTypographicQuotes from "remark-smartypants"; import * as runtime from "react/jsx-runtime";

import { useMDXComponents } from "../../mdx-components";

const createProcessor = createMdxProcessors((locale) => { return { remarkPlugins: [withGfm, [withTypographicQuotes, typographyConfig[locale]], withFootnotes], remarkRehypeOptions: { footnoteBackLabel(referenceIndex, rereferenceIndex) { return t("footnoteBackLabel", { reference: referenceIndex + 1 + (rereferenceIndex > 1 ? "-" + rereferenceIndex : ""), }); }, footnoteLabel: t("footnoteLabel"), }, rehypePlugins: [ withCustomHeadingIds, withHeadingIds, [withIframeTitles, { components: ["Embed", "Iframe", "Video"] }], // [withImageImports, { components: ["Figure"] }], [withImageSizes, { components: ["Figure"] }], withTableOfContents, ], }; });

export const compileMdx = createMdxCompiler(createProcessor, runtime, useMDXComponents); ```

Owner

  • Name: Austrian Centre for Digital Humanities & Cultural Heritage
  • Login: acdh-oeaw
  • Kind: organization
  • Email: acdh@oeaw.ac.at
  • Location: Vienna, Austria

GitHub Events

Total
  • Release event: 3
  • Delete event: 4
  • Push event: 3
  • Pull request event: 7
  • Create event: 6
Last Year
  • Release event: 3
  • Delete event: 4
  • Push event: 3
  • Pull request event: 7
  • Create event: 6

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 0
  • Total pull requests: 8
  • Average time to close issues: N/A
  • Average time to close pull requests: about 1 hour
  • Total issue authors: 0
  • Total pull request authors: 2
  • Average comments per issue: 0
  • Average comments per pull request: 0.0
  • Merged pull requests: 7
  • Bot issues: 0
  • Bot pull requests: 7
Past Year
  • Issues: 0
  • Pull requests: 8
  • Average time to close issues: N/A
  • Average time to close pull requests: about 1 hour
  • Issue authors: 0
  • Pull request authors: 2
  • Average comments per issue: 0
  • Average comments per pull request: 0.0
  • Merged pull requests: 7
  • Bot issues: 0
  • Bot pull requests: 7
Top Authors
Issue Authors
Pull Request Authors
  • github-actions[bot] (12)
  • stefanprobst (2)
Top Labels
Issue Labels
Pull Request Labels

Dependencies

.github/workflows/release.yml actions
  • actions/checkout v4 composite
  • actions/setup-node v4 composite
  • changesets/action v1 composite
  • pnpm/action-setup v4 composite
package.json npm
  • @acdh-oeaw/commitlint-config ^2.0.0 development
  • @acdh-oeaw/eslint-config ^2.0.1 development
  • @acdh-oeaw/eslint-config-node ^2.0.1 development
  • @acdh-oeaw/prettier-config ^2.0.0 development
  • @acdh-oeaw/tsconfig-lib ^1.1.1 development
  • @changesets/changelog-github ^0.5.0 development
  • @changesets/cli ^2.27.8 development
  • @commitlint/cli ^19.5.0 development
  • @keystatic/core ^0.5.35 development
  • @types/node ^22.5.4 development
  • eslint ^9.10.0 development
  • eslint-config-flat-gitignore ^0.3.0 development
  • globals ^15.9.0 development
  • is-ci ^3.0.1 development
  • lint-staged ^15.2.10 development
  • npm-run-all2 ^6.2.2 development
  • prettier ^3.3.3 development
  • simple-git-hooks ^2.11.1 development
  • tsup ^8.2.4 development
  • tsx ^4.19.1 development
  • typescript ^5.6.2 development
  • @acdh-oeaw/lib ^0.1.12
  • @mdx-js/mdx ^3.0.1
  • @types/estree ^1.0.5
  • @types/hast ^3.0.4
  • @types/mdast ^4.0.4
  • @types/mdx ^2.0.13
  • estree-util-value-to-estree ^3.1.2
  • hast-util-heading ^3.0.0
  • hast-util-heading-rank ^3.0.0
  • hast-util-to-string ^3.0.0
  • mdast-util-mdx-jsx ^3.1.3
  • unist-util-visit ^5.0.0
  • vfile ^6.0.3
pnpm-lock.yaml npm
  • 284 dependencies