<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>数字人文 |</title><link>https://clementgodbarge.com/zh/category/%E6%95%B0%E5%AD%97%E4%BA%BA%E6%96%87/</link><atom:link href="https://clementgodbarge.com/zh/category/%E6%95%B0%E5%AD%97%E4%BA%BA%E6%96%87/index.xml" rel="self" type="application/rss+xml"/><description>数字人文</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>zh-cn</language><lastBuildDate>Tue, 05 May 2026 00:00:00 +0000</lastBuildDate><image><url>https://clementgodbarge.com/media/icon_hu_64a6c3bec25b3d7b.png</url><title>数字人文</title><link>https://clementgodbarge.com/zh/category/%E6%95%B0%E5%AD%97%E4%BA%BA%E6%96%87/</link></image><item><title>tei-mcp v0.3：编码TEI，不动源文本一字</title><link>https://clementgodbarge.com/zh/post/tei-mcp-span-locked/</link><pubDate>Tue, 05 May 2026 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/zh/post/tei-mcp-span-locked/</guid><description>&lt;p&gt;我
时，目标是阻止AI助手幻觉出TEI标记。模式锚定解决了一部分问题：有了对P5规范的直接、基于工具的访问，模型不必再猜一个元素是什么意思、能带哪些属性。输出能通过验证。&lt;/p&gt;
&lt;p&gt;但在TEI编码里，幻觉有两副面孔，模式只抓得住一副。依规范验证，只能告诉您&lt;em&gt;标记&lt;/em&gt;是否合式；至于标记包裹的&lt;em&gt;文本&lt;/em&gt;，它一言不发。而破坏性更大的幻觉，恰恰就藏在文本本身里。v0.3的头号新功能——区间锁定合成（span-locked composition）——正是专为防范这类幻觉而设计的。&lt;/p&gt;
&lt;details class="print:hidden xl:hidden" &gt;
&lt;summary&gt;目录&lt;/summary&gt;
&lt;div class="text-sm"&gt;
&lt;nav id="TableOfContents"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#模式抓不住的幻觉"&gt;模式抓不住的幻觉&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#区间锁定合成"&gt;区间锁定合成&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#它是什么不是什么"&gt;它是什么，不是什么&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#为什么意义不止于tei"&gt;为什么意义不止于TEI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#获取更新"&gt;获取更新&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;
&lt;/div&gt;
&lt;/details&gt;
&lt;h2 id="模式抓不住的幻觉"&gt;模式抓不住的幻觉&lt;/h2&gt;
&lt;p&gt;让模型编码一封十六世纪的法文信，您往往会拿到一份看上去无可挑剔的TEI文档：头部填得满满当当，&lt;code&gt;&amp;lt;persName&amp;gt;&lt;/code&gt;标签放得恰到好处，&lt;code&gt;&amp;lt;dateline&amp;gt;&lt;/code&gt;合式规整。用&lt;code&gt;validate_document&lt;/code&gt;跑一遍，通过。&lt;/p&gt;
&lt;p&gt;然后拿正文和源文本比一比。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mesme&lt;/code&gt;变成了&lt;code&gt;même&lt;/code&gt;。一个逗号挪了窝。&lt;code&gt;luy&lt;/code&gt;被悄悄现代化成了&lt;code&gt;lui&lt;/code&gt;。手稿里一处难以辨认的分句，被“修正”成了更通顺的样子。这些改动没有一处是您要求的，也没有一处被标出来。文档在模式上有效，却错得悄无声息。&lt;/p&gt;
&lt;p&gt;对档案工作流来说——编码后的文本将成为永久记录，下游的读者、检索索引和引用都要倚赖它——这才是最要命的失效方式。标签格式不对，不过是烦人；一处五年没人发现的现代化拼写，就是讹误。&lt;/p&gt;
&lt;h2 id="区间锁定合成"&gt;区间锁定合成&lt;/h2&gt;
&lt;p&gt;新版本（v0.3）带来了一套直指这一失效方式的幻觉防范机制。设计目标是让正文幻觉从构造上就不可能发生，而不只是不大可能。&lt;/p&gt;
&lt;p&gt;思路很简单：&lt;strong&gt;模型从不键入正文&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;取而代之的工作流是这样的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;模型调用&lt;code&gt;get_source(&amp;quot;letter_001&amp;quot;)&lt;/code&gt;，取得源纯文本，一个不可变的字符串。&lt;/li&gt;
&lt;li&gt;每想施加一个标签，它就调用&lt;code&gt;tag_span(&amp;quot;letter_001&amp;quot;, start, end, element_path, attrs)&lt;/code&gt;——在源文本的某个字符区间上登记一个TEI元素。&lt;/li&gt;
&lt;li&gt;完事后，它调用&lt;code&gt;compose(&amp;quot;letter_001&amp;quot;)&lt;/code&gt;。服务器把登记的标签与原始纯文本交织起来，渲染出最终的TEI，再&lt;em&gt;逐字节&lt;/em&gt;核验：渲染文档的扁平文本内容必须与源文本相等。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;字节相符，文档就返回。若不相符——哪怕模型的标签只是隐含了一个与源文本差一个字符的正文——&lt;code&gt;compose()&lt;/code&gt;便抛出异常，绝不返回一份已经走样的文档。&lt;/p&gt;
&lt;p&gt;在这条工作流里，不存在任何一条路径能让模型产出正文与源文本不同的TEI文档。这个不变量是机械的，不是行为的。您不必信任模型不会幻觉，只需信任两个字节串之间的一次&lt;code&gt;==&lt;/code&gt;比较。&lt;/p&gt;
&lt;h2 id="它是什么不是什么"&gt;它是什么，不是什么&lt;/h2&gt;
&lt;p&gt;区间锁定合成是对模式锚定的&lt;strong&gt;补充&lt;/strong&gt;，不是替代。模式锚定工具（&lt;code&gt;validate_document&lt;/code&gt;、&lt;code&gt;lookup_element&lt;/code&gt;、&lt;code&gt;valid_children&lt;/code&gt;，以及最初十六个工具中的其余部分）帮模型产出&lt;em&gt;有效&lt;/em&gt;的TEI；区间锁定合成则保证TEI里的正文&lt;em&gt;忠于&lt;/em&gt;源文本。一条可以投入使用的编码工作流必须同时满足这两个维度，如今两者由同一个服务器一并覆盖。&lt;/p&gt;
&lt;p&gt;它也不是包治百病的灵丹。&lt;code&gt;compose()&lt;/code&gt;还不会检查登记的标签是否为已加载的ODD定制所允许——这是后续工作。登记的标签存在进程内存里，重启即失。源文件也必须能从服务器运行的地方读到。这些都有办法解决，没有一项动摇核心不变量。&lt;/p&gt;
&lt;h2 id="为什么意义不止于tei"&gt;为什么意义不止于TEI&lt;/h2&gt;
&lt;p&gt;这个模式可以推而广之。凡是让模型去注释、转换或包裹一段文本，而底层文本的完整性又比模型“改进”它的本事更要紧，同样形态的解法都适用：别让模型重打一遍文本；让它在文本之上生成指令，再由一个确定性的合成器在相等性不变量的约束下执行。&lt;/p&gt;
&lt;p&gt;具体到数字版本，这改变了您可以放心交给模型去做的事。编码忽然成了一项可以委托的任务，不必再手动把每份输出与源文本逐一比对。机器走枯燥的那条路；校勘者审的是标记，不是拼写。&lt;/p&gt;
&lt;h2 id="获取更新"&gt;获取更新&lt;/h2&gt;
&lt;p&gt;已经装了tei-mcp的话：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uvx tei-mcp@latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;或者全新安装：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install tei-mcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;要使用区间锁定合成，请把服务器指向存放源纯文本文件的目录：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;TEI_MCP_SPAN_SOURCE_ROOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/path/to/sources
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uvx tei-mcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;每个文件的主名即为其文档ID（&lt;code&gt;letter_001.txt&lt;/code&gt; →
&lt;code&gt;letter_001&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;源代码、完整文档以及该不变量的设计说明：
&lt;/p&gt;</description></item><item><title>另一种数字版本</title><link>https://clementgodbarge.com/zh/post/cavriana-edition/</link><pubDate>Tue, 24 Mar 2026 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/zh/post/cavriana-edition/</guid><description>&lt;p&gt;大多数原始史料从未出版。我们赖以补救的模式——靠经费资助的数字版本——太贵、太集中、太脆弱，根本无法推广。我刚发表了
，说明我为什么要换一种方式来做Cavriana书信的校勘本：数字化的原始史料有机生长，基础设施降到最低，维护自动进行，向协作开放，而且便宜到连经费都用不着申请。这是在为一种数字人文辩护：无论有没有机构撑腰，它都能运转。&lt;/p&gt;</description></item><item><title>tei-mcp：给AI智能体用的TEI P5</title><link>https://clementgodbarge.com/zh/post/tei-mcp/</link><pubDate>Sun, 15 Mar 2026 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/zh/post/tei-mcp/</guid><description>&lt;p&gt;如果您用AI编程助手写过TEI XML，大概已经领教过它的错误：元素放错地方，属性凭空捏造，嵌套规则视若无睹。模型对TEI长什么样有个大概印象，对规范本身却没有可靠的知识。&lt;/p&gt;
&lt;p&gt;tei-mcp的解法，是让AI智能体通过工具直接访问TEI P5指南。&lt;/p&gt;
&lt;details class="print:hidden xl:hidden" &gt;
&lt;summary&gt;目录&lt;/summary&gt;
&lt;div class="text-sm"&gt;
&lt;nav id="TableOfContents"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#mcp是什么"&gt;MCP是什么？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#tei-mcp做什么"&gt;tei-mcp做什么&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#为什么要紧"&gt;为什么要紧&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#上手"&gt;上手&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;
&lt;/div&gt;
&lt;/details&gt;
&lt;h2 id="mcp是什么"&gt;MCP是什么？&lt;/h2&gt;
&lt;p&gt;
（Model Context Protocol，MCP）是一项开放标准，让AI应用能接上外部数据源和工具。不妨把它看作AI的USB接口：一套协议，任何兼容的客户端——Claude、Cursor、Windsurf等等——都能借此接入专门的服务。&lt;/p&gt;
&lt;p&gt;MCP服务器对外提供&lt;em&gt;工具&lt;/em&gt;，AI在对话中可以随时调用。模型不必再靠记忆里的训练数据，而可以查询一个实时的、权威的来源。&lt;/p&gt;
&lt;h2 id="tei-mcp做什么"&gt;tei-mcp做什么&lt;/h2&gt;
&lt;p&gt;tei-mcp解析TEI P5的ODD规范，提供16个工具，涵盖校勘者或编码者最常问的问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;这个元素是什么？&lt;/strong&gt; 按名称查询任何元素、类、宏或模块，不区分大小写，拼错了还会给出建议。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;它能带哪些属性？&lt;/strong&gt; 沿完整的类层次解析属性——先列本地属性，再依次列出继承的属性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;它里面能放什么？&lt;/strong&gt; 把内容模型展开成结构化的树，或列出有效子元素的平面清单。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;这个元素能放在这儿吗？&lt;/strong&gt; 检查父子嵌套关系，或在完整的元素层次中追踪可达性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;我的文档有效吗？&lt;/strong&gt; 依据规范验证TEI XML文件：内容模型、属性值、封闭取值列表、引用完整性、弃用警告。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;我的项目模式呢？&lt;/strong&gt; 加载ODD定制文件，把上述一切约束到您项目特定的TEI子集。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="为什么要紧"&gt;为什么要紧&lt;/h2&gt;
&lt;p&gt;TEI编码离不开时时翻查指南。老手把最常见的模式记在心里，可遇到生僻元素或复杂的内容模型，照样得查规范。AI助手没有这种内化的知识，问题更严重：它们会幻觉出看似合理、实则错误的标记。&lt;/p&gt;
&lt;p&gt;有了tei-mcp，AI就不必猜了。写下第一个尖括号之前，它可以先去规范里查答案。结果便是符合TEI P5——或符合您项目ODD定制——的标记。&lt;/p&gt;
&lt;h2 id="上手"&gt;上手&lt;/h2&gt;
&lt;p&gt;从PyPI安装：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install tei-mcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后加入您MCP客户端的配置：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;mcpServers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;tei&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;uvx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tei-mcp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;服务器首次运行时下载TEI规范，可配合任何兼容MCP的客户端使用。&lt;/p&gt;
&lt;p&gt;源代码与完整文档：
&lt;/p&gt;</description></item><item><title>用ITA2电报模拟器讲二进制</title><link>https://clementgodbarge.com/zh/post/baudot/</link><pubDate>Thu, 13 Feb 2025 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/zh/post/baudot/</guid><description>&lt;h2 id="让抽象变得可触"&gt;让抽象变得可触&lt;/h2&gt;
&lt;p&gt;这个ITA2模拟器是一件实用的教具。它把抽象的编码概念变得看得见、摸得着，借此向学生引入计算与电信的一个核心概念：二进制表示——文字如何变成一串串1和0。
这一点我们通常讲得很抽象；而亲眼看着纸带上打出一个个孔，学生便更容易明白，物理系统是怎样表示数字信息的。
&lt;div class="baudot-emulator"&gt;
&lt;h2&gt;ITA2 (Baudot-Murray) Telegraph Type Emulator&lt;/h2&gt;
&lt;p&gt;Type a word in the input below to see its representation on the ITA2 tape.&lt;/p&gt;
&lt;div class="baudot-controls"&gt;
&lt;label for="baudot-input"&gt;Type word:&lt;/label&gt;
&lt;input id="baudot-input" class="text-input" size="50" maxlength="50" /&gt;
&lt;button type="button" id="baudot-ltr-button" class="control-button active"&gt;LTR&lt;/button&gt;
&lt;button type="button" id="baudot-fig-button" class="control-button"&gt;FIG&lt;/button&gt;
&lt;/div&gt;
&lt;div class="tape-outer-container"&gt;
&lt;div class="tape-container"&gt;
&lt;table&gt;
&lt;tbody id="baudot-tape"&gt;&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.baudot-emulator {
--light-color: #f3f4f6;
--dark-color: #1f2937;
--light-alt-color: #e5e7eb;
--dark-alt-color: #374151;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
max-width: 100%;
margin: 2rem 0;
padding: 0;
box-sizing: border-box;
}
.baudot-emulator {
--tape-bg: var(--light-color);
--hole-bg: var(--light-color);
--hole-border: #d1d5db;
--punched-bg: var(--dark-color);
--punched-border: var(--dark-color);
--sprocket-bg: var(--light-color);
--sprocket-border: #9ca3af;
--button-bg: var(--light-color);
--button-bg-active: #d1d5db;
--button-text: var(--dark-color);
--button-border: #d1d5db;
--input-bg: white;
--input-border: #d1d5db;
--input-text: var(--dark-color);
--line-number: #6b7280;
}
html.dark .baudot-emulator,
html[data-theme='dark'] .baudot-emulator,
body.dark .baudot-emulator {
--tape-bg: var(--dark-alt-color);
--hole-bg: var(--dark-alt-color);
--hole-border: #4b5563;
--punched-bg: var(--light-color);
--punched-border: var(--light-color);
--sprocket-bg: var(--dark-alt-color);
--sprocket-border: #9ca3af;
--button-bg: var(--dark-alt-color);
--button-bg-active: #4b5563;
--button-text: var(--light-color);
--button-border: #4b5563;
--input-bg: var(--dark-alt-color);
--input-border: #4b5563;
--input-text: var(--light-color);
--line-number: #9ca3af;
}
.baudot-controls {
margin-bottom: 1.5rem;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.5rem;
}
.baudot-emulator .text-input {
flex: 1;
min-width: 200px;
padding: 0.5rem;
font-size: 1rem;
border: 1px solid var(--input-border);
border-radius: 4px;
background: var(--input-bg);
color: var(--input-text);
}
.baudot-emulator .control-button {
padding: 0.5rem 1rem;
background: var(--button-bg);
color: var(--button-text);
border: 1px solid var(--button-border);
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
}
.baudot-emulator .control-button.active {
background: var(--button-bg-active);
font-weight: bold;
}
.tape-outer-container {
padding: 0;
margin-bottom: 1.5rem;
border-radius: 4px;
overflow: hidden;
}
.tape-container {
width: 100%;
overflow-x: auto;
background: var(--tape-bg);
padding: 1rem 0.5rem;
}
.baudot-emulator table {
border-collapse: collapse;
width: 100%;
table-layout: fixed;
border: none;
}
.baudot-emulator tr {
height: 24px;
border: none;
}
.baudot-emulator td {
border: none;
padding: 0;
}
.baudot-emulator .line-number {
width: 20px;
text-align: center;
color: var(--line-number);
font-size: 0.8rem;
padding: 0 8px 0 0;
font-weight: bold;
}
.baudot-emulator .cell {
position: relative;
width: 20px;
height: 20px;
}
.baudot-emulator .cell-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 12px;
height: 12px;
border-radius: 50%;
background: var(--hole-bg);
border: 1px solid var(--hole-border);
}
.baudot-emulator .punched .cell-content {
background: var(--punched-bg);
border: 1px solid var(--punched-border);
}
.baudot-emulator .sprocket-hole {
position: absolute;
left: 50%;
top: 100%;
transform: translate(-50%, -50%);
width: 4px;
height: 4px;
border-radius: 50%;
background: var(--sprocket-bg);
border: 1px solid var(--sprocket-border);
z-index: 2;
}
&lt;/style&gt;
&lt;script&gt;
document.addEventListener('DOMContentLoaded', function() {
initBaudotEmulator();
});
function initBaudotEmulator() {
if (!document.getElementById('baudot-input')) return;
const textInput = document.getElementById('baudot-input');
const tape = document.getElementById('baudot-tape');
const ltrButton = document.getElementById('baudot-ltr-button');
const figButton = document.getElementById('baudot-fig-button');
const ita2Code = {
'A': '00011', 'B': '11001', 'C': '01110', 'D': '01001', 'E': '00001',
'F': '01101', 'G': '11010', 'H': '10100', 'I': '00110', 'J': '01011',
'K': '01111', 'L': '10010', 'M': '11100', 'N': '01100', 'O': '11000',
'P': '10110', 'Q': '10111', 'R': '01010', 'S': '00101', 'T': '10000',
'U': '00111', 'V': '11110', 'W': '10011', 'X': '11101', 'Y': '10101',
'Z': '10001',
'1': '00011', '2': '11001', '3': '01110', '4': '01001', '5': '00001',
'6': '01101', '7': '11010', '8': '10100', '9': '01011', '0': '11000',
'-': '00011', '?': '00100', ':': '01010', '(': '11000', ')': '11101',
'.': '01000', ',': '00010', "'": '10001', '=': '01111', '/': '10011',
'+': '11011', ' ': '00100',
'FIG': '11011', 'LTR': '11111',
};
function generateTape() {
let rows = '';
for (let row = 0; row &lt; 5; row++) {
rows += '&lt;tr&gt;';
rows += `&lt;td class="line-number"&gt;${row + 1}&lt;/td&gt;`;
for (let col = 0; col &lt; 50; col++) {
rows += `&lt;td id="baudot_${row}_${col}" class="cell unpunched"&gt;
&lt;div class="cell-content"&gt;&lt;/div&gt;
${row === 2 ? '&lt;div class="sprocket-hole"&gt;&lt;/div&gt;' : ''}
&lt;/td&gt;`;
}
rows += '&lt;/tr&gt;';
}
tape.innerHTML = rows;
}
function updateITA2Code(word) {
clearTape();
word = word.toUpperCase();
let tapePosition = 0;
let currentCharType = 'LTR';
ltrButton.classList.add('active');
figButton.classList.remove('active');
for (let i = 0; i &lt; word.length; i++) {
const char = word[i];
let code = ita2Code[char] || ita2Code[' '];
let requiredCharType = /[A-Z ]/.test(char) ? 'LTR' : 'FIG';
if (requiredCharType !== currentCharType) {
const shiftCode = requiredCharType === 'LTR' ? ita2Code['LTR'] : ita2Code['FIG'];
punchTape(shiftCode, tapePosition++);
currentCharType = requiredCharType;
ltrButton.classList.toggle('active', currentCharType === 'LTR');
figButton.classList.toggle('active', currentCharType === 'FIG');
}
punchTape(code, tapePosition++);
}
}
function punchTape(code, tapePosition) {
if (tapePosition &gt;= 50) return;
for (let bit = 0; bit &lt; 5; bit++) {
const cell = document.getElementById(`baudot_${bit}_${tapePosition}`);
if (cell) {
cell.className = code[bit] === '1' ? 'cell punched' : 'cell unpunched';
}
}
}
function clearTape() {
for (let i = 0; i &lt; 50; i++) {
for (let bit = 0; bit &lt; 5; bit++) {
const cell = document.getElementById(`baudot_${bit}_${i}`);
if (cell) {
cell.className = 'cell unpunched';
}
}
}
}
generateTape();
textInput.addEventListener('input', function() {
updateITA2Code(this.value);
});
ltrButton.addEventListener('click', function() {
this.classList.add('active');
figButton.classList.remove('active');
if (textInput.value) {
updateITA2Code(textInput.value);
}
});
figButton.addEventListener('click', function() {
this.classList.add('active');
ltrButton.classList.remove('active');
if (textInput.value) {
updateITA2Code(textInput.value);
}
});
if (textInput.value) {
updateITA2Code(textInput.value);
}
}
&lt;/script&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id="历史背景从电报到计算"&gt;历史背景：从电报到计算&lt;/h2&gt;
&lt;p&gt;ITA2（国际电报字母表第2号），又称Baudot-Murray码，问世于二十世纪二十年代，是对埃米尔·博多（Émile Baudot）十九世纪七十年代原始电报码的改良。这些早期电信系统直接影响了后来计算技术的发展：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;5位编码方案是字符编码的早期范例&lt;/li&gt;
&lt;li&gt;字符集受限（5位只有32种组合），催生了巧妙的LETTERS/FIGURES（字母/数字）换挡机制&lt;/li&gt;
&lt;li&gt;这套系统在电传打字机上一直沿用到二十世纪很晚的时候&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="在玩中学状态机"&gt;在玩中学状态机&lt;/h2&gt;
&lt;p&gt;LETTERS/FIGURES换挡机制顺理成章地引出了状态机。学生一试便知：同一个图案，模式不同，代表的字符也不同。有了这种基于状态的编码的亲身体验，往后学更复杂的计算概念便有了根基。
譬如，位模式&lt;code&gt;00011&lt;/code&gt;表示：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LETTERS（字母）模式下是字母“A”&lt;/li&gt;
&lt;li&gt;FIGURES（数字）模式下是数字“1”
依状态而定的双重解读，正是计算机处理数据的根本原理。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="课堂活动"&gt;课堂活动&lt;/h2&gt;
&lt;p&gt;把ITA2模拟器融入教学，可以有这几种方式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;破译挑战&lt;/strong&gt;：让学生解码以ITA2图案编写的信息&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高效编码&lt;/strong&gt;：讨论换挡机制为何对节省带宽至关重要&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;编码的演变&lt;/strong&gt;：把ITA2的5位码与ASCII（7位）和Unicode作比较&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;物理计算&lt;/strong&gt;：把这套历史系统与Arduino等现代微控制器联系起来&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="无障碍方面的好处"&gt;无障碍方面的好处&lt;/h2&gt;
&lt;p&gt;除了历史趣味，这种方法也照顾到不同学习风格的学生：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;视觉型学习者看图案&lt;/li&gt;
&lt;li&gt;动觉型学习者直接上手操作编码过程&lt;/li&gt;
&lt;li&gt;概念型思考者可以探究信息论的数学层面&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="实现细节"&gt;实现细节&lt;/h2&gt;
&lt;p&gt;模拟器用JavaScript写成，可轻松嵌入任何网页学习平台。代码模块化，可按不同教学情境定制。
源代码和在线试用见：
&lt;/p&gt;</description></item></channel></rss>