diff --git a/src/plugins/rehype-unwrap-details-table.ts b/src/plugins/rehype-unwrap-details-table.ts index 544982c..ac6069f 100644 --- a/src/plugins/rehype-unwrap-details-table.ts +++ b/src/plugins/rehype-unwrap-details-table.ts @@ -2,6 +2,9 @@ import type {Element, ElementContent, Root, RootContent} from 'hast'; type Node = Root | RootContent | ElementContent; +const SHORT_ANSWER_TITLE = 'Короткий ответ'; +const FULL_ANSWER_TITLE = 'Полный ответ'; + const isElement = (node: Node): node is Element => node.type === 'element'; const isTag = (node: Node, tagName: string): node is Element => @@ -45,6 +48,51 @@ const getTextContent = (node: Node): string => { return node.children.map((child) => getTextContent(child)).join(''); }; +const isAnswerTitle = (node: ElementContent, title: string): node is Element => + isTag(node, 'p') && getTextContent(node).trim() === title; + +const createAnswerSection = (className: string, children: ElementContent[]): Element => ({ + type: 'element', + tagName: 'div', + properties: { + className: [className], + }, + children, +}); + +const splitAnswerSections = (children: ElementContent[]): ElementContent[] => { + const shortAnswerIndex = children.findIndex((child) => + isAnswerTitle(child, SHORT_ANSWER_TITLE), + ); + const fullAnswerIndex = children.findIndex( + (child, index) => + index > shortAnswerIndex && isAnswerTitle(child, FULL_ANSWER_TITLE), + ); + + if (shortAnswerIndex === -1 || fullAnswerIndex === -1) { + return children; + } + + const shortAnswerTitle = children[shortAnswerIndex]; + const fullAnswerTitle = children[fullAnswerIndex]; + + if (!isElement(shortAnswerTitle) || !isElement(fullAnswerTitle)) { + return children; + } + + shortAnswerTitle.properties.className = ['answer-title']; + fullAnswerTitle.properties.className = ['answer-title']; + + return [ + ...children.slice(0, shortAnswerIndex), + createAnswerSection( + 'answer-short', + children.slice(shortAnswerIndex, fullAnswerIndex), + ), + createAnswerSection('answer-full', children.slice(fullAnswerIndex)), + ]; +}; + const createSlug = (value: string): string => value .toLocaleLowerCase('ru') @@ -132,7 +180,7 @@ const unwrapDetailsTable = (details: Element): void => { properties: { className: ['answer'], }, - children: cellChildren, + children: splitAnswerSections(cellChildren), }); continue; diff --git a/src/styles/markdown-details.css b/src/styles/markdown-details.css index 9ca6bb2..a7772fa 100644 --- a/src/styles/markdown-details.css +++ b/src/styles/markdown-details.css @@ -59,6 +59,44 @@ font-weight: 800; } +.content details .answer-short { + margin-bottom: 28px; + padding: 16px 18px; + border: 1px solid var(--border); + border-inline-start: 4px solid var(--accent); + border-radius: 10px; + background: var(--accent-soft); +} + +.content details .answer-short > :last-child, +.content details .answer-full > :last-child { + margin-bottom: 0; +} + +.content details .answer .answer-title { + color: var(--text); + font-size: 1.05rem; + line-height: 1.4; +} + +.content details .answer-short .answer-title { + margin-bottom: 8px; + color: var(--accent-strong); +} + +.content details .answer-short .answer-title strong { + color: inherit; +} + +.content details .answer-full { + padding-top: 20px; + border-top: 1px solid var(--border); +} + +.content details .answer-full .answer-title { + margin-bottom: 12px; +} + .content details .answer ul, .content details .answer ol { margin: 12px 0 20px;