uzoncalc-writer

star 2

使用 uzoncalc 以编写 python 代码的方式创建工程计算书,实现公式自动计算、自动排版、自动渲染 HTML 文档等功能

uyoufu By uyoufu schedule Updated 5/27/2026

name: uzoncalc-writer description: 使用 uzoncalc 以编写 python 代码的方式创建工程计算书,实现公式自动计算、自动排版、自动渲染 HTML 文档等功能

uzoncalc-writer skill

UzonCalc 是一个基于 Python 的工程计算书生成工具。通过在 async def 函数中编写计算逻辑,UzonCalc 能自动捕获变量赋值、公式推导过程,并渲染为带目录、数学公式、表格、图表的 HTML 计算书。

在编写计算书时,应从专业高级设计工程师的角度,以工程计算算单为风格,以直接交付为目标进行编写。

最小模板示例

from uzoncalc import *

@uzon_calc()
async def sheet():
    doc_title("计算书标题")

    H1("示例章节")
    "这是一段说明文字。"

    a = 10 * unit.meter
    b = 5 * unit.meter
    c = a + b # 自动渲染公式:c = a + b = 15 m

if __name__ == "__main__":
    ctx = run_sync(sheet)
    ctx.save("output.html")   # 也可在函数外保存

核心规则

规则 说明
函数必须 async def @uzon_calc() 仅支持异步函数
字符串字面量即段落 函数体内裸字符串 "文本" / """多行""" 作为段落输出
变量赋值自动渲染 x = expr 被捕获并渲染为数学公式 x = expr = 值
变量名用 camelCase _ 被解析为下标(H_2 → H₂),避免用下划线命名变量
希腊字母自动转换 alpha→α,Beta→Β,首字母大写得大写希腊字母
纯函数调用不会插桩输出调用过程 f(x) 不会渲染为 f(x),而是直接调用

可用规则文档

文档结构

用于定义文档的结构和布局。

doc_title("页眉标题")      # 设置页面/打印页眉标题
page_size("A4")            # 页面大小:A4、A3、Letter 等
toc("目录")                # 在当前位置插入目录(自动编号)
font_family("Arial")       # 设置字体

H1("一级标题")             # H1~H6 对应六级标题,自动带有编号
H2("二级标题")
H3("三级标题")

Br()                       # 插入空行
Info("提示信息")           # 蓝色信息框
Code("代码", "python")     # 代码块,支持语法高亮
P("段落")                  # 显式段落(等价于裸字符串)

HTML 元素

可以使用以下预定义的函数,简化 HTML 内容的生成。其中,以小写字母开头的函数会返回 HTML 结果,而以大写字母开头的函数会直接渲染到文档中。

# 小写函数:返回 HTML 字符串,适合组合嵌套内容
content = div(
    [
        h2("截面参数"),
        p("以下参数用于承载力验算。"),
        span("重要", classes="text-red-600 font-bold"),
    ],
    classes="border p-2",
)
P(content)

# 大写函数:直接追加到当前文档
H1("设计依据")
P("本节列出主要设计参数。")
Div(
    [
        h3("材料"),
        p("混凝土强度等级为 C50。"),
    ],
    classes="bg-gray-50 p-3",
)

常用 HTML 元素如下:

函数 说明
h(tag, children, ...) 通用 HTML 构造器,children 支持字符串或字符串列表
h1h6 / H1H6 标题元素,小写返回字符串,大写直接渲染
title / Title 文档大标题,默认居中、加粗、大字号
subtitle / Subtitle 文档副标题,默认居中、加粗
p / P 段落
div / Div 块级容器
span / Span 行内容器
row / Row 行容器,默认渲染为 div,可通过 tag 指定标签
br / Br 换行,自闭合元素
img / Img 图片,支持 altwidthheight
input / Input 输入元素,当前主要用于生成带 value 的 HTML 输入标签
code / Code 代码块,language 会生成 language-python 等高亮类名
info / Info 蓝色提示框
laTex / LaTex 原始 LaTeX 内容标签
plot / Plot Matplotlib 图像或 PNG 二进制内容转为内嵌 base64 图片

属性与样式使用 classesprops()

# classes 会写入 HTML class 属性,适合 Tailwind/页面样式类
P("控制性参数", props=props(id="control-params"))
Div("验算通过", classes="text-green-700 font-bold")

# props 支持 id、classes、styles,并将自定义属性中的下划线转为短横线
P(
    "带自定义属性的段落",
    props=props(
        id="note-1",
        classes="text-sm",
        styles={"color": "#444", "margin-top": "8px"},
        data_value="section-note",
        aria_label="说明段落",
    ),
)

# 当同时传入 classes 和 props.classes 时,函数参数 classes 优先
Div(
    "最终使用 text-blue-700",
    classes="text-blue-700",
    props=props(classes="text-red-700"),
)

复杂内容建议先用小写函数组合,再用大写函数渲染:

parameterPanel = div(
    [
        h3("几何参数"),
        p(f"梁高:{beamHeight}"),
        p(f"梁宽:{beamWidth}"),
        info("单位统一采用 SI 制。"),
    ],
    classes="my-3 p-3 border",
)
P(parameterPanel)

插入图片、代码、LaTeX 与 Matplotlib 图:

Img("assets/section.png", alt="截面示意图", width=480)
Code(
    """
    stress = force / area
    """,
    language="python",
)
LaTex(r"\sigma = \frac{N}{A}")

import matplotlib.pyplot as plt

hide()
fig, ax = plt.subplots()
ax.plot([0, 1, 2], [0, 1, 4])
show()
Plot(fig, width=520)

注意:

  • HTML 内容不会自动转义 children,用户输入或外部文本应先自行清洗后再拼入 HTML。
  • children 列表会按顺序直接拼接,适合嵌套由 p()div()span() 等返回的 HTML 片段。
  • img() 会额外包一层居中容器;设置 alt 时会在图片下方显示说明文字。
  • Plot() 支持 Matplotlib savefig 对象,也支持 PNG 二进制数据;普通文件路径图片使用 Img()

变量与公式

变量名参考 linux 风格缩写,变量名不宜过长。

# 普通变量赋值(自动渲染公式)
force = 100 * unit.newton
area = 2 * unit.meter**2
stress = force / area

# 别名(用于中文变量名或复杂下标)
alias("rhoWater", "ρ_水")
rhoWater = 1000 * unit.kilogram / unit.meter**3
alias("rhoWater", None)    # 传 None 移除别名

# f-string:默认只显示结果
f"应力为 {stress}。"

# 启用后同时显示公式和结果
enable_fstring_equation()
f"应力为 {stress}。"
disable_fstring_equation()

# 海象运算符在 f-string 中赋值
f"面积 = {(A := 3 * unit.meter**2)}"

单位

from uzoncalc import unit

l = 5 * unit.meter
f = 100 * unit.newton
p = f / (l * l)              # 自动单位运算
v = l.to(unit.centimeter)    # 单位换算

# 常用单位:meter/m、kilogram/kg、newton/N、MPa、kN、second/s、hour、kilometer/km 等
# 完整列表见 pint 文档

控制渲染

hide()                       # 后续内容不输出到文档
def helper(): ...            # 辅助函数定义,不渲染
show()                       # 恢复渲染

inline()                     # 后续元素内联排列
x = 1; y = 2
endInline()                    # 结束内联

enable_substitution()        # 开启变量值代入(默认开启)
disable_substitution()       # 关闭代入(仅显示符号公式)

表格

Table(
    headers=[                           # 表头支持多行、th 合并单元格
        [
            th("构件", rowspan=2),
            th("材料", rowspan=2),
            th("弹性模量 (MPa)", colspan=2),
        ],
        ["Ec", "Es"],
    ],
    rows=[                              # 二维列表表示多行
        ["盖梁", "C60", 36000, 34500],
        ["墩柱", "C50", 34500, 32500],
    ],
    title="材料参数",
)

# Td 可设置单元格样式;Tr 可设置整行样式
Table(
    headers=["项目", "数值", "备注"],
    rows=[
        Tr(
            [
                Td("梁高", classes="font-bold"),
                1.8 * unit.meter,       # 任意值会通过 str() 渲染
                Td("控制参数", classes="text-red-600"),
            ],
            classes="bg-yellow-50",
        ),
        Tr(["混凝土等级", "C50", None]), # None 会显示为 "None"
    ],
)

# 扁平 rows 表示单行;Td 列表也会作为单行处理
Table(
    headers=["名称", "值"],
    rows=[Td("宽度", classes="font-bold"), 2.5 * unit.meter],
)

图表

生成图表的过程不需要显示过程,若图表复杂,在单独的函数中定义。 静态图首先使用 svg 方式,交互式图表使用 echarts 方式。

配色

进行图表配色时,优先选择以下配色方案:

  • primary: #7367f0;
  • secondary: #42b883;
  • dark-page: #e0e0e0;
  • positive: #42b883;
  • negative: #ff7a7a;
  • info: #65a0bb;

echarts 图表

通过 echarts 生成交互式图表, 在使用中,若对 echarts 中的参数不确定,读取 https://echarts.apache.org/zh/option.html 读取文档

# ECharts 交互式图表(推荐)
from uzoncalc.extension.echarts import use_echarts, EChart, Javascript

EChart({
    "xAxis": {"type": "category", "data": ["Mon", "Tue", "Wed"]},
    "yAxis": {"type": "value"},
    "series": [{"type": "bar", "data": [120, 200, 150]}],
})

# use_gl=True 时,渲染 ECharts GL 3D 图表
EChart({...}, use_gl=True)

svg

对于一般图示,建议使用 svg.py, 示例如下:

import svg
canvas = svg.SVG(
    width=60,
    height=60,
    elements=[
        svg.Circle(
            cx=30, cy=30, r=20,
            stroke="red",
            fill="white",
            stroke_width=5,
        ),
    ],
)
P(canvas)

Matplotlib 图表

也可以使用 Matplotlib 生成静态图表

# Matplotlib 静态图(适合打印)
import matplotlib.pyplot as plt
hide()
def make_fig():
    fig, ax = plt.subplots()
    ax.plot([1, 2, 3], [4, 5, 6])
    return plt
show()
Plot(make_fig())

UI 输入(交互模式)

from uzoncalc import UI, Field, FieldType

inputs = await UI(
    "结构参数",
    [
        Field("width",  "宽度",   FieldType.number, value=10),
        Field("height", "高度",   FieldType.number, value=5),
        Field("mat",    "材料",   FieldType.selectOne, options=["C30", "C40", "C50"]),
    ],
)
width = inputs.width * unit.meter

FieldType 可选值:textnumberselectOneselectManybooleantextarea

Excel 集成

from uzoncalc.extension.excel import get_excel_table

P(get_excel_table(
    excel_path="examples/calc.xlsx",
    values={
        "Sheet1!A2": 6,
        "Sheet1!B2": 10,
    },
    range="Sheet1!A1:C3",
))

保存文档

# 在函数内部保存
save("output/result.html")

# 在函数外部保存
ctx = run_sync(sheet)
ctx.save("output/result.html")

生成的 HTML 可用浏览器打印为 PDF,或用 pandoc 转为 Word。

运行方式

if __name__ == "__main__":
    ctx = run_sync(sheet)          # 同步执行(静默模式,UI 用默认值)
    ctx.save("output.html")

# 多个计算书
ctx1 = run_sync(sheet1)
ctx2 = run_sync(sheet2)
ctx1.save("out1.html")
ctx2.save("out2.html")

注意要点

  • 函数体内所有顶层赋值语句均被拦截渲染,若不希望某段代码渲染,用 hide() / show() 包裹
  • @uzon_calc() 函数外,其他函数均不被渲染
  • 变量名中的 _ 渲染为下标,命名时应使用 camelCase
  • 数组下标 arr[0, 1] 自动渲染为下标形式
  • @uzon_calc() 函数支持相互嵌套调用,内层函数的内容合并到当前上下文
  • 单位计算依赖 pint,量纲不匹配时会抛出错误

编写要点

  • 规范中涉及的公式,应在 @uzon_calc() 函数中编写,不要单独封装,其它函数不会渲染
Install via CLI
npx skills add https://github.com/uyoufu/UzonCalc --skill uzoncalc-writer
Repository Details
star Stars 2
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator