Merge remote-tracking branch 'origin/dev' into sub_laptop_4

This commit is contained in:
2026-09-19 02:05:29 +09:00
479 changed files with 10238 additions and 584 deletions
@@ -19,6 +19,7 @@ import difflib
import hashlib
import re
import sys
import unicodedata
from dataclasses import dataclass
from pathlib import Path
@@ -29,7 +30,8 @@ from resources.tester.test_const_pdf_coverage import _NUM, _page_rows # noqa: E
COST = ROOT / "resources/knowledge/original/원가계산"
#: 책마다 — PDF · 차례 쪽(PDF 쪽 번호) · 인쇄 1쪽이 놓인 PDF 쪽 · 머리 「문서」 칸 · 새 md 뿌리
#: 책마다 — PDF · 차례 쪽(PDF 쪽 번호) · 인쇄 1쪽이 놓인 PDF 쪽 · 머리 「문서」 칸 · 새 md 뿌리 ·
#: 차례 모양(block = 번호·이름·쪽이 줄마다 · inline = 한 줄에) · 절 머리 번호 뒤 마침표 · 쪽 꼬리(맨 아래 줄)
BOOKS = {
"산림": {
"pdf": COST / "산림_표준품셈/첨부/(산림청고시 제2025-82호) 산림사업 표준품셈.pdf",
@@ -37,6 +39,21 @@ BOOKS = {
"first_body": 13,
"doc": "산림사업 표준품셈(산림청고시 제2025-82호)",
"out": COST / "산림_표준품셈/본문",
"toc_layout": "block",
"dot": True,
"footer": re.compile(r"^-\s*\d+\s*-$"), # 「- 123 -」
},
"건설": {
"pdf": COST / "건설공사_표준품셈/2026년_건설공사_표준품셈.pdf",
"toc": (3, 51),
"first_body": 57,
"doc": "2026 건설공사 표준품셈",
"out": COST / "건설공사_표준품셈/본문",
"toc_layout": "inline",
"dot": False, # 「1-5 기타」
"footer": re.compile(
r"^\d+\s+\S+부문$|^제\s*\d+\s*장.*\s\d+$"
), # 「30 공통부문」·「제1장 적용기준 31」
},
}
@@ -72,15 +89,15 @@ class Entry:
page: int # 인쇄 쪽
def toc_entries(doc, first: int, last: int) -> list[Entry]:
"""차례 쪽(PDF first~last)의 줄 — 번호 줄 · 이름 줄(점선) · 쪽 줄이 차례로 옴."""
lines = [
line
for number in range(first - 1, last)
for line in doc[number].get_text().splitlines()
if line.strip() not in _TOC_SKIP
def toc_entries(doc, book: dict) -> list[Entry]:
"""차례 쪽의 줄 → 차례 줄 목록(건설은 부문 줄 `공통부문` 도 끼움 · 쪽 0)."""
first, last = book["toc"]
raw = [
line for number in range(first - 1, last) for line in doc[number].get_text().splitlines()
]
return parse_toc(lines)
if book["toc_layout"] == "inline":
return parse_toc_inline(raw)
return parse_toc([line for line in raw if line.strip() not in _TOC_SKIP])
def parse_toc(raw: list[str]) -> list[Entry]:
@@ -102,6 +119,31 @@ def parse_toc(raw: list[str]) -> list[Entry]:
return out
_INLINE = re.compile(r"^(\d+-\d+(?:-\d+)*)\s*(.*?)\s*[·․…]{3,}\s*(\d+)\s*$")
_DIVISION = re.compile(r"^\S+부문$")
def parse_toc_inline(raw: list[str]) -> list[Entry]:
"""건설 차례 — 절·항은 「1-1 일반사항····3」 한 줄 · 장은 「제1장 / 적용기준 / 3」 · 부문은 「공통부문」 한 줄."""
lines = [line.strip() for line in raw if line.strip()]
out, i = [], 0
while i < len(lines):
line = lines[i]
if found := _INLINE.match(line):
out.append(Entry(found[1], found[2], int(found[3])))
elif re.fullmatch(r"\d+장", line):
out.append(Entry(line, lines[i + 1], int(lines[i + 2])))
i += 2
elif _DIVISION.match(line):
out.append(Entry(line, "", 0))
elif not (
line.replace(" ", "") == "목차" or line.isdigit()
): # 쪽 머리 「목차」 · 차례 쪽 번호
raise ValueError(f"차례 모양이 다름: {line!r}")
i += 1
return out
#: 가운뎃점 여러 벌 — 차례는 「보수․복구」(U+2024) · 본문은 「보수·복구」(U+00B7). 맞대기에서만 같게 봄.
_DOTS = str.maketrans({"": "·", "": "·", "": "·", "": "·"})
@@ -122,13 +164,13 @@ def locate(doc, marker: str, first_pdf: int, slack: int = 3) -> tuple[int, int]:
raise ValueError(f"표지를 못 찾음: {marker} (PDF {first_pdf}~{first_pdf + slack})")
def heading_pattern(ident: str) -> re.Pattern:
def heading_pattern(ident: str, dot: bool = True) -> re.Pattern:
"""본문 머리 줄 — **번호로** 찾음. 차례 이름에 오타가 있어서(「면벅」=면벽 · 「조림」=조립 …)."""
if ident.startswith(""):
return re.compile(r"^제\s*" + ident[1:-1] + r"\s*장(?!\d)")
if ident.startswith("부록"):
return re.compile(r"^\[?" + re.escape(ident) + r"\]?(?!\d)")
return re.compile(r"^" + re.escape(ident) + r"\.(?!\d)")
return re.compile(r"^\[?부록\s*" + ident[2:] + r"\]?(?!\d)") # 「[부록 1]」
return re.compile(r"^" + re.escape(ident) + (r"\." if dot else "") + r"(?![\d-])")
#: 글자 사이 빈칸으로 볼 틈(글자 크기 대비) — 본문 머리 실측: 빈칸 7.7pt · 붙은 글자 0.7pt(14pt 글꼴)
@@ -154,19 +196,40 @@ def visual_text(page, row: str) -> str:
return row
def find_heading(doc, ident: str, first_pdf: int, slack: int = 3) -> tuple[int, int, str]:
def find_heading(
doc, ident: str, first_pdf: int, slack: int = 3, dot: bool = True
) -> tuple[int, int, str]:
"""(PDF 쪽, 쪽 안 줄 차례, 머리 글자) — 머리 글자는 PDF 그대로(번호 뒤 마침표 포함) · 띄어쓰기는 쪽 그림대로."""
pattern = heading_pattern(ident)
pattern = heading_pattern(ident, dot)
for number in range(first_pdf, min(first_pdf + slack, doc.page_count) + 1):
for index, row in enumerate(_page_rows(doc[number - 1])):
if pattern.match(row.strip()):
return number, index, visual_text(doc[number - 1], row.strip())
title = visual_text(doc[number - 1], row.strip())
cut = pattern.match(title).end()
lead, name = title[:cut].strip(), title[cut:].strip()
return number, index, f"{lead} {join_spaced(name)}".strip()
raise ValueError(f"머리를 못 찾음: {ident} (PDF {first_pdf}~{first_pdf + slack})")
def name_of(ident: str, title: str) -> str:
def join_spaced(name: str) -> str:
"""자간을 벌려 찍은 이름은 붙임(「측 량」 → 「측량」 · 규칙 3장) — 이름 전체가 한 글자씩일 때만."""
parts = name.split(" ")
if len(parts) > 1 and all(len(p) == 1 and "" <= p <= "" for p in parts):
return "".join(parts)
return name
def name_of(ident: str, title: str, dot: bool = True) -> str:
"""머리 글자에서 번호를 뗀 이름(「9-5. 발파암」 → 「발파암」)."""
return title[heading_pattern(ident).match(title).end() :].strip()
return title[heading_pattern(ident, dot).match(title).end() :].strip()
#: 파일 이름에서 뗄 개정 표지 — 「수치지도 작성('21, '22, '24, '26년 보완)」(머리 글자에는 남김)
_REVISION = re.compile(r"\s*\([^()]*(?:보완|신설|개정|삭제)[^()]*\)\s*$")
def file_label(ident: str, title: str, dot: bool = True) -> str:
return safe(_REVISION.sub("", name_of(ident, title, dot)))
def claimed_elsewhere(root: Path) -> set[str]:
@@ -231,87 +294,149 @@ def read_head(path: Path) -> dict[str, str]:
raise ValueError(f"머리 끝 없음: {path}")
_SLOT = re.compile(r"제(\d+)장_[^/]*/(\d+-\d+)_")
#: 자리 — (부문 폴더) / 장 번호 / 절(·항) 번호. 이름이 달라도 번호가 같으면 같은 자리
_SLOT = re.compile(r"(?:([^/]+)/)?제(\d+)장_[^/]*/(\d+-\d+(?:-\d+)?)_")
#: 한 파일 쪽 상한 — 넘는 절은 항(N-N-N) 단위로 쪼갬(규칙 1장)
_MAX_PAGES = 40
def _body_rows(page, footer: re.Pattern) -> list[str]:
"""쪽의 줄 — 맨 아래 쪽 꼬리(쪽 번호 · 장 이름)와 이어짐 표지 「→」 는 뺌."""
rows = [row.strip() for row in _page_rows(page)]
if rows and footer.match(rows[-1]):
rows = rows[:-1]
return [row for row in rows if row != ""]
def _blank(page, footer: re.Pattern) -> bool:
return len(re.sub(r"\s", "", "".join(_body_rows(page, footer)))) < _EMPTY_PAGE_CHARS
def _span_of(doc, book: dict, entry: Entry, following: Entry | None, cover: str = ""):
"""(시작 PDF 쪽, 머리 글자, 끝 PDF 쪽, 끝표지) — 끝은 다음 머리 앞 · 부문 표지 앞 · 뒤 빈 쪽 뺌."""
offset, dot, footer = book["first_body"] - 1, book["dot"], book["footer"]
start, _, title = find_heading(doc, entry.ident, entry.page + offset, dot=dot)
if following is None: # 문서 맨 끝
end, marker = doc.page_count, ""
else: # 장 마지막 절이면 다음 장 제목 · 부록 앞이면 부록 제목
nxt, at, marker = find_heading(doc, following.ident, following.page + offset, dot=dot)
end = nxt - 1 if at == 0 else nxt
for page in range(nxt - 1, start, -1) if cover else (): # 다음 부문 표지 쪽 앞에서 끊음
if any(r.strip() == cover for r in _page_rows(doc[page - 1])[:3]):
end = page - 1
break
while end > start and _blank(doc[end - 1], footer):
end -= 1
return start, title, max(end, start), marker
def plan(book_name: str) -> list[Path]:
"""장마다 `0-00_장머리.md` + 절마다 빈 파일(머리만 · 상태 대기).
"""장마다 `0-00_장머리.md` + 절마다 빈 파일(머리만 · 상태 대기) · 40쪽 넘는 절은 `N-NN-00_절머리.md` + 항마다.
**이미 있는 자리는 안 건드림** — 이 폴더에 있거나 다른 창 브랜치에 있는 장·절(이름이 달라도 번호로 봄).
건설은 부문 폴더(`01_공통부문`) 아래 · 부문마다 장 번호가 1부터.
"""
import pymupdf
book = BOOKS[book_name]
out = book["out"]
out, dot, footer = book["out"], book["dot"], book["footer"]
offset = book["first_body"] - 1 # 인쇄 쪽 + offset = PDF 쪽
have = claimed_elsewhere(out) | {p.relative_to(out).as_posix() for p in out.rglob("*.md")}
taken = {f"{int(m[1])}/{m[2]}" for m in map(_SLOT.match, have) if m}
folders = {int(m[1]): rel.split("/")[0] for rel in have if (m := _SLOT.match(rel))}
taken = {f"{m[1] or ''}/{int(m[2])}/{m[3]}" for m in map(_SLOT.match, have) if m}
folders = {
(m[1] or "", int(m[2])): rel.split("/")[-2] for rel in have if (m := _SLOT.match(rel))
}
written = []
def write(division, chapter_no, slot, file_name, start, title, end, marker, doc) -> None:
if f"{division}/{chapter_no}/{slot}" in taken:
return
# 그림 쪽 — 글자층 없이 그림만 있는 쪽이 끼면 받아쓰기는 그림 기준
drawn = any(
_blank(doc[p - 1], footer) and doc[p - 1].get_images() for p in range(start, end + 1)
)
path = out / division / folders[(division, chapter_no)] / file_name
path.parent.mkdir(parents=True, exist_ok=True)
values = {"문서": book["doc"], "": title, "시작표지": title, "끝표지": marker}
values |= {"PDF쪽": _span(start, end), "인쇄쪽": _span(start - offset, end - offset)}
values |= {"상태": "대기", "원천": "그림" if drawn else "글자층"}
path.write_text(head_text(values), encoding="utf-8")
written.append(path)
with pymupdf.open(book["pdf"]) as doc:
entries = toc_entries(doc, *book["toc"])
# 경계가 되는 차례 줄 — 장 · 절 · 부록N(항은 절 안 · 머리 없는 「부록」 묶음 줄은 뺌)
bounds = [e for e in entries if e.ident != "부록" and e.ident.count("-") < 2]
chapter_no = None
entries = toc_entries(doc, book)
# 경계가 되는 차례 줄 — 부문 · 장 · 절 · 부록N(항은 절 안 · 머리 없는 「부록」 묶음 줄은 뺌)
at = [i for i, e in enumerate(entries) if e.ident != "부록" and e.ident.count("-") < 2]
bounds = [entries[i] for i in at]
division, divisions, chapter_no = "", 0, None
for n, entry in enumerate(bounds):
if _DIVISION.match(entry.ident):
divisions += 1
division, chapter_no = f"{divisions:02d}_{entry.ident}", None
continue
if entry.ident.startswith("부록"):
continue
start_pdf, _, title = find_heading(doc, entry.ident, entry.page + offset)
following = bounds[n + 1] if n + 1 < len(bounds) else None
if following is None: # 문서 맨 끝 절
end_pdf, end_marker = doc.page_count, ""
else: # 장 마지막 절이면 다음 장 제목 · 부록 앞이면 부록 제목
next_pdf, at, end_marker = find_heading(
doc, following.ident, following.page + offset
)
end_pdf = max(next_pdf - 1 if at == 0 else next_pdf, start_pdf)
j = next(
(k for k in range(n + 1, len(bounds)) if not _DIVISION.match(bounds[k].ident)), None
)
following = bounds[j] if j is not None else None
cover = bounds[j - 1].ident if j is not None and j - 1 > n else "" # 사이에 낀 부문
start, title, end, marker = _span_of(doc, book, entry, following, cover)
if entry.ident.startswith(""):
chapter_no = int(entry.ident[1:-1])
folders.setdefault(
chapter_no, f"{chapter_no:02d}장_{safe(name_of(entry.ident, title))}"
(division, chapter_no),
f"{chapter_no:02d}장_{file_label(entry.ident, title, dot)}",
)
write(
division, chapter_no, "0-00", "0-00_장머리.md", start, title, end, marker, doc
)
slot, file_name = "0-00", "0-00_장머리.md"
else:
major, minor = entry.ident.split("-")
slot = f"{major}-{int(minor):02d}"
file_name = f"{slot}_{safe(name_of(entry.ident, title))}.md"
if chapter_no is None or f"{chapter_no}/{slot}" in taken:
continue
empty = any(
len(re.sub(r"\s", "", doc[p - 1].get_text())) < _EMPTY_PAGE_CHARS
for p in range(start_pdf, end_pdf + 1)
)
path = out / folders[chapter_no] / file_name
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(
head_text(
{
"문서": book["doc"],
"": title,
"PDF쪽": _span(start_pdf, end_pdf),
"인쇄쪽": _span(start_pdf - offset, end_pdf - offset),
"시작표지": title,
"끝표지": end_marker,
"상태": "대기",
"원천": "그림" if empty else "글자층",
}
),
encoding="utf-8",
)
written.append(path)
if chapter_no is None:
continue
major, minor = entry.ident.split("-")
slot = f"{major}-{int(minor):02d}"
region = entries[at[n] + 1 : at[n + 1] if n + 1 < len(at) else len(entries)]
items = [e for e in region if e.ident.rsplit("-", 1)[0] == entry.ident]
if end - start + 1 <= _MAX_PAGES or not items:
name = f"{slot}_{file_label(entry.ident, title, dot)}.md"
write(division, chapter_no, slot, name, start, title, end, marker, doc)
continue
# 40쪽 넘는 절 — 절머리(절 제목 ~ 첫 항 앞) + 항마다
head_end = _span_of(doc, book, entry, items[0])
write(division, chapter_no, f"{slot}-00", f"{slot}-00_절머리.md", *head_end, doc)
for k, item in enumerate(items):
piece = _span_of(
doc, book, item, items[k + 1] if k + 1 < len(items) else following, cover
)
if k + 1 == len(items): # 마지막 항은 절 끝까지
piece = (piece[0], piece[1], end, marker)
item_slot = f"{slot}-{int(item.ident.rsplit('-', 1)[1]):02d}"
name = f"{item_slot}_{file_label(item.ident, piece[1], dot)}.md"
write(division, chapter_no, item_slot, name, *piece, doc)
return written
# ── check ──────────────────────────────────────────────────────────────
#: 쪽 번호 줄(「- 123 -」) — 절 글자에서 뺌
_PAGE_NO = re.compile(r"^-\s*\d+\s*-$")
#: md 문법 — 글자 대조·수 대조에서 뺌(원문 글자가 아님)
_COMMENT = re.compile(r"<!--.*?-->", re.S)
_REPEATED = re.compile(r"<!--\s*되풀이 머리:(.*?)-->")
_IMAGE = re.compile(r"!\[[^\]]*\]\([^)]*\)")
_TABLE_RULE = re.compile(r"^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)*\|?\s*$")
#: 막음표 — 원문 글자가 md 문법으로 읽히지 않게 앞에 `\` 를 붙인 것(`\*` `\-` `\#` `\>` `\|` …)
_ESCAPED = re.compile(r"\\([\\`*_{}\[\]()#+\-.!|>~^])")
_HOLD = "\x00"
#: 글자층 밖 — PDF 글자층의 사용자 영역 글리프(U+E000–F8FF)는 뜻 없는 코드(식의 「(m³)」·분수선).
#: ①② 에서 빼고 개수·쪽을 기계검사 칸에 드러냄(③ 이 그림으로 봄). md 에서 그 자리를 받아쓴 글자는
#: `<!-- 글자층 밖 -->…<!-- /글자층 밖 -->` 로 감싸면 ①② 에서 빼고 「받아씀 N자」로 드러냄.
_PUA = re.compile("[\ue000-\uf8ff]")
_OFF_OPEN, _OFF_CLOSE = "\x01", "\x02"
_OFF_MARK = re.compile(r"<!--\s*(/?)글자층 밖\s*-->")
def _same_han(ch: str) -> str:
"""호환 한자(U+F900FAFF) → 통합 한자(率 U+F9DB → 率 U+7387). ⚠ NFKC 통째로는 안 씀 — ㎥·①·㎡ 가 풀림."""
return unicodedata.normalize("NFKC", ch) if "\uf900" <= ch <= "\ufaff" else ch
def book_of(path: Path) -> dict:
@@ -330,7 +455,12 @@ def split_head(text: str) -> tuple[str, str]:
def md_lines(body: str) -> list[tuple[int, str]]:
"""몸의 (줄 번호, 원문 글자) — 주석 · 그림 · 표 구분 줄 · md 문법 글자를 뺌. 줄 번호는 몸 기준 1부터."""
"""몸의 (줄 번호, 원문 글자) — 주석 · 그림 · 표 구분 줄 · md 문법 글자를 뺌. 줄 번호는 몸 기준 1부터.
`<!-- 되풀이 머리: … -->` 는 셈 — 쪽을 넘은 표가 PDF 에서 되풀이한 머리 줄(md 표에서는 뺌 · 규칙 4-5).
"""
body = _REPEATED.sub(r"\1", body)
body = _OFF_MARK.sub(lambda m: _OFF_CLOSE if m.group(1) else _OFF_OPEN, body)
body = _COMMENT.sub(lambda m: "\n" * m.group(0).count("\n"), body)
out = []
for number, line in enumerate(body.split("\n"), start=1):
@@ -348,8 +478,8 @@ def md_lines(body: str) -> list[tuple[int, str]]:
return out
def pdf_lines(doc, head: dict[str, str]) -> list[tuple[int, str]]:
"""그 절 PDF 글자층의 (PDF 쪽, 줄) — 시작표지 줄부터 끝표지 줄 앞까지 · 쪽 번호 줄 뺌."""
def pdf_lines(doc, head: dict[str, str], footer: re.Pattern) -> list[tuple[int, str]]:
"""그 절 PDF 글자층의 (PDF 쪽, 줄) — 시작표지 줄부터 끝표지 줄 앞까지 · 머리 PDF쪽 밖은 안 봄 · 쪽 꼬리 뺌."""
first, _, last = head["PDF쪽"].partition("~")
first, last = int(first), int(last or first)
start_page, start_row = locate(doc, head["시작표지"], first, slack=0)
@@ -360,21 +490,43 @@ def pdf_lines(doc, head: dict[str, str]) -> list[tuple[int, str]]:
except ValueError:
pass
out = []
for number in range(start_page, min(end_page, doc.page_count) + 1):
for index, row in enumerate(_page_rows(doc[number - 1])):
for number in range(start_page, min(end_page, last) + 1):
rows = [row.strip() for row in _page_rows(doc[number - 1])]
if rows and footer.match(rows[-1]):
rows[-1] = "" # 쪽 꼬리
for index, row in enumerate(rows):
if (number, index) < (start_page, start_row) or (number, index) >= (end_page, end_row):
continue
if not _PAGE_NO.match(row.strip()):
out.append((number, row))
if not row or row == "": # 이어짐 표지
continue
out.append((number, row))
return out
def _split_off(lines: list[tuple[int, str]]) -> tuple[list[tuple[int, str]], list[tuple[int, str]]]:
"""(셀 줄, 글자층 밖 줄) — PDF 는 사용자 영역 글리프 · md 는 `글자층 밖` 으로 감싼 글자를 떼어 냄."""
kept, off, inside = [], [], False
for at, line in lines:
keep, gone = [], []
for ch in line:
if ch in (_OFF_OPEN, _OFF_CLOSE):
inside = ch == _OFF_OPEN
elif inside or _PUA.match(ch):
gone.append(ch)
else:
keep.append(ch)
kept.append((at, "".join(keep)))
if "".join(gone).strip():
off.append((at, "".join(gone)))
return kept, off
def _tight(lines: list[tuple[int, str]]) -> tuple[str, list[int]]:
"""공백 뗀 글자 줄 + 글자마다 어디서 왔나(쪽 또는 md 줄)."""
"""공백 뗀 글자 줄 + 글자마다 어디서 왔나(쪽 또는 md 줄) · 호환 한자는 통합 한자로."""
text, where = [], []
for at, line in lines:
for ch in re.sub(r"\s", "", line):
text.append(ch)
text.append(_same_han(ch))
where.append(at)
return "".join(text), where
@@ -389,7 +541,9 @@ def _numbers(lines: list[tuple[int, str]]) -> tuple[collections.Counter, dict[st
def compare(pdf: list[tuple[int, str]], md: list[tuple[int, str]]) -> dict:
"""① 수(갯수까지) ② 글자(공백 뗌 · 갯수까지) — 양방향."""
"""① 수(갯수까지) ② 글자(공백 뗌 · 갯수까지) — 양방향. 글자층 밖(사용자 영역 글리프 · 감싼 받아쓰기)은 빼고 따로 셈."""
pdf, pdf_off = _split_off(pdf)
md, md_off = _split_off(md)
pdf_n, pdf_at = _numbers(pdf)
md_n, md_at = _numbers(md)
pdf_t, pdf_where = _tight(pdf)
@@ -418,6 +572,11 @@ def compare(pdf: list[tuple[int, str]], md: list[tuple[int, str]]) -> dict:
"char_missing": missing_c,
"char_extra": extra_c,
"spots": spots,
"off_pdf": (
sum(len(re.sub(r"\s", "", t)) for _, t in pdf_off),
sorted({a for a, _ in pdf_off}),
),
"off_md": sum(len(re.sub(r"\s", "", t)) for _, t in md_off),
}
@@ -429,9 +588,14 @@ def verdict(result: dict) -> str:
sum(result["char_extra"].values()),
)
word = "통과" if not any(counts) else "불통"
return (
line = (
f"{word} · ①수 결손 {counts[0]} 허구 {counts[1]} · ②글자 빠짐 {counts[2]} 더함 {counts[3]}"
)
glyphs, pages = result.get("off_pdf", (0, []))
if glyphs or result.get("off_md"): # ③ 이 그림으로 그 식을 꼭 보게
where = f"({', '.join(map(str, pages))}쪽)" if pages else ""
line += f" · 글자층 밖 글리프 {glyphs}{where} · 받아씀 {result.get('off_md', 0)}"
return line
def fingerprint(text: str) -> str:
@@ -452,8 +616,9 @@ def check_file(path: Path) -> tuple[dict, str]:
import pymupdf
_, body = split_head(path.read_text(encoding="utf-8").replace("\r\n", "\n"))
with pymupdf.open(book_of(path)["pdf"]) as doc:
result = compare(pdf_lines(doc, read_head(path)), md_lines(body))
book = book_of(path)
with pymupdf.open(book["pdf"]) as doc:
result = compare(pdf_lines(doc, read_head(path), book["footer"]), md_lines(body))
return result, verdict(result)
@@ -510,7 +675,7 @@ def status() -> str:
for name, book in BOOKS.items():
by_chapter: dict[str, collections.Counter] = {}
for path in sorted(book["out"].rglob("*.md")):
chapter = path.relative_to(book["out"]).parts[0]
chapter = path.parent.relative_to(book["out"]).as_posix()
by_chapter.setdefault(chapter, collections.Counter())[
read_head(path).get("상태", "")
] += 1
@@ -46,10 +46,10 @@ PDF쪽: 135~136
3. **글자·숫자·기호는 글자층과 그림 둘 다로 확인하고, 띄어쓰기와 줄바꿈 이음은 그림 기준**(글자층은 낱말 사이 빈칸을 잃는 일이 많음 — 「효과적/으로」 붙임 · 「수/있도록」 띄움을 그림으로 가림). 넓은 띄움은 빈칸 하나로.
4. 자간을 벌려 찍은 글자(「특 별 인 부」 · 「구 분」)는 붙여 씀(「특별인부」 · 「구분」). 낱말 사이 띄어쓰기는 PDF 대로.
5. 쪽 머리·꼬리(쪽 번호 · 되풀이되는 장 이름)는 뺌. 절 제목 옆 개정 표지(`('08, '20, 25년 보완)`)는 본문이므로 남김.
6. 제목 단계 — `#` 장 · `##` 절 · `###` 항 · `####` 목. 번호와 이름은 PDF 글자 그대로. **절 파일은 `##` 로 시작**하고 `#` 장 제목은 `0-00_장머리.md` 에만 둠.
6. 제목 단계 — `#` 장 · `##` 절 · `###` 항 · `####` 목. 번호와 이름은 PDF 글자 그대로. **절 파일은 `##` 로 시작**하고 `#` 장 제목은 `0-00_장머리.md` 에만 둠. 숫자로 시작하는 목 제목(`1. 천연림 모두베기`)은 `####` 로 적고 글자는 PDF 그대로.
7. 표 위의 밑수 줄(`(단위: 10㎡당)` · `(㎥당)`)은 **표 바로 위 한 줄로** 반드시 적고, 밑수 줄과 표 사이에 빈 줄 하나.
8. 표 아래 `[주]` · `비고` · `※` 는 빠짐없이, 번호(①②③ · 가나다)도 그대로. `[주]`**단독 줄**로 적고 그 아래 **항목마다 한 줄씩**(`① …`). PDF 가 `[주] ① …` 로 한 줄에 찍었어도 이렇게 나눔 — 줄 나눔은 내용이 아님. 목록 기호를 덧붙이지 않음. 표 안 마지막 줄에 든 비고는 표 안에 둠.
9. 테를 두른 글상자(【소요인력 산출 예시】 등)는 인용(`>`)으로 적음. 상자 안 줄 사이에 빈 `>` 줄을 넣지 않음(PDF 에 문단 띄움이 있을 때만).
9. 테를 두른 글상자(【소요인력 산출 예시】 등)는 인용(`>`)으로 적음. 상자 안 줄 사이에 빈 `>` 줄을 넣지 않음(PDF 에 문단 띄움이 있을 때만). 상자 안 줄 이음 판정 — **첫 줄이 상자 오른쪽 끝까지 차 있으면 줄넘김(이음) · 오른쪽이 비어 있으면 새 줄.** 상자 안에 표가 들어 있으면 표만 상자 밖 md 표로 적고 `<!-- 글상자 안 표: … -->` 주석.
12. md 문법으로 읽히는 원문 글자는 `\` 로 막아 씀 — 줄 첫머리 `\*` `\-` `\#` `\>` `1\.` · 표 칸 안 `\|`. 도구는 막음표를 빼고 셈.
10. 식은 글자로 옮김(`Q = 3,600 × q × f × E / Cm`). 위·아래 첨자는 `^` `_` 로(`10^-7`).
11. 원문이 틀려 보여도 **고치지 않음.** 그대로 적고 그 줄 아래 `<!-- 원문 그대로: … -->` 로 남김.
@@ -63,8 +63,11 @@ PDF쪽: 135~136
3. 머리가 두 단 이상이면 **윗머리를 md 머리 줄로, 아랫머리는 몸 첫 줄(들)로** 적고 주석을 담. 윗머리를 아랫머리마다 되풀이해 펼치지 않음.
`<!-- 머리: 몸 1행까지 머리 · 병합: 머리 2~4열 「소요인력(인/본당)」 -->`
4. 빈 칸은 빈 칸. `〃` · `-` · `·` 는 그대로 적음(위 값으로 채우지 않음).
5. 한 표가 쪽을 넘어가면 **한 표로 이음.** 넘어간 쪽에서 되풀이된 머리 줄은 뺌.
5. 한 표가 쪽을 넘어가면 **한 표로 이음.** 넘어간 쪽에서 되풀이된 머리 줄은 뺌. 뺀 자리(넘어간 첫 줄 앞)에 `<!-- 되풀이 머리: 명 칭 | 규 격 | 단위 -->` 로 그 글자를 적음 — 기계검사가 그 글자를 PDF 의 되풀이 머리와 맞대 셈.
6. 표가 너무 넓어 PDF 가 두 표로 나눠 찍었으면 PDF 대로 두 표.
7. 표 칸 안에 든 작은 표는 큰 표 바로 밑에 따로 적고 `<!-- 칸 안 표: 큰 표 N열 M행 안 -->` 주석.
8. 빗금으로 나뉜 머리 칸은 윗칸 글을 머리 줄에, 나머지를 몸 1행에 `<br>` 로 적고 `<!-- 빗금 칸: … -->` 주석.
9. 머리가 세 단·네 단이거나 선 없이 한 칸에 값이 줄마다 찍힌 표는 몸 줄로 펴고 주석에 그 사실을 적음.
## 5. 그림
@@ -80,6 +83,9 @@ PDF쪽: 135~136
| ② 글자 대조 | 도구 | PDF 글자(공백 뗌)가 md 에 빠짐없이 있고 md 에 없는 글자가 더해지지 않음 |
| ③ 자리 대조 | **작성하지 않은 다른 창** | 쪽 그림을 보며 표마다 수가 제 줄·제 칸에 있는지 · 병합 · 머리 · 밑수 · [주] |
- ①② 대조에서 빼는 것 — PDF 쪽: 쪽 맨 아래 꼬리(「- 51 -」 · 「30 공통부문」 · 「제1장 적용기준 31」) · 쪽 끝 이어짐 표지 「→」 / md 쪽: 머리 · `<!-- -->` · 그림 링크 · 표 문법(`|` · 구분 줄 · `<br>`) · 제목 `#` · 인용 `>` · 첨자 표시 `^` `_` (막음표 `\` 뒤 글자는 원문으로 셈).
- 글자층 밖 — PDF 글자층의 사용자 영역 글리프(U+E000–F8FF · 식의 「(m³)」·분수선)는 ①② 에서 빼고 기계검사 칸에 「글자층 밖 글리프 N개(쪽)」로 적음. 그 자리를 그림 보고 받아쓴 md 글자는 `<!-- 글자층 밖 -->(m^3)<!-- /글자층 밖 -->` 로 감쌈(①② 에서 빠지고 「받아씀 N자」로 드러남) — **이 칸이 뜬 파일은 ③ 이 그림으로 그 식을 꼭 봄.** 사용자 영역 글리프 자리 말고는 감싸지 않음.
- 호환 한자(U+F900FAFF · 率 U+F9DB)는 ② 에서 통합 한자(率 U+7387)와 같게 봄. 다른 글자(㎥·①·㎡ 등)는 그대로 견줌.
- ①②가 0 이어도 칸이 뒤바뀐 것은 못 잡음 → ③ 없이는 `확정` 아님.
- ③에서 고칠 곳이 나오면 검증 창이 고치지 않고 **작성 창에 돌려보냄**(줄 번호 + PDF 쪽 + 무엇이 다른지).
- `확정` 뒤 파일이 바뀌면 시험이 빨강. 고치려면 상태를 `작성중` 으로 되돌리고 ①②③ 다시.
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 제1장 적용기준
PDF쪽: 59
인쇄쪽: 3
시작표지: 제1장 적용기준
끝표지: 1-1 일반사항
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 1-1 일반사항
PDF쪽: 59
인쇄쪽: 3
시작표지: 1-1 일반사항
끝표지: 1-2 설계 및 수량
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 1-2 설계 및 수량
PDF쪽: 59~75
인쇄쪽: 3~19
시작표지: 1-2 설계 및 수량
끝표지: 1-3 재료 및 노임의 할증
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 1-3 재료 및 노임의 할증
PDF쪽: 76~79
인쇄쪽: 20~23
시작표지: 1-3 재료 및 노임의 할증
끝표지: 1-4 품의 할증('97, '01, '03, '11, '14, '15, '16, '17년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 1-4 품의 할증('97, '01, '03, '11, '14, '15, '16, '17년 보완)
PDF쪽: 79~86
인쇄쪽: 23~30
시작표지: 1-4 품의 할증('97, '01, '03, '11, '14, '15, '16, '17년 보완)
끝표지: 1-5 기타
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 1-5 기타
PDF쪽: 87~89
인쇄쪽: 31~33
시작표지: 1-5 기타
끝표지: 제2장 가설공사
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 제2장 가설공사
PDF쪽: 91
인쇄쪽: 35
시작표지: 제2장 가설공사
끝표지: 2-1 가설물의 한도
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 2-1 가설물의 한도
PDF쪽: 91~93
인쇄쪽: 35~37
시작표지: 2-1 가설물의 한도
끝표지: 2-2 손율
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 2-2 손율
PDF쪽: 94~96
인쇄쪽: 38~40
시작표지: 2-2 손율
끝표지: 2-3 가설건축물
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 2-3 가설건축물
PDF쪽: 97
인쇄쪽: 41
시작표지: 2-3 가설건축물
끝표지: 2-4 가설울타리 및 가설방음벽('09, '10, '17, '26년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 2-4 가설울타리 및 가설방음벽('09, '10, '17, '26년 보완)
PDF쪽: 97~99
인쇄쪽: 41~43
시작표지: 2-4 가설울타리 및 가설방음벽('09, '10, '17, '26년 보완)
끝표지: 2-5 규준틀
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 2-5 규준틀
PDF쪽: 99~100
인쇄쪽: 43~44
시작표지: 2-5 규준틀
끝표지: 2-6 동바리
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 2-6 동바리
PDF쪽: 101~103
인쇄쪽: 45~47
시작표지: 2-6 동바리
끝표지: 2-7 비계
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 2-7 비계
PDF쪽: 103~106
인쇄쪽: 47~50
시작표지: 2-7 비계
끝표지: 2-8 추락재해 및 낙하물방지시설
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 2-8 추락재해 및 낙하물방지시설
PDF쪽: 106~112
인쇄쪽: 50~56
시작표지: 2-8 추락재해 및 낙하물방지시설
끝표지: 2-9 통행안전시설
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 2-9 통행안전시설
PDF쪽: 112~114
인쇄쪽: 56~58
시작표지: 2-9 통행안전시설
끝표지: 2-10 피해방지시설
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 2-10 피해방지시설
PDF쪽: 115~117
인쇄쪽: 59~61
시작표지: 2-10 피해방지시설
끝표지: 2-11 현장관리
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 2-11 현장관리
PDF쪽: 117~119
인쇄쪽: 61~63
시작표지: 2-11 현장관리
끝표지: 2-12 공통장비
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 2-12 공통장비
PDF쪽: 120~122
인쇄쪽: 64~66
시작표지: 2-12 공통장비
끝표지: 제3장 토공사
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 제3장 토공사
PDF쪽: 123
인쇄쪽: 67
시작표지: 제3장 토공사
끝표지: 3-1 공통사항
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 3-1 공통사항
PDF쪽: 123
인쇄쪽: 67
시작표지: 3-1 공통사항
끝표지: 3-2 굴착
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 3-2 굴착
PDF쪽: 123~126
인쇄쪽: 67~70
시작표지: 3-2 굴착
끝표지: 3-3 암발파 및 파쇄
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 3-3 암발파 및 파쇄
PDF쪽: 126~130
인쇄쪽: 70~74
시작표지: 3-3 암발파 및 파쇄
끝표지: 3-4 쌓기
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 3-4 쌓기
PDF쪽: 130~133
인쇄쪽: 74~77
시작표지: 3-4 쌓기
끝표지: 3-5 절토부대공
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 3-5 절토부대공
PDF쪽: 133~134
인쇄쪽: 77~78
시작표지: 3-5 절토부대공
끝표지: 3-6 성토부대공
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 3-6 성토부대공
PDF쪽: 134
인쇄쪽: 78
시작표지: 3-6 성토부대공
끝표지: 3-7 비탈면 보호공
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 3-7 비탈면 보호공
PDF쪽: 134~138
인쇄쪽: 78~82
시작표지: 3-7 비탈면 보호공
끝표지: 3-8 보강토 옹벽
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 3-8 보강토 옹벽
PDF쪽: 138~139
인쇄쪽: 82~83
시작표지: 3-8 보강토 옹벽
끝표지: 3-9 벌개제근
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 3-9 벌개제근
PDF쪽: 140
인쇄쪽: 84
시작표지: 3-9 벌개제근
끝표지: 3-10 개간
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 3-10 개간
PDF쪽: 141
인쇄쪽: 85
시작표지: 3-10 개간
끝표지: 3-11 스마트 토공
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 3-11 스마트 토공
PDF쪽: 141~146
인쇄쪽: 85~90
시작표지: 3-11 스마트 토공
끝표지: 제4장 조경공사
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 제4장 조경공사
PDF쪽: 147
인쇄쪽: 91
시작표지: 제4장 조경공사
끝표지: 4-1 잔디 및 초화류
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 4-1 잔디 및 초화류
PDF쪽: 147~148
인쇄쪽: 91~92
시작표지: 4-1 잔디 및 초화류
끝표지: 4-2 관목
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 4-2 관목
PDF쪽: 149~150
인쇄쪽: 93~94
시작표지: 4-2 관목
끝표지: 4-3 교목
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 4-3 교목
PDF쪽: 150~152
인쇄쪽: 94~96
시작표지: 4-3 교목
끝표지: 4-4 조경시설물
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 4-4 조경시설물
PDF쪽: 153~154
인쇄쪽: 97~98
시작표지: 4-4 조경시설물
끝표지: 제5장 기초공사
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 제5장 기초공사
PDF쪽: 155
인쇄쪽: 99
시작표지: 제5장 기초공사
끝표지: 5-1 흙막이 및 물막이
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 5-1 흙막이 및 물막이
PDF쪽: 155~165
인쇄쪽: 99~109
시작표지: 5-1 흙막이 및 물막이
끝표지: 5-2 연약지반처리
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 5-2 연약지반처리
PDF쪽: 165~172
인쇄쪽: 109~116
시작표지: 5-2 연약지반처리
끝표지: 5-3 말뚝
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 5-3 말뚝
PDF쪽: 172~183
인쇄쪽: 116~127
시작표지: 5-3 말뚝
끝표지: 5-4 차수
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 5-4 차수
PDF쪽: 183~184
인쇄쪽: 127~128
시작표지: 5-4 차수
끝표지: 제6장 철근콘크리트공사
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 제6장 철근콘크리트공사
PDF쪽: 185
인쇄쪽: 129
시작표지: 제6장 철근콘크리트공사
끝표지: 6-1 콘크리트('25년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 6-1 콘크리트('25년 보완)
PDF쪽: 185~188
인쇄쪽: 129~132
시작표지: 6-1 콘크리트('25년 보완)
끝표지: 6-2 철근
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 6-2 철근
PDF쪽: 189~191
인쇄쪽: 133~135
시작표지: 6-2 철근
끝표지: 6-3 거푸집
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 6-3 거푸집
PDF쪽: 191~199
인쇄쪽: 135~143
시작표지: 6-3 거푸집
끝표지: 6-4 포스트텐션(Post Tension) 구조물 제작
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 6-4 포스트텐션(Post Tension) 구조물 제작
PDF쪽: 200~205
인쇄쪽: 144~149
시작표지: 6-4 포스트텐션(Post Tension) 구조물 제작
끝표지: 6-5 교량 가설공
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 6-5 교량 가설공
PDF쪽: 205~206
인쇄쪽: 149~150
시작표지: 6-5 교량 가설공
끝표지: 6-6 교량 부대공
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 6-6 교량 부대공
PDF쪽: 206~211
인쇄쪽: 150~155
시작표지: 6-6 교량 부대공
끝표지: 6-7 조립식 구조물 설치공
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 6-7 조립식 구조물 설치공
PDF쪽: 211~214
인쇄쪽: 155~158
시작표지: 6-7 조립식 구조물 설치공
끝표지: 제7장 돌공사
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 제7장 돌공사
PDF쪽: 215
인쇄쪽: 159
시작표지: 제7장 돌공사
끝표지: 7-1 돌쌓기
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 7-1 돌쌓기
PDF쪽: 215
인쇄쪽: 159
시작표지: 7-1 돌쌓기
끝표지: 7-2 돌붙임
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 7-2 돌붙임
PDF쪽: 216
인쇄쪽: 160
시작표지: 7-2 돌붙임
끝표지: 7-3 전석쌓기 및 깔기
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 7-3 전석쌓기 및 깔기
PDF쪽: 216~217
인쇄쪽: 160~161
시작표지: 7-3 전석쌓기 및 깔기
끝표지: 7-4 석재판 붙임
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 7-4 석재판 붙임
PDF쪽: 217~218
인쇄쪽: 161~162
시작표지: 7-4 석재판 붙임
끝표지: 제8장 건설기계
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 제8장 건설기계
PDF쪽: 219
인쇄쪽: 163
시작표지: 제8장 건설기계
끝표지: 8-1 적용기준
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-1 적용기준
PDF쪽: 219~224
인쇄쪽: 163~168
시작표지: 8-1 적용기준
끝표지: 8-2 시공능력
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2 시공능력
PDF쪽: 224
인쇄쪽: 168
시작표지: 8-2 시공능력
끝표지: 8-2-1 불도저('25년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-1 불도저('25년 보완)
PDF쪽: 224~226
인쇄쪽: 168~170
시작표지: 8-2-1 불도저('25년 보완)
끝표지: 8-2-2 리퍼(유압식)('25년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-2 리퍼(유압식)('25년 보완)
PDF쪽: 226~227
인쇄쪽: 170~171
시작표지: 8-2-2 리퍼(유압식)('25년 보완)
끝표지: 8-2-3 굴착기('04, '07, '09, '25년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-3 굴착기('04, '07, '09, '25년 보완)
PDF쪽: 227~229
인쇄쪽: 171~173
시작표지: 8-2-3 굴착기('04, '07, '09, '25년 보완)
끝표지: 8-2-4 트랜처
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-4 트랜처
PDF쪽: 229~230
인쇄쪽: 173~174
시작표지: 8-2-4 트랜처
끝표지: 8-2-5 로더('07, '20년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-5 로더('07, '20년 보완)
PDF쪽: 230~232
인쇄쪽: 174~176
시작표지: 8-2-5 로더('07, '20년 보완)
끝표지: 8-2-6 모터 스크레이퍼
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-6 모터 스크레이퍼
PDF쪽: 232~233
인쇄쪽: 176~177
시작표지: 8-2-6 모터 스크레이퍼
끝표지: 8-2-7 모터 그레이더('25년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-7 모터 그레이더('25년 보완)
PDF쪽: 234~235
인쇄쪽: 178~179
시작표지: 8-2-7 모터 그레이더('25년 보완)
끝표지: 8-2-8 덤프트럭('17년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-8 덤프트럭('17년 보완)
PDF쪽: 235~237
인쇄쪽: 179~181
시작표지: 8-2-8 덤프트럭('17년 보완)
끝표지: 8-2-9 롤러('04, '17, '25년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-9 롤러('04, '17, '25년 보완)
PDF쪽: 238~240
인쇄쪽: 182~184
시작표지: 8-2-9 롤러('04, '17, '25년 보완)
끝표지: 8-2-10 아스팔트 플랜트
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-10 아스팔트 플랜트
PDF쪽: 241
인쇄쪽: 185
시작표지: 8-2-10 아스팔트 플랜트
끝표지: 8-2-11 스테이빌라이저(노상안정기)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-11 스테이빌라이저(노상안정기)
PDF쪽: 241~242
인쇄쪽: 185~186
시작표지: 8-2-11 스테이빌라이저(노상안정기)
끝표지: 8-2-12 크러셔
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-12 크러셔
PDF쪽: 242~248
인쇄쪽: 186~192
시작표지: 8-2-12 크러셔
끝표지: 8-2-13 대형브레이커('14, '17, '25년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-13 대형브레이커('14, '17, '25년 보완)
PDF쪽: 248~249
인쇄쪽: 192~193
시작표지: 8-2-13 대형브레이커('14, '17, '25년 보완)
끝표지: 8-2-14 압쇄기(콘크리트 소할용)('04년 신설)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-14 압쇄기(콘크리트 소할용)('04년 신설)
PDF쪽: 249
인쇄쪽: 193
시작표지: 8-2-14 압쇄기(콘크리트 소할용)('04년 신설)
끝표지: 8-2-15 법면다짐기
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-15 법면다짐기
PDF쪽: 250
인쇄쪽: 194
시작표지: 8-2-15 법면다짐기
끝표지: 8-2-16 골재세척설비('01년 신설)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-16 골재세척설비('01년 신설)
PDF쪽: 250
인쇄쪽: 194
시작표지: 8-2-16 골재세척설비('01년 신설)
끝표지: 8-2-17 콘크리트 믹서
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-17 콘크리트 믹서
PDF쪽: 250
인쇄쪽: 194
시작표지: 8-2-17 콘크리트 믹서
끝표지: 8-2-18 콘크리트 배치플랜트(강제 혼합식)('00, '02, '11년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-18 콘크리트 배치플랜트(강제 혼합식)('00, '02, '11년 보완)
PDF쪽: 250~251
인쇄쪽: 194~195
시작표지: 8-2-18 콘크리트 배치플랜트(강제 혼합식)('00, '02, '11년 보완)
끝표지: 8-2-19 콘크리트 운반
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-19 콘크리트 운반
PDF쪽: 251~252
인쇄쪽: 195~196
시작표지: 8-2-19 콘크리트 운반
끝표지: 8-2-20 기관차
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-20 기관차
PDF쪽: 252~253
인쇄쪽: 196~197
시작표지: 8-2-20 기관차
끝표지: 8-2-21 경운기
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-21 경운기
PDF쪽: 253
인쇄쪽: 197
시작표지: 8-2-21 경운기
끝표지: 8-2-22  디젤 파일 해머
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-22  디젤 파일 해머
PDF쪽: 254~258
인쇄쪽: 198~202
시작표지: 8-2-22  디젤 파일 해머
끝표지: 8-2-23 유압 파일 해머
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-23 유압 파일 해머
PDF쪽: 258~262
인쇄쪽: 202~206
시작표지: 8-2-23 유압 파일 해머
끝표지: 8-2-24 진동파일 해머('96, '26년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-24 진동파일 해머('96, '26년 보완)
PDF쪽: 262~266
인쇄쪽: 206~210
시작표지: 8-2-24 진동파일 해머('96, '26년 보완)
끝표지: 8-2-25 진동파일해머(워터제트 병용 압입공)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-25 진동파일해머(워터제트 병용 압입공)
PDF쪽: 267~270
인쇄쪽: 211~214
시작표지: 8-2-25 진동파일해머(워터제트 병용 압입공)
끝표지: 8-2-26 유압식 압입 인발기(유압식 압입 인발공)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-26 유압식 압입 인발기(유압식 압입 인발공)
PDF쪽: 270~272
인쇄쪽: 214~216
시작표지: 8-2-26 유압식 압입 인발기(유압식 압입 인발공)
끝표지: 8-2-27 수중펌프
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-27 수중펌프
PDF쪽: 272~273
인쇄쪽: 216~217
시작표지: 8-2-27 수중펌프
끝표지: 8-2-28 터널전단면 굴착기(TBM)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-28 터널전단면 굴착기(TBM)
PDF쪽: 273~274
인쇄쪽: 217~218
시작표지: 8-2-28 터널전단면 굴착기(TBM)
끝표지: 8-2-29 펌프식 준설선('10, '11년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-29 펌프식 준설선('10, '11년 보완)
PDF쪽: 274~279
인쇄쪽: 218~223
시작표지: 8-2-29 펌프식 준설선('10, '11년 보완)
끝표지: 8-2-30 그래브 준설선('10, '11년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-30 그래브 준설선('10, '11년 보완)
PDF쪽: 279~282
인쇄쪽: 223~226
시작표지: 8-2-30 그래브 준설선('10, '11년 보완)
끝표지: 8-2-31 쇄암선(중추식)('11년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-31 쇄암선(중추식)('11년 보완)
PDF쪽: 282~283
인쇄쪽: 226~227
시작표지: 8-2-31 쇄암선(중추식)('11년 보완)
끝표지: 8-2-32 이동식 임목파쇄기('07년 신설, '11년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-32 이동식 임목파쇄기('07년 신설, '11년 보완)
PDF쪽: 283~284
인쇄쪽: 227~228
시작표지: 8-2-32 이동식 임목파쇄기('07년 신설, '11년 보완)
끝표지: 8-2-33 하천골재채취선('05년 신설)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-2-33 하천골재채취선('05년 신설)
PDF쪽: 284~285
인쇄쪽: 228~229
시작표지: 8-2-33 하천골재채취선('05년 신설)
끝표지: 8-3 기계손료
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-3 기계손료
PDF쪽: 285
인쇄쪽: 229
시작표지: 8-3 기계손료
끝표지: 8-3-1 [00]토공기계('19년 보완)
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-3-1 [00]토공기계('19년 보완)
PDF쪽: 285~290
인쇄쪽: 229~234
시작표지: 8-3-1 [00]토공기계('19년 보완)
끝표지: 8-3-2 [10]다짐기계
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-3-2 [10]다짐기계
PDF쪽: 290~292
인쇄쪽: 234~236
시작표지: 8-3-2 [10]다짐기계
끝표지: 8-3-3 [20]운반 및 하역기계
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-3-3 [20]운반 및 하역기계
PDF쪽: 292~296
인쇄쪽: 236~240
시작표지: 8-3-3 [20]운반 및 하역기계
끝표지: 8-3-4 [30]포장기계
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-3-4 [30]포장기계
PDF쪽: 296~299
인쇄쪽: 240~243
시작표지: 8-3-4 [30]포장기계
끝표지: 8-3-5 [40]콘크리트기계
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-3-5 [40]콘크리트기계
PDF쪽: 299~301
인쇄쪽: 243~245
시작표지: 8-3-5 [40]콘크리트기계
끝표지: 8-3-6 [50]골재생산기계 등
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-3-6 [50]골재생산기계 등
PDF쪽: 302~310
인쇄쪽: 246~254
시작표지: 8-3-6 [50]골재생산기계 등
끝표지: 8-3-7 [60]기초공사용 기계
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---
@@ -0,0 +1,14 @@
---
문서: 2026 건설공사 표준품셈
: 8-3-7 [60]기초공사용 기계
PDF쪽: 311~315
인쇄쪽: 255~259
시작표지: 8-3-7 [60]기초공사용 기계
끝표지: 8-3-8 [70]기타기계
상태: 대기
작성:
검증:
원천: 글자층
기계검사:
확정지문:
---

Some files were not shown because too many files have changed in this diff Show More