diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rehype/admonition-title-to-heading-before-toc.js | 49 | ||||
-rw-r--r-- | src/rehype/admonition-title-to-heading.js | 31 | ||||
-rw-r--r-- | src/remark/admonition-title-to-heading-before-toc.js | 60 | ||||
-rw-r--r-- | src/theme/Admonition.js | 6 | ||||
-rw-r--r-- | src/theme/Admonition/Layout/index.js | 99 | ||||
-rw-r--r-- | src/theme/Admonition/Type/Caution.js | 34 | ||||
-rw-r--r-- | src/theme/Admonition/Type/Danger.js | 32 | ||||
-rw-r--r-- | src/theme/Admonition/Type/Info.js | 32 | ||||
-rw-r--r-- | src/theme/Admonition/Type/Note.js | 32 | ||||
-rw-r--r-- | src/theme/Admonition/Type/Tip.js | 32 | ||||
-rw-r--r-- | src/theme/Admonition/Type/Warning.js | 32 | ||||
-rw-r--r-- | src/theme/Admonition/Types.js | 33 | ||||
-rw-r--r-- | src/theme/Admonition/index.js | 24 |
13 files changed, 496 insertions, 0 deletions
diff --git a/src/rehype/admonition-title-to-heading-before-toc.js b/src/rehype/admonition-title-to-heading-before-toc.js new file mode 100644 index 00000000..2770610d --- /dev/null +++ b/src/rehype/admonition-title-to-heading-before-toc.js @@ -0,0 +1,49 @@ +import {visit} from 'unist-util-visit'; +import {u} from 'unist-builder' + +function createHeadingNode(depth, text) { + return { + type: 'heading', + depth: depth, + children: [{ type: 'text', value: text }], + }; +} + +const plugin = (options) => { + const transformer = async (ast) => { + let hId = null; + let hContent = null; + let offset = 0; + visit(ast, 'element', (node, index, parent) => { + if(node && node.tagName == "admonition") { + let headingNode = u('heading', { depth: 4 }, [ + u('text', 'New Heading') + ]); + parent.children.splice(index + offset, 0, {type: 'element', tagName: 'h4', children:[{type: 'text', value: 'テスト'}]}); + offset++; + // if (/^h[3-6]$/.test(node.tagName) && node.properties && node.properties.id) { + // h3~h6のタグを見つけたら + /* + hId = node.properties.id; + hContent = node.children && node.children[0] ? node.children[0].value : ''; + // h3~h6タグの隣にあるdivタグを探す + const nextNode = parent.children[index + 1]; + if (nextNode && nextNode.tagName === 'admonition') { + // 該当のdiv要素を見つけたらHタグの内容とline-5の#以降の文字列が一致した場合 + const contentAfterHash = nextNode.properties.title ? nextNode.properties.title.replace(/^#+/, '').trim() : ''; + + if (contentAfterHash === hContent.trim()) { + // Hタグのidを取得しそれをdivのidに設定 + nextNode.properties.id = hId; + // Hタグを削除 + parent.children.splice(index, 1); + } + }*/ +// } + } + }); + }; + return transformer; +}; + +export default plugin;
\ No newline at end of file diff --git a/src/rehype/admonition-title-to-heading.js b/src/rehype/admonition-title-to-heading.js new file mode 100644 index 00000000..d84b27b2 --- /dev/null +++ b/src/rehype/admonition-title-to-heading.js @@ -0,0 +1,31 @@ +import {visit} from 'unist-util-visit'; + +const plugin = (options) => { + const transformer = async (ast) => { + let hId = null; + let hContent = null; + visit(ast, 'element', (node, index, parent) => { + if (/^h[2-6]$/.test(node.tagName) && node.properties && node.properties.id) { + // h2~h6のタグを見つけたら + hId = node.properties.id; + hContent = node.children && node.children[0] ? node.children[0].value : ''; + // h3~h6タグの隣にあるdivタグを探す + const nextNode = parent.children[index + 1]; + if (nextNode && nextNode.tagName === 'admonition') { + // 該当のdiv要素を見つけたらHタグの内容とline-5の#以降の文字列が一致した場合 + const contentAfterHash = nextNode.properties.title ? nextNode.properties.title.replace(/^#+/, '').trim() : ''; + + if (contentAfterHash === hContent.trim()) { + // Hタグのidを取得しそれをdivのidに設定 + nextNode.properties.id = hId; + // Hタグを削除 + parent.children.splice(index, 1); + } + } + } + }); + }; + return transformer; +}; + +export default plugin;
\ No newline at end of file diff --git a/src/remark/admonition-title-to-heading-before-toc.js b/src/remark/admonition-title-to-heading-before-toc.js new file mode 100644 index 00000000..34d2f9fa --- /dev/null +++ b/src/remark/admonition-title-to-heading-before-toc.js @@ -0,0 +1,60 @@ +import {visit, SKIP, EXIT, INDEX, CONTINUE} from 'unist-util-visit'; +import {inspect} from 'unist-util-inspect' + +const plugin = (options) => { + const transformer = async (ast) => { + let hId = null; + let hContent = null; + let offset = 0; + + // Visitor関数を定義 + const visitor = ((node, index, parent) => { + if (node.type === 'containerDirective') { + const val = node.children[0].children[0].value; + if(/^##/.test(val)) { + // headingノードをparentのchildrenに追加 + parent.children.splice(index, 0, { + type: 'heading', + depth: 4, // Headingの深さを適切に設定 + children: [{ type: 'text', value: val.replace(/^#+/, '').trim() }], + }); + //次に検索するのはindexを2つ飛ばしたノード。 + return index + 2; + } + } + }); + + visit(ast, 'containerDirective', visitor); + /* + visit(ast, 'containerDirective', (node, index, parent) => { + //console.log(node); + parent.children.splice(index, 0, {type: 'heading', depth: 4, children:[{type: 'text', value: 'テスト'}]}); + index++; + //offset++; + //console.log(offset); + //return EXIT; + // if (/^h[3-6]$/.test(node.tagName) && node.properties && node.properties.id) { + // h3~h6のタグを見つけたら + /* + hId = node.properties.id; + hContent = node.children && node.children[0] ? node.children[0].value : ''; + // h3~h6タグの隣にあるdivタグを探す + const nextNode = parent.children[index + 1]; + if (nextNode && nextNode.tagName === 'admonition') { + // 該当のdiv要素を見つけたらHタグの内容とline-5の#以降の文字列が一致した場合 + const contentAfterHash = nextNode.properties.title ? nextNode.properties.title.replace(/^#+/, '').trim() : ''; + + if (contentAfterHash === hContent.trim()) { + // Hタグのidを取得しそれをdivのidに設定 + nextNode.properties.id = hId; + // Hタグを削除 + parent.children.splice(index, 1); + } + }*/ +// } +// }); + }; + return transformer; +}; + +export default plugin;
\ No newline at end of file diff --git a/src/theme/Admonition.js b/src/theme/Admonition.js new file mode 100644 index 00000000..cd35ae9d --- /dev/null +++ b/src/theme/Admonition.js @@ -0,0 +1,6 @@ +import React from 'react'; +import Admonition from './Admonition'; + +export default function AdmonitionWrapper(props) { + return <Admonition {...props} />; +} diff --git a/src/theme/Admonition/Layout/index.js b/src/theme/Admonition/Layout/index.js new file mode 100644 index 00000000..7bc2802b --- /dev/null +++ b/src/theme/Admonition/Layout/index.js @@ -0,0 +1,99 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import React from 'react'; +import clsx from 'clsx'; +import { ThemeClassNames } from '@docusaurus/theme-common'; +import admonitionStyles from '@docusaurus/theme-classic/lib/theme/Admonition/Layout/styles.module.css'; +import headingStyles from '@docusaurus/theme-classic/lib/theme/Heading/styles.module.css'; + +function AdmonitionContainer({type, className, children}) { + return ( + <div + className={clsx( + ThemeClassNames.common.admonition, + ThemeClassNames.common.admonitionType(type), + admonitionStyles.admonition, + className, + )} + > + {children} + </div> + ); +} +function AdmonitionHeading({icon, id, title}) { + // 文字列冒頭の#の数を数える + const depth = title.match ? (title.match(/^#+/) || [''])[0].length : 0; + // #を省いたタイトルを得る + const trimmedTitle = depth > 0 ? title.replace(/^#+/, '').trim() : title; + // スクロール位置調整のcss + const classNames = clsx("anchor", "title", headingStyles.anchorWithStickyNavbar); + // depthに応じて見出しタグをレンダー + return ( + <div className={admonitionStyles.admonitionHeading}> + <span className={admonitionStyles.admonitionIcon}>{icon}</span> + {(() => { + if (depth == 3) { + return( + <h3 + id={id} + className={classNames} + > + {trimmedTitle} + </h3> + ) + } else if (depth == 4) { + return( + <h4 + id={id} + className={classNames} + > + {trimmedTitle} + </h4> + ) + } else if (depth == 5) { + return( + <h5 + id={id} + className={classNames} + > + {trimmedTitle} + </h5> + ) + } else if (depth == 6) { + return( + <h6 + id={id} + className={classNames} + > + {trimmedTitle} + </h6> + ) + } else { + return( + <> + {trimmedTitle} + </> + ) + } + })()} + </div> + ); +} +function AdmonitionContent({children}) { + return children ? ( + <div className={admonitionStyles.admonitionContent}>{children}</div> + ) : null; +} +export default function AdmonitionLayout(props) { + const {type, icon, title, children, className, id} = props; + return ( + <AdmonitionContainer type={type} className={className}> + <AdmonitionHeading title={title} icon={icon} id={id} /> + <AdmonitionContent>{children}</AdmonitionContent> + </AdmonitionContainer> + ); +} diff --git a/src/theme/Admonition/Type/Caution.js b/src/theme/Admonition/Type/Caution.js new file mode 100644 index 00000000..a7bc5440 --- /dev/null +++ b/src/theme/Admonition/Type/Caution.js @@ -0,0 +1,34 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import React from 'react'; +import clsx from 'clsx'; +import Translate from '@docusaurus/Translate'; +import AdmonitionLayout from '../Layout'; +import IconWarning from '@docusaurus/theme-classic/lib/theme/Admonition/Icon/Warning'; +const infimaClassName = 'alert alert--warning'; +const defaultProps = { + icon: <IconWarning />, + title: ( + <Translate + id="theme.admonition.caution" + description="The default label used for the Caution admonition (:::caution)"> + caution + </Translate> + ), +}; +// TODO remove before v4: Caution replaced by Warning +// see https://github.com/facebook/docusaurus/issues/7558 +export default function AdmonitionTypeCaution(props) { + return ( + <AdmonitionLayout + {...defaultProps} + {...props} + className={clsx(infimaClassName, props.className)}> + {props.children} + </AdmonitionLayout> + ); +} diff --git a/src/theme/Admonition/Type/Danger.js b/src/theme/Admonition/Type/Danger.js new file mode 100644 index 00000000..39e37f69 --- /dev/null +++ b/src/theme/Admonition/Type/Danger.js @@ -0,0 +1,32 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import React from 'react'; +import clsx from 'clsx'; +import Translate from '@docusaurus/Translate'; +import AdmonitionLayout from '../Layout'; +import IconDanger from '@docusaurus/theme-classic/lib/theme/Admonition/Icon/Danger'; +const infimaClassName = 'alert alert--danger'; +const defaultProps = { + icon: <IconDanger />, + title: ( + <Translate + id="theme.admonition.danger" + description="The default label used for the Danger admonition (:::danger)"> + danger + </Translate> + ), +}; +export default function AdmonitionTypeDanger(props) { + return ( + <AdmonitionLayout + {...defaultProps} + {...props} + className={clsx(infimaClassName, props.className)}> + {props.children} + </AdmonitionLayout> + ); +} diff --git a/src/theme/Admonition/Type/Info.js b/src/theme/Admonition/Type/Info.js new file mode 100644 index 00000000..44409a44 --- /dev/null +++ b/src/theme/Admonition/Type/Info.js @@ -0,0 +1,32 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import React from 'react'; +import clsx from 'clsx'; +import Translate from '@docusaurus/Translate'; +import AdmonitionLayout from '../Layout'; +import IconInfo from '@docusaurus/theme-classic/lib/theme/Admonition/Icon/Info'; +const infimaClassName = 'alert alert--info'; +const defaultProps = { + icon: <IconInfo />, + title: ( + <Translate + id="theme.admonition.info" + description="The default label used for the Info admonition (:::info)"> + info + </Translate> + ), +}; +export default function AdmonitionTypeInfo(props) { + return ( + <AdmonitionLayout + {...defaultProps} + {...props} + className={clsx(infimaClassName, props.className)}> + {props.children} + </AdmonitionLayout> + ); +} diff --git a/src/theme/Admonition/Type/Note.js b/src/theme/Admonition/Type/Note.js new file mode 100644 index 00000000..01226d2f --- /dev/null +++ b/src/theme/Admonition/Type/Note.js @@ -0,0 +1,32 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import React from 'react'; +import clsx from 'clsx'; +import Translate from '@docusaurus/Translate'; +import AdmonitionLayout from '../Layout'; +import IconNote from '@docusaurus/theme-classic/lib/theme/Admonition/Icon/Note'; +const infimaClassName = 'alert alert--secondary'; +const defaultProps = { + icon: <IconNote />, + title: ( + <Translate + id="theme.admonition.note" + description="The default label used for the Note admonition (:::note)"> + note + </Translate> + ), +}; +export default function AdmonitionTypeNote(props) { + return ( + <AdmonitionLayout + {...defaultProps} + {...props} + className={clsx(infimaClassName, props.className)}> + {props.children} + </AdmonitionLayout> + ); +} diff --git a/src/theme/Admonition/Type/Tip.js b/src/theme/Admonition/Type/Tip.js new file mode 100644 index 00000000..bbe7de19 --- /dev/null +++ b/src/theme/Admonition/Type/Tip.js @@ -0,0 +1,32 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import React from 'react'; +import clsx from 'clsx'; +import Translate from '@docusaurus/Translate'; +import AdmonitionLayout from '../Layout'; +import IconTip from '@docusaurus/theme-classic/lib/theme/Admonition/Icon/Tip'; +const infimaClassName = 'alert alert--success'; +const defaultProps = { + icon: <IconTip />, + title: ( + <Translate + id="theme.admonition.tip" + description="The default label used for the Tip admonition (:::tip)"> + tip + </Translate> + ), +}; +export default function AdmonitionTypeTip(props) { + return ( + <AdmonitionLayout + {...defaultProps} + {...props} + className={clsx(infimaClassName, props.className)}> + {props.children} + </AdmonitionLayout> + ); +} diff --git a/src/theme/Admonition/Type/Warning.js b/src/theme/Admonition/Type/Warning.js new file mode 100644 index 00000000..ac28ae39 --- /dev/null +++ b/src/theme/Admonition/Type/Warning.js @@ -0,0 +1,32 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import React from 'react'; +import clsx from 'clsx'; +import Translate from '@docusaurus/Translate'; +import AdmonitionLayout from '../Layout'; +import IconWarning from '@docusaurus/theme-classic/lib/theme/Admonition/Icon/Warning'; +const infimaClassName = 'alert alert--warning'; +const defaultProps = { + icon: <IconWarning />, + title: ( + <Translate + id="theme.admonition.warning" + description="The default label used for the Warning admonition (:::warning)"> + warning + </Translate> + ), +}; +export default function AdmonitionTypeWarning(props) { + return ( + <AdmonitionLayout + {...defaultProps} + {...props} + className={clsx(infimaClassName, props.className)}> + {props.children} + </AdmonitionLayout> + ); +} diff --git a/src/theme/Admonition/Types.js b/src/theme/Admonition/Types.js new file mode 100644 index 00000000..d5f1f089 --- /dev/null +++ b/src/theme/Admonition/Types.js @@ -0,0 +1,33 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import React from 'react'; +import AdmonitionTypeNote from './Type/Note'; +import AdmonitionTypeTip from './Type/Tip'; +import AdmonitionTypeInfo from './Type/Info'; +import AdmonitionTypeWarning from './Type/Warning'; +import AdmonitionTypeDanger from './Type/Danger'; +import AdmonitionTypeCaution from './Type/Caution'; +const admonitionTypes = { + note: AdmonitionTypeNote, + tip: AdmonitionTypeTip, + info: AdmonitionTypeInfo, + warning: AdmonitionTypeWarning, + danger: AdmonitionTypeDanger, +}; +// Undocumented legacy admonition type aliases +// Provide hardcoded/untranslated retrocompatible label +// See also https://github.com/facebook/docusaurus/issues/7767 +const admonitionAliases = { + secondary: (props) => <AdmonitionTypeNote title="secondary" {...props} />, + important: (props) => <AdmonitionTypeInfo title="important" {...props} />, + success: (props) => <AdmonitionTypeTip title="success" {...props} />, + caution: AdmonitionTypeCaution, +}; +export default { + ...admonitionTypes, + ...admonitionAliases, +}; diff --git a/src/theme/Admonition/index.js b/src/theme/Admonition/index.js new file mode 100644 index 00000000..c66baaea --- /dev/null +++ b/src/theme/Admonition/index.js @@ -0,0 +1,24 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import React from 'react'; +import {processAdmonitionProps} from '@docusaurus/theme-common'; +import AdmonitionTypes from './Types'; +function getAdmonitionTypeComponent(type) { + const component = AdmonitionTypes[type]; + if (component) { + return component; + } + console.warn( + `No admonition component found for admonition type "${type}". Using Info as fallback.`, + ); + return AdmonitionTypes.info; +} +export default function Admonition(unprocessedProps) { + const props = processAdmonitionProps(unprocessedProps); + const AdmonitionTypeComponent = getAdmonitionTypeComponent(props.type); + return <AdmonitionTypeComponent {...props} />; +} |