Skip to content

Commit

Permalink
chore: update doc tool to support special cases
Browse files Browse the repository at this point in the history
  • Loading branch information
lowlighter committed Oct 29, 2024
1 parent 0ab2109 commit e796905
Show file tree
Hide file tree
Showing 5 changed files with 309 additions and 48 deletions.
88 changes: 82 additions & 6 deletions .github/tools/mod_html_to_readme_md.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,47 @@
// Imports
import type { rw } from "@libs/typing/types"
import { Window } from "@mizu/internal/vdom"
import { dirname, join } from "@std/path"
import { dirname, fromFileUrl, join } from "@std/path"
import { expandGlob } from "@std/fs"
import * as JSONC from "@std/jsonc"
import { Logger } from "@libs/logger"
import { command } from "@libs/run/command"
import server from "@www/serve.ts"
const window = new Window()
const log = new Logger()

if (import.meta.main) {
// Directives
for await (const { path: source } of expandGlob("**/mod.html", { root: Deno.args[0], includeDirs: false })) {
const destination = join(dirname(source), "README.md")
await Deno.writeTextFile(destination, await htmlToMd(await Deno.readTextFile(source)))
await command("deno", ["fmt", destination], { stdout: null, stderr: null })
log.with({ source, destination }).ok("done")
}

// Special cases
for await (const { path: source } of expandGlob("**/deno.jsonc", { root: Deno.args[0], includeDirs: false })) {
const jsonc = JSONC.parse(await Deno.readTextFile(source)) as rw
if ((jsonc.name === "@mizu/render") || ("workspace" in jsonc)) {
const destination = join(dirname(source), "README.md")
await Deno.writeTextFile(destination, await mdWithHtmlInclude(destination))
await command("deno", ["fmt", destination], { stdout: null, stderr: null })
log.with({ source, destination }).ok("done")
}
}
}

/** Read markdown file and include HTML content. */
export async function mdWithHtmlInclude(path: string) {
const content = await Deno.readTextFile(path)
return content
.replace(/(?<open><!-- (?<include>@mizu\/[\/.\w]+\.html) -->)[\s\S]*(?<close><!-- \k<include> -->)/g, (_, open, include, close) => {
const html = Deno.readTextFileSync(join(fromFileUrl(import.meta.resolve("../../")), include.replace("@mizu/", "")))
const window = new Window(`<body>${html}</body>`)
const markdown = toMarkdown(window.document.querySelector("body"))
window.close()
return `${open}\n\n${markdown}\n\n${close}`
})
}

/** Convert `<mizu-directive>` documentation from HTML to markdown. */
Expand Down Expand Up @@ -119,24 +146,70 @@ function toMarkdown(elements: Array<Node> | Node | null, markdown = "") {
// Ignore
case "WBR":
break
// Content
case "SPAN":
// New line
case "BR":
markdown += "\\"
break
// Heading
case "H1":
case "H2":
case "H3":
case "H4":
case "H5":
case "H6":
markdown += `\n${"#".repeat(Number(node.tagName[1]))} ${toMarkdown(Array.from(node.childNodes))}\n\n`
break
//
case "PRE": {
if (node.querySelector("code")) {
const language = Array.from(node.querySelector("code")!.attributes).find((attr) => attr.name.startsWith("*code"))?.name.match(/\[(.*)\]/)?.[1] ?? ""
markdown += `\n\`\`\`${language}\n${unindent(node.textContent)}\n\`\`\`\n`
break
}
}
/* falls through */
// Block
case "DIV": {
if (node.classList.contains("flash")) {
const type = node.classList.contains("attention") ? "WARNING" : "NOTE"
markdown += prefix(`[!${type}]\n\n${toMarkdown(Array.from(node.childNodes))}`, "> ")
break
}
}
/* falls through */
case "BODY":
case "SECTION":
case "P":
markdown += `${toMarkdown(Array.from(node.childNodes))}\n\n`
break
// Content
case "UL":
case "SPAN":
case "SMALL":
case "ABBR":
markdown += toMarkdown(Array.from(node.childNodes))
break
// Code
case "CODE":
case "VAR":
markdown += `\`${toMarkdown(Array.from(node.childNodes))}\``
break
// Italic
// Italic (or swapped icons)
case "I":
if (node.hasAttribute("%response.swap")) {
const icon = node.getAttribute("%http")?.match(/\/([-\w]+)-16\.svg$/)?.[1] ?? ""
const emoji = { rocket: "🍜", "project-symlink": "🍤", "ai-model": "🍣", "code-review": "🍱", apps: "🥡", "code-of-conduct": "🍙" }[icon] ?? ""
markdown += emoji
if (node.nextSibling?.nodeType === window.Node.TEXT_NODE) {
node.nextSibling.textContent = ` ${node.nextSibling.textContent?.trimStart()}`
}
break
}
markdown += `*${toMarkdown(Array.from(node.childNodes))}*`
break
// Bold
case "STRONG":
case "B":
case "STRONG":
markdown += `**${toMarkdown(Array.from(node.childNodes))}**`
break
// Italic and bold
Expand All @@ -151,6 +224,10 @@ function toMarkdown(elements: Array<Node> | Node | null, markdown = "") {
case "A":
markdown += `[${toMarkdown(Array.from(node.childNodes))}](${node.getAttribute("href")})`
break
// Image
case "IMG":
markdown += `![${node.getAttribute("alt") ?? ""}](${node.getAttribute("src")})`
break
// List
case "LI": {
let depth = 0
Expand All @@ -163,7 +240,6 @@ function toMarkdown(elements: Array<Node> | Node | null, markdown = "") {
markdown += `\n${" ".repeat(Math.max(0, depth - 1))}- ${toMarkdown(Array.from(node.childNodes))}`
break
}

// Callouts
case "MIZU-NOTE":
case "MIZU-WARN":
Expand Down
4 changes: 3 additions & 1 deletion @mizu/http/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,4 +224,6 @@ Alias for `.consume[xml]`.
### `.swap[boolean]`

Consume body using [`response.text()`](https://developer.mozilla.org/docs/Web/API/Response/text) and set target's [`outerHTML`](https://developer.mozilla.org/docs/Web/API/Element/outerHTML). This modifier takes precedence over the `.consume` modifier and makes it effectless,
although if `.consume[text]` is set, swapped content will be escaped.Any non-directive HTML attributes on the target will be applied to the swapped content elements.
although if `.consume[text]` is set, swapped content will be escaped.

Any non-directive HTML attributes on the target will be applied to the swapped content elements.
126 changes: 126 additions & 0 deletions @mizu/render/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,129 @@
<p align="center"><a href="https://mizu.sh"><img src="https://mizu.sh/logo.png" width="300"></a></p>

Full documentation is available at [mizu.sh](https://mizu.sh).

<!-- @mizu/www/html/mizu/features.html -->

# [Features](#features)

## 🍜 Plug-and-play

Simply [include the library](#usage) and start building amazing things instantly with vanilla JavaScript and HTML.

## 🍤 Cross-platform

Compatible across a wide range of JavaScript and TypeScript runtimes, including all major browsers.

## 🍣 Any-side

Render your content wherever you need it and however you want it with [user-friendly APIs](#api-user).

## 🍱 Hackable

Cherry-pick features and craft your own setup easily with [developer-friendly APIs](#api-dev) and our [custom builder](/build).

## 🥡 Community-driven

Build, [share and reuse](/community) custom elements and directives to supercharge your development.

Want to effortlessly theme your page? Check out [matcha.css](https://matcha.mizu.sh)!

## 🍙 Open-core

Licensed under the [AGPLv3 License](https://github.com/lowlighter/mizu/blob/main/LICENSE#L13-L658), source code fully available on [github.com](https://github.com/lowlighter/mizu).

Use [MIT License](https://github.com/lowlighter/mizu/blob/main/LICENSE#L662-L685) terms for non-commercial projects or with an active [$1+ monthly sponsorship](https://github.com/sponsors/lowlighter).

<!-- @mizu/www/html/mizu/features.html -->

<!-- @mizu/www/html/mizu/usage.html -->

# [Usage](#usage)

> [!WARNING]
>
> _**mizu.js**_ is still in active development.
>
> See [github.com/lowlighter/mizu/issues/34](https://github.com/lowlighter/mizu/issues/34) for more information.
## [Client-side](#usage-client)

Set up _**mizu.js**_ in your browser environment using one of two methods:

- [Immediately Invoked Function Expression (IIFE)](https://developer.mozilla.org/docs/Glossary/IIFE)
- [EcmaScript Module (ESM)](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Modules)

> [!NOTE]
>
> On the client-side...
>
> - **Rendering is explicit**, requiring the [`*mizu`](#mizu) attribute to enable _**mizu.js**_ on a subtree.
> - **Reactivity is enabled**, so changes to [contexts](#concept-context) will trigger a re-render.
### [IIFE _( `.js`)_](#usage-client-iife)

This setup automatically starts rendering the page once the script is loaded. It's the simplest way to get started but limited to the default configuration.

```html
<script src="https://mizu.sh/client.js" defer></script>
```

### [ESM _( `.mjs`)_](#usage-client-esm)

This setup requires you to import and start _**mizu.js**_ manually, allowing customization of the rendering process, such as setting the initial context and loading additional directives.

```
<script type="module">
  import Mizu from "https://mizu.sh/client.mjs"
  await Mizu.render(document.body, { context: { foo: "🌊 Yaa, mizu!" } })
</script>
```

## [Server-side](#usage-server)

To set up _**mizu.js**_ in a server environment, install it locally. _**mizu.js**_ packages are hosted on [![](https://jsr.io/badges/@mizu)](https://jsr.io/@mizu).

> [!NOTE]
>
> On the server side...
>
> - **Rendering is implicit**, so the [`*mizu`](#mizu) attribute is not required.
> - **Reactivity is disabled**, meaning changes to [contexts](#concept-context) are not tracked and will not trigger a re-render.
### [Deno](#usage-server-deno)

Deno supports the `jsr:` specifier natively, allowing you to import _**mizu.js**_ directly.

```ts
import Mizu from "jsr:@mizu/render/server"
await Mizu.render(`<div *text="foo"></div>`, { context: { foo: "🌊 Yaa, mizu!" } })
```

Alternatively, add it to your project using the Deno CLI.

```bash
deno add jsr:@mizu/render
```

### [Other runtimes (NodeJS, Bun, etc.)](#usage-server-others-runtimes)

Add _**mizu.js**_ to your project using the [JSR npm compatibility layer](https://jsr.io/docs/npm-compatibility).

```bash
# NodeJS
npx jsr add @mizu/render
```

```bash
# Bun
bunx jsr add @mizu/render
```

Once installed, use it in your project.

```ts
import Mizu from "@mizu/render/server"
await Mizu.render(`<div *text="foo"></div>`, { context: { foo: "🌊 Yaa, mizu!" } })
```

<!-- @mizu/www/html/mizu/usage.html -->
Loading

0 comments on commit e796905

Please sign in to comment.