import React from "react"; import * as std from "../../law/std"; import { assertNever, NotImplementedError } from "../../util"; import type { HTMLComponentProps } from "../common/html"; import { elProps, HTMLMarginSpan, wrapHTMLComponent } from "../common/html"; import { DOCXSentenceChildrenRun, HTMLSentenceChildrenRun } from "./sentenceChildrenRun"; import { DOCXColumnsOrSentencesRun, HTMLColumnsOrSentencesRun } from "./columnsOrSentencesRun"; import type { DOCXComponentProps } from "../common/docx/component"; import { DOCXMargin, wrapDOCXComponent } from "../common/docx/component"; import { w } from "../common/docx/tags"; import { DOCXItemStruct, HTMLItemStruct } from "./itemStruct"; import { DOCXList, HTMLList } from "./list"; import { DOCXAmendProvision, HTMLAmendProvision } from "./amendProvision"; import { withKey } from "../common"; export interface ParagraphItemProps { el: std.ParagraphItem, indent: number, ArticleTitle?: std.ArticleTitle, decorations?: React.ComponentType[], } export const HTMLParagraphItemCSS = /*css*/` .paragraph-item-any { position: relative; } .paragraph-item-any > div:not(.paragraph-item-decoration-block) { position: relative; } .paragraph-item-decoration-block { position: absolute; width: calc(100% - var(--paragraph-item-indent, 0)); left: var(--paragraph-item-indent, 0); height: 100%; } .paragraph-item-decoration-left-border { margin: 0 0 0 -1em; border-left: 0.1em solid transparent; width: 100%; height: 100%; transition: border-left-color 0.3s; } .paragraph-item-any:hover > * > .paragraph-item-decoration-left-border { border-left-color: rgba(255, 166, 0, 0.5); } ${ std.paragraphItemTags .filter(tag => tag !== "Paragraph") .map(tag => ".paragraph-item-" + tag).join(", ") } { clear: both; } .article-title { font-weight: bold; } .paragraph-item-title { font-weight: bold; } .paragraph-item-main { position: relative; padding-left: 1em; text-indent: -1em; } `; const HTMLParagraphItemLeftBorder: React.FC = () => { return
; }; export const HTMLParagraphItem = wrapHTMLComponent("HTMLParagraphItem", ((props: HTMLComponentProps & ParagraphItemProps) => { const { el, htmlOptions, indent, ArticleTitle } = props; const blocks: React.JSX.Element[] = []; const ParagraphCaption = (el.children as (typeof el.children)[number][]).find(el => std.isParagraphCaption(el) || std.isArticleCaption(el)) as std.ParagraphCaption | undefined; if (ParagraphCaption && std.isArticleCaption(ParagraphCaption)) { console.error(`unexpected element! ${JSON.stringify(ParagraphCaption, undefined, 2)}`); } const ParagraphItemTitle = (el.children as (typeof el.children)[number][]).find(std.isParagraphItemTitle); const ParagraphItemSentence = (el.children as (typeof el.children)[number][]).find(std.isParagraphItemSentence); const OldParatraphNum = ( (std.isParagraph(el) && el.attr.OldNum === "true") ? String.fromCharCode("①".charCodeAt(0) - 1 + Number(el.attr.Num)) : undefined ); if (ParagraphCaption) { blocks.push((
)); } if (ParagraphItemTitle || ParagraphItemSentence) { blocks.push((
{Boolean(ParagraphItemTitle || ArticleTitle || OldParatraphNum) && (( <> {ArticleTitle && ( )} {ParagraphItemTitle && ((!ArticleTitle && !OldParatraphNum) || (ParagraphItemTitle.text().length > 0)) && (<> {ArticleTitle && ( )} )} {OldParatraphNum && (<> {ArticleTitle && ( )} )} {Boolean(ParagraphItemSentence) && ( )} ))}
)); } for (const child of el.children) { if ( std.isArticleCaption(child) || std.isParagraphCaption(child) || std.isParagraphItemTitle(child) || std.isParagraphItemSentence(child) ) { continue; } else if (std.isParagraphItem(child)) { blocks.push(); /* >>>> INDENT >>>> */ } else if (std.isTableStruct(child) || std.isFigStruct(child) || std.isStyleStruct(child)) { blocks.push(); /* >>>> INDENT >>>> */ } else if (std.isList(child)) { blocks.push(); /* >>>> INDENT ++++ INDENT >>>> */ } else if (std.isAmendProvision(child)) { blocks.push(); /* >>>> INDENT >>>> */ } else if (std.isClass(child)) { throw new NotImplementedError(child.tag); } else { throw assertNever(child); } } const decorations = [HTMLParagraphItemLeftBorder, ...(props.decorations ?? [])]; return (
{(decorations.length > 0) && <> {decorations.map((D, i) => (
))} } {withKey(blocks)}
); })); export const DOCXParagraphItem = wrapDOCXComponent("DOCXParagraphItem", ((props: DOCXComponentProps & ParagraphItemProps) => { const { el, docxOptions, indent, ArticleTitle } = props; const blocks: React.JSX.Element[] = []; const ParagraphCaption = (el.children as (typeof el.children)[number][]).find(el => std.isParagraphCaption(el) || std.isArticleCaption(el)) as std.ParagraphCaption | undefined; if (ParagraphCaption && std.isArticleCaption(ParagraphCaption)) { console.error(`unexpected element! ${JSON.stringify(ParagraphCaption, undefined, 2)}`); } const ParagraphItemTitle = (el.children as (typeof el.children)[number][]).find(std.isParagraphItemTitle); const ParagraphItemSentence = (el.children as (typeof el.children)[number][]).find(std.isParagraphItemSentence); const OldParatraphNum = ( (std.isParagraph(el) && el.attr.OldNum === "true") ? String.fromCharCode("①".charCodeAt(0) - 1 + Number(el.attr.Num)) : undefined ); if (ParagraphCaption) { blocks.push(( )); } if (ParagraphItemTitle || ParagraphItemSentence) { blocks.push(( {(ArticleTitle || ParagraphItemTitle) ? ( ) : ( )} {ArticleTitle && ( )} {ParagraphItemTitle && ((!ArticleTitle && !OldParatraphNum) || (ParagraphItemTitle.text().length > 0)) && (<> {ArticleTitle && ( {DOCXMargin} )} )} {OldParatraphNum && (<> {ArticleTitle && ( {DOCXMargin} )} )} {Boolean((ParagraphItemTitle || ArticleTitle) && ParagraphItemSentence) && ( {DOCXMargin} )} )); } for (const child of el.children) { if ( std.isArticleCaption(child) || std.isParagraphCaption(child) || std.isParagraphItemTitle(child) || std.isParagraphItemSentence(child) ) { continue; } else if (std.isParagraphItem(child)) { blocks.push(); /* >>>> INDENT >>>> */ } else if (std.isTableStruct(child) || std.isFigStruct(child) || std.isStyleStruct(child)) { blocks.push(); /* >>>> INDENT >>>> */ } else if (std.isList(child)) { blocks.push(); /* >>>> INDENT ++++ INDENT >>>> */ } else if (std.isAmendProvision(child)) { blocks.push(); /* >>>> INDENT >>>> */ } else if (std.isClass(child)) { throw new NotImplementedError(child.tag); } else { throw assertNever(child); } } return (<> {withKey(blocks)} ); }));