
简介面向小学生及其家长的文言文启蒙资料收录《陈元方候袁公》《画蛇添足》《父善游》《人有亡斧者》等经典短篇以“小故事”承载品德与智慧教育既有应对尊者提问的机敏也有“画蛇添足”的适度提醒贴合小学阶段文言起步与价值观塑造需求。资源打包为1个docx文档整体大小仅57KB内容排版便于直接阅读、打印或导入学习设备。目前已有63人学习/下载。文档在每个故事下均给出原文、重点字词注释、完整译文及鉴赏分析部分篇目还附有方言证古与哲理提炼可帮助孩子扫清字词障碍也为家长伴读、教师备课提供了现成的讲解框架。除古文阅读训练外这些故事本身具有很强的现实教育意义适合作为课前导入、晨读材料或拓展阅读使用。1. 从一团 docx 里拆出一套文言文教学语料收到这份《小学生文言文小故事》的 docx 时第一反应不是急着打印给孩子背而是打开看它的段落结构。文档里除了原文还混着注释、译文、鉴赏和朗读停顿标记比如《陈元方候袁公》后面跟着十几条注释和一段“方言证古”《杨氏之子》里还有“朗读方法 / 停顿的地方”这种非正文内容。这些内容对做课件、生成背诵卡、做断句练习都很有用但前提是把它们从 Word 段落里规规矩矩地拆出来。我的做法是写一套 Python 脚本先按故事的书写边界切分再按区块关键词归类最后落成一份 JSON 语料库。这份被标为“教育精品资料”的收藏整理后可以直接喂给复习卡、TTS 朗读和在线练习页而不是永远躺在网盘里。2. 用 python-docx 拆解《陈元方候袁公》的段落层级2.1 先搞清楚 Word 里的四种段落类型这类教育资料 docx 有一个特点作者用空行和标题样式划分故事但正文部分没有统一的“一级标题”“二级标题”规范。打开文件后看到的基本是四种段落故事名如“陈元方候袁公-”、正文文言文原文、解释类段落注释、译文、翻译、鉴赏、启示、道理、以及注释里的条目如“1、候拜访问候。”。第 1 章里提到的“朗读方法”也属于解释类但格式更特殊是“词语停顿标记”的形式。我一般会先把这些段落全部读出来去掉空行得到一个按顺序排列的文本列表。然后观察每个故事内部的小标题出现规律。从这篇文档看解释类段落几乎都以“注释”“译文”“翻译”“鉴赏”“道理”“启示”“寓意”“评点”“分析点评”“含义”等词开头。故事标题则单独占一行且多数以分隔符“-”结尾像“陈元方候袁公-”“画蛇添足-”但也有不带的如“狼-”“伯牙绝弦-”。因此解析时不能只认“-”还要配合“下一个解释区块出现前的内容归属”来做判断。2.2 用 python-docx 提取段落并按标记归类下面这段脚本的作用是把 docx 中的所有非空段落读出来并初步打上区块标签。我这里用的是 python-docx 的标准读取方式不依赖 Word 样式名因为这份文档的样式大概率是全文正文样式名没有参考价值。import re from docx import Document def read_paragraphs(path): doc Document(path) return [p.text.strip() for p in doc.paragraphs if p.text.strip()] # 区块关键词映射到统一的角色名 ROLE_MAP { 注释: note, 译文: translation, 翻译: translation, 原文: original, 鉴赏: analysis, 分析点评: analysis, 启示: analysis, 寓意: analysis, 道理: analysis, 评点: analysis, 含义: analysis, 朗读方法: reading, 词句与词语解析: analysis, } def tag_paragraphs(paras): tagged [] current_role None for para in paras: found None for marker, role in ROLE_MAP.items(): if para.startswith(marker) and len(para) 20: found role break if found: current_role found tagged.append((current_role, para)) else: # 保持继承最近一个区块 tagged.append((current_role or title, para)) return tagged这段代码最需要注意的是len(para) 20这个限定。像“注释”两个字单独成段时才断言为一个新区块而“词句与词语解析”虽然长也被映射到了 analysis。如果不加长度限制正文里出现“注释”字样的句子极少数情况会被误判。这里的current_role是“状态持有”写法适合这种按顺序阅读的文档后续段落无论有没有显式标记都会沿用上一个区块的角色。2.3 故事边界的切分与标题判定有了角色标签下一步是切故事。标题段通常满足三个条件不带区块角色被标记成 title、以“-”结尾或短于 15 个字、且下属三段内会出现 note 或 translation。STORY_TITLE_SUFFIX - def split_stories(tagged): stories [] current None for role, text in tagged: if role title and (text.endswith(STORY_TITLE_SUFFIX) or len(text) 12): if current: stories.append(current) current {title: text.rstrip(-), blocks: []} elif current: current[blocks].append((role, text)) if current: stories.append(current) return stories切分后的每个故事块都带一个块列表。这份文档一共有 17 个故事切出来后可以把《陈元方候袁公》《狼》《伯牙绝弦》这类结构完整的优先入库。表 2-1 是几个常见区块关键词在本文档中的实际映射情况我建议你结合自己的文档微调这个映射表。区块关键词角色标识常见内容对应处理注释note单字或双字词条逐行拆分生成词条译文 / 翻译translation白话文翻译与原文段落对齐鉴赏 / 评点 / 分析点评analysis人物评价与写作分析生成思考题素材启示 / 道理 / 寓意analysis概括寓意生成“中心思想”字段朗读方法reading停顿位置标志拆分后做断句注音提示如果某个故事标题没有按“-”结尾比如“北人食菱-”和“北人食菱的的道理”这种变体需要注意过滤“的的道理”这类说明性后缀否则会多拆出一个伪故事。3. 通假字、词类活用与虚词给注释建一套 JSON 标注模型3.1 为什么要做语言点标注带注释的文言文文档直接读没问题但做课程设计时需要把“候拜访”“亡丢掉”“意同‘臆’估计”这类注释变成一个可查询的数据结构。比如给孩子做练习时系统要能随机抽取“通假字”或“词类活用”题做阅读软件时鼠标悬停在“洞”字上要能弹出“名词作动词打洞”做错题本时要能按“一词多义”聚合同一个字的不同用法。这些都要求我们把散落在注释区的文本转成结构化字段。3.2 从注释文本提取词条注释区最常见的格式是“序号分词冒号解释”例如“2、亡丢掉丢失。”“3、意同‘臆’估计怀疑。”。也有少数不带序号的比如“老父对父亲的敬称”。我常用一个正则表达式一次性拆出词条、目标字、释义和通假标记import re NOTE_PATTERN re.compile( r^(?Pnum\d)?[、.\s]* r(?Pterm[\u4e00-\u9fff]{1,6}) r[:] r(?Pdesc.)$ ) def parse_note_line(line): m NOTE_PATTERN.match(line.strip()) if not m: return None term m.group(term) desc m.group(desc) # 识别通假标记同、通、与“同”等 tong re.search(r同[“‘\\”]?([\u4e00-\u9fff]), desc) jia re.search(r通[“‘\\”]?([\u4e00-\u9fff]), desc) return { term: term, definition: desc, 假借字: tong.group(1) if tong else None, 通假字: jia.group(1) if jia else None, }这里的term最多取 6 个汉字是避免把整句解释当词条。像“周旋动静这里指思想和行动”这种词条实际上是四字短语6 字以内恰好能覆盖。通假字在《郑人买履》里很明显“反”通“返”《杨氏之子》里“惠”同“慧”这类信息拆出来后要单独存字段方便之后按“通假”筛选。3.3 设计故事语料的 JSON Schema整个语料库我建议按“故事库—故事—词条”三层来组织。下面是一个简化但可直接落地的结构每篇故事包含 metadata、原文、译文、词条和中心思想五个部分{ version: 1.0, stories: [ { id: shih_shuo_001, title: 陈元方候袁公, source: 世说新语, original: 陈元方年十一岁时候袁公。袁公问曰……, translation: 陈元方十一岁时去拜会袁公。……, notes: [ { term: 候, definition: 拜访问候, type: 实词 }, { term: 绥, definition: 安安抚, type: 实词 } ], theme: 随机应变不卑不亢 } ] }实际生成时我还会把“通假字”“词类活用”“一词多义”等单独拆成type字段。表 3-1 整理了这份文档里比较典型的语言现象整理时可以直接从注释中批量抽取但需要人工复核。故事字词语言现象释义出处注释郑人买履反通假字通“返”返回反通假字同“返”杨氏之子惠通假字同“慧”智慧惠惠同“慧”狼洞词类活用名词作动词打洞洞名词用为动词打洞狼犬词类活用名词作状语像狗一样犬名词用作状语郑人买履度一词多义量 / 量好的尺码度duó/ 度dù嫦娥奔月斫生僻字用刀斧砍斫大锄引申为砍把这个 JSON 生成好以后后续做课件、题目和朗读对齐都从这个文件读取不再回到 docx 里翻原句。这样即使原始文档的排版调整过只要重新跑一遍解析脚本语料库就能同步更新。4. 批量生成 Anki 卡与带拼音课件4.1 把词条转成 Anki 复习卡Anki 是很多语文老师做字词复习的工具但它的导入格式是 CSV需要自己拼字段。我通常会生成三列故事标题、原文例句、字词解释。例句直接从原文中截取而不是只给词条这样孩子能看到上下文。import csv def export_anki(stories, output_pathanki_cards.csv): with open(output_path, w, newline, encodingutf-8) as f: writer csv.writer(f) writer.writerow([故事, 例句, 词条, 释义]) for story in stories: for note in story[notes]: # 在原文中定位词条所在句 sentence find_sentence(story[original], note[term]) writer.writerow([ story[title], sentence, note[term], note[definition] ]) print(f已生成 {output_path})find_sentence的实现可以用正则按句号、问号、叹号切句再定位包含词条的句子。这样每个词条都配一个真实语境而不是干巴巴的字词对应。4.2 用模板生成带拼音和断句的 HTML 课件相比 Anki更常用的是直接生成一个可打印或可投影的 HTML 页面。我采用模板字符串的方式把故事原文里的生字加span包裹并高亮再在顶部插入注音。html_template !DOCTYPE html html headmeta charsetutf-8title{title}/title/head body h1{title}/h1 p classoriginal{original_html}/p p classtranslation{translation}/p ol classnotes {note_items} /ol /body /html def render_story_html(story, pinyin_map): original_html story[original] for term, pinyin in pinyin_map.items(): original_html original_html.replace( term, fruby{term}rt{pinyin}/rt/ruby ) ...pinyin_map可以直接用pypinyin库生成from pypinyin import lazy_pinyin def build_pinyin_map(story): chars set(.join(story[original])) return {ch: .join(lazy_pinyin(ch)) for ch in chars}这里要注意pypinyin对多音字的处理不一定对比如“度”在《郑人买履》里有 duó 和 dù 两个读音不能只按单字默认读音生成。我的做法是给生字表加一个覆盖参数遇到多音字时手工指定读音脚本优先读覆盖表读不到再走lazy_pinyin。4.3 命令行参数怎么设为了让这套脚本能在不同场景复用我用argparse做了四个参数命令行调用长这样python build_lessons.py --input stories.json --format anki --output cards.csv python build_lessons.py --input stories.json --format html --output lesson.html --tone true参数说明见表 4-1。参数作用示例值--input指定故事 JSON 路径stories.json--format输出格式anki或htmlanki--output输出文件路径cards.csv--tone是否启用多音字覆盖表true这样生成的 HTML 可以直接在课堂投影Anki CSV 可以导入手机端做碎片化复习。一次处理 17 个故事脚本运行时间不到 3 秒主要耗时在启动 pypinyin 的字典加载上。5. 用断言脚本守住建库数据质量整理语料库最容易出的问题恰恰就是《画蛇添足》这个故事本身的寓意多干了一件多余的事结果坏了整件事。我在处理《狼》这篇时注释里出现了三处“足”一处解释为“脚”一处是“画脚”如果不做去重和一致性检查导出的词条就会被同一个字占掉多个位置。所以在入库的最后一步我跑一个校验脚本专门检查这些数据毛病。def validate_stories(stories): errors [] for story in stories: required [id, title, original, translation, notes] for field in required: if not story.get(field): errors.append(f{story.get(title)} 缺字段 {field}) # 检查注释词条是否在原文中出现过 for note in story[notes]: if note[term] and note[term] not in story[original]: errors.append( f{story[title]} 中词条 {note[term]} 未在原文中找到 ) # 检查通假标记是否成对出现 if 通假字 in str(story.get(notes)): # 简化处理仅统计是否有“同”“通” pass assert not errors, \n.join(errors) print(f校验通过共 {len(stories)} 个故事)这个脚本的思路是凡是词条里的字必须在原文里能直接找到凡是必填字段为空直接报错。对于《杨氏之子》里的“未闻孔雀是夫子家禽”人工注释里提到“家禽”和现代汉语的家禽不同这类语义差异脚本无法判断但字面出现与否完全可以自动检查。另外还会做一步“断句完整性检查”。很多故事原文里带了朗读停顿符号比如《杨氏之子》的“梁国/杨氏子/九岁”。我在切分成句子时会把/保留为一个特殊字段但在生成 HTML 时再决定是否显示。校验时会确认去掉/后的文本和原始原文一致防止切句子时把“杨梅”拆成“杨/梅”这种破坏词义的操作。def validate_reading_marks(story): original story[original] cleaned re.sub(r[/], , original) assert cleaned re.sub(r[/], , story[reading_marked]), \ f{story[title]} 断句标记导致原文被改动最后把校验脚本接到构建脚本的末尾每次生成课件前先跑一遍。这样能让“画蛇添足”式的多余操作在进入孩子屏幕前就被拦截。整套处理流程跑通后这份收藏资料就成了一个可持续维护的语料库以后想加题目、换课件模板、做 AB 测试都只需要改输出端不用再回头改 Word。本文还有配套的精品资源点击获取