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:
143 files changed
+4097
No files matched your search
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,72 @@
|
||||
"""TEMPLATE — Technical Note (TN). Copy this folder to <PROJECT>/source/ and fill it in.
|
||||
|
||||
A TN answers ONE engineering question (does it fit, how much power, is a cut needed)
|
||||
and puts the answer first. 1–3 pages. See MPM_Document_Standard.md §9.3.
|
||||
|
||||
Order (do not reorder):
|
||||
masthead (automatic) → KPI tiles → Result → evidence sections (tables, calc, figures)
|
||||
→ Assumptions and open items → Revision history (automatic)
|
||||
"""
|
||||
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 Doc, KeyRow, up, dn
|
||||
from figs import FIGS, MEASURED, LIMIT # keep every number in ONE place (figs.py) and derive the rest
|
||||
|
||||
F = {k: f() for k, f in FIGS.items()}
|
||||
MARGIN = LIMIT - MEASURED
|
||||
|
||||
doc = Doc(
|
||||
number="TN-MPM-SUBJ-01", # TYPE-CUST-SUBJ-NN · register CUST + number in registry.md
|
||||
rev="0.1", # 0.x = Draft · 1.0 = first release
|
||||
date="2026-11-05", # ISO in source; displayed as "Nov 5, 2026"
|
||||
customer=None, # None = name from the CUST code; override for a fuller name
|
||||
subject="Subject", # short: the thing studied ("Bay 17", "Pingo P2.5 LED module")
|
||||
title="Question-Shaped Title: The Thing Being Checked",
|
||||
lede=("Two to three sentences: the situation, and what this note works out. "
|
||||
"Write it so someone who reads only this paragraph knows why the note exists."),
|
||||
meta=[("Site", "Where / what"), ("Requirement", "The criterion · e.g. ≤ 60 W")], # exactly two cells
|
||||
slug="Customer_Short-Title", # → TN-MPM-SUBJ-01_Customer_Short-Title_Rev0.1.pdf
|
||||
history=[("0.1", "2026-11-05", "Initial draft.")],
|
||||
)
|
||||
|
||||
doc.add(
|
||||
# 3–4 tiles: the input(s), THE ANSWER (tone="key"), and the verdict (tone="ok"/"bad")
|
||||
doc.kpis([
|
||||
("Measured", f"{MEASURED:.1f} W", "How it was measured"),
|
||||
("Limit", f"{LIMIT:.1f} W", "Where the limit comes from", "strong"),
|
||||
("Margin", f"{MARGIN:+.1f} W", "Limit − measured", "ok" if MARGIN >= 0 else "bad"),
|
||||
]),
|
||||
# 2–4 bullets. First bullet = the answer, with the number in bold. Then conditions / what to do.
|
||||
doc.result([
|
||||
f"The answer in one sentence, with the key value in <b>bold ({MEASURED:.1f} W)</b>.",
|
||||
"The condition the answer depends on, and what changes if it doesn't hold.",
|
||||
]),
|
||||
|
||||
doc.section("Comparison"),
|
||||
doc.table(
|
||||
[("Item", ""), ("Value", "m r"), ("Change", "d r"), ("Notes", "")],
|
||||
[
|
||||
["Row", "1.0", up("+1.0"), "Source of the number"],
|
||||
KeyRow(["<b>The row that matters</b>", "2.0", dn("−0.5"), "Highlight max. one row"]),
|
||||
],
|
||||
caption="What the table shows, units, and the datum.", ref="cmp"),
|
||||
|
||||
doc.section("Calculation"),
|
||||
doc.calc([
|
||||
"# One comment line per step, saying why",
|
||||
("Margin", "limit − measured = {:.1f} − {:.1f}".format(LIMIT, MEASURED), f"{MARGIN:+.1f} W",
|
||||
"PASS" if MARGIN >= 0 else "FAIL"),
|
||||
]),
|
||||
|
||||
doc.section("Figure"),
|
||||
doc.figure(F["bars"], "Caption says what to look at, not just what it is. Refer to it in text as [[fig:bars]].", ref="bars"),
|
||||
|
||||
doc.assumptions(
|
||||
["Every assumption the answer rests on, one per bullet."],
|
||||
["Everything still to confirm, phrased as an action (Confirm …, Add …)."],
|
||||
),
|
||||
)
|
||||
|
||||
doc.build()
|
||||
@@ -0,0 +1,76 @@
|
||||
"""TEMPLATE — Technical Note, Simplified Chinese edition (技术说明 · 中文版).
|
||||
Copy next to the English build.py in <PROJECT>/source/. See MPM_Document_Standard.md §12.
|
||||
|
||||
Rules:
|
||||
* Same number, slug, revision and figures as build.py; the engine adds _ZH to the file name and refuses
|
||||
to build until the English PDF at this revision is in the project folder. Build English first.
|
||||
* Translate every string here, in the same order as build.py, so the two can be compared side by side.
|
||||
* Figure text goes through i18n.Translator: this document's TERMS first, then _STANDARDS/glossary_zh.md.
|
||||
tr.check() fails the build on any English left in a figure.
|
||||
* Numbers come from figs.py exactly as in English. Metric first, imperial in [ ].
|
||||
* The masthead carries "英文版为准" (English governs) automatically.
|
||||
"""
|
||||
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 Doc, KeyRow, up, dn, i18n
|
||||
from figs import FIGS, MEASURED, LIMIT
|
||||
|
||||
MARGIN = LIMIT - MEASURED
|
||||
|
||||
TERMS = { # this document's figure phrases (single terms: glossary)
|
||||
f"LIMIT · {LIMIT:.1f} W": f"限值 · {LIMIT:.1f} W",
|
||||
}
|
||||
tr = i18n.Translator(TERMS)
|
||||
F = {k: tr.svg(f()) for k, f in FIGS.items()}
|
||||
tr.check()
|
||||
|
||||
doc = Doc(
|
||||
number="TN-MPM-SUBJ-01", rev="0.1", date="2026-11-05", lang="zh",
|
||||
customer="客户名称", subject="主题",
|
||||
title="以问题为标题:被核查的对象",
|
||||
lede="两到三句话:现状,以及本说明要解决的问题。只读这一段的人也应知道本说明的目的。",
|
||||
meta=[("地点", "位置 / 对象"), ("要求", "判定标准 · 例如 ≤ 60 W")],
|
||||
slug="Customer_Short-Title", # identical to the English slug
|
||||
history=[("0.1", "2026-11-05", "初稿。")],
|
||||
)
|
||||
|
||||
doc.add(
|
||||
doc.kpis([
|
||||
("实测", f"{MEASURED:.1f} W", "测量方法"),
|
||||
("限值", f"{LIMIT:.1f} W", "限值来源", "strong"),
|
||||
("余量", f"{MARGIN:+.1f} W", "限值 − 实测", "ok" if MARGIN >= 0 else "bad"),
|
||||
]),
|
||||
doc.result([
|
||||
f"一句话结论,关键数值加粗 <b>({MEASURED:.1f} W)</b>。",
|
||||
"结论成立的前提条件,以及条件不满足时的变化。",
|
||||
]),
|
||||
|
||||
doc.section("对比"),
|
||||
doc.table(
|
||||
[("项目", ""), ("数值", "m r"), ("变化", "d r"), ("备注", "")],
|
||||
[
|
||||
["行", "1.0", up("+1.0"), "数据来源"],
|
||||
KeyRow(["<b>关键行</b>", "2.0", dn("−0.5"), "最多突出一行"]),
|
||||
],
|
||||
caption="表格内容、单位及基准。", ref="cmp"),
|
||||
|
||||
doc.section("计算"),
|
||||
doc.calc([
|
||||
"# 每步一行注释,说明原因",
|
||||
("余量", "限值 − 实测 = {:.1f} − {:.1f}".format(LIMIT, MEASURED), f"{MARGIN:+.1f} W",
|
||||
"PASS" if MARGIN >= 0 else "FAIL"),
|
||||
]),
|
||||
|
||||
doc.section("图示"),
|
||||
doc.figure(F["bars"], "图注说明应关注的内容。正文中引用为 [[fig:bars]]。", ref="bars"),
|
||||
|
||||
doc.assumptions(
|
||||
["结论所依据的每项假设,每条一项。"],
|
||||
["所有待确认事项,以动作表述(确认……、补充……)。"],
|
||||
),
|
||||
)
|
||||
|
||||
doc.build()
|
||||
@@ -0,0 +1,31 @@
|
||||
"""TEMPLATE figures for a TN. Keep the source numbers here; build.py imports them.
|
||||
Each figure is a function returning an SVG string; register it in FIGS."""
|
||||
from mpmdoc.figkit import T, svg_open, INK, KICK, MUTE, LINE, RED, GRY
|
||||
|
||||
# ---- source numbers (one place only) ----
|
||||
MEASURED = 51.0
|
||||
LIMIT = 63.8
|
||||
|
||||
|
||||
def bars():
|
||||
W, L, R, top, rowh = 700, 150, 640, 30, 30
|
||||
rows = [("Measured", MEASURED, INK), ("Reference", 20.4, GRY)]
|
||||
vmax = 70.0
|
||||
x = lambda v: L + v * (R - L) / vmax
|
||||
bot = top + rowh * len(rows)
|
||||
o = [svg_open(W, bot + 30)]
|
||||
for v in range(0, 71, 10):
|
||||
o.append(f'<line x1="{x(v):.1f}" y1="{top-6}" x2="{x(v):.1f}" y2="{bot}" stroke="{LINE}" stroke-width="0.8"/>')
|
||||
o.append(T(x(v), bot + 14, v, size=7.4, w=500, fill=MUTE, anchor="middle", fam="JetBrains Mono", ls=0))
|
||||
o.append(f'<line x1="{x(LIMIT):.1f}" y1="{top-14}" x2="{x(LIMIT):.1f}" y2="{bot}" stroke="{RED}" stroke-width="1.4" stroke-dasharray="5 3"/>')
|
||||
o.append(T(x(LIMIT), top - 18, f"LIMIT · {LIMIT:.1f} W", size=6.8, w=800, fill=RED, anchor="middle", ls=1.0))
|
||||
for i, (name, v, c) in enumerate(rows):
|
||||
cy = top + i * rowh + rowh / 2
|
||||
o.append(T(L - 10, cy + 3, name, size=8.2, anchor="end"))
|
||||
o.append(f'<rect x="{L}" y="{cy-8.5:.1f}" width="{x(v)-L:.1f}" height="17" rx="2" fill="{c}"/>')
|
||||
o.append(T(x(v) + 6, cy + 3.2, f"{v:.1f} W", size=8.6, w=700, fam="JetBrains Mono", ls=0, halo=True))
|
||||
o.append("</svg>")
|
||||
return "".join(o)
|
||||
|
||||
|
||||
FIGS = {"bars": bars}
|
||||
Reference in new issue
Block a user