首页 程序笔记 Markdoc 新一代Markdown文档内容发布框架

Markdoc 新一代Markdown文档内容发布框架

今天给大家介绍的主题是 Markdoc,即由 Stripe 开发的一种基于 Markdown 的文档格式和内容发布框架。

Markdoc官网:https://markdoc.dev/

什么是 Markdoc

Markdoc 是一种基于 Markdown 的文档格式和内容发布框架, 它由是 Stripe 内部设计的,以满足面向用户的产品文档的需求。 Markdoc 使用标签和注释的自定义语法扩展了 Markdown,提供了一种为个人用户定制内容并引入交互元素的方法。

可以通过如下方式快速使用 Markdoc:

npm install @markdoc/markdoc
// 或者
yarn add @markdoc/markdoc

安装后就可以在代码中直接引用:

const Markdoc = require('@markdoc/markdoc');
//或者
import Markdoc from '@markdoc/markdoc';

然后调用 parse, transform 和 render 函数来渲染内容。

const source = '# Markdoc';
const ast = Markdoc.parse(source);
const content = Markdoc.transform(ast, /* config */);
const html = Markdoc.renderers.html(content);

目前 Markdoc 在 Github 上有 6.2k 的 star、150+ 的 fork、超过 1k 的项目依赖它,是一个值得长期关注的前端项目。

Markdoc 如何工作

Markdoc 的三大渲染器

按照设计,Markdoc 不是一种成熟的模板语言,并且不允许混合任意代码和内容。 然而,它是一种完全声明的格式,从上到下都是机器可读的:它解析为可以遍历的数据结构,以支持强大的静态分析、验证和程序化内容转换。

Markdoc 渲染器解释自定义标签和节点定义,将文档数据结构转换为可渲染节点树,最终转换为所需的输出格式。 Markdoc 框架目前包括三个渲染器:

一个 HTML 字符串渲染器 一个将文档转换为 JavaScript 代码的静态 React 渲染器 一个将可渲染树节点直接转换为 React 元素的动态 React 渲染器

Markdoc 的 React 渲染器使在 Markdown 内容中使用 React 组件成为可能,其支持选项卡切换器和可折叠部分等交互功能。 可以实现引入对其他输出格式和客户端框架的支持的自定义渲染器。

解析器生成器 PEG.js

PEG.js 是一个简单的 JavaScript 解析器生成器,可生成具有出色错误报告的快速解析器。开发者可以使用它来处理复杂的数据或计算机语言,并轻松构建转换器、解释器、编译器和其他工具。

PEG.js 具有以下显著特征:

简单而富有表现力的语法 集成词法和句法分析 解析器具有开箱即用的出色错误报告 基于解析表达式语法形式主义——比传统的 LL(k) 和 LR(k) 解析器更强大 可从浏览器、命令行或通过 JavaScript API 使用

目前 PEG.js 在 Github 上有 4.6k 的 star、450+ 的 fork、191k 的项目依赖它。可以使用下面的示例快速使用 PEG.js:

npm install -g pegjs
$ pegjs -o arithmetics-parser.js arithmetics.pegjs

markdown-it 的助力

Markdoc 的解析器建立在一个名为 markdown-it 的流行开源 Markdown 库之上。 Markdoc 使用 markdown-it 作为标记器,从 markdown-it 输出的标记数组构建抽象语法树 (AST)。

Markdown-it 解析器的特性包括:具有 100% CommonMark 支持、 扩展支持、语法插件、安全和极致的速度。目前 Markdown-it 在 Github 上有 15.2k 的 star、1.6k 的 fork、432k 的项目依赖它。可以使用下面的示例快速使用 markdown-it:

// node.js经典方式
var MarkdownIt = require('markdown-it'),
  md = new MarkdownIt();
var result = md.render('# markdown-it rulezz!');

// node.js的语法糖
var md = require('markdown-it')();
var result = md.render('# markdown-it rulezz!');

// 没有 AMD 的浏览器,在脚本加载时添加到 window
// 注意,“markdownit”中没有破折号。
var md = window.markdownit();
var result = md.render('# markdown-it rulezz!');

Markdoc 的自定义标记语法在 markdown-it 插件中实现, 解析标记语法的逻辑是从 peg.js 语法生成的。 Markdoc 有自己专用的渲染架构,而不是依赖 markdown-it 来生成它的输出。 为了处理 Markdoc 的自定义标签和支持多种输出格式,其开发了一个独立的渲染系统。

Markdoc 在 Markdown 中添加标记

Markdoc 选择 Markdown 作为起点,因为它易于阅读和推理,许多工程师和技术作家已经非常熟悉,并且得到众多现有工具的大型生态系统的广泛支持。 然而,Markdown 本身并不适合编写复杂的、高度结构化的内容,如文档等等。

Markdoc 提供了一个可扩展的系统,用于定义可以在 Markdown 内容中无缝使用的自定义标签。 使用自定义标记语法,开发者能够表达更精细的文档层次结构,插入交互式组件,并支持条件内容、内容包含和变量插值等功能。 Markdoc 对 Markdown 语法的扩展被设计为可组合且侵入性最小,在不影响可读性的情况下提供关键功能。

比如下面示例使用 .my-class-name 和 #my-id 作为 class=my-class-name 和 id=my-id 的简写。

# Examples {% #examples %}

{% table .striped #exampletable %}
- One
- Two
- Three
{% /table %}

Markdoc 也允许开发者为每个标签配置自定义属性类型,比如以下示例定义了 Callout 标记的属性。 默认情况下,该属性设置为注意并根据匹配数组进行验证。

{
  render: 'Callout',
  children: ['paragraph', 'tag', 'list'],
  attributes: {
    type: {
      type: String,
      default: 'note',
      required: true,
      matches: ['caution', 'check', 'note', 'warning'],
      errorLevel: 'critical',
    },
  }
};

在 React 中使用 Markdoc

Markdoc 支持使用 React 开箱即用地渲染 Markdoc 语法。按照以下步骤使用 create-react-app 和 express 构建 Markdoc 应用程序。

按照 create-react-app 入门步骤创建初始应用程序

设置 Markdoc 架构

schema/
├── Callout.markdoc.js
└── heading.markdoc.js

schema/Callout.markdoc.js 的内容如下:

// schema/Callout.markdoc.js

module.exports = {
  render: 'Callout',
  children: ['paragraph', 'tag', 'list'],
  attributes: {
    type: {
      type: String,
      default: 'note',
      matches: ['check', 'error', 'note', 'warning'],
    },
  },
};

schema/heading.markdoc.js 的内容如下:

// schema/heading.markdoc.js

const { nodes } = require('@markdoc/markdoc');

function generateID(children, attributes) {
  if (attributes.id && typeof attributes.id === 'string') {
    return attributes.id;
  }
  return children
    .filter((child) => typeof child === 'string')
    .join(' ')
    .replace(/[?]/g, '')
    .replace(/\s+/g, '-')
    .toLowerCase();
}

module.exports = {
  ...nodes.heading,
  transform(node, config) {
    const base = nodes.heading.transform(node, config);
    base.attributes.id = generateID(base.children, base.attributes);
    return base;
  },
};

解析服务器上的 Markdoc 文档

// ...
const rawText = fs.readFileSync(file, 'utf-8');
const ast = Markdoc.parse(rawText);

在服务端调用 Markdoc.transform

// server.js

const express = require('express');

const app = express();

const callout = require('./schema/callout.markdoc');
const heading = require('./schema/heading.markdoc');
// ...

app.get('/markdoc', (req, res) => {
  const ast = contentManifest[req.query.path];

  const config = {
    tags: {
      callout,
    },
    nodes: {
      heading,
    },
    variables: {},
  };

  const content = Markdoc.transform(ast, config);

  return res.json(content);
});

app.listen(4242, () => {
  console.log(`Example app listening on port ${4242}`);
});

在客户端调用 Markdoc.renderers.react

// src/App.js

import React from 'react';
import Markdoc from '@markdoc/markdoc';

import { Callout } from './Callout';

export default function App() {
  const [content, setContent] = React.useState(null);

  React.useEffect(() => {
    (async () => {
      const response = await fetch(
        `/markdoc?` + new URLSearchParams({ path: window.location.pathname }),
        { headers: { Accept: 'application/json' } }
      );

      if (response.status === 404) {
        setContent('404');
        return;
      }

      const content = await response.json();
      setContent(content);
    })();
  }, []);

  if (content === '404') {
    return <p>Page not found.</p>;
  }

  if (!content) {
    return <p>Loading...</p>;
  }

  const components = {
    Callout,
  };

  return Markdoc.renderers.react(content, React, { components });
}

启动客户端和服务器

npm run start:client
npm run start:server

除了与React集成外,Markdoc还支持与HTML、Next.js等集成。

参考资料

https://markdoc.dev/docs/overview

https://github.com/markdown-it/markdown-it

https://pegjs.org/

https://github.com/pegjs/pegjs

https://markdoc.dev/docs/attributes

https://stripe.com/blog/markdoc

https://markdoc.dev/docs/examples/react#setup

https://transloadit.com/blog/2022/06/devtimes-055/

3

声明 本站内容部分来源于网络,仅供参考学习交流并不代表本站观念,如无意中侵犯您的权益( 包括/图片/视频/个人隐私等信息 )请来信告知,本站收到信息会尽快处理并回访,联系邮箱:laodilailiao@foxmail.com

站心网

今天给大家介绍的主题是 Markdoc,即由 Stripe 开发的一种基于 Markdown 的文档格式和内容发布框架。 Markd..

为您推荐

值得探索的 8 个机器学习 JavaScript 框架

JavaScript开发人员倾向于寻找可用于机器学习模型训练的JavaScript框架。下面是一些机器学习算法,基于这些算法可以使用本文中列出的不同JavaScript框架来模型训练:简单的线性回归多变量线性回归逻辑回归朴素贝叶斯..

BotSharp 基于 .NET 平台的开源 AI 聊天机器人框架

BotSharp 是一个开源的、基于 .NET 平台的 AI 聊天机器人框架,旨在简化构建智能对话系统的过程。它主要通过自然语言处理(NLP)技术,帮助开发者构建具备语言理解和对话能力的应用。BotSharp 提供了丰富的功能和扩..

帝国CMS8.0即将发布2025年1月18号闪亮登场

一、新增支持PostgreSQL数据库和国产数据库:(支持国产数据库如:国产华为高斯(openGauss)、国产金仓数据库(kingbase)等)1、为了适配其它数据库,所有数据表查询限制数量单独函数返回,并保存在各数据库操作类文件里..

微软于发布了.NET 9 Release Candidate 2 提高整体质量

微软于2024年10月8日发布了 .NET 9 的第二个也是最后一个候选版本(Release Candidate 2),标志着正式版发布前的最后阶段。主要更新内容:质量提升:专注于提高整体质量,修复已知问题,确保框架的稳定性和可靠性。..

.NET 游戏开发框架有哪些?

在游戏开发领域,.NET 框架因其强大的功能和灵活性而广受欢迎。对于希望使用 .NET 进行游戏开发的开发者来说,了解可用的框架是至关重要的。以下是一些流行的 .NET 游戏开发框架:1. Unity: 尽管 Unity 主要使用 C# ..

通过js修改tinymce的编辑器的内容

在网页开发中,TinyMCE是一个流行的富文本编辑器。它允许用户轻松地创建和编辑HTML内容,而无需直接操作代码。然而,有时我们可能需要通过JavaScript来动态修改编辑器中的内容。本文将介绍如何使用JavaScript来修改T..

PluginCore 基于 ASP.NET Core 的轻量级插件框架

项目概述PluginCore 是一个基于 ASP.NET Core 的轻量级插件框架,旨在简化插件的集成与管理。通过最少的配置,开发者可以快速集成并专注于业务逻辑的开发。它支持动态 WebAPI、插件隔离与共享、前后端分离、热插拔等..

微软发布VS Code AI工具包,集成多模型AI能力

微软发布了VS Code AI工具包,增强了代码编辑器的AI功能!微软推出了VS Code AI工具包,这是一个全新的扩展,旨在将AI功能集成到Visual Studio Code中。该工具包支持多种AI模型,包括本地和远程模型,用户可以配置自..

微软 .NET 9 正式发布!专为云原生和生成式 AI 应用设计

微软正式发布了 .NET 9,这是一次重大的版本更新。微软在 .NET 9 中带来了一系列新特性和改进,主要聚焦在性能优化、云原生支持、AI集成以及开发者体验的提升。以下是一些重要的更新亮点:性能改进:在 .NET 9 中,..

.NET框架和CLR的工作原理?

.NET 框架和 CLR(公共语言运行时,Common Language Runtime)共同构成了一个应用程序运行和开发的环境,为多种编程语言提供跨平台支持、内存管理、异常处理、安全性、以及其他服务。它们各自的工作原理如下:.NET F..

十大前端开发框架

编者按:考虑到英文原文的长度以及可读性,十大前端开发框架将分成上下两部分呈现给大家。上半部分着重讲的是Bootstrap家族框架,第二节将会跟大家分享更多其他的框架。随着互联网的不断成熟以及我们越来越多的用各..

跨平台UI框架 MAUI Avalonia Flutter怎么选?

选择跨平台 UI 框架取决于你的项目需求、目标平台、开发团队的技能和框架的特点。以下是 MAUI、Avalonia 和 Flutter 的比较,帮助你做出合适的选择。1. .NET MAUI (Multi-platform App UI)微软推出的跨平台框架,可..

尤雨溪成立VoidZero 成前端开发主流框架

尤雨溪和他的虚空帝国:VoidZero,一场前端的创世纪!2024年初秋,一个名字,VoidZero,如同代码中突然插入的一行神秘指令,瞬间扰乱了前端世界的平静。而这行指令的编写者,正是前端界的传奇,Vue.js之父—&md..

强大的 .NET Mock 框架 单元测试模拟库Moq使用教程

单元测试是确保代码质量和可靠性的重要手段。当我们的代码依赖于外部系统、数据库或第三方服务时,编写有效的单元测试可能会变得复杂且耗时。为了简化这一过程,模拟(Mocking)技术应运而生。在 .NET 生态系统中,M..

Docsify | 轻量级无静态构建文档站点生成器

什么是 Docsify?Docsify 可以即时生成你的文档网站。与 GitBook 不同,它不会生成静态 html 文件。相反,它会智能地加载和解析你的 Markdown 文件并将其显示为网站。要开始使用它,你需要做的就是创建一个 index.ht..

asp.net母版页和内容页PageLoad顺序

关于ASP页面Page_Load发生在事件之前而导致的问题已经喜闻乐见,以下是内容页和母版页(如果有)的事件发生顺序: ContentPage.PreInit Master.Init ContentPage.Init ContentPage.InitComplite ContentPage.PreLoa..

使用htmlagilitypack+xpath抓取网页内容示例

本文使用htmlagilitypack+xpath抓取网页内容示例,用简单的例子展示如何使用htmlagilitypack抓取网页,可以用来做数据采集等功能。用htmlagilitypack+xpath抓取网页内容示例源码下载首先在nuget中获取htmlagilitypac..

CentOS7部署发布.NET Core网站Ngnix安装配置图文教程

Linux服务器部署.NET Core网站运行速度更快,最近打算把原来windows server上的网站迁到linux的云服务器上。 顺便记录一下CentOS7安装.NET运行环境,安装和配置Ngnix的过程。首先安装.NET运行时sudorpm-Uvhhttps://p..

什么是.NET框架?它的主要组成部分是什么?

.NET框架是由微软公司开发的一个软件开发平台,用于构建和运行各种类型的应用程序,包括桌面应用程序、Web应用程序、移动应用程序和服务。它提供了一个统一的环境,使开发人员能够使用多种编程语言(如C#、VB.NET和F..

2023年主流的前端框架有哪些?

当前主流的前端框架当前主流的前端框架有React,Angular,Vue.js,还有一些相对小众但也具有一定影响力的框架,例如 Svelte、Ember、Backbone 等。React:React 是一个由 Facebook 开发的 JavaScript 库,专注于构建..

发表回复

返回顶部