import React from "react";
import * as std from "../../law/std";
import { assertNever } from "../../util";
import type { HTMLComponentProps } from "../common/html";
import { elProps, wrapHTMLComponent } from "../common/html";
import { DOCXSentenceChildrenRun, HTMLSentenceChildrenRun } from "./sentenceChildrenRun";
import type { DOCXComponentProps } from "../common/docx/component";
import { wrapDOCXComponent } from "../common/docx/component";
import { w } from "../common/docx/tags";
import { DOCXParagraphItem, HTMLParagraphItem } from "./paragraphItem";
import { DOCXColumnsOrSentencesRun, HTMLColumnsOrSentencesRun } from "./columnsOrSentencesRun";
import { DOCXArticleGroup, HTMLArticleGroup } from "./articleGroup";
import { DOCXArticle, HTMLArticle } from "./article";
import { newStdEL } from "../../law/std";
import { DOCXRemarks, HTMLRemarks } from "./remarks";
import { DOCXItemStruct, HTMLItemStruct } from "./itemStruct";
import { withKey } from "../common";
export interface TableProps {
el: std.Table,
indent: number,
}
export const HTMLTableCSS = /*css*/`
.table {
border-collapse: collapse;
text-indent: 0;
table-layout: fixed;
width: calc(100% - var(--margin-left));
}
.table-column {
border: 1px solid black;
min-height: 1em;
height: 1em;
}
.table-header-column {
border: 1px solid black;
min-height: 1em;
height: 1em;
}
`;
export const HTMLTable = wrapHTMLComponent("HTMLTable", ((props: HTMLComponentProps & TableProps) => {
const { el, htmlOptions, indent } = props;
const rows: React.JSX.Element[] = [];
for (const child of el.children) {
if (
std.isTableRow(child)
|| std.isTableHeaderRow(child)
) {
rows.push();
}
else { assertNever(child); }
}
return (
);
}));
export interface TableRowProps {
el: std.TableRow | std.TableHeaderRow,
}
export const HTMLTableRow = wrapHTMLComponent("HTMLTableRow", ((props: HTMLComponentProps & TableRowProps) => {
const { el, htmlOptions } = props;
const columns: React.JSX.Element[] = [];
for (const child of el.children) {
if (
std.isTableColumn(child)
|| std.isTableHeaderColumn(child)
) {
columns.push();
}
else { assertNever(child); }
}
return (
{withKey(columns)}
);
}));
export interface TableColumnProps {
el: std.TableColumn | std.TableHeaderColumn,
}
export const HTMLTableColumn = wrapHTMLComponent("HTMLTableColumn", ((props: HTMLComponentProps & TableColumnProps) => {
const { el, htmlOptions } = props;
const blocks: React.JSX.Element[] = [];
if (std.isTableHeaderColumn(el)) {
blocks.push((
));
} else if (std.isTableColumn(el)) {
if (el.children.every(std.isColumn)) {
blocks.push((
));
} else if (el.children.every(std.isSentence)) {
for (const child of el.children) {
blocks.push((
));
}
} else {
for (const child of el.children) {
if (child.tag === "Sentence" || child.tag === "Column") {
blocks.push((
));
} else if (std.isFigStruct(child)) {
blocks.push();
} else if (std.isRemarks(child)) {
blocks.push();
} else if (std.isArticleGroup(child)) {
blocks.push((
));
} else if (std.isArticle(child)) {
blocks.push((
));
} else if (std.isParagraphItem(child)) {
blocks.push((
));
}
else { assertNever(child); }
}
}
}
else { assertNever(el); }
const style: React.CSSProperties = {};
if (el.attr.BorderTop) style.borderTopStyle = el.attr.BorderTop;
if (el.attr.BorderBottom) style.borderBottomStyle = el.attr.BorderBottom;
if (el.attr.BorderLeft) style.borderLeftStyle = el.attr.BorderLeft;
if (el.attr.BorderRight) style.borderRightStyle = el.attr.BorderRight;
if (el.attr.Align) style.textAlign = el.attr.Align;
if (el.attr.Valign) style.verticalAlign = el.attr.Valign;
const attr = {
style,
...((el.attr.rowspan !== undefined) ? { rowSpan: Number(el.attr.rowspan) } : {}),
...((el.attr.colspan !== undefined) ? { colSpan: Number(el.attr.colspan) } : {}),
};
if (std.isTableHeaderColumn(el)) {
return (
{withKey(blocks)}
|
);
} else {
return (
{withKey(blocks)}
|
);
}
}));
const restructureTable = (table: std.Table): std.Table => {
const newTableChildren: std.Table["children"] = [];
const rowspanState: Record = {};
const colspanValue: Record = {};
for (const row of table.children) {
const newRowChildren: (typeof row)["children"][number][] = [];
let c = 0;
let ci = 0;
while (true) {
const rss = rowspanState[c] || 0;
if (rss) {
const colspan = colspanValue[c] || 0;
newRowChildren.push(std.newStdEL(
std.isTableHeaderRow(row) ? "TableHeaderColumn" : "TableColumn",
{
__merged: "__merged",
...(
colspan ? {
colspan: `${colspan}`,
} : {}
),
},
[],
));
rowspanState[c] = rss - 1;
if (colspan) {
c += colspan - 1;
}
c += 1;
continue;
}
if (ci >= row.children.length) {
break;
}
const column = row.children[ci];
newRowChildren.push(column.copy(true) as typeof column);
{
const colspan = Number(column.attr.colspan || 0);
if (column.attr.rowspan !== undefined) {
const rowspan = Number(column.attr.rowspan);
rowspanState[c] = rowspan - 1;
colspanValue[c] = colspan;
if (colspan) {
c += colspan - 1;
}
}
c += 1;
ci += 1;
}
}
newTableChildren.push(newStdEL(
row.tag,
{ ...row.attr },
newRowChildren,
));
}
const ret = newStdEL(
table.tag,
{ ...table.attr },
newTableChildren,
);
return ret;
};
export const DOCXTable = wrapDOCXComponent("DOCXTable", ((props: DOCXComponentProps & TableProps) => {
const { el: origEL, docxOptions, indent } = props;
const rows: React.JSX.Element[] = [];
const el = restructureTable(origEL);
for (const child of el.children) {
if (
std.isTableRow(child)
|| std.isTableHeaderRow(child)
) {
rows.push();
}
else { assertNever(child); }
}
return (
{withKey(rows)}
);
}));
export interface TableRowProps {
el: std.TableRow | std.TableHeaderRow,
}
export const DOCXTableRow = wrapDOCXComponent("DOCXTableRow", ((props: DOCXComponentProps & TableRowProps) => {
const { el, docxOptions } = props;
const columns: React.JSX.Element[] = [];
for (const child of el.children) {
if (
std.isTableColumn(child)
|| std.isTableHeaderColumn(child)
) {
columns.push();
}
else { assertNever(child); }
}
return (
{withKey(columns)}
);
}));
export interface TableColumnProps {
el: std.TableColumn | std.TableHeaderColumn,
}
const valignDict = {
top: "top",
middle: "center",
bottom: "bottom",
};
const borderDict = {
none: "nil",
solid: "single",
dotted: "dotted",
double: "double",
};
export const DOCXTableColumn = wrapDOCXComponent("DOCXTableColumn", ((props: DOCXComponentProps & TableColumnProps) => {
const { el, docxOptions } = props;
const blocks: React.JSX.Element[] = [];
if (std.isTableHeaderColumn(el)) {
blocks.push((
));
} else if (std.isTableColumn(el)) {
if (el.children.every(std.isColumn)) {
blocks.push((
));
} else if (el.children.every(std.isSentence)) {
for (const child of el.children) {
blocks.push((
));
}
} else {
for (const child of el.children) {
if (child.tag === "Sentence" || child.tag === "Column") {
blocks.push((
));
} else if (std.isFigStruct(child)) {
blocks.push();
} else if (std.isRemarks(child)) {
blocks.push();
} else if (std.isArticleGroup(child)) {
blocks.push((
));
} else if (std.isArticle(child)) {
blocks.push((
));
} else if (std.isParagraphItem(child)) {
blocks.push((
));
}
else { assertNever(child); }
}
}
}
else { assertNever(el); }
if ((el.attr as Record).__merged !== undefined) {
return (
{(el.attr.colspan !== undefined) && }
);
} else {
return (
{(el.attr.colspan !== undefined) && }
{(el.attr.rowspan !== undefined) && }
{(el.attr.Align !== undefined) && }
{(el.attr.Valign !== undefined) && }
{((el.attr.BorderTop ?? el.attr.BorderBottom ?? el.attr.BorderLeft ?? el.attr.BorderRight) !== undefined) && (
{(el.attr.BorderTop !== undefined) && }
{(el.attr.BorderBottom !== undefined) && }
{(el.attr.BorderLeft !== undefined) && }
{(el.attr.BorderRight !== undefined) && }
)}
{withKey(blocks)}
);
}
}));