fix(est): preserve links and formula precision
This commit is contained in:
@@ -17,15 +17,16 @@ const EstText = (() => {
|
||||
function expression(text) {
|
||||
return clean(
|
||||
String(text).replace(
|
||||
/\x0e[^\x0e]*\x0e|\x13[^\x13]*\x13|\x15[^\x15]*\x15|\{[^}]*\}|\([가-힣][^()]*\)|\(\s*\d+(?:\.\d+)?\s*[˚°]\s*\)|<[^>]*>/g,
|
||||
/\x0e[^\x0e]*\x0e|\x13[^\x13]*\x13|\x15[^\x15]*\x15|\{[^}]*\}|〔[^〕]*〕|[[^]]*]|\([가-힣][^()]*\)|\(\s*\d+(?:\.\d+)?\s*[˚°]\s*\)|<[^>]*>/g,
|
||||
"",
|
||||
),
|
||||
)
|
||||
.replace(
|
||||
/(\d)\s*(?:공\/?㎥|공|단|면|겹|경간|개월|월|년|인|㎥|㎢|㎡|hr|sec|min|kwh|kw|km|ton|kg|㎏|㎞|ℓ|회|개소|개|대|분|초|본|장|매|병|조|식|일|시간|원|포|동|주|톤|μ|₩|EA|mm|cm|m3|m2|m|g|L|a)(?:\/(?:개소|경간|개|대|본|인|분|포|매|주|톤|\$|hr|일|㎥|㎡|m|a|EA))?/gi,
|
||||
/(?<![A-Za-z0-9_가-힣.])(\d[\d,.]*|\.\d+)\s*(?:공\/?㎥|공|단|면|겹|경간|개월|월|년|인|㎥|㎢|㎠|㎡|hr|sec|min|kwh|kw|km|ton|kg|㎏|㎞|ℓ|회|개소|개|대|분|초|본|장|매|병|조|식|일|시간|원|포|동|주|톤|μ|₩|EA|mm|cm|m3|m2|m|g|L|a)(?:\/(?:개소|경간|개|대|본|인|분|포|매|주|톤|공|회|조|span|ton|\$|hr|일|㎥|㎡|m3|m2|m|a|EA))?/gi,
|
||||
"$1",
|
||||
)
|
||||
.replace(/(?<=\d)\s*\/(?:일|㎥|㎡)(?=\s|$)/g, "")
|
||||
.replace(/(?<=\d)\s*\/\s*(?:일|㎥|㎡|hr)(?=\s|$|[×*+)])/gi, "")
|
||||
.replace(/[】]〕]\s*$/, "")
|
||||
.replace(/(?<=\))\s*(?:개|인|본|면|단|회)(?:\/(?:㎡|㎥|hr))?/g, "")
|
||||
.replace(/^\s*[-*•]?\s*[가-힣][가-힣\s]*\s+(?=[\d.(])/, "")
|
||||
.replace(/[①-⑳]/g, "")
|
||||
@@ -99,7 +100,7 @@ const EstText = (() => {
|
||||
errors.push(`${head.Code}:${index + 1} ${error.message}`);
|
||||
}
|
||||
}
|
||||
let text = original;
|
||||
let text = original.replace(/\{([+-])\}/g, "$1");
|
||||
if (currentSource && sc < 0 && component[sc])
|
||||
text = text.replace(
|
||||
/\x03([-\d.,]+)\x03/g,
|
||||
@@ -134,14 +135,14 @@ const EstText = (() => {
|
||||
const assignedNames = new Map();
|
||||
let componentDeclaration;
|
||||
try {
|
||||
if (matched && /─/.test(text)) {
|
||||
if ((matched || /^\s*[A-Za-z][A-Za-z0-9]*\s*=/.test(text)) && /─/.test(text)) {
|
||||
const above = clean(rows[index - 1]?.LineData),
|
||||
below = clean(rows[index + 1]?.LineData);
|
||||
const columns = (value) =>
|
||||
value
|
||||
.replace(/\s*([×÷+*/−-])\s*/g, "$1")
|
||||
.replace(/\s*([×÷·+*/−-])\s*/g, "$1")
|
||||
.trim()
|
||||
.split(/\s{2,}/);
|
||||
.split(/\s+/);
|
||||
const tops = columns(above),
|
||||
bottoms = columns(below);
|
||||
let part = 0;
|
||||
@@ -187,7 +188,7 @@ const EstText = (() => {
|
||||
let body = stripLabels(text.slice(0, text.indexOf("\x12"))).replace(/=\s*$/, "");
|
||||
if (body.includes(":")) body = body.slice(body.indexOf(":") + 1);
|
||||
const parts = body.split("=");
|
||||
if (parts.length > 1 && /^[A-Za-z][A-Za-z0-9]*$/.test(parts[0].trim())) {
|
||||
if (parts.length > 1 && /^[A-Za-z가-힣][A-Za-z0-9가-힣]*$/.test(parts[0].trim())) {
|
||||
componentDeclaration = parts[0].trim();
|
||||
body = parts[1];
|
||||
} else body = parts[0];
|
||||
@@ -210,7 +211,9 @@ const EstText = (() => {
|
||||
end = assignments[j + 1]?.index ?? text.length;
|
||||
let body = text.slice(assignment.index + assignment[0].length, end);
|
||||
if (!matched && /^\s*\*.*\*\s*$/.test(text)) body = body.replace(/\s+\*\s*$/, "");
|
||||
body = body.split(/\{(?!%)|\s+[::]\s*/)[0].replace(/[},,]\s*$/, "");
|
||||
body = body.replace(/\{[^}]*\}/g, "");
|
||||
if (!matched) body = body.split("{")[0];
|
||||
body = body.split(/\s+[::]\s*/)[0].replace(/[,,]\s*$/, "");
|
||||
if (body.includes("─") && calculated !== null) {
|
||||
variables[assignment[1]] = floating(calculated, 2, 1);
|
||||
continue;
|
||||
@@ -265,7 +268,7 @@ const EstText = (() => {
|
||||
.pop();
|
||||
if (body.includes(":")) body = body.slice(body.indexOf(":") + 1);
|
||||
body = expression(body)
|
||||
.replace(/\s*([×÷+*/−-])\s*/g, "$1")
|
||||
.replace(/\s*([×÷·+*/−-])\s*/g, "$1")
|
||||
.trim()
|
||||
.split(/\s{2,}/)
|
||||
.pop();
|
||||
@@ -278,7 +281,8 @@ const EstText = (() => {
|
||||
explicit?.digits ??
|
||||
(sc < 0 || num(row.LinkIndex) !== 0
|
||||
? (num(row.Level) === finalLevel && text.includes("\x1a")) ||
|
||||
index === singleComponent
|
||||
index === singleComponent ||
|
||||
options.CostValueTrunc
|
||||
? 0
|
||||
: 1
|
||||
: Math.max(2, matched[1].split(".")[1]?.length || 0));
|
||||
@@ -289,8 +293,8 @@ const EstText = (() => {
|
||||
results.length > 1 && sc < 0 && !explicit && row.Precision === undefined;
|
||||
calculated = floating(
|
||||
calculated,
|
||||
intermediate ? Math.max(2, matched[1].split(".")[1]?.length || 0) : digits,
|
||||
intermediate ? 1 : method,
|
||||
intermediate ? (options.MidCostDiget ?? 2) : digits,
|
||||
intermediate ? 2 : method,
|
||||
);
|
||||
const firstValue = calculated;
|
||||
let rendered = text.replace(marker, `\x12${calculated}\x12`);
|
||||
@@ -311,9 +315,9 @@ const EstText = (() => {
|
||||
),
|
||||
format?.digits ??
|
||||
(intermediate && part < results.length - 1
|
||||
? Math.max(2, next[1].split(".")[1]?.length || 0)
|
||||
? (options.MidCostDiget ?? 2)
|
||||
: digits),
|
||||
format?.method ?? (intermediate && part < results.length - 1 ? 1 : method),
|
||||
format?.method ?? (intermediate && part < results.length - 1 ? 2 : method),
|
||||
);
|
||||
assignmentName = assignedNames.get(next.index) || assignmentName;
|
||||
if (assignmentName) variables[assignmentName] = calculated;
|
||||
|
||||
Reference in New Issue
Block a user