Files
dela 866173a831 Add source linter, negative test fixtures, and fallback guidance
- scripts/lint.py: reject raw rectangles, absolute coordinates, hue-budget
  and callout/group/formula-order violations at the source level
- tests/invalid/ + tests/lint-invalid/: negative fixtures proving the
  package and linter reject bad input; test.sh now runs both directions
- references/fallback.md: degraded path when no LaTeX is available
- tests/group-callout.tex: exercise \stgroup and \stcallout
- agents/openai.yaml: agent config
- Docs and .sty updated to match
2026-08-05 16:41:22 +08:00

86 lines
3.6 KiB
TeX

% Anti-pattern gallery -- four ways to draw a figure that compiles cleanly and
% still teaches the reader something false. Left of each pair is wrong.
% ../scripts/build.sh antipatterns.tex
% supertensor-lint: allow-absolute, allow-missing-formula
\documentclass[border=10pt]{standalone}
\usepackage[cjk]{supertensor}
\stsetrole{k}{stOrange}
\stsetrole{r1}{stTeal}
\stsetrole{r2}{stCoral}
\stsetrole{idx}{stViolet}
\stsetrole{act}{stTeal}
\stdim{T}{5}
\stdim{dh}{3}
\stdim{d}{6}
\stdim{k}{2}
\newcommand{\bad}[1]{{\color{stCoral}$\times$}\;#1}
\newcommand{\good}[1]{{\color{stTeal}$\checkmark$}\;#1}
\begin{document}
\begin{tikzpicture}
% ------------------------------------------------------------- pair 1 + 2 ---
\node[st stage, anchor=north west] (S1) at (0,0) {(1) 转置只改了标签};
\coordinate (p1) at ($(S1.west)+(1.0,-1.7)$);
% WRONG: same face as K, relabelled. The reader cannot see the contracted axis.
\stface[role=k, bracket=true]{A1}{(p1)}{T}{dh}
\stface[role=k, bracket=true]{A2}{($(A1.east)+(2.2,0)$)}{dh}{T}
\node[st stage, anchor=north west] (S2) at ($(S1.west)+(7.6,0)$) {(2) 分片没有铺满母体};
\coordinate (p2) at ($(S2.west)+(1.0,-1.7)$);
% WRONG: a gap between the shards. The parent's width is now a lie.
\stface[role=r1]{B1a}{(p2)}{T}{dh}
\stface[role=r2]{B1b}{($(B1a.east)+(2.6*\stunit,0)$)}{T}{dh}
\stface[role=r1]{B2a}{($(B1b.east)+(2.4,0)$)}{T}{dh}
\stface[role=r2]{B2b}{($(B2a.east)+(1.5*\stunit,0)$)}{T}{dh}
\node[inner sep=0pt, fit=(A1)(A2)(B1a)(B2b)] (row1) {};
\stlane{row1}
\stcaption{A1}{\bad{$\mathbf K^{\top}$}}{面仍是 $T\times d_h$}
\stcaption{A2}{\good{$\mathbf K^{\top}$}}{面已换成 $d_h\times T$}
\stcaption{B1a}{\bad{$[\mathbf W^{(1)}\mid\mathbf W^{(2)}]$}}{中间凭空多出空隙}
\stcaption{B2a}{\good{$[\mathbf W^{(1)}\mid\mathbf W^{(2)}]$}}{两片正好铺满}
\stnolane
% ------------------------------------------------------------- pair 3 + 4 ---
\coordinate (y2) at ($(A1-shape.south)+(0,-10mm)$);
\node[st stage, anchor=north west] (S3) at (S1.west |- y2) {(3) 索引画成了热力图};
\coordinate (p3) at ($(S3.west)+(1.0,-1.6)$);
% WRONG: a lightness ramp on an index invites `expert 3 > expert 0'.
\stface[role=idx]{C1}{(p3)}{T}{k}
\stindexface[role=idx]{C2}{($(C1.east)+(2.4,0)$)}{T}{k}{0,1, 1,2, 2,3, 3,0, 0,2}
\node[st stage, anchor=north west] (S4) at (S2.west |- y2) {(4) 全图一个色阶};
\coordinate (p4) at ($(S4.west)+(1.0,-1.6)$);
% WRONG: one pale level everywhere -- nothing is legible at thumbnail size.
\stface[role=act, pattern=solid, level=1]{D1}{(p4)}{T}{d}
\stface[role=act]{D2}{($(D1.east)+(2.6,0)$)}{T}{d}
\node[inner sep=0pt, fit=(C1)(C2)(D1)(D2)] (row2) {};
\stlane{row2}
\stcaption{C1}{\bad{$\mathcal I$}}{深浅暗示大小可比}
\stcaption{C2}{\good{$\mathcal I$}}{离散符号,无色阶}
\stcaption{D1}{\bad{$\mathbf X$}}{只有一档淡色}
\stcaption{D2}{\good{$\mathbf X$}}{三档亮度,非周期}
\stnolane
% ============================================================== meaning box ==
\node[inner sep=0pt, fit=(S1)(row1)(row2)(D2-shape)(B2a-shape)] (all) {};
\stmeaningbox{mb}{16.2cm}{all}
{}
{四张“错图”都能干净编译。编译器只检查 \TeX{} 的语法,不检查图讲的事情对不对,
所以交付前必须按 \texttt{references/checklist.md} 做一次人眼审图}
{(1) 转置要物理交换面宽高;(2) 分片必须精确铺满母体,省略要画省略号;
(3) 索引、掩码、数值是三套画法;(4) 亮度分档是对比度的来源,不是饱和度}
\stsignature{反面示例:编译通过但讲错的四种画法}{mb}
\end{tikzpicture}
\end{document}