"""mpmdoc.Drawing — 11×17 landscape drawing sheets (DWG). See MPM_Document_Standard.md §9.7. dwg = Drawing(number="DWG-NSH-B17-01", rev="0.1", date="2026-11-06", title="Bay 17 Sign Hanger", subtitle="Mounting arrangement", project="Nashville MCC Bay 17", client="Nashville MCC (WeGo)", location="Nashville, TN", discipline="Mechanical drawing · Mounting", drawn="JS", checked="—", approved="—", slug="Nashville_Bay17_Sign-Hanger", history=[("0.1", "2026-11-06", "Initial issue.")]) dwg.sheet(views=[dwg.view(svg, 1, "Elevation A", "1:10", area="1 / 1 / 3 / 4"), ...], schedule=[("B-1", "Bracket", "6 mm HDG steel", 1)], notes=["All dimensions in mm.", ...], scale="As shown") dwg.build() Each dwg.sheet(...) is one 11×17 page. The view area is a 6-column × 4-row grid; place each view with a CSS grid-area "row-start / col-start / row-end / col-end". Sheet numbers and the title block are automatic. """ import base64 from pathlib import Path from . import brand from .doc import Doc from .units import show_date from . import i18n W_IN, H_IN = 17, 11 CSS = """ @page{size:17in 11in;margin:0} *{box-sizing:border-box} body{margin:0;font-family:'Open Sans',Montserrat,sans-serif;color:var(--ink);-webkit-print-color-adjust:exact} .sheet{width:17in;height:11in;padding:.3in;position:relative;break-after:page;overflow:hidden} .sheet:last-child{break-after:auto} .frame{position:absolute;inset:.3in;border:1.6px solid var(--ink)} .zones{position:absolute;inset:.3in;pointer-events:none} .zh,.zv{position:absolute;font-family:Montserrat;font-weight:700;font-size:7pt;color:var(--mute);display:flex} .zh{left:0;right:0;height:.2in;justify-content:space-around;align-items:center} .zh.t{top:0;border-bottom:1px solid var(--ink)}.zh.b{bottom:0;border-top:1px solid var(--ink)} .zv{top:.2in;bottom:.2in;width:.2in;flex-direction:column;justify-content:space-around;align-items:center} .zv.l{left:0;border-right:1px solid var(--ink)}.zv.r{right:0;border-left:1px solid var(--ink)} .inner{position:absolute;inset:.62in .64in .6in .64in;display:grid;grid-template-columns:1fr 3.35in;grid-template-rows:.62in 1fr;gap:.12in} .hbar{grid-column:1 / 3;display:flex;align-items:center;gap:16px;border-bottom:2px solid var(--gold);padding-bottom:6px} .hbar img{height:.44in} .hbar .disc{font-family:Montserrat;font-weight:800;font-size:10pt;letter-spacing:.14em;text-transform:uppercase;border-left:1.5px solid var(--line);padding-left:16px} .hbar .dno{margin-left:auto;text-align:right;font-family:Montserrat;font-weight:700;font-size:7.5pt;letter-spacing:.12em;color:var(--kick);text-transform:uppercase} .hbar .dno b{display:block;font-family:'JetBrains Mono',Montserrat,monospace;font-size:11pt;color:var(--ink);letter-spacing:0} .views{display:grid;grid-template-columns:repeat(6,1fr);grid-template-rows:repeat(4,1fr);gap:.12in;min-height:0} .view{border:1px solid var(--line);border-radius:4px;display:flex;flex-direction:column;min-height:0;padding:6px 8px 6px} .view .art{flex:1;min-height:0;display:flex;align-items:center;justify-content:center} .view .art svg{max-width:100%;max-height:100%;width:100%;height:100%} .vlab{display:flex;align-items:center;gap:8px;border-top:1px solid var(--line);padding-top:5px;margin-top:4px} .vlab .bub{width:24px;height:24px;border-radius:50%;border:1.6px solid var(--ink);font-family:Montserrat;font-weight:800;font-size:9pt;display:flex;align-items:center;justify-content:center;flex:none} .vlab b{font-family:Montserrat;font-weight:800;font-size:8.5pt;letter-spacing:.08em;text-transform:uppercase;display:block} .vlab small{font-family:'JetBrains Mono',Montserrat,monospace;font-size:7pt;color:var(--mute)} .side{display:flex;flex-direction:column;gap:.1in;min-height:0} .blk{border:1px solid var(--line);border-radius:4px;padding:6px 9px} .blk .kicker{font-size:6.6pt;margin-bottom:4px} .side table{width:100%;border-collapse:collapse;font-size:7.2pt} .side th{font-family:Montserrat;font-weight:700;font-size:6pt;letter-spacing:.1em;text-transform:uppercase;text-align:left;padding:3px 4px;border-bottom:1.5px solid var(--gold)} .side td{padding:2.5px 4px;border-bottom:1px solid var(--line);vertical-align:top} .tag{display:inline-block;min-width:26px;text-align:center;font-family:Montserrat;font-weight:800;font-size:6.6pt;background:var(--gold);border-radius:8px;padding:1px 4px} .notes ol{margin:0;padding-left:15px;font-size:7.2pt}.notes li{margin:1.5px 0} .tb{margin-top:auto;border:1.6px solid var(--ink);border-radius:0;padding:0} .tb .brandrow{display:flex;justify-content:space-between;align-items:center;padding:6px 9px;border-bottom:1px solid var(--ink)} .tb .brandrow img{height:.3in} .tb .brandrow span{font-family:Montserrat;font-weight:600;font-size:6.6pt;color:var(--mute);text-align:right;line-height:1.3} .tb .proj{padding:6px 9px;border-bottom:1px solid var(--ink)} .tb .proj .kicker{font-size:6pt} .tb .proj h1{font-family:Montserrat;font-weight:800;font-size:15pt;line-height:1.05;margin:2px 0 1px} .tb .proj p{margin:0;font-size:7.4pt;color:var(--mute)} .tb .cells{display:grid;grid-template-columns:1fr 1fr 1fr} .tb .cells div{padding:4px 8px;border-bottom:1px solid var(--ink);border-right:1px solid var(--ink)} .tb .cells div:nth-child(3),.tb .cells div:nth-child(6),.tb .cells div:nth-child(8),.tb .cells div:nth-child(10){border-right:none} .tb .cells .w2{grid-column:span 2} .tb .cells b{display:block;font-family:Montserrat;font-weight:700;font-size:5.6pt;letter-spacing:.12em;text-transform:uppercase;color:var(--mute)} .tb .cells span{font-family:'JetBrains Mono',Montserrat,monospace;font-size:8pt;font-weight:700} .tb .revs2{padding:4px 8px;font-size:6.8pt;border-bottom:1px solid var(--ink)} .tb .revs2 .kicker{font-size:5.6pt;margin-bottom:1px} .tb .revs2 div{display:flex;gap:6px}.tb .revs2 code{font-family:'JetBrains Mono',Montserrat,monospace;font-weight:700} .tb .conf{background:var(--ink);color:#fff;display:flex;justify-content:space-between;align-items:center;padding:5px 9px;font-size:6.4pt} .tb .conf em{font-style:normal;font-family:Montserrat;font-weight:700;color:var(--gold-light,#F5CD15)} """ class Drawing(Doc): def __init__(self, number, rev, date, title, subtitle, project, client, slug, history, location="", discipline="Mechanical drawing", drawn="JS", checked="—", approved="—", classification=None, lang="en"): super().__init__(number=number, rev=rev, date=date, title=title, lede=subtitle, meta=[("Project", project), ("Client", client)], slug=slug, history=history, customer=client, classification=classification, lang=lang) if self.type != "DWG": raise ValueError("Drawing numbers must start with DWG-") import inspect self.src_dir = Path(inspect.stack()[1].filename).resolve().parent self.subtitle, self.project, self.client, self.location = subtitle, project, client, location self.discipline, self.drawn, self.checked, self.approved = discipline, drawn, checked, approved self.sheets = [] # ---- building blocks ---------------------------------------------------- def view(self, svg, n, title, scale="N.T.S.", area="1 / 1 / 5 / 7"): sep = ":" if self.lang == "zh" else ": " return (f'
| {L("Tag")} | {L("Designation")} | {L("Description")} | {L("Qty")} |
|---|
{r}{D(d)}{t}{self.subtitle}