Skip to content

Commit

Permalink
ドキュメントサイトを追加
Browse files Browse the repository at this point in the history
  • Loading branch information
dc7290 committed Dec 17, 2024
1 parent 1f46fe3 commit 0632aae
Show file tree
Hide file tree
Showing 19 changed files with 1,851 additions and 38 deletions.
2 changes: 1 addition & 1 deletion __tests__/actual-usecase.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe("microCMSRichEditorHandler", () => {
console.log(html);

expect(html).toBe(
'<h1 id="ha879678dfe">&#x898b;&#x51fa;&#x3057;1</h1><h2 id="had7ce3f1cb">&#x898b;&#x51fa;&#x3057;2</h2><figure><picture><source type="image/webp" sizes="100vw" width="1200" height="630" srcset="https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=640&amp;fm=webp 640w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=750&amp;fm=webp 750w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=828&amp;fm=webp 828w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=1080&amp;fm=webp 1080w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=1200&amp;fm=webp 1200w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=1920&amp;fm=webp 1920w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=2048&amp;fm=webp 2048w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=3840&amp;fm=webp 3840w"><img src="https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png" alt width="1200" height="630" sizes="100vw" loading="lazy" decoding="async" srcset="https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=640 640w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=750 750w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=828 828w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=1080 1080w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=1200 1200w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=1920 1920w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=2048 2048w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=3840 3840w"></picture></figure><div data-filename="aaa"><pre class="shiki vitesse-light" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span>import aaa from &apos;ccc&apos;;</span></span>\n<span class="line"><span></span></span>\n<span class="line"><span>aaa();</span></span></code></pre></div><pre class="shiki vitesse-light" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span>import aaa from &apos;ccc&apos;;</span></span>\n<span class="line"><span></span></span>\n<span class="line"><span>aaa();</span></span></code></pre><div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.25%;"><iframe src="https://www.youtube.com/embed/zknKqGwCiSs?rel=0" style="top: 0; left: 0; width: 100%; height: 100%; position: absolute; border: 0;" allowfullscreen scrolling="no" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share;"></iframe></div>',
'<h1 id="ha879678dfe">&#x898b;&#x51fa;&#x3057;1</h1><h2 id="had7ce3f1cb">&#x898b;&#x51fa;&#x3057;2</h2><figure><picture><source type="image/webp" sizes="100vw" width="1200" height="630" srcset="https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=640&amp;fm=webp 640w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=750&amp;fm=webp 750w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=828&amp;fm=webp 828w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=1080&amp;fm=webp 1080w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=1200&amp;fm=webp 1200w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=1920&amp;fm=webp 1920w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=2048&amp;fm=webp 2048w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=3840&amp;fm=webp 3840w"><img src="https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=3840" alt width="1200" height="630" sizes="100vw" loading="lazy" decoding="async" srcset="https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=640 640w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=750 750w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=828 828w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=1080 1080w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=1200 1200w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=1920 1920w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=2048 2048w, https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe719d255/04a3790c7ab94dff9379027920f60040/blog-template.png?w=3840 3840w"></picture></figure><div data-filename="aaa"><pre class="shiki vitesse-light" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span>import aaa from &apos;ccc&apos;;</span></span>\n<span class="line"><span></span></span>\n<span class="line"><span>aaa();</span></span></code></pre></div><pre class="shiki vitesse-light" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span>import aaa from &apos;ccc&apos;;</span></span>\n<span class="line"><span></span></span>\n<span class="line"><span>aaa();</span></span></code></pre><div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.25%;"><iframe src="https://www.youtube.com/embed/zknKqGwCiSs?rel=0" style="top: 0; left: 0; width: 100%; height: 100%; position: absolute; border: 0;" allowfullscreen scrolling="no" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share;"></iframe></div>',
);
expect(data).toEqual({
toc: [
Expand Down
6 changes: 6 additions & 0 deletions __tests__/transformer/responsive-image.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ describe("ResponsiveImageTransformer", () => {

expect(imgSrcset).toEqual(expectedImgSrcset);

const imgSrc = imgTags.attr("src");
const expectedImgSrc =
"https://images.microcms-assets.io/assets/88f12f69f3bd4e13b769561fe720d255/04a3790c7ab94dff9379025420f60040/blog-template.png?w=3840";

expect(imgSrc).toEqual(expectedImgSrc);

// sizes 属性が正しいかをチェック
const sizes = sourceTags.attr("sizes");
const expectedSizes = "(max-width: 640px) 100vw, 1200px";
Expand Down
80 changes: 80 additions & 0 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { defineConfig } from "vitepress";

// https://vitepress.dev/reference/site-config
export default defineConfig({
title: "microCMS RichEditor Handler",
titleTemplate: ":title | microCMS RichEditor Handler",
description:
"microCMSのリッチエディタコンテンツを変換したりデータを抽出します。",
cleanUrls: true,
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
nav: [
{ text: "Introduction", link: "/" },
{ text: "Examples", link: "/examples/responsive-image" },
],

sidebar: [
{
text: "Introduction",
items: [
{ text: "What is This?", link: "/" },
{ text: "Getting Started", link: "/introduction/getting-started" },
],
},
{
text: "Features",
items: [
{ text: "Handler", link: "/features/handler" },
{
text: "Transformer",
link: "/features/transformer",
items: [
{
text: "Responsive Image",
link: "/features/transformer/responsive-image",
},
{
text: "Syntax Highlighting by Shiki",
link: "/features/transformer/syntax-highlighting-by-shiki",
},
{
text: "Attributes",
link: "/features/transformer/attributes",
},
],
},
{
text: "Extractor",
link: "/features/extractor",
items: [
{
text: "TOCExtractor",
link: "/features/extractor/toc",
},
],
},
],
},
{
text: "Examples",
items: [
{ text: "Responsive Image", link: "/examples/responsive-image" },
{ text: "Lazy Loading", link: "/examples/lazy-loading" },
],
},
],

socialLinks: [
{
icon: "github",
link: "https://github.com/dc7290/microcms-rich-editor-handler",
},
{ icon: "x", link: "https://x.com/d_suke_09" },
],

search: {
provider: "local",
},
},
});
45 changes: 45 additions & 0 deletions docs/examples/lazy-loading.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Lazy Loading Example

`img`要素と`iframe`要素に`loading="lazy"`属性を追加する例です。
AttributesTransformerを使用して、`img`要素と`iframe`要素に`loading="lazy"`属性を追加します。

```ts
import { microCMSRichEditorHandler, attributesTransformer } from "microcms-rich-editor-handler";

const html = `
<img src="image.jpg" alt="Image">
<iframe src="https://www.youtube.com/embed/VIDEO_ID" title="YouTube video" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"></iframe>
`;

const main = async () => {
const { html: transformedHtml } = await microCMSRichEditorHandler(html, {
transformers: [
attributesTransformer({
elements: {
img: {
addAttributes: {
loading: "lazy",
},
},
iframe: {
addAttributes: {
loading: "lazy",
},
},
},
}),
],
});

console.log(transformedHtml);
};

main();
```

Output

```html
<img src="image.jpg" alt="Image" loading="lazy">
<iframe src="https://www.youtube.com/embed/VIDEO_ID" title="YouTube video" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" loading="lazy"></iframe>
```
52 changes: 52 additions & 0 deletions docs/examples/responsive-image.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Responsive Image Example

`<img>`要素を複数の拡張子とサイズに対応するレスポンシブ画像に変換する例です。
`responsiveImageTransformer`を使用して、`<img>`要素をレスポンシブ画像に変換します。

```ts
import { microCMSRichEditorHandler, responsiveImageTransformer } from "microcms-rich-editor-handler";

const html = `
<img src="https://images.microcms-assets.io/assets/image.png" width="1200" height="600" alt="">
`;

const main = async () => {
const { html: transformedHtml } = await microCMSRichEditorHandler(html, {
transformers: [
responsiveImageTransformer({
attributes: {
sizes: "(min-width: 768px) 920px, 95vw"
},
formats: ["webp", "avif"],
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
}),
],
});

console.log(transformedHtml);
};

main();
```

Output

```html
<picture>
<source
type="image/webp"
srcset="https://images.microcms-assets.io/assets/image.webp 640w, https://images.microcms-assets.io/assets/image.webp 750w, https://images.microcms-assets.io/assets/image.webp 828w, https://images.microcms-assets.io/assets/image.webp 1080w, https://images.microcms-assets.io/assets/image.webp 1200w, https://images.microcms-assets.io/assets/image.webp 1920w, https://images.microcms-assets.io/assets/image.webp 2048w, https://images.microcms-assets.io/assets/image.webp 3840w"
sizes="(min-width: 768px) 920px, 95vw"
width="1200"
height="600">
<img
src="https://images.microcms-assets.io/assets/image.png?w=3840"
srcset="https://images.microcms-assets.io/assets/image.png?w=640 640w, https://images.microcms-assets.io/assets/image.png?w=750 750w, https://images.microcms-assets.io/assets/image.png?w=828 828w, https://images.microcms-assets.io/assets/image.png?w=1080 1080w, https://images.microcms-assets.io/assets/image.png?w=1200 1200w, https://images.microcms-assets.io/assets/image.png?w=1920 1920w, https://images.microcms-assets.io/assets/image.png?w=2048 2048w, https://images.microcms-assets.io/assets/image.png?w=3840 3840w"
alt=""
loading="lazy"
decoding="async"
sizes="(min-width: 768px) 920px, 95vw"
width="1200"
height="600">
</picture>
```
75 changes: 75 additions & 0 deletions docs/features/extractor/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
prev:
text: Attributes Transformer
link: /features/transformer/attributes
next:
text: TOC Extractor
link: /features/extractor/toc
---

# Extractor

`Extractor` は、HTML文字列からデータを抽出する関数です。
見出し要素から目次を表示するためのデータを抽出したり、特定の要素からデータを抽出するために使用します。

## Type Definition

```ts
import type { CheerioAPI } from "cheerio";

export type Extractor<T> = ($: CheerioAPI) => Promise<T> | T;
```

## Creating Custom Extractor

このライブラリが提供しているExtractor以外にも、独自のExtractorを作成することができます。

以下の例では、リンク要素のPDFファイルのリンクを抽出するExtractorを作成しています。

```ts [extractor.ts]
import type { Extractor } from "microcms-rich-editor-handler";

export const pdfLinkExtractor: Extractor<string[]> = ($) => {
const pdfLinks: string[] = [];

$("a").each((_, element) => {
const href = $(element).attr("href");

if (href && href.endsWith(".pdf")) {
pdfLinks.push(href);
}
});

return pdfLinks;
};
```

このExtractorを使用するには、`microCMSRichEditorHandler`関数の`options.extractors`に追加します。

```ts [index.ts]
import { microCMSRichEditorHandler } from "microcms-rich-editor-handler";
import { pdfLinkExtractor } from "./extractor";

const html = `
<a href="document.pdf">Document</a>
<a href="image.jpg">Image</a>
`;

const main = async () => {
const { data } = await microCMSRichEditorHandler(html, {
extractors: {
pdfLinks: [pdfLinkExtractor],
},
});

console.log(data.pdfLinks);
};

main();
```

Output

```ts
["document.pdf"]
```
71 changes: 71 additions & 0 deletions docs/features/extractor/toc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# TOC Extractor

`TOC Extractor` は、HTML文字列から見出し要素を抽出して目次リストのデータを生成するExtractorです。

## Type Definition

```ts
import type { Extractor } from "./types";

const defaultTargetLevels = [1, 2, 3, 4, 5] as const;

type Options = {
/**
* 目次を生成する際に無視する見出しのレベル
*/
ignoreLevels?: (typeof defaultTargetLevels)[number][];
};

type TocItem = {
id: string;
text: string;
level: number;
};

// 目次リストを抽出する
const tocExtractor: (options?: Options | undefined) => Extractor<TocItem[]>
```
## Usage
```ts
import { microCMSRichEditorHandler, tocExtractor } from "microcms-rich-editor-handler";

const html = `
<h1 id="id1">Heading 1-1</h1>
<h2 id="id2">Heading 1-2</h2>
<h3 id="id3">Heading 1-3</h3>
<h1 id="id4">Heading 2-1</h1>
<h2 id="id5">Heading 2-2</h2>
<h3 id="id6">Heading 2-3</h3>
<h4 id="id7">Heading 2-4</h4>
<h5 id="id8">Heading 2-5</h5>
`;

const main = async () => {
const { data } = await microCMSRichEditorHandler(html, {
extractors: {
toc: [tocExtractor()],
},
});

console.log(data.toc);
};

main();
```

Output

```ts
[
{ id: "id1", text: "Heading 1-1", level: 1 },
{ id: "id2", text: "Heading 1-2", level: 2 },
{ id: "id3", text: "Heading 1-3", level: 3 },
{ id: "id4", text: "Heading 2-1", level: 1 },
{ id: "id5", text: "Heading 2-2", level: 2 },
{ id: "id6", text: "Heading 2-3", level: 3 },
{ id: "id7", text: "Heading 2-4", level: 4 },
{ id: "id8", text: "Heading 2-5", level: 5 },
]
```
Loading

0 comments on commit 0632aae

Please sign in to comment.