MPM Documentation Kit v1.3 (CW-034)

MPM Document Standard 1.3, mpmdoc build engine, templates for TN, INS, SOP,
BOM, SVY, TAP, DWG, TSB, PRO, SOW and WO (Chinese editions for TN and DWG),
glossary, MPM fonts and logos, and the mpm-technical-documents plugin 1.3.0.
Worked examples ship in the kit zip on Drive only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NWatTMmqmGatgHjDZvWs5b
This commit is contained in:
Jason StedwellandClaude Opus 5.5 committed 2026-11-09 11:51:56 -06:00
commit 5b52636003
143 files changed
+4097

No files matched your search

Binary file not shown.
+50
View File
@@ -0,0 +1,50 @@
"""TEMPLATE — Drawing sheet (DWG), 11×17 landscape. Copy this folder to <PROJECT>/source/ and fill it in.
Mechanical, mounting, cable or fit-out drawings someone will fabricate or approve from.
See MPM_Document_Standard.md §9.7. Each dwg.sheet(...) is one page; the title block, sheet numbers,
zone grid, revision history and confidentiality strip are automatic.
View area = 6 columns × 4 rows. Place each view with area="row-start / col-start / row-end / col-end"
(e.g. "1 / 1 / 5 / 3" = full height, left third).
"""
import sys, pathlib
HERE = pathlib.Path(__file__).resolve().parent
sys.path.insert(0, str(next(p / "_STANDARDS" for p in HERE.parents if (p / "_STANDARDS").is_dir())))
from mpmdoc import Drawing
from figs import FIGS
F = {k: f() for k, f in FIGS.items()}
dwg = Drawing(
number="DWG-MPM-SUBJ-01", rev="0.1", date="2026-11-06",
title="Wall-Plate Sign Bracket",
subtitle="Mounting bracket, general arrangement",
project="Project name", client="Customer", location="City, ST",
discipline="Mechanical drawing · Mounting",
drawn="JS", checked="—", approved="—",
slug="Customer_Sign-Bracket_GA",
history=[("0.1", "2026-11-06", "Initial issue for review.")],
)
dwg.sheet(
views=[
dwg.view(F["elevation"], 1, "Elevation · wall plate", "1:4", area="1 / 1 / 5 / 3"),
dwg.view(F["section"], 2, "Section A · side", "1:4", area="1 / 3 / 4 / 7"),
dwg.view(F["detail"], 3, "Detail B · anchor", "1:1", area="4 / 3 / 5 / 5"),
],
schedule=[ # (tag, designation, description, qty)
("B-1", "Wall plate", "6 mm HDG steel, 200 × 300", 1),
("A-1", "Arm", "60 × 60 × 4 SHS, HDG, 400 long", 1),
("F-1", "Anchor", "M12 wedge anchor, A4 stainless", 4),
],
notes=[
"All dimensions in mm unless noted. Do not scale from drawing.",
"Hot-dip galvanize all steel after fabrication.",
"Confirm wall / post construction before drilling.",
"Sign and its hanging hardware supplied by others.",
],
scale="As shown",
)
dwg.build()
+62
View File
@@ -0,0 +1,62 @@
"""TEMPLATE — Drawing sheet, Simplified Chinese edition (图纸 · 中文版).
Copy next to the English build.py in <PROJECT>/source/. See MPM_Document_Standard.md §12.
Rules:
* Same number, slug, revision, sheets and views as build.py; figs.py is shared. Build English first:
the engine refuses to build the _ZH file without the English PDF at this revision.
* Dimensions mm first, imperial in [ ]: if figs.py formats dimensions through a function F, replace it
here before drawing the figures (figs functions read F at call time).
* Figure text goes through i18n.Translator (TERMS, then _STANDARDS/glossary_zh.md); tr.check() fails the
build on any English left. Tags (B-1), part numbers, standards and place names stay in Latin script.
* The frame (title block, schedule and notes headings, dates) is translated by the engine; the
"英文版为准" note is added to each sheet's notes unless you place it yourself.
"""
import sys, pathlib
HERE = pathlib.Path(__file__).resolve().parent
sys.path.insert(0, str(next(p / "_STANDARDS" for p in HERE.parents if (p / "_STANDARDS").is_dir())))
sys.path.insert(0, str(HERE))
from mpmdoc import Drawing, i18n
from figs import FIGS
TERMS = { # this document's figure phrases (single terms: glossary)
"WALL / POST": "墙体 / 立柱",
"SIGN (BY OTHERS)": "显示屏(他方供货)",
"M12 ANCHOR · SEE SCHEDULE": "M12 锚栓 · 见部件表",
}
tr = i18n.Translator(TERMS)
F = {k: tr.svg(f()) for k, f in FIGS.items()}
tr.check()
dwg = Drawing(
number="DWG-MPM-SUBJ-01", rev="0.1", date="2026-11-06", lang="zh",
title="墙板式显示屏支架",
subtitle="安装支架总图",
project="项目名称", client="Customer", location="城市, 州",
discipline="机械图纸 · 安装",
drawn="JS", checked="—", approved="—",
slug="Customer_Sign-Bracket_GA", # identical to the English slug
history=[("0.1", "2026-11-06", "首次发布,供审核。")],
)
dwg.sheet(
views=[
dwg.view(F["elevation"], 1, "立面 · 墙板", "1:4", area="1 / 1 / 5 / 3"),
dwg.view(F["section"], 2, "剖面 A · 侧视", "1:4", area="1 / 3 / 4 / 7"),
dwg.view(F["detail"], 3, "详图 B · 锚栓", "1:1", area="4 / 3 / 5 / 5"),
],
schedule=[
("B-1", "墙板", "6 mm 热镀锌钢板,200 × 300", 1),
("A-1", "悬臂", "60 × 60 × 4 方钢管,热镀锌,长 400", 1),
("F-1", "锚栓", "M12 膨胀锚栓,A4 不锈钢", 4),
],
notes=[
"除注明外尺寸单位为 mm。请勿从图纸量取尺寸。",
"所有钢件加工完成后热镀锌。",
"钻孔前确认墙体 / 立柱结构。",
"显示屏及其吊挂件由他方供货。",
],
scale="As shown",
)
dwg.build()
+78
View File
@@ -0,0 +1,78 @@
"""TEMPLATE figures for a DWG sheet: a generic wall-plate sign bracket in three views.
Drafting conventions: ink linework, centrelines in Dark Gold (long-dash-dot), hidden lines dashed,
dimensions in mm (JetBrains Mono), schedule tags as gold bubbles. One mm = SCALE px."""
from mpmdoc.figkit import T, svg_open, dim_h, dim_v, tag, INK, KICK, MUTE, CREAM
S = 0.9 # px per mm in these views
PLATE_W, PLATE_H, T_PL = 200, 300, 10
HOLE_X, HOLE_Y, HOLE_D = 150, 250, 14
ARM_L, ARM_H = 400, 60
def _cl(x1, y1, x2, y2):
return f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" stroke="{KICK}" stroke-width=".8" stroke-dasharray="14 3 2 3"/>'
def elevation():
"""Front view of the wall plate with the four anchor holes."""
W, H = 360, 420
ox, oy = 80, 50
pw, ph = PLATE_W * S, PLATE_H * S
o = [svg_open(W, H, grid=True)]
o.append(f'<rect x="{ox}" y="{oy}" width="{pw}" height="{ph}" fill="{CREAM}" stroke="{INK}" stroke-width="1.4"/>')
cx, cy = ox + pw / 2, oy + ph / 2
for dx in (-HOLE_X / 2, HOLE_X / 2):
for dy in (-HOLE_Y / 2, HOLE_Y / 2):
o.append(f'<circle cx="{cx + dx * S}" cy="{cy + dy * S}" r="{HOLE_D / 2 * S}" fill="#fff" stroke="{INK}" stroke-width="1.1"/>')
o.append(_cl(cx, oy - 14, cx, oy + ph + 14) + _cl(ox - 14, cy, ox + pw + 14, cy))
o.append(f'<rect x="{cx - ARM_H / 2 * S}" y="{cy - ARM_H / 2 * S}" width="{ARM_H * S}" height="{ARM_H * S}" fill="none" stroke="{INK}" stroke-width="1" stroke-dasharray="4 3"/>')
o.append(dim_h(ox, ox + pw, oy + ph + 34, f"{PLATE_W}", ext_from=oy + ph))
o.append(dim_h(cx - HOLE_X / 2 * S, cx + HOLE_X / 2 * S, oy - 22, f"{HOLE_X}", ext_from=oy + (PLATE_H - HOLE_Y) / 2 * S))
o.append(dim_v(ox - 30, oy, oy + ph, f"{PLATE_H}", ext_from=ox))
o.append(dim_v(ox + pw + 30, cy - HOLE_Y / 2 * S, cy + HOLE_Y / 2 * S, f"{HOLE_Y}", ext_from=cx + HOLE_X / 2 * S))
o.append(tag(ox + pw + 52, oy + 18, "B-1"))
o.append(T(ox + pw - 4, oy + ph - 8, f"4× Ø{HOLE_D} THRU", size=7.5, w=700, anchor="end", ls=.6))
o.append("</svg>")
return "".join(o)
def section():
"""Side section: plate, arm and sign hanging point."""
W, H = 640, 420
ox, oy = 70, 50
ph = PLATE_H * S
o = [svg_open(W, H, grid=True)]
o.append(f'<rect x="{ox - 18}" y="{oy - 30}" width="18" height="{ph + 60}" fill="url(#fh)" stroke="{INK}" stroke-width="1"/>')
o.append(T(ox - 26, oy - 36, "WALL / POST", size=7, w=700, fill=MUTE, ls=1))
o.append(f'<rect x="{ox}" y="{oy}" width="{T_PL * S}" height="{ph}" fill="{CREAM}" stroke="{INK}" stroke-width="1.4"/>')
ay = oy + ph / 2 - ARM_H / 2 * S
o.append(f'<rect x="{ox + T_PL * S}" y="{ay}" width="{ARM_L * S}" height="{ARM_H * S}" fill="#fff" stroke="{INK}" stroke-width="1.4"/>')
ex = ox + T_PL * S + ARM_L * S
o.append(f'<line x1="{ex - 30}" y1="{ay + ARM_H * S}" x2="{ex - 30}" y2="{ay + ARM_H * S + 60}" stroke="{INK}" stroke-width="1.2"/>')
o.append(f'<rect x="{ex - 130}" y="{ay + ARM_H * S + 60}" width="200" height="70" rx="3" fill="{INK}"/>')
o.append(T(ex - 30, ay + ARM_H * S + 100, "SIGN (BY OTHERS)", size=7.5, w=700, fill="#fff", anchor="middle", ls=1))
o.append(_cl(ox - 30, oy + ph / 2, ex + 30, oy + ph / 2))
o.append(dim_h(ox, ex, oy - 16, f"{T_PL + ARM_L}", ext_from=ay))
o.append(dim_v(ex + 26, ay, ay + ARM_H * S, f"{ARM_H}", ext_from=ex))
o.append(tag(ox + 40, ay - 16, "A-1") + tag(ox + 4, oy + ph + 16, "B-1"))
o.append("</svg>")
return "".join(o)
def detail():
"""Detail: anchor at the plate, enlarged."""
W, H = 300, 220
o = [svg_open(W, H, grid=True)]
o.append(f'<rect x="40" y="30" width="40" height="160" fill="url(#fh)" stroke="{INK}"/>')
o.append(f'<rect x="80" y="40" width="22" height="140" fill="{CREAM}" stroke="{INK}" stroke-width="1.3"/>')
o.append(f'<rect x="20" y="102" width="150" height="16" fill="#fff" stroke="{INK}" stroke-width="1.1"/>')
o.append(f'<rect x="102" y="92" width="8" height="36" fill="{CREAM}" stroke="{INK}"/>')
o.append(f'<polygon points="110,96 126,96 126,124 110,124" fill="#fff" stroke="{INK}"/>')
o.append(_cl(10, 110, 190, 110))
o.append(tag(150, 70, "F-1") + f'<line x1="142" y1="76" x2="122" y2="98" stroke="{INK}" stroke-width=".7"/>')
o.append(T(150, 200, "M12 ANCHOR · SEE SCHEDULE", size=7, w=700, anchor="middle", fill=MUTE, ls=.8))
o.append("</svg>")
return "".join(o)
FIGS = {"elevation": elevation, "section": section, "detail": detail}