353 lines
45 KiB
JavaScript
353 lines
45 KiB
JavaScript
/**
|
||
* L1 Pedagogy Rules v1.0
|
||
* 教研内容校验规则模块
|
||
*
|
||
* 用法: <script src="l1_pedagogy_rules.js"></script>
|
||
* API: PedagogyRules.validate(componentContent, chapterPrefix)
|
||
*/
|
||
(function(global) {
|
||
"use strict";
|
||
|
||
var WORD_LISTS = {
|
||
L1: {"red": {"pos": "adj", "meaning": "红色的", "unit": "S0-U0-L1", "difficulty": 1}, "hat": {"pos": "n", "meaning": "帽子", "unit": "S0-U0-L1", "difficulty": 1}, "blue": {"pos": "adj", "meaning": "蓝的", "unit": "S0-U0-L1", "difficulty": 1}, "bag": {"pos": "n", "meaning": "袋,包", "unit": "S0-U0-L1", "difficulty": 1}, "orange": {"pos": "n", "meaning": "橙子", "unit": "S1-U10-L3", "difficulty": 1}, "green": {"pos": "adj", "meaning": "绿色的", "unit": "S0-U0-L2", "difficulty": 1}, "dress": {"pos": "n", "meaning": "连衣裙", "unit": "S0-U0-L2", "difficulty": 1}, "there": {"pos": "adv", "meaning": "那里", "unit": "S0-U0-L3", "difficulty": 1}, "put": {"pos": "v", "meaning": "放", "unit": "S0-U0-L3", "difficulty": 1}, "purple": {"pos": "adj", "meaning": "紫色的", "unit": "S0-U0-L5", "difficulty": 1}, "give": {"pos": "v", "meaning": "给", "unit": "S0-U0-L3", "difficulty": 1}, "water": {"pos": "n", "meaning": "水", "unit": "S0-U0-L4", "difficulty": 1}, "here": {"pos": "adv", "meaning": "在这里", "unit": "S0-U0-L4", "difficulty": 1}, "dirty": {"pos": "adj", "meaning": "肮脏的", "unit": "S0-U0-L4", "difficulty": 1}, "clean": {"pos": "v", "meaning": "清洁", "unit": "S0-U0-L4", "difficulty": 1}, "pink": {"pos": "adj", "meaning": "粉红色的", "unit": "S0-U0-L2", "difficulty": 1}, "get": {"pos": "v", "meaning": "收到", "unit": "", "difficulty": 1}, "wall": {"pos": "n", "meaning": "墙", "unit": "S1-U1-L1", "difficulty": 1}, "table": {"pos": "n", "meaning": "桌子", "unit": "S1-U1-L1", "difficulty": 1}, "floor": {"pos": "n", "meaning": "地板", "unit": "S1-U1-L1", "difficulty": 1}, "hand": {"pos": "n", "meaning": "手", "unit": "S1-U1-L2", "difficulty": 1}, "foot": {"pos": "n", "meaning": "脚", "unit": "S1-U1-L2", "difficulty": 1}, "black": {"pos": "adj", "meaning": "黑的", "unit": "S1-U1-L2", "difficulty": 1}, "tomato": {"pos": "n", "meaning": "西红柿", "unit": "S1-U1-L3", "difficulty": 1}, "fish": {"pos": "n", "meaning": "鱼", "unit": "S1-U1-L3", "difficulty": 1}, "chicken": {"pos": "n", "meaning": "鸡肉", "unit": "S1-U1-L3", "difficulty": 1}, "nose": {"pos": "n", "meaning": "鼻子", "unit": "S1-U1-L4", "difficulty": 1}, "eye": {"pos": "n", "meaning": "眼睛", "unit": "S1-U1-L4", "difficulty": 1}, "brown": {"pos": "adj", "meaning": "棕色的", "unit": "S1-U1-L4", "difficulty": 1}, "yellow": {"pos": "adj", "meaning": "黄色的", "unit": "S1-U1-L5", "difficulty": 1}, "white": {"pos": "adj", "meaning": "白色的", "unit": "S1-U1-L5", "difficulty": 1}, "go": {"pos": "v", "meaning": "去,走", "unit": "S1-U2-L1", "difficulty": 1}, "dog": {"pos": "n", "meaning": "狗", "unit": "S1-U2-L1", "difficulty": 1}, "come": {"pos": "v", "meaning": "来", "unit": "S1-U2-L1", "difficulty": 1}, "cat": {"pos": "n", "meaning": "猫", "unit": "S1-U2-L1", "difficulty": 1}, "pie": {"pos": "n", "meaning": "馅饼", "unit": "S1-U2-L2", "difficulty": 1}, "can": {"pos": "v", "meaning": "能,会", "unit": "S1-U2-L4", "difficulty": 1}, "open": {"pos": "adj", "meaning": "开着的", "unit": "", "difficulty": 1}, "happy": {"pos": "adj", "meaning": "快乐的", "unit": "S1-U2-L5", "difficulty": 1}, "see": {"pos": "v", "meaning": "看见", "unit": "S1-U3-L1", "difficulty": 1}, "1": {"pos": "num", "meaning": "1", "unit": "S1-U3-L1", "difficulty": 1}, "paper": {"pos": "adj", "meaning": "纸质的", "unit": "", "difficulty": 1}, "book": {"pos": "n", "meaning": "书", "unit": "S1-U3-L2", "difficulty": 1}, "3": {"pos": "num", "meaning": "3", "unit": "S1-U3-L2", "difficulty": 1}, "2": {"pos": "num", "meaning": "2", "unit": "S1-U3-L2", "difficulty": 1}, "pen": {"pos": "n", "meaning": "钢笔", "unit": "S1-U3-L3", "difficulty": 1}, "box": {"pos": "n", "meaning": "盒子", "unit": "S1-U3-L3", "difficulty": 1}, "4": {"pos": "num", "meaning": "4", "unit": "S1-U3-L3", "difficulty": 1}, "6": {"pos": "num", "meaning": "6", "unit": "S1-U3-L4", "difficulty": 1}, "5": {"pos": "num", "meaning": "5", "unit": "S1-U3-L4", "difficulty": 1}, "sing": {"pos": "v", "meaning": "唱", "unit": "S1-U4-L1", "difficulty": 1}, "eat": {"pos": "v", "meaning": "吃", "unit": "S1-U4-L2", "difficulty": 1}, "7": {"pos": "num", "meaning": "7", "unit": "S1-U4-L2", "difficulty": 1}, "rug": {"pos": "n", "meaning": "小地毯", "unit": "S1-U4-L3", "difficulty": 1}, "door": {"pos": "n", "meaning": " 门", "unit": "", "difficulty": 1}, "bed": {"pos": "n", "meaning": "床", "unit": "S1-U4-L3", "difficulty": 1}, "9": {"pos": "num", "meaning": "9", "unit": "S1-U4-L4", "difficulty": 1}, "8": {"pos": "num", "meaning": "8", "unit": "S1-U4-L4", "difficulty": 1}, "10": {"pos": "num", "meaning": "10", "unit": "S1-U4-L5", "difficulty": 1}, "zoo": {"pos": "n", "meaning": "动物园", "unit": "", "difficulty": 1}, "zebra": {"pos": "n", "meaning": "斑马", "unit": "S1-U7-L2", "difficulty": 1}, "young": {"pos": "adj", "meaning": "年轻的", "unit": "", "difficulty": 1}, "year": {"pos": "n", "meaning": "年", "unit": "", "difficulty": 1}, "write": {"pos": "v", "meaning": "写", "unit": "", "difficulty": 1}, "woman": {"pos": "n", "meaning": "女人", "unit": "S1-U5-L1", "difficulty": 1}, "window": {"pos": "n", "meaning": "窗户", "unit": "S1-U12-L4", "difficulty": 1}, "warm": {"pos": "adj", "meaning": "温暖的", "unit": "", "difficulty": 1}, "want": {"pos": "v", "meaning": "想要", "unit": "", "difficulty": 1}, "walk": {"pos": "v", "meaning": "走", "unit": "S1-U7-L2", "difficulty": 1}, "very": {"pos": "adv", "meaning": "非常", "unit": "", "difficulty": 1}, "under": {"pos": "prep", "meaning": "在...下面", "unit": "S2-U14-L5", "difficulty": 1}, "try": {"pos": "v", "meaning": "尝试", "unit": "S1-U12-L5", "difficulty": 1}, "tree": {"pos": "n", "meaning": "树", "unit": "S1-U7-L1", "difficulty": 1}, "train": {"pos": "n", "meaning": "火车", "unit": "S1-U8-L1", "difficulty": 1}, "too": {"pos": "adv", "meaning": "也", "unit": "S1-U12-L2", "difficulty": 1}, "tomorrow": {"pos": "n", "meaning": "明天", "unit": "", "difficulty": 1}, "today": {"pos": "n", "meaning": "今天", "unit": "", "difficulty": 1}, "tiger": {"pos": "n", "meaning": "老虎", "unit": "S1-U5-L3", "difficulty": 1}, "those": {"pos": "pron", "meaning": "那些", "unit": "S1-U12-L1", "difficulty": 1}, "this": {"pos": "pron", "meaning": "这个", "unit": "S1-U12-L1", "difficulty": 1}, "these": {"pos": "pron", "meaning": "这些", "unit": "S1-U12-L1", "difficulty": 1}, "that": {"pos": "pron", "meaning": "那个", "unit": "S1-U12-L1", "difficulty": 1}, "tell": {"pos": "v", "meaning": "告诉", "unit": "", "difficulty": 1}, "teacher": {"pos": "n", "meaning": "老师", "unit": "S2-U14-L2", "difficulty": 1}, "talk": {"pos": "v", "meaning": "说话", "unit": "", "difficulty": 1}, "swim": {"pos": "v", "meaning": "游泳", "unit": "S1-U11-L5", "difficulty": 1}, "sun": {"pos": "n", "meaning": "太阳", "unit": "S1-U8-L2", "difficulty": 1}, "study": {"pos": "v", "meaning": "学习", "unit": "S2-U14-L1", "difficulty": 1}, "student": {"pos": "n", "meaning": "学生", "unit": "S2-U14-L1", "difficulty": 1}, "speak": {"pos": "v", "meaning": "说", "unit": "", "difficulty": 1}, "some": {"pos": "det", "meaning": "一些", "unit": "", "difficulty": 1}, "sofa": {"pos": "n", "meaning": "沙发", "unit": "", "difficulty": 1}, "sock": {"pos": "n", "meaning": "袜子", "unit": "", "difficulty": 1}, "small": {"pos": "adj", "meaning": "小的", "unit": "S1-U9-L1", "difficulty": 1}, "sleep": {"pos": "v", "meaning": "睡觉", "unit": "S1-U7-L4", "difficulty": 1}, "skirt": {"pos": "n", "meaning": "裙子", "unit": "S1-U9-L4", "difficulty": 1}, "sit": {"pos": "v", "meaning": "坐下", "unit": "S1-U8-L1", "difficulty": 1}, "sister": {"pos": "n", "meaning": "姐姐、妹妹", "unit": "S1-U8-L1", "difficulty": 1}, "short": {"pos": "adj", "meaning": "短的", "unit": "", "difficulty": 1}, "shoe": {"pos": "n", "meaning": "鞋", "unit": "", "difficulty": 1}, "shirt": {"pos": "n", "meaning": "衬衫", "unit": "S1-U9-L1", "difficulty": 1}, "ship": {"pos": "n", "meaning": "船", "unit": "", "difficulty": 1}, "sheep": {"pos": "n", "meaning": "绵羊", "unit": "S1-U5-L3", "difficulty": 1}, "school": {"pos": "n", "meaning": "学校", "unit": "S2-U14-L1", "difficulty": 1}, "say": {"pos": "v", "meaning": "说", "unit": "", "difficulty": 1}, "sad": {"pos": "adj", "meaning": "悲伤的", "unit": "", "difficulty": 1}, "run": {"pos": "v", "meaning": "跑", "unit": "", "difficulty": 1}, "ruler": {"pos": "n", "meaning": "尺子", "unit": "", "difficulty": 1}, "room": {"pos": "n", "meaning": "房间", "unit": "", "difficulty": 1}, "rice": {"pos": "n", "meaning": "米饭", "unit": "S1-U6-L4", "difficulty": 1}, "read": {"pos": "v", "meaning": "阅读", "unit": "", "difficulty": 1}, "radio": {"pos": "n", "meaning": "收音机", "unit": "S1-U9-L2", "difficulty": 1}, "potato": {"pos": "n", "meaning": "土豆", "unit": "S1-U7-L3", "difficulty": 1}, "play": {"pos": "v", "meaning": "玩", "unit": "S2-U14-L1", "difficulty": 1}, "plane": {"pos": "n", "meaning": "飞机", "unit": "S1-U8-L3", "difficulty": 1}, "pig": {"pos": "n", "meaning": "猪", "unit": "S1-U7-L4", "difficulty": 1}, "phone": {"pos": "v", "meaning": "给…...打电话", "unit": "", "difficulty": 1}, "people": {"pos": "n", "meaning": "人", "unit": "", "difficulty": 1}, "pencil": {"pos": "n", "meaning": "铅笔", "unit": "", "difficulty": 1}, "pea": {"pos": "n", "meaning": "豌豆", "unit": "", "difficulty": 1}, "pe": {"pos": "n", "meaning": "体育", "unit": "S1-U10-L4", "difficulty": 1}, "paint": {"pos": "v", "meaning": "(用颜料)绘画", "unit": "", "difficulty": 1}, "one": {"pos": "pron", "meaning": "一个人(或物)", "unit": "", "difficulty": 1}, "old": {"pos": "adj", "meaning": "年老的", "unit": "", "difficulty": 1}, "now": {"pos": "adv", "meaning": "现在", "unit": "", "difficulty": 1}, "night": {"pos": "n", "meaning": "夜晚", "unit": "S1-U12-L5", "difficulty": 1}, "nice": {"pos": "adj", "meaning": "好的", "unit": "S1-U6-L3", "difficulty": 1}, "new": {"pos": "adj", "meaning": "新的", "unit": "S1-U9-L2", "difficulty": 1}, "mum": {"pos": "n", "meaning": "妈妈", "unit": "S1-U8-L4", "difficulty": 1}, "mouth": {"pos": "n", "meaning": "嘴巴", "unit": "", "difficulty": 1}, "mother": {"pos": "n", "meaning": "母亲", "unit": "", "difficulty": 1}, "morning": {"pos": "n", "meaning": "早上", "unit": "S1-U12-L5", "difficulty": 1}, "month": {"pos": "n", "meaning": "月", "unit": "", "difficulty": 1}, "monkey": {"pos": "n", "meaning": "猴子", "unit": "S1-U7-L1", "difficulty": 1}, "minute": {"pos": "n", "meaning": "分钟", "unit": "", "difficulty": 1}, "mine": {"pos": "pron", "meaning": "我的", "unit": "", "difficulty": 1}, "milk": {"pos": "n", "meaning": "牛奶", "unit": "S1-U5-L2", "difficulty": 1}, "men": {"pos": "n", "meaning": "男人(man 的复数)", "unit": "", "difficulty": 1}, "meat": {"pos": "n", "meaning": "肉类", "unit": "S1-U10-L3", "difficulty": 1}, "me": {"pos": "pron", "meaning": "我", "unit": "S1-U12-L2", "difficulty": 1}, "mat": {"pos": "n", "meaning": "地垫", "unit": "S2-U14-L4", "difficulty": 1}, "many": {"pos": "det", "meaning": "许多", "unit": "", "difficulty": 1}, "man": {"pos": "n", "meaning": "男人", "unit": "S1-U5-L1", "difficulty": 1}, "make": {"pos": "v", "meaning": "制造", "unit": "S1-U6-L3", "difficulty": 1}, "love": {"pos": "v", "meaning": "爱", "unit": "S1-U12-L2", "difficulty": 1}, "lots of": {"pos": "det", "meaning": "大量的", "unit": "", "difficulty": 1}, "long": {"pos": "adj", "meaning": "长的", "unit": "S1-U7-L5 ", "difficulty": 1}},
|
||
L2: {"dentist": {"pos": "n", "meaning": "牙医", "cefr": "A1", "cambridge": "Movers", "difficulty": 2}, "department": {"pos": "n", "meaning": "部门", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "department store": {"pos": "n", "meaning": "百货商店", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "describe": {"pos": "v", "meaning": "描述", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "desert": {"pos": "v", "meaning": "遗弃", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "design": {"pos": "v", "meaning": "设计", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "dessert": {"pos": "n", "meaning": "甜点", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "detailed": {"pos": "adj", "meaning": "详细的", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "diary": {"pos": "n", "meaning": "日记", "cefr": "A2", "cambridge": "KET/Flyers", "difficulty": 2}, "dictionary": {"pos": "n", "meaning": "词典", "cefr": "A2", "cambridge": "KET/Flyers", "difficulty": 2}, "die": {"pos": "v", "meaning": "消失;灭亡", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "difference": {"pos": "n", "meaning": "差别", "cefr": "A1", "cambridge": "Movers", "difficulty": 2}, "different": {"pos": "adj", "meaning": "不同的", "cefr": "A1", "cambridge": "Movers", "difficulty": 2}, "difficult": {"pos": "adj", "meaning": "困难的", "cefr": "A1", "cambridge": "Movers", "difficulty": 2}, "digital": {"pos": "adj", "meaning": "数字的", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "digital camera": {"pos": "n", "meaning": "数码相机", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "dinosaur": {"pos": "n", "meaning": "恐龙", "cefr": "A2", "cambridge": "KET/Flyers", "difficulty": 2}, "diploma": {"pos": "n", "meaning": "文凭", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "directions": {"pos": "n", "meaning": "方向", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "dirty": {"pos": "adj", "meaning": "脏的", "cefr": "Pre-A1", "cambridge": "Starters", "difficulty": 2}, "disco": {"pos": "n", "meaning": "迪斯科", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "discount": {"pos": "n", "meaning": "折扣", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "discover": {"pos": "v", "meaning": "发现", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "discuss": {"pos": "vt", "meaning": "讨论", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "dish": {"pos": "n", "meaning": "菜肴", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "display": {"pos": "v", "meaning": "显示", "cefr": "B1", "cambridge": "PET", "difficulty": 2}, "dive": {"pos": "v", "meaning": "潜水", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "diving": {"pos": "n", "meaning": "潜水", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "doctor": {"pos": "n", "meaning": "医生", "cefr": "A1", "cambridge": "Movers", "difficulty": 2}, "document": {"pos": "n", "meaning": "文件", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "dollar": {"pos": "n", "meaning": "美元", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "dot": {"pos": "n", "meaning": "点", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "double": {"pos": "v", "meaning": "使加倍", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "double room": {"pos": "phrase", "meaning": "双人间", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "doubt": {"pos": "v", "meaning": "怀疑", "cefr": "B1", "cambridge": "PET", "difficulty": 2}, "download": {"pos": "v", "meaning": "下载", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "downstairs": {"pos": "adj", "meaning": "楼下的", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "dozen": {"pos": "det", "meaning": "十二", "cefr": "B1", "cambridge": "PET", "difficulty": 2}, "draw": {"pos": "n", "meaning": "抽签", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "drawer": {"pos": "n", "meaning": "抽屉", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "dream": {"pos": "v", "meaning": "梦想", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "dress": {"pos": "v", "meaning": "穿衣服", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "dressed": {"pos": "adj", "meaning": "穿着衣服的", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "drive": {"pos": "v", "meaning": "驾车送(人)", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "driving licence": {"pos": "n", "meaning": "驾驶执照", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "drop": {"pos": "n", "meaning": "滴", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "drugstore": {"pos": "n", "meaning": "药店", "cefr": "A2", "cambridge": "KET", "difficulty": 2}, "drum": {"pos": "n", "meaning": "鼓", "cefr": "A2", "cambridge": "KET/Flyers", "difficulty": 2}, "dry": {"pos": "v", "meaning": "变干", "cefr": "A1", "cambridge": "Movers", "difficulty": 2}, "during": {"pos": "prep", "meaning": "在……期间", "cefr": "A2", "cambridge": "KET/Flyers", "difficulty": 2}, "duty-free": {"pos": "adj", "meaning": "免税的", "cefr": "B1", "cambridge": "PET", "difficulty": 2}, "dvd player": {"pos": "n", "meaning": "DVD播放机", "cefr": "A2", "cambridge": "KET", "difficulty": 2}}
|
||
};
|
||
|
||
var PATTERNS = {
|
||
L1: [{"structure": "be + adj", "module": "形容词结构", "module_id": "M1", "examples": ["I am happy today.", "I am sad today."], "meaning": ["今天我很开心。", "今天我很难过。"]}, {"structure": "feel + adj", "module": "系表结构", "module_id": "M1", "examples": ["I feel tired.", "I feel happy."], "meaning": ["我感到累。", "我感到开心。"]}, {"structure": "look + adj", "module": "系表结构", "module_id": "M1", "examples": ["You look happy.", "He looks tired."], "meaning": ["你看起来很高兴。", "他看起来累了。"]}, {"structure": "adj and adj", "module": "并列形容词", "module_id": "M1", "examples": ["The room is big and clean.", "The dog is small and cute."], "meaning": ["房间又大又干净。", "这只狗又小又可爱。"]}, {"structure": "S + V", "module": "动词与时态", "module_id": "M2", "examples": ["I read books.", "We go to school."], "meaning": ["我读书。", "我们去上学。"]}, {"structure": "S + be + V-ing", "module": "动词与时态", "module_id": "M2", "examples": ["I am reading now.", "She is cooking."], "meaning": ["我正在读书。", "她在做饭。"]}, {"structure": "do/does + V", "module": "动词与时态", "module_id": "M2", "examples": ["Do you like apples?", "Does he like milk?"], "meaning": ["你喜欢苹果吗?", "他喜欢牛奶吗?"]}, {"structure": "can + V", "module": "动词与时态", "module_id": "M2", "examples": ["I can swim.", "She can sing."], "meaning": ["我会游泳。", "她会唱歌。"]}],
|
||
L2: [{"structure": "be + adj", "module": "形容词结构", "module_id": "M1", "example": "I am happy today because the sun is shining.", "meaning": "今天我很开心,因为阳光灿烂。"}, {"structure": "feel/look + adj", "module": "系表结构", "module_id": "M1", "example": "I feel nervous before my first day of school.", "meaning": "开学第一天前,我感到有些紧张。"}, {"structure": "look + adj", "module": "系表结构", "module_id": "M1", "example": "He looks friendly, and he always says hello to everyone.", "meaning": "他看起来很友好,而且总是主动跟每个人打招呼。"}, {"structure": "adj and adj", "module": "并列形容词", "module_id": "M1", "example": "She has a nice and friendly dog.", "meaning": "她有一只温顺友好的狗。"}, {"structure": "Something doesn’t feel right.", "module": "感觉异常", "module_id": "M1", "example": "Something doesn’t feel right with my phone.", "meaning": "我的手机有点不太对劲。"}, {"structure": "This looks ..., but I’ll try my best.", "module": "状态对比", "module_id": "M1", "example": "This looks difficult, but I’ll try my best.", "meaning": "这看起来很难,但我会尽力而为。"}, {"structure": "You look ... now.", "module": "感觉状态", "module_id": "M1", "example": "You look happy now.", "meaning": "你现在看起来很开心。"}, {"structure": "The ice is too ... so we can’t ...", "module": "困难描述", "module_id": "M1", "example": "The ice is too thin so we can't skate on it.", "meaning": "冰面太薄了,我们不能在上面滑冰。"}, {"structure": "How are you feeling today?", "module": "be + adj 描述", "module_id": "M1", "example": "How are you feeling today? \nYou look happy!", "meaning": "你今天感觉怎么样? \n你看起来挺开心的!"}, {"structure": "I’m feeling ... today.", "module": "be + adj 描述", "module_id": "M1", "example": "I'm feeling tired today.", "meaning": "今天我感觉有点累。"}, {"structure": "It’s very ... outside today.", "module": "be + adj 描述", "module_id": "M1", "example": "It's very cold outside today.", "meaning": "今天外面非常冷。"}, {"structure": "You look ... in this picture.", "module": "be + adj 描述", "module_id": "M1", "example": "You look happy in this picture.", "meaning": "在这张照片里,你看起来很开心。"}, {"structure": "My room is always ... and ....", "module": "be + adj 描述", "module_id": "M1", "example": "My room is always warm and cozy.", "meaning": "我的房间总是温暖又舒适。"}, {"structure": "The movie was really ....", "module": "be + adj 描述", "module_id": "M1", "example": "The movie was really funny.", "meaning": "这部电影真是太好笑了。"}, {"structure": "Our teacher is very ....", "module": "be + adj 描述", "module_id": "M1", "example": "Our teacher is very patient.", "meaning": "我们的老师非常有耐心。"}, {"structure": "This bag is too ....", "module": "be + adj 描述", "module_id": "M1", "example": "This bag is too small for all my books.", "meaning": "这个包装不下我所有的书。"}, {"structure": "Are you sure this is ....?", "module": "be + adj 描述", "module_id": "M1", "example": "Are you sure this is warm enough?", "meaning": "你确定这够暖和吗?"}, {"structure": "I’m not sure if it’s ....", "module": "be + adj 描述", "module_id": "M1", "example": "I’m not sure if it’s warm enough to swim today.", "meaning": "今天不太确定水温是否适合游泳。"}, {"structure": "What colour is ...?", "module": "be + adj 描述", "module_id": "M1", "example": "What color is your new school uniform?", "meaning": "你的新校服是什么颜色的?"}, {"structure": "It’s ...", "module": "be + adj 描述", "module_id": "M1", "example": "It's sunny today.", "meaning": "今天天气晴朗。"}, {"structure": "Are you tired?", "module": "be + adj 描述", "module_id": "M1", "example": "Are you hungry after playing?", "meaning": "玩完之后你饿了吗?"}, {"structure": "Yes, I’m a bit ....", "module": "be + adj 描述", "module_id": "M1", "example": "Yes, I’m a bit nervous about my first day at school.", "meaning": "是的,我对开学第一天有点紧张。"}, {"structure": "No, I’m not ....", "module": "be + adj 描述", "module_id": "M1", "example": "No, I'm not tired.", "meaning": "不,我不累。"}, {"structure": "It’s so ... today!", "module": "be + adj 描述", "module_id": "M1", "example": "It's so sunny today!", "meaning": "今天阳光真好啊!"}, {"structure": "This looks ....", "module": "be + adj 描述", "module_id": "M1", "example": "This looks delicious.", "meaning": "这看起来很好吃。"}, {"structure": "You’re very ....", "module": "be + adj 描述", "module_id": "M1", "example": "You're very kind.", "meaning": "你真是太好了。"}, {"structure": "How’s the weather today?", "module": "be + adj 描述", "module_id": "M1", "example": "How’s the weather today? \nIt's sunny and warm.", "meaning": "今天天气怎么样? \n阳光很好,也很暖和。"}, {"structure": "It’s ... today.", "module": "be + adj 描述", "module_id": "M1", "example": "It's sunny today.", "meaning": "今天天气晴朗。"}, {"structure": "Is it hot or cold?", "module": "be + adj 描述", "module_id": "M1", "example": "Is it hot or cold?", "meaning": "是热还是冷?"}, {"structure": "It’s not very ....", "module": "be + adj 描述", "module_id": "M1", "example": "It's not very expensive.", "meaning": "{中文翻译}\n这个不是很贵。"}, {"structure": "The sky is so ....", "module": "be + adj 描述", "module_id": "M1", "example": "The sky is so blue today.", "meaning": "今天天空真蓝。"}, {"structure": "Everything looks....", "module": "be + adj 描述", "module_id": "M1", "example": "Everything looks tidy.", "meaning": "一切看起来都井井有条。"}, {"structure": "The view is really ....", "module": "be + adj 描述", "module_id": "M1", "example": "The view is really beautiful.", "meaning": "景色真是太美了。"}, {"structure": "That was very ....", "module": "be + adj 描述", "module_id": "M1", "example": "That was very interesting.", "meaning": "那可真有意思。"}, {"structure": "You seem ....", "module": "be + adj 描述", "module_id": "M1", "example": "You seem tired this morning.", "meaning": "今天早上你看起来有点累。"}, {"structure": "That’s really ...!", "module": "be + adj 描述", "module_id": "M1", "example": "That’s really amazing!", "meaning": "这真是太棒了!"}, {"structure": "The story is very ....", "module": "be + adj 描述", "module_id": "M1", "example": "The story is very exciting.", "meaning": "这个故事非常扣人心弦。"}, {"structure": "My parents are both ....", "module": "be + adj 描述", "module_id": "M1", "example": "My parents are both very busy on weekdays.", "meaning": "我父母在工作日都非常忙。"}, {"structure": "I’m afraid it’s ....", "module": "be + adj 描述", "module_id": "M1", "example": "I’m afraid it’s too cold.", "meaning": "恐怕天气太冷了。"}, {"structure": "It’s difficult to ....", "module": "be + adj 描述", "module_id": "M1", "example": "It's difficult to find a good restaurant.", "meaning": "很难找到一家好餐馆。"}, {"structure": "It’s strange that ....", "module": "be + adj 描述", "module_id": "M1", "example": "It's strange that the cat is sleeping so much today.", "meaning": "今天这只猫睡得这么多,真是奇怪。"}, {"structure": "The food smells....", "module": "be + adj 描述", "module_id": "M1", "example": "The food smells wonderful.", "meaning": "这食物闻起来真香。"}, {"structure": "-er than", "module": "比较级", "module_id": "M2", "example": "He is taller than me, but I run faster than him.", "meaning": "他比我高,但我跑得比他快。"}, {"structure": "What did you do yesterday?", "module": "动词与时态", "module_id": "M2", "example": "What did you do yesterday? I watched a movie with my family.", "meaning": "你昨天干什么了?我和家人一起看了场电影。"}, {"structure": "I ... yesterday.", "module": "动词与时态", "module_id": "M2", "example": "I called my grandmother yesterday.", "meaning": "昨天我给奶奶打了个电话。"}, {"structure": "What are you doing now?", "module": "动词与时态", "module_id": "M2", "example": "What are you doing now? \nI am helping my mom cook dinner.", "meaning": "你现在在做什么? \n我正在帮我妈妈做晚饭。"}, {"structure": "I’m ... now.", "module": "动词与时态", "module_id": "M2", "example": "I'm eating lunch now.", "meaning": "我正在吃午饭。"}, {"structure": "What will you do tomorrow?", "module": "动词与时态", "module_id": "M2", "example": "What will you do tomorrow?", "meaning": "你明天打算做什么?"}]
|
||
};
|
||
|
||
var BRITISH_SPELLING_MAP = {"color": "colour", "colors": "colours", "colored": "coloured", "coloring": "colouring", "favorite": "favourite", "favorites": "favourites", "center": "centre", "centers": "centres", "centered": "centred", "meter": "metre", "meters": "metres", "theater": "theatre", "theaters": "theatres", "traveling": "travelling", "traveled": "travelled", "traveler": "traveller", "canceled": "cancelled", "canceling": "cancelling", "jewelry": "jewellery", "organize": "organise", "organizes": "organises", "organized": "organised", "organizing": "organising", "realize": "realise", "realizes": "realises", "realized": "realised", "realizing": "realising", "recognize": "recognise", "recognizes": "recognises", "recognized": "recognised", "recognizing": "recognising", "apologize": "apologise", "apologizes": "apologises", "apologized": "apologised", "license": "licence", "defense": "defence", "offense": "offence", "pretense": "pretence", "dialog": "dialogue", "catalog": "catalogue", "analog": "analogue", "neighbor": "neighbour", "neighbors": "neighbours", "neighborhood": "neighbourhood", "honor": "honour", "honors": "honours", "honored": "honoured", "humor": "humour", "labor": "labour", "flavor": "flavour", "flavors": "flavours", "behavior": "behaviour", "behaviors": "behaviours", "rumor": "rumour", "program": "programme", "check": "cheque", "gray": "grey", "tire": "tyre", "tires": "tyres", "mold": "mould", "plow": "plough", "aluminum": "aluminium", "sulfur": "sulphur", "mom": "mum", "mommy": "mummy", "soccer": "football", "vacation": "holiday", "vacations": "holidays", "elevator": "lift", "elevators": "lifts", "apartment": "flat", "apartments": "flats", "trash": "rubbish", "garbage": "rubbish", "cookie": "biscuit", "cookies": "biscuits", "candy": "sweet", "candies": "sweets", "faucet": "tap", "faucets": "taps", "sidewalk": "pavement", "sidewalks": "pavements", "sneakers": "trainers", "pants": "trousers", "eraser": "rubber", "erasers": "rubbers", "fall": "autumn", "pajamas": "pyjamas", "highway": "motorway", "highways": "motorways", "railroad": "railway", "airplane": "aeroplane", "airplanes": "aeroplanes", "movie": "film", "movies": "films", "schedule": "timetable", "schedules": "timetables", "yard": "garden", "yards": "gardens", "cell phone": "mobile phone", "cell phones": "mobile phones", "gas": "petrol", "gas station": "petrol station", "mail": "post", "mailbox": "postbox", "mailman": "postman", "intersection": "crossroads", "intersections": "crossroads", "popsicle": "ice lolly", "popsicles": "ice lollies", "french fries": "chips", "eggplant": "aubergine", "zucchini": "courgette", "cilantro": "coriander", "rutabaga": "swede"};
|
||
|
||
var NEGATIVE_SELF_REGEX = ["i\\s*(?:'m|am)\\s+not\\s+good\\s+at", "i\\s*(?:'m|am)\\s+(?:so\\s+)?(?:bad|terrible|awful|stupid|dumb|ugly|fat|useless|hopeless)", "i\\s+(?:can't|cannot)\\s+do\\s+(?:it|this|that|anything)", "i\\s+(?:hate|dislike)\\s+(?:myself|me)", "i\\s*(?:'m|am)\\s+(?:too|so)\\s+(?:slow|dumb|stupid|weak)", "nobody\\s+(?:likes|loves)\\s+me", "i\\s*(?:'m|am)\\s+(?:never|always)\\s+(?:wrong|bad)"];
|
||
|
||
var TYPE_STAGE_RULES = {
|
||
listening_drag: ['L1'],
|
||
listening_choicePic: ['L1'],
|
||
listening_tableCloze: ['L2'],
|
||
listening_choiceLong: ['L2'],
|
||
listening_choiceShort: ['L2'],
|
||
listening_matchInfo: ['L2'],
|
||
reading_pic_judge: ['L1','L2'],
|
||
reading_pic_qa: ['L1','L2'],
|
||
reading_matchInfo: ['L2'],
|
||
reading_matchPara: ['L2'],
|
||
reading_choiceLong: ['L2'],
|
||
reading_cloze: ['L2'],
|
||
reading_openCloze: ['L2'],
|
||
writing_pic_qa: ['L1','L2'],
|
||
writing_email: ['L2'],
|
||
writing_picWrite: ['L2'],
|
||
speaking_pic_qa: ['L1'],
|
||
speaking_pic_recognize: ['L1'],
|
||
speaking_qa: ['L1','L2'],
|
||
speaking_topic: ['L2']
|
||
};
|
||
|
||
var TYPE_ALIASES = {
|
||
'核心听力选择': 'listening_choicePic', '核心听力拖拽': 'listening_drag',
|
||
'听力拖拽': 'listening_drag', '听力选择': 'listening_choicePic', '听力选图': 'listening_choicePic',
|
||
'听音选图': 'listening_choicePic', '听力长对话': 'listening_choiceLong',
|
||
'听力短对话': 'listening_choiceShort', '听力信息匹配': 'listening_matchInfo',
|
||
'听力表格填空': 'listening_tableCloze', '听力填空': 'listening_tableCloze',
|
||
'阅读单选': 'reading_choiceLong', '阅读判断': 'reading_pic_judge',
|
||
'看图判断': 'reading_pic_judge', '看图回答': 'reading_pic_qa',
|
||
'阅读信息匹配': 'reading_matchInfo', '阅读段落匹配': 'reading_matchPara',
|
||
'阅读完形': 'reading_cloze', '阅读开放填空': 'reading_openCloze',
|
||
'写作看图': 'writing_pic_qa', '写作邮件': 'writing_email',
|
||
'口语日常': 'speaking_qa', '口语看图': 'speaking_pic_qa',
|
||
'口语话题': 'speaking_topic', '口语识物': 'speaking_pic_recognize',
|
||
'中对话跟读': 'speaking_qa', '中对话朗读': 'speaking_qa',
|
||
'中对话选读': 'listening_choiceShort', '中对话选义': 'listening_choiceShort',
|
||
'中对话挖空': 'reading_cloze', '中对话组句': 'reading_cloze',
|
||
'中对话选图': 'listening_choicePic', '中对话练习': 'listening_choiceShort',
|
||
'中对话口语': 'speaking_qa', '中对话听选': 'listening_choiceShort',
|
||
'选词补句': 'reading_cloze', '选词填空': 'reading_cloze',
|
||
'图片单选': 'reading_pic_judge', '图片多选': 'reading_pic_judge',
|
||
'选词排序': 'reading_cloze', '跟读判断': 'speaking_qa',
|
||
'朗读练习': 'speaking_qa', '选图填空': 'listening_choicePic',
|
||
'中图片单选': 'reading_pic_judge', '中选图单选': 'listening_choicePic',
|
||
'中跟读': 'speaking_qa', '中跟读练习': 'speaking_qa'
|
||
};
|
||
|
||
var RULES = {
|
||
dialog: { maxWordsPerSentence: 8, maxWordsCoreSentence: 7, warnWordsPerSentence: 10 },
|
||
textFormat: { allowMarkdown: false },
|
||
vocabulary: { allowL2WordsInL1: false },
|
||
spelling: { preferBritish: true }
|
||
};
|
||
|
||
// ── Utils ──
|
||
function extractWords(text) {
|
||
if (!text) return [];
|
||
return text.toLowerCase().replace(/[^a-z\s'-]/g, ' ').split(/\s+/).filter(function(w) { return w.length > 1; });
|
||
}
|
||
|
||
function normalizeType(name) {
|
||
if (!name) return '';
|
||
var clean = name.trim();
|
||
return TYPE_ALIASES[clean] || clean.toLowerCase().replace(/\s+/g, '_');
|
||
}
|
||
|
||
// ── 1. Vocabulary check ──
|
||
function checkVocabulary(content, prefix) {
|
||
var issues = [];
|
||
var words = (content && content.keyPreview) || [];
|
||
var level = (prefix || 'L1').toUpperCase();
|
||
var allowed = level === 'L1' ? WORD_LISTS.L1 : Object.assign({}, WORD_LISTS.L1, WORD_LISTS.L2);
|
||
|
||
words.forEach(function(raw) {
|
||
var w = (raw || '').toLowerCase().trim();
|
||
if (!w) return;
|
||
if (allowed[w]) {
|
||
var info = allowed[w];
|
||
issues.push({ level: 'good', word: w, message: '"' + w + '" 在' + level + '词库内 (' + info.pos + ' ' + info.meaning + ')', detail: info });
|
||
} else {
|
||
issues.push({ level: 'danger', word: w, message: '"' + w + '" 不在' + level + '词库中,疑似超纲词汇', detail: null });
|
||
}
|
||
});
|
||
|
||
var failCount = issues.filter(function(i) { return i.level === 'danger'; }).length;
|
||
return {
|
||
title: '词汇超纲检测',
|
||
issues: issues,
|
||
passCount: issues.length - failCount,
|
||
failCount: failCount,
|
||
summary: issues.length === 0 ? '未检测到目标词汇'
|
||
: failCount === 0 ? '全部 ' + issues.length + ' 个目标词汇均在词库范围内'
|
||
: failCount + ' 个词汇疑似超纲 / ' + issues.length + ' 个目标词汇'
|
||
};
|
||
}
|
||
|
||
// ── 2. British spelling ──
|
||
function checkBritishSpelling(texts) {
|
||
var issues = [];
|
||
var allText = (texts || []).filter(Boolean).join(' ');
|
||
var words = extractWords(allText);
|
||
var seen = {};
|
||
|
||
words.forEach(function(w) {
|
||
var lowered = w.toLowerCase();
|
||
if (seen[lowered]) return;
|
||
if (BRITISH_SPELLING_MAP[lowered]) {
|
||
seen[lowered] = true;
|
||
issues.push({ level: 'warn', word: w, suggested: BRITISH_SPELLING_MAP[lowered],
|
||
message: '"' + w + '" 为美式拼写,建议改为英式 "' + BRITISH_SPELLING_MAP[lowered] + '"' });
|
||
}
|
||
});
|
||
|
||
return {
|
||
title: '英式拼写检测',
|
||
issues: issues, passCount: 0, failCount: issues.length,
|
||
summary: issues.length === 0 ? '未检测到美式拼写' : '发现 ' + issues.length + ' 处美式拼写'
|
||
};
|
||
}
|
||
|
||
// ── 3. Markdown detection ──
|
||
function checkMarkdownUsage(texts) {
|
||
var issues = [];
|
||
var text = (texts || []).filter(Boolean).join('\n');
|
||
var mdPat = /\*\*|__|`[^`]+`|^#{1,6}\s|^\s*[-*+]\s|^\s*\d+\.\s|\*[^*]+\*|_[^_]+_/gm;
|
||
var match;
|
||
while ((match = mdPat.exec(text)) !== null) {
|
||
var start = Math.max(0, match.index - 20);
|
||
var end = Math.min(text.length, match.index + 40);
|
||
issues.push({ level: 'warn', mark: match[0],
|
||
context: '...' + text.substring(start, end).replace(/\n/g, ' ') + '...',
|
||
message: '检测到 Markdown 标记 "' + match[0] + '",应移除(文本输出禁止 Markdown)',
|
||
position: match.index });
|
||
}
|
||
return { title: 'Markdown格式检测', issues: issues, passCount: 0, failCount: issues.length,
|
||
summary: issues.length === 0 ? '未检测到 Markdown 标记' : '发现 ' + issues.length + ' 处 Markdown 标记' };
|
||
}
|
||
|
||
// ── 4. Punctuation ──
|
||
function checkPunctuation(texts) {
|
||
var issues = [];
|
||
(texts || []).filter(Boolean).forEach(function(text) {
|
||
var cnMatch = text.match(/[\u3001\u3002\uff0c\uff1b\uff1a\u201c\u201d\u2018\u2019\uff01\uff08\uff09\u300a\u300b]/g);
|
||
if (cnMatch) {
|
||
issues.push({ level: 'warn', text: text.substring(0, 60), found: cnMatch,
|
||
message: '文本包含中文标点(英文内容应使用半角标点)' });
|
||
}
|
||
if (/~/.test(text)) issues.push({ level: 'warn', text: text, message: '检测到非标准标点 "~",应使用标准英文标点' });
|
||
if (/!!!|\?\?\?|!!\?|\?!!/.test(text)) issues.push({ level: 'warn', text: text, message: '检测到连续感叹号/问号,应使用标准英文标点' });
|
||
});
|
||
return { title: '标点符号规范', issues: issues, passCount: 0, failCount: issues.length,
|
||
summary: issues.length === 0 ? '标点符号使用规范' : '发现 ' + issues.length + ' 处标点符号不规范' };
|
||
}
|
||
|
||
// ── 5. Type-stage match ──
|
||
function checkTypeMatch(name, prefix) {
|
||
var level = (prefix || 'L1').toUpperCase();
|
||
var normalized = normalizeType(name);
|
||
var allowed = TYPE_STAGE_RULES[normalized];
|
||
if (!allowed) {
|
||
return { title: '题型-阶段匹配', resolvedType: normalized, isUnknown: true,
|
||
message: '组件类型 "' + name + '" 未在已知题型表中匹配,无法校验阶段归属' };
|
||
}
|
||
if (allowed.indexOf(level) >= 0) {
|
||
return { title: '题型-阶段匹配', resolvedType: normalized, allowedStages: allowed, isMatch: true,
|
||
message: '题型 "' + name + '" -> ' + normalized + ' 在 ' + level + ' 阶段允许' };
|
||
}
|
||
return { title: '题型-阶段匹配', resolvedType: normalized, allowedStages: allowed, isMatch: false,
|
||
message: '题型 "' + name + '" -> ' + normalized + ' 仅允许 ' + allowed.join(', ') + ',' + level + ' 不允许!' };
|
||
}
|
||
|
||
// ── 6. Dialog quality ──
|
||
function checkDialogQuality(lines, prefix) {
|
||
var issues = [];
|
||
var isL1 = (prefix || 'L1').toUpperCase() === 'L1';
|
||
var maxWords = isL1 ? 7 : RULES.dialog.maxWordsPerSentence;
|
||
var warnWords = RULES.dialog.warnWordsPerSentence;
|
||
|
||
(lines || []).filter(Boolean).forEach(function(line) {
|
||
var text = (line.text || line.content || line.sentence || line.dialog || '').trim();
|
||
if (!text) return;
|
||
var wc = text.split(/\s+/).length;
|
||
if (wc > warnWords) {
|
||
issues.push({ level: 'danger', text: text, wordCount: wc,
|
||
message: '台词 ' + wc + ' 词,超过 ' + warnWords + ' 词上限,建议拆分为 2-3 个短句' });
|
||
} else if (wc > maxWords) {
|
||
issues.push({ level: 'warn', text: text, wordCount: wc,
|
||
message: '台词 ' + wc + ' 词,超过 ' + maxWords + ' 词建议上限' });
|
||
}
|
||
for (var j = 0; j < NEGATIVE_SELF_REGEX.length; j++) {
|
||
if (new RegExp(NEGATIVE_SELF_REGEX[j], 'i').test(text)) {
|
||
issues.push({ level: 'danger', text: text,
|
||
message: '台词含负面自我评价,违反价值观导向规范,应替换为正向表达' });
|
||
break;
|
||
}
|
||
}
|
||
});
|
||
|
||
return { title: '对话台词质量', issues: issues, passCount: lines.length - issues.length, failCount: issues.length,
|
||
summary: issues.length === 0 ? lines.length + ' 句台词均符合质量标准' : issues.length + ' 项质量问题' };
|
||
}
|
||
|
||
// ── 7. Key exposure ──
|
||
function checkKeyExposure(targets, allDialogText) {
|
||
var issues = [];
|
||
var dialogLower = (allDialogText || '').toLowerCase();
|
||
(targets || []).filter(Boolean).forEach(function(w) {
|
||
var lowered = w.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||
var count = (dialogLower.match(new RegExp('\\b' + lowered + '\\b', 'g')) || []).length;
|
||
if (count === 0) {
|
||
issues.push({ level: 'danger', word: w, message: '目标词 "' + w + '" 在台词中未出现,知识点零暴露' });
|
||
} else if (count === 1) {
|
||
issues.push({ level: 'warn', word: w, count: count, message: '目标词 "' + w + '" 仅在台词中出现 1 次,暴露不充分' });
|
||
} else {
|
||
issues.push({ level: 'good', word: w, count: count, message: '"' + w + '" 出现 ' + count + ' 次,曝光充分' });
|
||
}
|
||
});
|
||
var passCnt = issues.filter(function(i) { return i.level === 'good'; }).length;
|
||
return { title: '知识点曝光度', issues: issues, passCount: passCnt, failCount: issues.length - passCnt,
|
||
summary: passCnt === issues.length ? '全部 ' + issues.length + ' 个知识点曝光充分' : (issues.length - passCnt) + ' 个知识点曝光不足' };
|
||
}
|
||
|
||
// ── 8. Pattern compliance ──
|
||
function checkPatternCompliance(sentences, prefix) {
|
||
var issues = [];
|
||
var level = (prefix || 'L1').toUpperCase();
|
||
var allPatterns = level === 'L1' ? PATTERNS.L1 : PATTERNS.L1.concat(PATTERNS.L2);
|
||
var toCheck = (sentences || []).filter(Boolean).slice(0, 10);
|
||
|
||
toCheck.forEach(function(sentence) {
|
||
var lowered = sentence.toLowerCase();
|
||
var matched = false;
|
||
for (var p = 0; p < allPatterns.length; p++) {
|
||
var pat = allPatterns[p];
|
||
var struct = pat.structure.toLowerCase();
|
||
var keywords = struct.replace(/[^a-z\s]/g, ' ').split(/\s+/).filter(function(k) { return k.length > 2; });
|
||
var matchedKw = keywords.filter(function(kw) { return lowered.indexOf(kw) >= 0; });
|
||
if (matchedKw.length >= Math.ceil(keywords.length * 0.5) && keywords.length >= 2) {
|
||
matched = true;
|
||
issues.push({ level: 'good', sentence: sentence.substring(0, 80), pattern: pat.structure, module: pat.module,
|
||
message: '句型近似匹配到 "' + pat.structure + '" (' + pat.module + ')' });
|
||
break;
|
||
}
|
||
}
|
||
if (!matched) {
|
||
issues.push({ level: 'info', sentence: sentence.substring(0, 80),
|
||
message: '句子未在' + level + '句型库中匹配到已知结构' });
|
||
}
|
||
});
|
||
|
||
return { title: '句型合规检测', issues: issues, passCount: issues.filter(function(i) { return i.level === 'good'; }).length,
|
||
failCount: issues.filter(function(i) { return i.level !== 'good'; }).length,
|
||
summary: issues.length === 0 ? '未检测到待校验句型' : '完成句型合规检查' };
|
||
}
|
||
|
||
// ── Main API ──
|
||
function validate(content, prefix) {
|
||
var level = (prefix || 'L1').toUpperCase();
|
||
var allTexts = [];
|
||
var allDialogs = [];
|
||
|
||
if (content.realContent) {
|
||
var rc = content.realContent;
|
||
[rc.dialogs, rc.targets, rc.questions, rc.learning, rc.feedback].forEach(function(arr) {
|
||
if (Array.isArray(arr)) { allDialogs.push.apply(allDialogs, arr); allTexts.push.apply(allTexts, arr); }
|
||
else if (arr) { allDialogs.push(arr); allTexts.push(arr); }
|
||
});
|
||
}
|
||
|
||
var dialogLines = allDialogs.map(function(text) { return { text: text, isPoint: false }; });
|
||
var results = [];
|
||
|
||
var vr = checkVocabulary(content, level);
|
||
if (vr.issues.length > 0) results.push(vr);
|
||
|
||
var sr = checkBritishSpelling(allTexts);
|
||
if (sr.issues.length > 0) results.push(sr);
|
||
|
||
var mr = checkMarkdownUsage(allTexts);
|
||
if (mr.issues.length > 0) results.push(mr);
|
||
|
||
var pr = checkPunctuation(allTexts);
|
||
if (pr.issues.length > 0) results.push(pr);
|
||
|
||
if (dialogLines.length > 0) { results.push(checkDialogQuality(dialogLines, level)); }
|
||
|
||
var targets = content.keyPreview || [];
|
||
var dialogText = allDialogs.join(' ');
|
||
if (targets.length > 0 && dialogText) { results.push(checkKeyExposure(targets, dialogText)); }
|
||
|
||
if (allDialogs.length > 0) { results.push(checkPatternCompliance(allDialogs, level)); }
|
||
|
||
var totalIssues = results.reduce(function(sum, r) { return sum + r.issues.length; }, 0);
|
||
var dangerCount = results.reduce(function(sum, r) { return sum + r.issues.filter(function(i) { return i.level === 'danger'; }).length; }, 0);
|
||
var warnCount = results.reduce(function(sum, r) { return sum + r.issues.filter(function(i) { return i.level === 'warn'; }).length; }, 0);
|
||
|
||
return {
|
||
level: level, timestamp: new Date().toISOString(),
|
||
totalChecks: results.length, totalIssues: totalIssues, dangerCount: dangerCount, warnCount: warnCount,
|
||
results: results,
|
||
summary: totalIssues === 0 ? '内容校验通过' : (dangerCount > 0 ? dangerCount + ' 项严重问题,' + warnCount + ' 项警告' : warnCount + ' 项可优化项')
|
||
};
|
||
}
|
||
|
||
// ── Export ──
|
||
global.PedagogyRules = {
|
||
VERSION: '1.0.0',
|
||
validate: validate,
|
||
checkTypeMatch: checkTypeMatch,
|
||
checkVocabulary: checkVocabulary,
|
||
checkBritishSpelling: checkBritishSpelling,
|
||
checkMarkdownUsage: checkMarkdownUsage,
|
||
checkPunctuation: checkPunctuation,
|
||
checkDialogQuality: checkDialogQuality,
|
||
checkKeyExposure: checkKeyExposure,
|
||
checkPatternCompliance: checkPatternCompliance,
|
||
WORD_LISTS: WORD_LISTS, PATTERNS: PATTERNS, TYPE_STAGE_RULES: TYPE_STAGE_RULES,
|
||
BRITISH_SPELLING_MAP: BRITISH_SPELLING_MAP, RULES: RULES
|
||
};
|
||
|
||
console.log('[PedagogyRules] v1.0.0 | L1 words:' + Object.keys(WORD_LISTS.L1).length +
|
||
' L2 words:' + Object.keys(WORD_LISTS.L2).length + ' L1 patterns:' + PATTERNS.L1.length +
|
||
' L2 patterns:' + PATTERNS.L2.length + ' Type rules:' + Object.keys(TYPE_STAGE_RULES).length +
|
||
' British:' + Object.keys(BRITISH_SPELLING_MAP).length);
|
||
|
||
})(typeof window !== 'undefined' ? window : this);
|