Skip to content

Commit

Permalink
Improve mdxJsxTextElementToHtml
Browse files Browse the repository at this point in the history
  • Loading branch information
slorber committed Aug 25, 2023
1 parent b3c8f5c commit e90fc28
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 188 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ exports[`toc remark plugin works on non text phrasing content 1`] = `
value: '<code>inline.code()</code>',
id: 'inlinecode',
level: 2
},
{
value: 'some <span class="some-class">styled</span> <strong>heading</strong> <span class="myClassName &lt;&gt; weird char"></span> test',
id: 'some-styled-heading--test',
level: 2
}
]
Expand All @@ -183,6 +188,8 @@ exports[`toc remark plugin works on non text phrasing content 1`] = `
## <i>HTML</i>
## \`inline.code()\`
## some <span className="some-class" style={{border: "solid"}}>styled</span> <strong>heading</strong> <span class="myClass" className="myClassName <> weird char" data-random-attr="456" /> test
"
`;

Expand Down
39 changes: 35 additions & 4 deletions packages/docusaurus-mdx-loader/src/remark/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,56 @@ import escapeHtml from 'escape-html';
import type {Parent} from 'unist';
import type {PhrasingContent, Heading} from 'mdast';
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
import type {MdxJsxAttributeValueExpression} from 'mdast-util-mdx';
import type {
MdxJsxAttribute,
MdxJsxAttributeValueExpression,
MdxJsxTextElement,
} from 'mdast-util-mdx';

export function stringifyContent(
node: Parent,
toString: (param: unknown) => string, // TODO weird but works): string {
toString: (param: unknown) => string, // TODO weird but works
): string {
return (node.children as PhrasingContent[])
.map((item) => toValue(item, toString))
.join('');
}

// TODO This is really a workaround, and not super reliable
// For now we only support serializing tagName, className and content
// Can we implement the TOC with real JSX nodes instead of html strings later?
function mdxJsxTextElementToHtml(
element: MdxJsxTextElement,
toString: (param: unknown) => string, // TODO weird but works
): string {
const tag = element.name;

const attributes = element.attributes.filter(
(child): child is MdxJsxAttribute => child.type === 'mdxJsxAttribute',
);

const classAttribute =
attributes.find((attr) => attr.name === 'className') ??
attributes.find((attr) => attr.name === 'class');

const classAttributeString = classAttribute
? `class="${escapeHtml(classAttribute.value)}"`
: ``;

const allAttributes = classAttributeString ? ` ${classAttributeString}` : '';

const content = stringifyContent(element, toString);

return `<${tag}${allAttributes}>${content}</${tag}>`;
}

export function toValue(
node: PhrasingContent | Heading,
toString: (param: unknown) => string, // TODO weird but works
): string {
switch (node.type) {
case 'mdxJsxTextElement': {
const tag = node.name;
return `<${tag}>${stringifyContent(node, toString)}</${tag}>`;
return mdxJsxTextElementToHtml(node as MdxJsxTextElement, toString);
}
case 'text':
return escapeHtml(node.value);
Expand Down
188 changes: 4 additions & 184 deletions website/docs/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,190 +5,10 @@ slug: /

# Introduction

⚡️ Docusaurus will help you ship a **beautiful documentation site in no time**.
## Some <span style={{border: "solid"}}>styled</span> heading

💸 Building a custom tech stack is expensive. Instead, **focus on your content** and just write Markdown files.
## Some <span className="xyz">styled</span> heading v2

💥 Ready for more? Use **advanced features** like versioning, i18n, search and theme customizations.
## some <span className="some-class" style={{border: "solid"}}>styled</span> <strong>heading</strong>

💅 Check the **[best Docusaurus sites](/showcase?tags=favorite)** for inspiration and read some **[testimonials](https://twitter.com/sebastienlorber/timelines/1392048416872706049)**.

🧐 Docusaurus is a **static-site generator**. It builds a **single-page application** with fast client-side navigation, leveraging the full power of **React** to make your site interactive. It provides out-of-the-box **documentation features** but can be used to create **any kind of site** (personal website, product, blog, marketing landing pages, etc).

![](/img/slash-introducing.svg)

## Fast Track ⏱️ {#fast-track}

Understand Docusaurus in **5 minutes** by playing!

Create a new Docusaurus site and follow the **very short** embedded tutorial.

Install [Node.js](https://nodejs.org/en/download/) and create a new Docusaurus site:

```bash
npx create-docusaurus@latest my-website classic
```

Start the site:

```bash
cd my-website
npx docusaurus start
```

Open [`http://localhost:3000`](http://localhost:3000) and follow the tutorial.

:::tip

Use **[docusaurus.new](https://docusaurus.new)** to test Docusaurus immediately in your browser!

Or read the **[5-minute tutorial](https://tutorial.docusaurus.io)** online.

:::

## Docusaurus: Documentation Made Easy

In this presentation at [Algolia Community Event](https://www.algolia.com/), [Meta Open Source team](https://opensource.facebook.com/) shared a brief walk-through of Docusaurus. They covered how to get started with the project, enable plugins, and set up functionalities like documentation and blogging.

{/* cSpell:ignore Yhyx Sksg */}

```mdx-code-block
import LiteYouTubeEmbed from 'react-lite-youtube-embed';
<div className="video-container">
<LiteYouTubeEmbed
id="Yhyx7otSksg"
params="autoplay=1&autohide=1&showinfo=0&rel=0"
title="Docusaurus: Documentation Made Easy"
poster="maxresdefault"
webp
/>
</div>
```

## Migrating from v1 {#migrating-from-v1}

Docusaurus v2 has been a total rewrite from Docusaurus v1, taking advantage of a completely modernized toolchain. After [v2's official release](https://docusaurus.io/blog/2022/08/01/announcing-docusaurus-2.0), we highly encourage you to **use Docusaurus v2 over Docusaurus v1**, as Docusaurus v1 has been deprecated.

A [lot of users](/showcase) are already using Docusaurus v2 ([trends](https://www.npmtrends.com/docusaurus-vs-@docusaurus/core)).

**Use Docusaurus v2 if:**

- :white_check_mark: You want a modern Jamstack documentation site
- :white_check_mark: You want a single-page application (SPA) with client-side routing
- :white_check_mark: You want the full power of React and MDX
- :white_check_mark: You do not need support for IE11

**Use [Docusaurus v1](https://v1.docusaurus.io/) if:**

- :x: You don't want a single-page application (SPA)
- :x: You need support for IE11 (...do you? IE [has already reached end-of-life](https://docs.microsoft.com/en-us/lifecycle/products/internet-explorer-11) and is no longer officially supported)

For existing v1 users that are seeking to upgrade to v2, you can follow our [migration guide](./migration/migration-overview.mdx).

## Features {#features}

Docusaurus is built with high attention to the developer and contributor experience.

- ⚛️ **Built with 💚 and React**:
- Extend and customize with React
- Gain full control of your site's browsing experience by providing your own React components
- **Pluggable**:
- Bootstrap your site with a basic template, then use advanced features and plugins
- Open source your plugins to share with the community
- ✂️ **Developer experience**:
- Start writing your docs right now
- Universal configuration entry point to make it more maintainable by contributors
- Hot reloading with lightning-fast incremental build on changes
- Route-based code and data splitting
- Publish to GitHub Pages, Netlify, Vercel, and other deployment services with ease

Our shared goal—to help your users quickly find what they need and understand your products better. We share our best practices to help you build your docs site right and well.

- 🎯 **SEO friendly**:
- HTML files are statically generated for every possible path.
- Page-specific SEO to help your users land on your official docs directly relating their problems at hand.
- 📝 **Powered by MDX**:
- Write interactive components via JSX and React embedded in Markdown.
- Share your code in live editors to get your users to love your products on the spot.
- 🔍 **Search**: Your full site is searchable.
- 💾 **Document Versioning**: Helps you keep documentation in sync with project releases.
- 🌍 **Internationalization (i18n)**: Translate your site in multiple locales.

Docusaurus 2 is born to be compassionately accessible to all your users, and lightning-fast.

- ⚡️ **Lightning-fast**. Docusaurus 2 follows the [PRPL Pattern](https://developers.google.com/web/fundamentals/performance/prpl-pattern/) that makes sure your content loads blazing fast.
- 🦖 **Accessible**. Attention to accessibility, making your site equally accessible to all users.

## Design principles {#design-principles}

- **Little to learn**. Docusaurus should be easy to learn and use as the API is quite small. Most things will still be achievable by users, even if it takes them more code and more time to write. Not having abstractions is better than having the wrong abstractions, and we don't want users to have to hack around the wrong abstractions. Mandatory talk—[Minimal API Surface Area](https://www.youtube.com/watch?v=4anAwXYqLG8).
- **Intuitive**. Users will not feel overwhelmed when looking at the project directory of a Docusaurus project or adding new features. It should look intuitive and easy to build on top of, using approaches they are familiar with.
- **Layered architecture**. The separations of concerns between each layer of our stack (content/theming/styling) should be clear—well-abstracted and modular.
- **Sensible defaults**. Common and popular performance optimizations and configurations will be done for users but they are given the option to override them.
- **No vendor lock-in**. Users are not required to use the default plugins or CSS, although they are highly encouraged to. Certain core infrastructures like React Loadable and React Router cannot be swapped because we do default performance optimization on them, but not higher-level ones. Choice of Markdown engines, CSS frameworks, CSS methodology, and other architectures will be entirely up to users.

We believe that, as developers, knowing how a library works helps us become better at using it. Hence we're dedicating effort to explaining the architecture and various components of Docusaurus with the hope that users reading it will gain a deeper understanding of the tool and be even more proficient in using it.

## Comparison with other tools {#comparison-with-other-tools}

Across all static site generators, Docusaurus has a unique focus on documentation sites and has many out-of-the-box features.

We've also studied other main static site generators and would like to share our insights on the comparison, hopefully helping you navigate through the prismatic choices out there.

### Gatsby {#gatsby}

[Gatsby](https://www.gatsbyjs.com/) is packed with a lot of features, has a rich ecosystem of plugins, and is capable of doing everything that Docusaurus does. Naturally, that comes at a cost of a higher learning curve. Gatsby does many things well and is suitable for building many types of websites. On the other hand, Docusaurus tries to do one thing super well - be the best tool for writing and publishing content.

GraphQL is also pretty core to Gatsby, although you don't necessarily need GraphQL to build a Gatsby site. In most cases when building static websites, you won't need the flexibility that GraphQL provides.

Many aspects of Docusaurus 2 were inspired by the best things about Gatsby and it's a great alternative.

[Docz](https://github.com/pedronauck/docz) is a Gatsby theme to build documentation websites. It is currently less featured than Docusaurus.

### Next.js {#nextjs}

[Next.js](https://nextjs.org/) is another very popular hybrid React framework. It can help you build a good documentation website, but it is not opinionated toward the documentation use-case, and it will require a lot more work to implement what Docusaurus provides out-of-the-box.

[Nextra](https://github.com/shuding/nextra) is an opinionated static site generator built on top of Next.js. It is currently less featured than Docusaurus.

### VuePress {#vuepress}

[VuePress](https://vuepress.vuejs.org/) has many similarities with Docusaurus - both focus heavily on content-centric website and provides tailored documentation features out of the box. However, VuePress is powered by Vue, while Docusaurus is powered by React. If you want a Vue-based solution, VuePress would be a decent choice.

### MkDocs {#mkdocs}

[MkDocs](https://www.mkdocs.org/) is a popular Python static site generator with value propositions similar to Docusaurus.

It is a good option if you don't need a single-page application and don't plan to leverage React.

[Material for MkDocs](https://squidfunk.github.io/mkdocs-material/) is a beautiful theme.

### Docsify {#docsify}

[Docsify](https://docsify.js.org/) makes it easy to create a documentation website, but is not a static-site generator and is not SEO friendly.

### GitBook {#gitbook}

[GitBook](https://www.gitbook.com/) has a very clean design and has been used by many open source projects. With its focus shifting towards a commercial product rather than an open-source tool, many of its requirements no longer fit the needs of open source projects' documentation sites. As a result, many have turned to other products. You may read about Redux's switch to Docusaurus [here](https://github.com/reduxjs/redux/issues/3161).

Currently, GitBook is only free for open-source and non-profit teams. Docusaurus is free for everyone.

### Jekyll {#jekyll}

[Jekyll](https://github.com/jekyll/jekyll) is one of the most mature static site generators around and has been a great tool to use — in fact, before Docusaurus, most of Facebook's Open Source websites are/were built on Jekyll! It is extremely simple to get started. We want to bring a similar developer experience as building a static site with Jekyll.

In comparison with statically generated HTML and interactivity added using `<script />` tags, Docusaurus sites are React apps. Using modern JavaScript ecosystem tooling, we hope to set new standards on doc sites' performance, asset building pipeline and optimizations, and ease to set up.

## Staying informed {#staying-informed}

- [GitHub](https://github.com/facebook/docusaurus)
- [Twitter](https://twitter.com/docusaurus)
- [Blog](/blog)
- [Discord](https://discord.gg/docusaurus)

## Something missing? {#something-missing}

If you find issues with the documentation or have suggestions on how to improve the documentation or the project in general, please [file an issue](https://github.com/facebook/docusaurus) for us, or send a tweet mentioning the [@docusaurus](https://twitter.com/docusaurus) Twitter account.

For new feature requests, you can create a post on our [feature requests board (Canny)](/feature-requests), which is a handy tool for road-mapping and allows for sorting by upvotes, which gives the core team a better indicator of what features are in high demand, as compared to GitHub issues which are harder to triage. Refrain from making a Pull Request for new features (especially large ones) as someone might already be working on it or will be part of our roadmap. Talk to us first!
## hey <button onClick={() => alert("click me")}>click me </button> ho

0 comments on commit e90fc28

Please sign in to comment.