├── .gitattributes ├── .gitignore ├── README.md ├── box.png ├── box.psd ├── btn.psd ├── caution.psd ├── choose.psd ├── code0.jpg ├── code1.jpg ├── debug.log ├── iconfinder_pencil_1055013.png ├── iconfinder_pencil_1055013.psd ├── mpproj ├── app.js ├── app.json ├── app.wxss ├── pages │ └── index │ │ ├── index.js │ │ ├── index.json │ │ ├── index.wxml │ │ └── index.wxss ├── project.config.json ├── static │ ├── alert_dlg_bg.png │ ├── btn_bg.jpg │ ├── btn_ok.png │ ├── code.jpg │ ├── icons │ │ ├── brush.jpg │ │ ├── choose.jpg │ │ ├── eraser.jpg │ │ ├── foot.jpg │ │ ├── hand.png │ │ ├── mean.jpg │ │ ├── pen.png │ │ └── search.png │ ├── star_1.png │ ├── star_2.png │ └── star_3.png └── teacher │ └── pages │ └── index │ ├── index.js │ ├── index.json │ ├── index.wxml │ ├── index.wxss │ ├── teacher.js │ └── util.js ├── ok.psd ├── screenrecorder.gif ├── screenshot0.png ├── screenshot1.png ├── screenshot2.png ├── screenshot3.png ├── star.psd └── teacher ├── .gitignore ├── .vscode └── settings.json ├── ARTICLS ├── Cargo.toml ├── PINYIN ├── POEMS ├── build.cmd ├── gendict ├── .gitignore ├── ARTICLS ├── Cargo.toml ├── DICT ├── DICT.zip ├── KaiTi_GB2312.ttf ├── KaiTi_GB2312_0.ttf ├── KaiTi_GB2312_1.ttf ├── OLD_STROKE.map ├── PINYIN ├── POEMS ├── WORD ├── gb2312.data ├── handwriting-zh_CN-gb2312.json ├── src │ └── main.rs ├── strokes.bzip ├── strokes.bzip.txt ├── stylesheet0.css ├── stylesheet1.css ├── test.js ├── word.json ├── xml2json.js ├── 《宋词三百首》.txt ├── 唐诗三百首.txt └── 课文.txt ├── replace.js └── src ├── main.rs ├── mmp.rs ├── pdollarplus.rs ├── platform.rs ├── teacher.rs └── web.rs /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 识字画板小程序源码 2 | 3 | 小程序二维码: 4 | 5 | 6 | 7 | 代码目录结构说明: 8 | 9 | /teacher Rust代码 10 | 11 | /mpproj 微信小程序项目代码 12 | 13 | 其中, 14 | 15 | 手写笔画识别(pdollarplus.rs)是基于[$P+ Point-Cloud Recognizer](http://depts.washington.edu/madlab/proj/dollar/pdollarplus.html "多笔画识别器")多笔画识别器改写的Rust版本。 16 | 17 | 笔画数据库是基于https://github.com/huzheng001/stroke-editor 的笔画识别器的数据和源码改写的Rust版本,Rust版本源码地址:https://github.com/planet0104/rust-stroke-editor 18 | 19 | 20 | 小程序运行截图: 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/box.png -------------------------------------------------------------------------------- /box.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/box.psd -------------------------------------------------------------------------------- /btn.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/btn.psd -------------------------------------------------------------------------------- /caution.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/caution.psd -------------------------------------------------------------------------------- /choose.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/choose.psd -------------------------------------------------------------------------------- /code0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/code0.jpg -------------------------------------------------------------------------------- /code1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/code1.jpg -------------------------------------------------------------------------------- /debug.log: -------------------------------------------------------------------------------- 1 | [1130/140808:ERROR:renderer_main.cc(203)] Running without renderer sandbox 2 | [1130/140809:INFO:CONSOLE(0)] "The Content-Security-Policy directive 'block-all-mixed-content' is implemented behind a flag which is currently disabled. 3 | ", source: https://github.com/lifthrasiir/rust-encoding/blob/master/README.md (0) 4 | [1130/140809:INFO:CONSOLE(0)] "The Content-Security-Policy directive 'manifest-src' is implemented behind a flag which is currently disabled. 5 | ", source: https://github.com/lifthrasiir/rust-encoding/blob/master/README.md (0) 6 | [1130/140809:ERROR:child_discardable_shared_memory_manager.cc(266)] size: 4194304 7 | [1130/140810:INFO:CONSOLE(112)] "Uncaught RangeError: Maximum call stack size exceeded", source: (112) 8 | [1130/140811:ERROR:child_discardable_shared_memory_manager.cc(266)] size: 33177600 9 | [1130/140811:ERROR:child_discardable_shared_memory_manager.cc(266)] size: 4194304 10 | [1130/140812:ERROR:child_discardable_shared_memory_manager.cc(266)] size: 33177600 11 | [1130/140814:ERROR:child_discardable_shared_memory_manager.cc(266)] size: 33177600 12 | [1130/140814:ERROR:child_discardable_shared_memory_manager.cc(266)] size: 4194304 13 | [1130/140907:ERROR:renderer_main.cc(203)] Running without renderer sandbox 14 | [1130/140908:INFO:CONSOLE(0)] "The Content-Security-Policy directive 'block-all-mixed-content' is implemented behind a flag which is currently disabled. 15 | ", source: https://github.com/lifthrasiir/rust-encoding/blob/master/README.md (0) 16 | [1130/140908:INFO:CONSOLE(0)] "The Content-Security-Policy directive 'manifest-src' is implemented behind a flag which is currently disabled. 17 | ", source: https://github.com/lifthrasiir/rust-encoding/blob/master/README.md (0) 18 | [1130/140908:ERROR:child_discardable_shared_memory_manager.cc(266)] size: 4194304 19 | -------------------------------------------------------------------------------- /iconfinder_pencil_1055013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/iconfinder_pencil_1055013.png -------------------------------------------------------------------------------- /iconfinder_pencil_1055013.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/iconfinder_pencil_1055013.psd -------------------------------------------------------------------------------- /mpproj/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | "pages/index/index" 4 | ], 5 | "cloud": "true", 6 | "subpackages": [ 7 | { 8 | "root": "teacher", 9 | "pages": [ 10 | "pages/index/index" 11 | ] 12 | } 13 | ], 14 | "window": { 15 | "backgroundTextStyle": "light", 16 | "navigationBarBackgroundColor": "#1e756d", 17 | "navigationBarTitleText": "识字画板", 18 | "navigationBarTextStyle": "white" 19 | } 20 | } -------------------------------------------------------------------------------- /mpproj/pages/index/index.js: -------------------------------------------------------------------------------- 1 | //index.js 2 | //获取应用实例 3 | const app = getApp(); 4 | 5 | Page({ 6 | data: {}, 7 | onReady: function(){ 8 | wx.redirectTo({ 9 | url: '/teacher/pages/index/index' 10 | }); 11 | }, 12 | onLoad: function () { 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /mpproj/pages/index/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "backgroundColor": "#1e756d" 3 | } -------------------------------------------------------------------------------- /mpproj/pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 正在启动... 4 | 5 | -------------------------------------------------------------------------------- /mpproj/pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | /**index.wxss**/ 2 | page{ 3 | background: #1e756d; 4 | } 5 | 6 | .container{ 7 | display: flex; 8 | justify-content: center; 9 | padding-top: 460rpx; 10 | } 11 | 12 | .container text{ 13 | color: white; 14 | } -------------------------------------------------------------------------------- /mpproj/project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件", 3 | "packOptions": { 4 | "ignore": [] 5 | }, 6 | "setting": { 7 | "urlCheck": true, 8 | "es6": true, 9 | "postcss": true, 10 | "minified": true, 11 | "newFeature": true, 12 | "autoAudits": false 13 | }, 14 | "compileType": "miniprogram", 15 | "libVersion": "2.4.3", 16 | "appid": "wxba95ccbda3f8ddd6", 17 | "projectname": "teacher", 18 | "debugOptions": { 19 | "hidedInDevtools": [] 20 | }, 21 | "isGameTourist": false, 22 | "condition": { 23 | "search": { 24 | "current": -1, 25 | "list": [] 26 | }, 27 | "conversation": { 28 | "current": -1, 29 | "list": [] 30 | }, 31 | "game": { 32 | "currentL": -1, 33 | "list": [] 34 | }, 35 | "miniprogram": { 36 | "current": -1, 37 | "list": [] 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /mpproj/static/alert_dlg_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/alert_dlg_bg.png -------------------------------------------------------------------------------- /mpproj/static/btn_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/btn_bg.jpg -------------------------------------------------------------------------------- /mpproj/static/btn_ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/btn_ok.png -------------------------------------------------------------------------------- /mpproj/static/code.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/code.jpg -------------------------------------------------------------------------------- /mpproj/static/icons/brush.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/icons/brush.jpg -------------------------------------------------------------------------------- /mpproj/static/icons/choose.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/icons/choose.jpg -------------------------------------------------------------------------------- /mpproj/static/icons/eraser.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/icons/eraser.jpg -------------------------------------------------------------------------------- /mpproj/static/icons/foot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/icons/foot.jpg -------------------------------------------------------------------------------- /mpproj/static/icons/hand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/icons/hand.png -------------------------------------------------------------------------------- /mpproj/static/icons/mean.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/icons/mean.jpg -------------------------------------------------------------------------------- /mpproj/static/icons/pen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/icons/pen.png -------------------------------------------------------------------------------- /mpproj/static/icons/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/icons/search.png -------------------------------------------------------------------------------- /mpproj/static/star_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/star_1.png -------------------------------------------------------------------------------- /mpproj/static/star_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/star_2.png -------------------------------------------------------------------------------- /mpproj/static/star_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/mpproj/static/star_3.png -------------------------------------------------------------------------------- /mpproj/teacher/pages/index/index.js: -------------------------------------------------------------------------------- 1 | // teacher/pages/index.js 2 | var title = "呵呵"; 3 | require("teacher.js"); 4 | var util = require("util.js"); 5 | 6 | Page({ 7 | 8 | /** 9 | * 页面的初始数据 10 | */ 11 | data: { 12 | showShare: false, 13 | showInput: false, 14 | inputContent: "", 15 | 16 | showModal: false, 17 | modalText: "提示", 18 | modalConfirm: "确定", 19 | 20 | //完成进度预览 21 | words: [], 22 | showCanvasPlace: false, 23 | showMenu: false, 24 | showChoose: false, 25 | exerciseValue: [], 26 | exerciseGroups: [], 27 | exerciseNames: [], 28 | 29 | brushDotHidden: true, 30 | brushDotBackground: 'rgba(255,255,0,.4)', 31 | 32 | rewriteTipHidden: true, 33 | rewriteTipAnimation: "", 34 | 35 | histories: [], 36 | showHistoryStroke: false, 37 | historyStrokeText: [], 38 | historyStrokeImageSrc: "", 39 | 40 | hideScoreToast: true, 41 | scoreToastImage: "/static/star_2.png", 42 | scoreToastText: "", 43 | scoreToastAnimation: "showtoast 1000ms", 44 | historyStrokeScoreImage: "", 45 | historyStrokeScoreText: "", 46 | }, 47 | 48 | inputFeedback: function(){ 49 | this.hideMenu(); 50 | getApp().add_feedback(); 51 | }, 52 | 53 | addFeedback: function(feedback, callback){ 54 | const db = wx.cloud.database(); 55 | db.collection('feedbacks').add({ 56 | data: { 57 | description: feedback, 58 | due: new Date() 59 | }, 60 | success(res) { 61 | callback(true); 62 | }, 63 | fail: function(res){ 64 | callback(false); 65 | console.log(res); 66 | } 67 | }); 68 | }, 69 | 70 | showMenu: function(){ 71 | this.setData({ showMenu: true }); 72 | }, 73 | hideMenu: function(){ 74 | this.setData({ showMenu: false }); 75 | }, 76 | 77 | showShare: function(){ 78 | this.setData({ showCanvasPlace: true, showMenu: false, showShare: true }); 79 | }, 80 | 81 | //显示选择对话框 82 | showChoose: function(){ 83 | getApp().show_choose(); 84 | }, 85 | //关闭选择对话框 86 | hideChoose: function(){ 87 | this.setData({ showChoose: false, showCanvasPlace: false, }); 88 | }, 89 | hideChooseAndSet: function () { 90 | this.setData({ showChoose: false, showCanvasPlace: false, }); 91 | getApp().handle_choose(this.data.exerciseValue[0], this.data.exerciseValue[1]); 92 | }, 93 | bindChooseChange: function(e){ 94 | const val = e.detail.value; 95 | getApp().handle_choose_change(this.data.exerciseValue[0], this.data.exerciseValue[1], val[0], val[1]); 96 | }, 97 | //搜索选择对话框 98 | searchTitle: function(e){ 99 | getApp().search(e.detail.value); 100 | }, 101 | 102 | //显示练习记录 103 | showHistory: function(){ 104 | getApp().histories(); 105 | }, 106 | drawStrokes: function (history, index){ 107 | //画布大小计算 108 | var canvasWidth = (wx.getSystemInfoSync().windowWidth / 750) * 400;//400rpx 109 | var scale = canvasWidth/320.0; 110 | var canvasContext = wx.createCanvasContext("strokeCanvas"); 111 | //------------------ 绘制用户的笔画 ----------------------------- 112 | canvasContext.setStrokeStyle("#333"); 113 | canvasContext.setFillStyle("#333"); 114 | canvasContext.scale(scale, scale); 115 | var lineWidth = 15; 116 | canvasContext.setLineWidth(lineWidth); 117 | //选择对应得笔画 118 | let strokes = history.strokes[index]; 119 | let score = history.scores[index]; 120 | for(var i=0; i= 8.5){ 149 | image = "/static/star_3.png"; 150 | } else if (score >= 7.5){ 151 | image = "/static/star_2.png"; 152 | } else { 153 | image = "/static/star_1.png"; 154 | }; 155 | this.setData({ 156 | historyStrokeScoreImage: image, 157 | historyStrokeScoreText: score.toFixed(1)+"分", 158 | }); 159 | }, 160 | //隐藏练习记录笔画预览对话框 161 | hideHistoryStroke: function(){ 162 | this.setData({ showCanvasPlace: false,showHistoryStroke: false }); 163 | }, 164 | //历史记录笔画选择以后,生成图片 165 | onHistoryStrokesChange: function(e){ 166 | getApp().handle_history(e.detail.value); 167 | }, 168 | 169 | previousCharacter: function(){ 170 | this.hideMenu(); 171 | getApp().previous(); 172 | }, 173 | 174 | about: function(){ 175 | this.setData({ 176 | showModal: true, 177 | modalConfirm: "确定", 178 | modalText: "\r\n识字画板\r\n\r\n作者:planet2@qq.com\r\n\r\n", 179 | }); 180 | }, 181 | 182 | rewrite: function(){ 183 | getApp().eraser(); 184 | }, 185 | 186 | queryDict: function(){ 187 | getApp().query_dict(); 188 | }, 189 | 190 | //开始/停止 动画演示 191 | strokeAnim: function(){ 192 | getApp().stroke_anim(); 193 | }, 194 | 195 | showModal : function (obj) { 196 | getApp().page.modalObject = obj; 197 | getApp().page.setData({ 198 | showModal: true, 199 | modalConfirm: obj.confirmText, 200 | modalText: obj.content, 201 | }); 202 | }, 203 | 204 | onReady: function(){ 205 | //console.log("onReady>>>", new Date(), Date.now()); 206 | getApp().page = this; 207 | getApp().canvasContext = wx.createCanvasContext("firstCanvas"); 208 | 209 | let rpx = 620; 210 | let width = rpx / 750 * wx.getSystemInfoSync().windowWidth; 211 | 212 | getApp().page.setData({ renderSize: width }); 213 | //console.log("call on_ready>>>", new Date(), Date.now()); 214 | getApp().on_ready(); 215 | 216 | /* 217 | wx.getStorage({ 218 | key: 'showtip', 219 | fail: function(res) { 220 | wx.setStorage({ 221 | key: 'showtip', 222 | data: 'showtip', 223 | }); 224 | getApp().page.showModal({ 225 | showCancel: false, 226 | confirmText: "确定", 227 | title: "提示", 228 | content: "使用电容笔练字更方便!", 229 | success: function (res) { 230 | } 231 | }); 232 | } 233 | }); 234 | */ 235 | }, 236 | 237 | /** 238 | * 生命周期函数--监听页面加载 239 | */ 240 | onLoad: function (options) { 241 | }, 242 | 243 | /** 244 | * 用户点击右上角分享 245 | */ 246 | onShareAppMessage: function () { 247 | this.hideShare(); 248 | return { 249 | title: '快来使用识字画板', 250 | path: 'pages/index/index', 251 | } 252 | }, 253 | 254 | hideShare: function(){ 255 | this.setData({ showCanvasPlace: false, showShare: false }); 256 | }, 257 | 258 | /** 259 | * 弹出框蒙层截断touchmove事件 260 | */ 261 | preventTouchMove: function () {}, 262 | 263 | hideInput: function(){ 264 | this.setData({ showInput: false, showCanvasPlace: false, }); 265 | }, 266 | showInput: function(){ 267 | var page = this; 268 | this.hideMenu(); 269 | getApp().show_input(); 270 | }, 271 | onInputChange: function(e){ 272 | //缓存数据 273 | this.setData({ inputContent: e.detail.value}); 274 | }, 275 | confirmInput: function(){ 276 | this.hideInput(); 277 | var text = this.data.inputContent; 278 | getApp().handle_input(text); 279 | }, 280 | 281 | /** 282 | * 隐藏模态对话框 283 | */ 284 | hideModal: function () { 285 | if (this.modalObject) this.modalObject.success(); 286 | this.setData({ showModal: false }); 287 | }, 288 | /** 289 | * 对话框确认按钮点击事件 290 | */ 291 | onConfirm: function () { 292 | this.hideModal(); 293 | }, 294 | onTouchstart: function(e){ 295 | var touch = e.touches[0]; 296 | getApp().on_touchstart(touch.x, touch.y, e.target.offsetLeft, e.target.offsetTop); 297 | }, 298 | onTouchmove: function (e) { 299 | var touch = e.touches[0]; 300 | getApp().on_touchmove(touch.x, touch.y, e.target.offsetLeft, e.target.offsetTop); 301 | }, 302 | onTouchcancel: function () { getApp().on_touchcancel(); }, 303 | onTouchend: function () { getApp().on_touchend(); }, 304 | }) -------------------------------------------------------------------------------- /mpproj/teacher/pages/index/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "disableScroll": true 3 | } -------------------------------------------------------------------------------- /mpproj/teacher/pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 选择练习内容 16 | 17 | 18 | 19 | {{item}} 20 | 21 | 22 | {{item}} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 练习记录 33 | 34 | 35 | {{item}} 36 | 37 | 38 | 39 | 40 | 41 | {{historyStrokeScoreText}} 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 选 择 60 | 61 | 62 | 63 | 输 入 64 | 65 | 66 | 67 | 回 退 68 | 69 | 73 | 74 | 75 | 分 享 76 | 77 | 78 | 79 | 关 闭 80 | 81 | 82 | 83 | 84 | 85 | 86 | {{character}} 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | {{word.text}} 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | {{modalText}} 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 130 | 131 | -------------------------------------------------------------------------------- /mpproj/teacher/pages/index/util.js: -------------------------------------------------------------------------------- 1 | function formatTime(date) { 2 | var year = date.getFullYear() 3 | var month = date.getMonth() + 1 4 | var day = date.getDate() 5 | 6 | var hour = date.getHours() 7 | var minute = date.getMinutes() 8 | var second = date.getSeconds() 9 | 10 | //return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') 11 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute].map(formatNumber).join(':') 12 | } 13 | 14 | function formatNumber(n) { 15 | n = n.toString() 16 | return n[1] ? n : '0' + n 17 | } 18 | 19 | module.exports = { 20 | formatTime: formatTime 21 | } -------------------------------------------------------------------------------- /ok.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/ok.psd -------------------------------------------------------------------------------- /screenrecorder.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/screenrecorder.gif -------------------------------------------------------------------------------- /screenshot0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/screenshot0.png -------------------------------------------------------------------------------- /screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/screenshot1.png -------------------------------------------------------------------------------- /screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/screenshot2.png -------------------------------------------------------------------------------- /screenshot3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/screenshot3.png -------------------------------------------------------------------------------- /star.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/star.psd -------------------------------------------------------------------------------- /teacher/.gitignore: -------------------------------------------------------------------------------- 1 | # Windows 2 | [Dd]esktop.ini 3 | Thumbs.db 4 | $RECYCLE.BIN/ 5 | 6 | # macOS 7 | .DS_Store 8 | .fseventsd 9 | .Spotlight-V100 10 | .TemporaryItems 11 | .Trashes 12 | 13 | # Node.js 14 | node_modules/ 15 | 16 | /target 17 | **/*.rs.bk 18 | -------------------------------------------------------------------------------- /teacher/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "rust.target": "asmjs-unknown-emscripten", 3 | } -------------------------------------------------------------------------------- /teacher/ARTICLS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/ARTICLS -------------------------------------------------------------------------------- /teacher/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "teacher" 3 | version = "0.1.0" 4 | authors = ["planet0104 "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | bincode = "1.0.1" 9 | stdweb = "0.4.13" 10 | serde_derive = "*" 11 | serde = "*" 12 | bzip2 = "*" 13 | base64 = "0.10.0" 14 | chrono = { version = "0.4", default-features = false } 15 | 16 | [profile.release] 17 | lto = true #必须加,否则asm.js编译不过 18 | opt-level = 's' 19 | panic = 'abort' -------------------------------------------------------------------------------- /teacher/PINYIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/PINYIN -------------------------------------------------------------------------------- /teacher/POEMS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/POEMS -------------------------------------------------------------------------------- /teacher/build.cmd: -------------------------------------------------------------------------------- 1 | cargo build --target=asmjs-unknown-emscripten --release 2 | 3 | node replace.js -------------------------------------------------------------------------------- /teacher/gendict/.gitignore: -------------------------------------------------------------------------------- 1 | # Windows 2 | [Dd]esktop.ini 3 | Thumbs.db 4 | $RECYCLE.BIN/ 5 | 6 | # macOS 7 | .DS_Store 8 | .fseventsd 9 | .Spotlight-V100 10 | .TemporaryItems 11 | .Trashes 12 | 13 | # Node.js 14 | node_modules/ 15 | 16 | /target 17 | **/*.rs.bk 18 | -------------------------------------------------------------------------------- /teacher/gendict/ARTICLS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/gendict/ARTICLS -------------------------------------------------------------------------------- /teacher/gendict/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gendict" 3 | version = "0.1.0" 4 | authors = ["Jia Ye "] 5 | # edition = "2018" 6 | 7 | [dependencies] 8 | serde_json = "*" 9 | bincode = "*" 10 | bzip2 = "0.3.2" 11 | base64 = "0.10.0" 12 | serde_derive = "*" 13 | serde = "*" -------------------------------------------------------------------------------- /teacher/gendict/DICT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/gendict/DICT -------------------------------------------------------------------------------- /teacher/gendict/DICT.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/gendict/DICT.zip -------------------------------------------------------------------------------- /teacher/gendict/KaiTi_GB2312.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/gendict/KaiTi_GB2312.ttf -------------------------------------------------------------------------------- /teacher/gendict/KaiTi_GB2312_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/gendict/KaiTi_GB2312_0.ttf -------------------------------------------------------------------------------- /teacher/gendict/KaiTi_GB2312_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/gendict/KaiTi_GB2312_1.ttf -------------------------------------------------------------------------------- /teacher/gendict/OLD_STROKE.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/gendict/OLD_STROKE.map -------------------------------------------------------------------------------- /teacher/gendict/PINYIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/gendict/PINYIN -------------------------------------------------------------------------------- /teacher/gendict/POEMS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/gendict/POEMS -------------------------------------------------------------------------------- /teacher/gendict/WORD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/gendict/WORD -------------------------------------------------------------------------------- /teacher/gendict/gb2312.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/gendict/gb2312.data -------------------------------------------------------------------------------- /teacher/gendict/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate bincode; 2 | use bincode::{serialize, deserialize}; 3 | extern crate bzip2; 4 | use bzip2::Compression; 5 | extern crate serde_json; 6 | use std::collections::HashMap; 7 | use std::fs::File; 8 | use std::str::FromStr; 9 | use serde_json::Value; 10 | use std::io::prelude::*; 11 | extern crate base64; 12 | use base64::{encode, decode}; 13 | #[macro_use] 14 | extern crate serde_derive; 15 | extern crate serde; 16 | 17 | #[derive(Clone, Serialize, Deserialize, Debug)] 18 | pub struct Word { 19 | pub strokes: String, 20 | pub pinyin: String, 21 | pub radicals: String, 22 | pub explanation: String, 23 | } 24 | 25 | enum Status{ 26 | AppendLine, 27 | WaitStart, 28 | } 29 | 30 | enum LineType{ 31 | Normal, 32 | Blank, 33 | Start 34 | } 35 | 36 | fn main111(){ 37 | let mut sarr = vec![String::from("010"), String::from("100"), String::from("012")]; 38 | sarr.sort(); 39 | println!("{:?}", sarr); 40 | } 41 | 42 | fn gen_articls(){ 43 | let mut file = File::open("课文.txt").unwrap(); 44 | let mut contents = String::new(); 45 | file.read_to_string(&mut contents).unwrap(); 46 | let num:Vec = "0123456789".chars().collect(); 47 | 48 | let mut articls = HashMap::new(); 49 | 50 | let mut article_title = String::new(); 51 | let mut article_content = String::new(); 52 | let mut status = Status::WaitStart; 53 | 54 | let mut titles = vec![]; 55 | 56 | for line in contents.lines(){ 57 | let line_type = { 58 | let s = line.trim(); 59 | let chars = s.chars(); 60 | let count = chars.count(); 61 | if count == 0{ 62 | LineType::Blank 63 | }else{ 64 | let ch = line.chars().next().unwrap(); 65 | if let Ok(_idx) = num.binary_search(&ch){ 66 | LineType::Start 67 | }else{ 68 | LineType::Normal 69 | } 70 | } 71 | }; 72 | 73 | match line_type{ 74 | LineType::Start => { 75 | if let Status::AppendLine = status{ 76 | //保存当前poem 77 | articls.insert(String::from(article_title.as_str()), String::from(article_content.as_str())); 78 | println!("添加:{} total:{}", article_title, articls.len()); 79 | } 80 | //作者和诗名 81 | let mut title_str = String::from(line); 82 | titles.push(line); 83 | println!("----------------------------------------------------{} 总共:{}", line, titles.len()); 84 | let mut title_key = String::from(line); 85 | title_key.retain(|ch|{ 86 | num.binary_search(&ch).is_ok() 87 | }); 88 | 89 | title_str.retain(|ch|{ 90 | num.binary_search(&ch).is_err() 91 | }); 92 | //保存标题 93 | article_title = title_key+"-"+&title_str; 94 | //清空内容 95 | article_content = String::new(); 96 | //修改状态 97 | status = Status::AppendLine; 98 | } 99 | LineType::Normal => { 100 | if let Status::AppendLine = status{ 101 | article_content.push_str(line); 102 | } 103 | }, 104 | LineType::Blank => { 105 | if let Status::AppendLine = status{ 106 | status = Status::WaitStart; 107 | //保存当前poem 108 | articls.insert(String::from(article_title.as_str()), String::from(article_content.as_str())); 109 | println!("添加:{} total:{}", article_title, articls.len()); 110 | } 111 | } 112 | } 113 | } 114 | // for (key, val) in &poems{ 115 | // println!("{}", key); 116 | // } 117 | println!("总数:{} titles={}", articls.len(), titles.len()); 118 | 119 | //序列化 120 | let encoded: Vec = serialize(&articls).unwrap(); 121 | 122 | //压缩 123 | let mut zip = bzip2::write::BzEncoder::new(vec![], Compression::Best); 124 | zip.write_all(&encoded).unwrap(); 125 | let result = zip.finish().unwrap(); 126 | 127 | //写入文件 128 | let mut file = File::create("ARTICLS").unwrap(); 129 | file.write_all(&result).unwrap(); 130 | } 131 | 132 | fn gen_strokes(){ 133 | //bzip压缩 134 | let strokes = include_bytes!("../gb2312.data"); 135 | let mut zip = bzip2::write::BzEncoder::new(vec![], Compression::Best); 136 | zip.write_all(strokes).unwrap(); 137 | let result = zip.finish().unwrap(); 138 | let mut file = File::create("strokes.bzip").unwrap(); 139 | file.write_all(&result).unwrap(); 140 | 141 | let base64 = encode(&result); 142 | let mut file = File::create("strokes.bzip.txt").unwrap(); 143 | file.write_all(base64.as_bytes()).unwrap(); 144 | } 145 | 146 | fn main(){ 147 | //gen_dict(); 148 | gen_dict_v2(); 149 | // gen_strokes(); 150 | // gen_articls(); 151 | // gen_pinyin(); 152 | } 153 | 154 | fn maintttt(){ 155 | let mut file = File::open("唐诗三百首.txt").unwrap(); 156 | let mut contents = String::new(); 157 | file.read_to_string(&mut contents).unwrap(); 158 | let num:Vec = "0123456789".chars().collect(); 159 | let mut total = 0; 160 | 161 | //let mut author = String::new(); 162 | //let mut title = String::new(); 163 | 164 | enum Status{ 165 | AppendLine, 166 | WaitStart, 167 | } 168 | 169 | enum LineType{ 170 | Normal, 171 | Blank, 172 | Start 173 | } 174 | 175 | let mut poems = HashMap::new(); 176 | 177 | let mut poem_title = String::new(); 178 | let mut poem_content = String::new(); 179 | let mut status = Status::WaitStart; 180 | 181 | let mut titles = vec![]; 182 | 183 | for line in contents.lines(){ 184 | //如果是空行,并且状态是AppendLine,那么切换成WaitStart,【保存当前行】 185 | //如果是空行,并且状态是WaitStart,不做更改。 186 | //如果是正常行,并且状态是WaitStart,不做更改。 187 | //如果是正常行,并且状态时AppendLine,【poem_content加入当前行】。状态不做更改。 188 | //如果是起始,并且状态是WaitStart,那么【创建新的poem_title】,切换成AppendLine 189 | //如果时起始,并且状态是AppendLine,【保存当前行,创建新的poem_title】 190 | 191 | let line_type = { 192 | let s = line.trim(); 193 | let chars = s.chars(); 194 | let count = chars.count(); 195 | if count == 0{ 196 | LineType::Blank 197 | }else{ 198 | let ch = line.chars().next().unwrap(); 199 | if let Ok(_idx) = num.binary_search(&ch){ 200 | LineType::Start 201 | }else{ 202 | LineType::Normal 203 | } 204 | } 205 | }; 206 | 207 | match line_type{ 208 | LineType::Start => { 209 | if let Status::AppendLine = status{ 210 | //保存当前poem 211 | poems.insert(String::from(poem_title.as_str()), String::from(poem_content.as_str())); 212 | println!("添加:{} total:{}", poem_title, poems.len()); 213 | } 214 | //作者和诗名 215 | let mut title_str = String::from(line); 216 | titles.push(line); 217 | println!("----------------------------------------------------{} 总共:{}", line, titles.len()); 218 | let mut title_key = String::from(line); 219 | title_key.retain(|ch|{ 220 | num.binary_search(&ch).is_ok() 221 | }); 222 | 223 | title_str.retain(|ch|{ 224 | num.binary_search(&ch).is_err() 225 | }); 226 | //保存标题 227 | poem_title = title_key+"-"+&title_str; 228 | //清空内容 229 | poem_content = String::new(); 230 | //修改状态 231 | status = Status::AppendLine; 232 | } 233 | LineType::Normal => { 234 | if let Status::AppendLine = status{ 235 | poem_content.push_str(line); 236 | } 237 | }, 238 | LineType::Blank => { 239 | if let Status::AppendLine = status{ 240 | status = Status::WaitStart; 241 | //保存当前poem 242 | poems.insert(String::from(poem_title.as_str()), String::from(poem_content.as_str())); 243 | println!("添加:{} total:{}", poem_title, poems.len()); 244 | } 245 | } 246 | } 247 | } 248 | // for (key, val) in &poems{ 249 | // println!("{}", key); 250 | // } 251 | println!("总数:{} titles={}", poems.len(), titles.len()); 252 | 253 | //序列化 254 | let encoded: Vec = serialize(&poems).unwrap(); 255 | //写入文件 256 | let mut file = File::create("POEMS").unwrap(); 257 | file.write_all(&encoded).unwrap(); 258 | } 259 | 260 | // fn main(){ 261 | // let mut zip = bzip2::write::BzEncoder::new(vec![], Compression::Best); 262 | // zip.write_all(gb2312).unwrap(); 263 | // let result = zip.finish().unwrap(); 264 | // let mut file = File::create("gb2312.data.bzip").unwrap(); 265 | // file.write_all(&result).unwrap(); 266 | 267 | // let mut zip = bzip2::write::BzEncoder::new(vec![], Compression::Best); 268 | // zip.write_all(ttf).unwrap(); 269 | // let result = zip.finish().unwrap(); 270 | // let mut file = File::create("KaiTi_GB2312.ttf.bzip").unwrap(); 271 | // file.write_all(&result).unwrap(); 272 | 273 | // let mut zip = bzip2::write::BzEncoder::new(vec![], Compression::Best); 274 | // zip.write_all(word).unwrap(); 275 | // let result = zip.finish().unwrap(); 276 | // let mut file = File::create("WORD.bzip").unwrap(); 277 | // file.write_all(&result).unwrap(); 278 | // } 279 | 280 | fn gen_pinyin() { 281 | let mut file = File::open("word.json").unwrap(); 282 | let mut contents = String::new(); 283 | file.read_to_string(&mut contents).unwrap(); 284 | 285 | let v: Value = serde_json::from_str(&contents).unwrap(); 286 | let array = v.as_array().unwrap(); 287 | 288 | //填充 289 | let mut data:HashMap = HashMap::new(); 290 | for character in array{ 291 | let info = character.as_object().unwrap(); 292 | let word = info["word"].as_str().unwrap(); 293 | let pinyin = info["pinyin"].as_str().unwrap(); 294 | data.insert(word.chars().next().unwrap(), pinyin); 295 | } 296 | 297 | //序列化整个字典 298 | let pinyin: Vec = serialize(&data).unwrap(); 299 | 300 | //压缩 301 | let mut zip = bzip2::write::BzEncoder::new(vec![], Compression::Best); 302 | zip.write_all(&pinyin).unwrap(); 303 | let result = zip.finish().unwrap(); 304 | 305 | //写入文件 306 | let mut file = File::create("PINYIN").unwrap(); 307 | file.write_all(&result).unwrap(); 308 | } 309 | 310 | fn gen_dict_v2() { 311 | let strokes = include_bytes!("../gb2312.data"); 312 | let strokes_map:HashMap>> = deserialize(strokes).unwrap(); 313 | 314 | let mut file = File::open("word.json").unwrap(); 315 | let mut contents = String::new(); 316 | file.read_to_string(&mut contents).unwrap(); 317 | 318 | let v: Value = serde_json::from_str(&contents).unwrap(); 319 | let array = v.as_array().unwrap(); 320 | 321 | //搜索字典中不存在的词 322 | let mut all = vec![]; 323 | for character in array{ 324 | let info = character.as_object().unwrap(); 325 | let word = info["word"].as_str().unwrap(); 326 | all.push(word); 327 | } 328 | let mut count = 0; 329 | for (ch, _) in strokes_map{ 330 | if all.contains(&format!("{}", ch).as_str()){ 331 | 332 | }else{ 333 | count += 1; 334 | 335 | let mut data = r#" { 336 | "word": "_word_", 337 | "oldword": "", 338 | "strokes": "", 339 | "pinyin": "", 340 | "radicals": "", 341 | "explanation": "", 342 | "more": "" 343 | },"#; 344 | let data = data.replace("_word_", &format!("{}", ch)); 345 | 346 | println!("{}", data); 347 | } 348 | } 349 | println!("总共缺少{}个字的解释", count); 350 | 351 | //填充 352 | let mut data:HashMap = HashMap::new(); 353 | for character in array{ 354 | let info = character.as_object().unwrap(); 355 | let word = info["word"].as_str().unwrap(); 356 | let strokes = info["strokes"].as_str().unwrap(); 357 | let pinyin = info["pinyin"].as_str().unwrap(); 358 | let radicals = info["radicals"].as_str().unwrap(); 359 | let explanation = info["explanation"].as_str().unwrap(); 360 | 361 | let word_data = Word{ 362 | strokes: String::from(strokes), 363 | pinyin: String::from(pinyin), 364 | radicals: String::from(radicals), 365 | explanation: String::from(explanation) 366 | }; 367 | 368 | data.insert(word.to_string(), word_data); 369 | } 370 | 371 | //序列化整个字典 372 | let dict: Vec = serialize(&data).unwrap(); 373 | 374 | //写入文件 375 | let mut file = File::create("DICT").unwrap(); 376 | file.write_all(&dict).unwrap(); 377 | } 378 | 379 | fn gen_dict() { 380 | 381 | let strokes = include_bytes!("../gb2312.data"); 382 | let strokes_map:HashMap>> = deserialize(strokes).unwrap(); 383 | 384 | let mut file = File::open("word.json").unwrap(); 385 | let mut contents = String::new(); 386 | file.read_to_string(&mut contents).unwrap(); 387 | 388 | //map中保存压缩的数据Hashmap>, key=笔画数 389 | let mut data:HashMap> = HashMap::new(); 390 | 391 | let v: Value = serde_json::from_str(&contents).unwrap(); 392 | let array = v.as_array().unwrap(); 393 | 394 | //搜索字典中不存在的词 395 | let mut all = vec![]; 396 | for character in array{ 397 | let info = character.as_object().unwrap(); 398 | let word = info["word"].as_str().unwrap(); 399 | all.push(word); 400 | } 401 | let mut count = 0; 402 | for (ch, _) in strokes_map{ 403 | if all.contains(&format!("{}", ch).as_str()){ 404 | 405 | }else{ 406 | count += 1; 407 | 408 | let mut data = r#" { 409 | "word": "_word_", 410 | "oldword": "", 411 | "strokes": "", 412 | "pinyin": "", 413 | "radicals": "", 414 | "explanation": "", 415 | "more": "" 416 | },"#; 417 | let data = data.replace("_word_", &format!("{}", ch)); 418 | 419 | println!("{}", data); 420 | } 421 | } 422 | println!("总共缺少{}个字的解释", count); 423 | 424 | //填充 425 | let mut tmp_data:HashMap> = HashMap::new(); 426 | for character in array{ 427 | let info = character.as_object().unwrap(); 428 | let word = info["word"].as_str().unwrap(); 429 | let strokes = info["strokes"].as_str().unwrap(); 430 | let pinyin = info["pinyin"].as_str().unwrap(); 431 | let radicals = info["radicals"].as_str().unwrap(); 432 | let explanation = info["explanation"].as_str().unwrap(); 433 | 434 | let word_data = Word{ 435 | strokes: String::from(strokes), 436 | pinyin: String::from(pinyin), 437 | radicals: String::from(radicals), 438 | explanation: String::from(explanation) 439 | }; 440 | 441 | if !tmp_data.contains_key(strokes){ 442 | tmp_data.insert(String::from(strokes), HashMap::new()); 443 | } 444 | tmp_data.get_mut(strokes).as_mut().unwrap().insert(word.chars().next().unwrap(), word_data); 445 | } 446 | 447 | for (key, map) in tmp_data{ 448 | println!("笔画数:{} 汉字个数:{}", key, map.len()); 449 | //序列化 450 | let encoded: Vec = serialize(&map).unwrap(); 451 | //压缩 452 | let mut zip = bzip2::write::BzEncoder::new(vec![], Compression::Fastest); 453 | zip.write_all(&encoded).unwrap(); 454 | let result = zip.finish().unwrap(); 455 | data.insert(key, result); 456 | } 457 | 458 | //序列化整个字典 459 | let dict: Vec = serialize(&data).unwrap(); 460 | 461 | //写入文件 462 | let mut file = File::create("DICT").unwrap(); 463 | file.write_all(&dict).unwrap(); 464 | } 465 | 466 | fn main1() { 467 | 468 | // let mut file = File::open("../handwriting-zh_CN-gb2312.json").unwrap(); 469 | // let mut contents = String::new(); 470 | // file.read_to_string(&mut contents).unwrap(); 471 | 472 | // let mut data:HashMap>> = HashMap::new(); 473 | 474 | // let v: Value = serde_json::from_str(&contents).unwrap(); 475 | // //所有字符数组 476 | // let characters = v["dictionary"]["character"].as_array().unwrap(); 477 | // for character in characters{ 478 | // //let ch = character.as_object().unwrap(); 479 | // //strokes - 对象 480 | // //stroke - 对象/对象数组 481 | // let stroke = &character["strokes"]["stroke"]; 482 | // let mut c_strokes = vec![]; 483 | // if stroke.is_object(){ 484 | // //单笔画 485 | // let points = stroke["point"].as_array().unwrap(); 486 | // c_strokes.push(points.iter().map(|v| { 487 | // (FromStr::from_str(v["x"].as_str().unwrap()).unwrap(), FromStr::from_str(v["y"].as_str().unwrap()).unwrap()) 488 | // }).collect()); 489 | // }else{ 490 | // //多笔画 491 | // let strokes = stroke.as_array().unwrap(); 492 | // for stroke in strokes{ 493 | // //单笔画 494 | // let points = stroke["point"].as_array().unwrap(); 495 | // c_strokes.push(points.iter().map(|v| { 496 | // (FromStr::from_str(v["x"].as_str().unwrap()).unwrap(), FromStr::from_str(v["y"].as_str().unwrap()).unwrap()) 497 | // }).collect()); 498 | // } 499 | // } 500 | // data.insert(character["utf8"].as_str().unwrap().chars().next().unwrap(), c_strokes); 501 | // } 502 | 503 | //存储文件----------------------------------------------- 504 | 505 | //序列化 506 | // let encoded: Vec = serialize(&data).unwrap(); 507 | 508 | let font_data = include_bytes!("../KaiTi_GB2312.ttf"); 509 | 510 | println!(">>11 {}", font_data.len()); 511 | 512 | //压缩 513 | let mut zip = bzip2::write::BzEncoder::new(vec![], Compression::Best); 514 | zip.write_all(font_data).unwrap(); 515 | let result = zip.finish().unwrap(); 516 | 517 | println!(">>22 {}", result.len()); 518 | 519 | //写入文件 520 | // let mut file = File::create("../KaiTi_GB2312.bzip").unwrap(); 521 | // file.write_all(&result).unwrap(); 522 | 523 | let base64 = encode(&result); 524 | 525 | let sp4 = base64.len()/7; 526 | 527 | let part1 = &base64[0..sp4*6]; 528 | let part2 = &base64[sp4*6..]; 529 | 530 | let mut file = File::create("KaiTi_GB2312.bzip.base64.part1.txt").unwrap(); 531 | file.write_all(part1.as_bytes()).unwrap(); 532 | 533 | let mut file = File::create("KaiTi_GB2312.bzip.base64.part2.txt").unwrap(); 534 | file.write_all(part2.as_bytes()).unwrap(); 535 | 536 | //-------------------------------------------------------- 537 | } -------------------------------------------------------------------------------- /teacher/gendict/strokes.bzip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planet0104/miniprogram-write-teacher/e55f9bfc6c05ded6d9a8b8443b7fa9097444fb31/teacher/gendict/strokes.bzip -------------------------------------------------------------------------------- /teacher/gendict/test.js: -------------------------------------------------------------------------------- 1 | function left_zero_4(str) { 2 | if (str != null && str != '' && str != 'undefined') { 3 | if (str.length == 2) { 4 | return '00' + str; 5 | } 6 | } 7 | return str; 8 | } 9 | 10 | function unicode(str) { 11 | var value = ''; 12 | for (var i = 0; i < str.length; i++) { 13 | value += left_zero_4(parseInt(str.charCodeAt(i)).toString(16)); 14 | } 15 | return value; 16 | } 17 | 18 | 19 | console.log(unicode('你')); -------------------------------------------------------------------------------- /teacher/gendict/xml2json.js: -------------------------------------------------------------------------------- 1 | var parser = require('xml2json'); 2 | var fs = require("fs"); 3 | 4 | var xml = fs.readFileSync("./handwriting-zh_CN-gb2312.xml", "utf-8"); 5 | 6 | // xml to json 7 | var json = parser.toJson(xml); 8 | 9 | fs.writeFileSync("./handwriting-zh_CN-gb2312.json", json); -------------------------------------------------------------------------------- /teacher/gendict/唐诗三百首.txt: -------------------------------------------------------------------------------- 1 | 第一卷 第一章 2 | 唐诗300首 1-50 3 | 490王维:画 4 | 远看山有色,近听水无声。 5 | 春去花还在,人来鸟不惊。 6 | 000李绅:悯农二首其一 7 | 春种一粒粟,秋收万颗子。 8 | 四海无闲田,农夫犹饿死。 9 | 001李绅:悯农二首其二 10 | 锄禾日当午,汗滴禾下土。 11 | 谁知盘中餐,粒粒皆辛苦? 12 | 002骆宾王:咏鹅 13 | 鹅,鹅,鹅,曲项向天歌。 14 | 白毛浮绿水,红掌拨清波。 15 | 003袁枚:所见 16 | 牧童骑黄牛,歌声振林樾。 17 | 意欲捕鸣蝉,忽然闭口立。 18 | 004李白:夜宿山寺 19 | 危楼高百尺,手可摘星辰。 20 | 不敢高声语,恐惊天上人。 21 | 005张俞:蚕妇 22 | 昨日入城市,归来泪满巾。 23 | 遍身罗绮者,不是养蚕人。 24 | 006查慎行:舟夜书所见 25 | 月黑见渔灯,孤光一点萤。 26 | 微微风簇浪,散作满河星。 27 | 007范仲淹:江上渔者 28 | 江上往来人,但爱鲈鱼美。 29 | 君看一叶舟,出没风波里。 30 | 008杜牧:山行 31 | 远上寒山石径斜,白云生处有人家。 32 | 停车坐爱枫林晚,霜叶红于二月花。 33 | 009贺知章:咏柳 34 | 碧玉妆成一树高, 35 | 万条垂下绿丝绦。 36 | 不知细叶谁裁出, 37 | 二月春风似剪刀。 38 | 400杨万里:宿新市徐公店二首其一 39 | 春光都在柳梢头,拣折长条插酒楼。 40 | 便作在家寒食看,村歌社舞更风流。 41 | 401杨万里:宿新市徐公店二首其二 42 | 篱落疏疏一径深,树头花落未成阴。 43 | 儿童急走追黄蝶,飞入菜花无处寻。 44 | 402王安石:梅花 45 | 墙角数枝梅,凌寒独自开。 46 | 遥知不是雪,为有暗香来。 47 | 403杜甫:江畔独步寻花其一 48 | 江上被花恼不彻,无处告诉只颠狂。 49 | 走觅南邻爱酒伴,经旬出饮独空床。 50 | 404杜甫:江畔独步寻花其二 51 | 稠花乱蕊畏江滨,行步欹危实怕春。 52 | 诗酒尚堪驱使在,未须料理白头人。 53 | 405杜甫:江畔独步寻花其三 54 | 江深竹静两三家,多事红花映白花。 55 | 报答春光知有处,应须美酒送生涯。 56 | 406杜甫:江畔独步寻花其四 57 | 东望少城花满烟,百花高楼更可怜。 58 | 谁能载酒开金盏,唤取佳人舞绣筵。 59 | 407杜甫:江畔独步寻花其五 60 | 黄师塔前江水东,春光懒困倚微风。 61 | 桃花一簇开无主,可爱深红爱浅红? 62 | 408杜甫:江畔独步寻花其六 63 | 黄四娘家花满蹊,千朵万朵压枝低。 64 | 留连戏蝶时时舞,自在娇莺恰恰啼。 65 | 409杜甫:江畔独步寻花其七 66 | 不是爱花即肯死,只恐花尽老相催。 67 | 繁枝容易纷纷落,嫩蕊商量细细开。 68 | 410白居易:暮江吟 69 | 一道残阳铺水中,半江瑟瑟半江红。 70 | 可怜九月初三夜,露似真珠月似弓。 71 | 010杜甫:佳人 72 | 绝代有佳人,幽居在空谷。 73 | 自云良家子,零落依草木。 74 | 关中昔丧乱,兄弟遭杀戮。 75 | 官高何足论,不得收骨肉。 76 | 世情恶衰歇,万事随转烛。 77 | 夫婿轻薄儿,新人美如玉。 78 | 合昏尚知时,鸳鸯不独宿。 79 | 但见新人笑,那闻旧人哭! 80 | 在山泉水清,出山泉水浊。 81 | 侍婢卖珠回,牵萝补茅屋。 82 | 摘花不插发,采柏动盈掬。 83 | 天寒翠袖薄,日暮倚修竹。 84 | 011杜甫:梦李白二首之一 85 | 死别已吞声,生别常恻恻。 86 | 江南瘴疠地,逐客无消息。 87 | 故人入我梦,明我长相忆。 88 | 君今在罗网,何以有羽翼? 89 | 恐非平生魂,路远不可测。 90 | 魂来枫林青,魂返关塞黑。 91 | 落月满屋梁,犹疑照颜色。 92 | 水深波浪阔,无使蛟龙得。 93 | 012杜甫:梦李白二首之二 94 | 浮云终日行,游子久不至。 95 | 三夜频梦君,情亲见君意。 96 | 告归常局促,苦道来不易。 97 | 江湖多风波,舟楫恐失坠。 98 | 出门搔白首,若负平生志。 99 | 冠盖满京华,斯人独憔悴。 100 | 孰云网恢恢,将老身反累。 101 | 千秋万岁名,寂寞身后事。 102 | 013王维:送别 103 | 下马饮君酒,问君何所之。 104 | 君言不得意,归卧南山陲。 105 | 但去莫复闻,白云无尽时。 106 | 014王维:送綦毋潜落第还乡 107 | 圣代无隐者,英灵尽来归。 108 | 遂令东山客,不得顾采薇。 109 | 既至金门远,孰云吾道非? 110 | 江淮度寒食,京洛缝春衣。 111 | 置酒长安道,同心与我违。 112 | 行当浮桂棹,未几拂荆扉。 113 | 远树带行客,孤城当落晖。 114 | 吾谋适不用,勿谓知音稀。 115 | 015王维:青溪 116 | 言入黄花川,每逐青溪水。 117 | 随山将万转,趣途无百里。 118 | 声喧乱石中,色静深松里。 119 | 漾漾泛菱荇,澄澄映葭苇。 120 | 我心素已闲,清川澹如此。 121 | 请留盘石上,垂钓将已矣。 122 | 017王维:西施咏 123 | 艳色天下重,西施宁久微。 124 | 朝为越溪女,暮作吴宫妃。 125 | 贱日岂殊众,贵来方悟稀。 126 | 邀人傅脂粉,不自著罗衣。 127 | 君宠益娇态,君怜无是非。 128 | 当时浣纱伴,莫得同车归。 129 | 持谢邻家子,效颦安可希! 130 | 018孟浩然:秋登兰山寄张五 131 | 北山白云里,隐者自怡悦。 132 | 相望始登高,心随雁飞灭。 133 | 愁因薄暮起,兴是清秋发。 134 | 时见归村人,沙行渡头歇。 135 | 天边树若荠,江畔洲如月。 136 | 何当载酒来,共醉重阳节。 137 | 019孟浩然:夏日南亭怀辛大 138 | 山光忽西落,池月渐东上。 139 | 散发乘夜凉,开轩卧闲敞。 140 | 荷风送香气,竹露滴清响。 141 | 欲取鸣琴弹,恨无知音赏。 142 | 感此怀故人,中宵劳梦想。 143 | 020孟浩然:宿业师山房待丁大不至 144 | 夕阳度西岭,群壑倏已暝。 145 | 松月生夜凉,风泉满清听。 146 | 樵人归欲尽,烟鸟栖初定。 147 | 之子期宿来,孤琴候萝径。 148 | 021王昌龄:同从弟南斋玩月忆山阴崔少府 149 | 高卧南斋时,开帷月初吐。 150 | 清辉淡水木,演漾在窗户。 151 | 苒苒几盈虚,澄澄变今古。 152 | 美人清江畔,是夜越吟苦。 153 | 千里其如何,微风吹兰杜。 154 | 022邱为:寻西山隐者不遇 155 | 绝顶一茅茨,直上三十里。 156 | 扣关无僮仆,窥室惟案几。 157 | 若非巾柴车,应是钓秋水。 158 | 差池不相见,黾勉空仰止。 159 | 草色新雨中,松声晚窗里。 160 | 及兹契幽绝,自足荡心耳。 161 | 虽无宾主意,颇得清净理。 162 | 兴尽方下山,何必待之子。 163 | 023綦毋潜:春泛若耶溪 164 | 幽意无断绝,此去随所偶。 165 | 晚风吹行舟,花路入溪口。 166 | 际夜转西壑,隔山望南斗。 167 | 潭烟飞溶溶,林月低向后。 168 | 生事且弥漫,愿为持竿叟。 169 | 024常建:宿王昌龄隐居 170 | 清溪深不测,隐处唯孤云。 171 | 松际露微月,清光犹为君。 172 | 茅亭宿花影,药院滋苔纹。 173 | 余亦谢时去,西山鸾鹤群。 174 | 025岑参:与高适薛据登慈恩寺浮图 175 | 塔势如涌出,孤高耸天宫。 176 | 登临出世界,磴道盘虚空。 177 | 突兀压神州,峥嵘如鬼工。 178 | 四角碍白日,七层摩苍穹。 179 | 下窥指高鸟,俯听闻惊风。 180 | 连山若波涛,奔凑如朝东。 181 | 青槐夹驰道,宫馆何玲珑! 182 | 秋色从西来,苍然满关中。 183 | 五陵北原上,万古青蒙蒙。 184 | 净理了可悟,胜因夙所宗。 185 | 誓将挂冠去,觉道资无穷。 186 | 026元结:贼退示官吏并序 187 | 癸卯岁,西原贼入道州,焚烧杀掠,几尽而去。明年,贼又攻永州,破邵,不犯此 188 | 州边鄙而退,岂力能制敌欤?盖蒙其伤怜而已!诸史何为忍苦征敛!故作诗一篇以 189 | 示官吏。 190 | 昔岁逢太平,山林二十年。 191 | 泉源在庭户,洞壑当门前。 192 | 井税有常期,日晏犹得眠。 193 | 忽然遭时变,数岁亲戎旃。 194 | 今来典斯郡,山夷又纷然。 195 | 城小贼不屠,人贫伤可怜。 196 | 是以陷邻境,此州独见全。 197 | 使臣将王命,岂不如贼焉! 198 | 令彼征敛者,迫之如火煎。 199 | 谁能绝人命,以作时世贤。 200 | 思欲委符节,引竿自刺船。 201 | 将家就鱼麦,归老江湖边。 202 | 027韦应物:郡斋雨中与诸文士燕集 203 | 兵卫森画戟,宴寝凝清香。 204 | 海上风雨至,逍遥池阁凉。 205 | 烦疴近消散,嘉宾复满堂。 206 | 自惭居处崇,未睹斯民康。 207 | 理会是非遣,性达形迹忘。 208 | 鲜肥属时禁,蔬果幸见尝。 209 | 俯饮一杯酒,仰聆金玉章。 210 | 神欢体自轻,意欲凌风翔。 211 | 吴中盛文史,群彦今汪洋。 212 | 方知大蕃地,岂曰财赋强。 213 | 028韦应物:初发扬子寄元大校书 214 | 凄凄去亲爱,泛泛入烟雾。 215 | 归棹洛阳人,残钟广陵树。 216 | 今朝为此别,何处还相遇。 217 | 世事波上舟,沿洄安得住。 218 | 029韦应物:寄全椒山中道士 219 | 今朝郡斋冷,忽念山中客。 220 | 涧底束荆薪,归来煮白石。 221 | 欲持一瓢酒,远慰风雨夕。 222 | 落叶满空山,何处寻行迹。 223 | 030韦应物:长安遇冯著 224 | 客从东方来,衣上灞陵雨。 225 | 问客何为来,采山因买斧。 226 | 冥冥花正开,扬扬燕新乳。 227 | 昨别今已春,鬓丝生几缕。 228 | 031韦应物:夕次盱眙县 229 | 落帆逗淮镇,停舫临孤驿。 230 | 浩浩风起波,冥冥日沈夕。 231 | 人归山郭暗,雁下芦洲白。 232 | 独夜忆秦关,听钟未眠客。 233 | 032韦应物:东郊 234 | 吏舍局终年,出郊旷清曙。 235 | 杨柳散和风,青山澹吾虑。 236 | 依丛适自憩,缘涧还复去。 237 | 微雨霭芳原,春鸠鸣何处? 238 | 乐幽心屡止,遵事迹犹遽。 239 | 终罢斯结庐,慕陶真可庶。 240 | 033韦应物:送杨氏女 241 | 永日方戚戚,出行复悠悠。 242 | 女子今有行,大江溯轻舟。 243 | 尔辈苦无恃,抚念益慈柔。 244 | 幼为长所育,两别泣不休。 245 | 对此结中肠,义往难复留! 246 | 自小阙内训,事姑贻我忧。 247 | 赖兹托令门,仁恤庶无尤。 248 | 贫俭诚所尚,资从岂待周? 249 | 孝恭遵妇道,容止顺其猷。 250 | 别离在今晨,见尔当何秋。 251 | 居闲始自遣,临感忽难收。 252 | 归来视幼女,零泪缘缨流。 253 | 034柳宗元:晨诣超师院读禅经 254 | 汲井漱寒齿,清心拂尘服。 255 | 闲持贝叶书,步出东斋读。 256 | 真源了无取,忘迹世所逐。 257 | 遗言冀可冥,缮性何由熟? 258 | 道人庭宇静,苔色连深竹。 259 | 日出雾露馀,青松如膏沐。 260 | 澹然离言说,悟悦心自足。 261 | 035柳宗元:溪居 262 | 久为簪组累,幸此南夷谪。 263 | 闲依农圃邻,偶似山林客。 264 | 晓耕翻露草,夜榜响溪石。 265 | 来往不逢人,长歌楚天碧。 266 | 036王昌龄:塞上曲 267 | 蝉鸣空桑林,八月萧关道。 268 | 出塞复入塞,处处黄芦草。 269 | 从来幽并客,皆向沙场老。 270 | 莫学游侠儿,矜夸紫骝好。 271 | 037王昌龄:塞下曲 272 | 饮马渡秋水,水寒风似刀。 273 | 平沙日未没,黯黯见临洮。 274 | 昔日长城战,咸言意气高。 275 | 黄尘足今古,白骨乱蓬蒿。 276 | 038李白:关山月 277 | 明月出天山,苍茫云海间。 278 | 长风几万里,吹度玉门关。 279 | 汉下白登道,胡窥青海湾。 280 | 由来征战地,不见有人还。 281 | 戍客望边色,思归多苦颜。 282 | 高楼当此夜,叹息未应闲。 283 | 039李白:子夜四时歌:春歌 284 | 秦地罗敷女,采桑绿水边。 285 | 素手青条上,红妆白日鲜。 286 | 蚕饥妾欲去,五马莫留连。 287 | 040李白:子夜四时歌:夏歌 288 | 镜湖三百里,菡萏发荷花。 289 | 五月西施采,人看隘若耶。 290 | 回舟不待月,归去越王家。 291 | 041李白:子夜四时歌:秋歌 292 | 长安一片月,万户捣衣声。 293 | 秋风吹不尽,总是玉关情。 294 | 何日平胡虏,良人罢远征? 295 | 042李白:子夜四时歌:冬歌 296 | 明朝驿使发,一夜絮征袍。 297 | 素手抽针冷,那堪把剪刀。 298 | 裁缝寄远道,几日到临洮? 299 | 043李白:长干行 300 | 妾发初覆额,折花门前剧。 301 | 郎骑竹马来,绕床弄青梅。 302 | 同居长干里,两小无嫌猜。 303 | 十四为君妇,羞颜未尝开。 304 | 低头向暗壁,千唤不一回。 305 | 十五始展眉,愿同尘与灰。 306 | 常存抱柱信,岂上望夫台! 307 | 十六君远行,瞿塘滟预堆。 308 | 五月不可触,猿鸣天上哀。 309 | 门前迟行迹,一一生绿苔。 310 | 苔深不能扫,落叶秋风早。 311 | 八月蝴蝶来,双飞西园草。 312 | 感此伤妾心,坐愁红颜老。 313 | 早晚下三巴,预将书报家。 314 | 相迎不道远,直至长风沙。 315 | 044孟郊:烈女操 316 | 梧桐相待老,鸳鸯会双死。 317 | 贞妇贵殉夫,舍生亦如此。 318 | 波澜誓不起,妾心井中水。 319 | 045孟郊:游子吟 320 | 慈母手中线,游子身上衣。 321 | 临行密密缝,意恐迟迟归。 322 | 谁言寸草心,报得三春辉? 323 | 046陈子昂:登幽州台歌 324 | 前不见古人,后不见来者。 325 | 念天地之悠悠,独怆然而涕下! 326 | 047李颀:古意 327 | 男儿事长征,少小幽燕客。 328 | 赌胜马蹄下,由来轻七尺。 329 | 杀人莫敢前,须如猬毛磔。 330 | 黄云陇底白雪飞,未得报恩不能归。 331 | 辽东小妇年十五,惯弹琵琶解歌舞。 332 | 今为羌笛出塞声,使我三军泪如雨! 333 | 048李颀:送陈章甫 334 | 四月南风大麦黄,枣花未落桐叶长。 335 | 青山朝别暮还见,嘶马出门思故乡。 336 | 陈侯立身何坦荡,虬须虎眉仍大颡。 337 | 腹中贮书一万卷,不肯低头在草莽。 338 | 东门酤酒饮我曹,心轻万事皆鸿毛。 339 | 醉卧不知白日暮,有时空望孤云高。 340 | 长河浪头连天黑,津口停舟渡不得。 341 | 郑国游人未及家,洛阳行子空叹息。 342 | 闻道故林相识多,罢官昨日今如何? 343 | 049李颀:琴歌 344 | 主人有酒欢今夕,请奏鸣琴广陵客。 345 | 月照城头乌半飞,霜凄万树风入衣。 346 | 铜炉华烛烛增辉,初弹渌水后楚妃。 347 | 一声已动物皆静,四座无言星欲稀。 348 | 清淮奉使千馀里,敢告云山从此始? 349 | 350 | 第一卷 第二章 351 | 352 | 353 | 唐诗300首 51-10 354 | 052孟浩然:夜归鹿门山歌 355 | 山寺钟鸣昼已昏,渔梁渡头争渡喧。 356 | 人随沙路向江村,余亦乘舟归鹿门。 357 | 鹿门月照开烟树,忽到庞公栖隐处。 358 | 岩扉松径长寂寥,惟有幽人自来去。 359 | 053李白:庐山谣寄卢侍御虚舟 360 | 我本楚狂人,凤歌笑孔丘。 361 | 手持绿玉杖,朝别黄鹤楼。 362 | 五岳寻仙不辞远,一生好入名山游。 363 | 庐山秀出南斗傍,屏风九叠云锦张。 364 | 影落明湖青黛光,金阙前开二峰长。 365 | 银河倒挂三石梁,香炉瀑布遥相望。 366 | 回崖沓障凌苍苍。 367 | 翠影红霞映朝日,鸟飞不到吴天长。 368 | 登高壮观天地间,大江茫茫去不黄。 369 | 黄云万里动风色,白波九道流雪山。 370 | 好为庐山谣,兴因庐山发。 371 | 闲窥石镜清我心,谢公行处苍苔没。 372 | 早服还丹无世情,琴心三叠道初成。 373 | 遥见仙人彩云里,手把芙蓉朝玉京。 374 | 先期汗漫九垓上,愿接卢敖游太清。 375 | 054李白:梦游天姥吟留别 376 | 海客谈瀛洲,烟涛微茫信难求。 377 | 越人语天姥,云霓明灭或可睹。 378 | 天姥连天向天横,势拔五岳掩赤城。 379 | 天台四万八千丈,对此欲倒东南倾。 380 | 我欲因之梦吴越,一夜飞渡镜湖月。 381 | 湖月照我影,送我至剡溪。 382 | 谢公宿处今尚在,渌水荡漾清猿啼。 383 | 脚著谢公屐,身登青云梯。 384 | 半壁见海日,空中闻天鸡。 385 | 千岩万壑路不定,迷花倚石忽已暝。 386 | 熊咆龙吟殷岩泉,栗深林兮惊层巅。 387 | 云青青兮欲雨,水澹澹兮生烟。 388 | 裂缺霹雳,丘峦崩摧。 389 | 洞天石扇,訇然中开。 390 | 青冥浩荡不见底,日月照耀金银台。 391 | 霓为衣兮风为马,云之君兮纷纷而来下。 392 | 虎鼓瑟兮鸾回车,仙之人兮列如麻。 393 | 忽魂悸以魄动,恍惊起而长嗟。 394 | 惟觉时之枕席,失向来之烟霞。 395 | 世间行乐亦如此,古来万事东流水。 396 | 别君去兮何时还?且放白鹿青崖间。 397 | 须行即骑访名山。 398 | 安能摧眉折腰事权贵,使我不得开心颜! 399 | 055李白:金陵酒肆留别 400 | 风吹柳花满店香,吴姬压酒唤客尝。 401 | 金陵子弟来相送,欲行不行各尽觞。 402 | 请君试问东流水,别意与之谁短长? 403 | 056李白:宣州谢朓楼饯别校书叔云 404 | 弃我去者,昨日之日不可留。 405 | 乱我心者,今日之日多烦忧! 406 | 长风万里送秋雁,对此可以酣高楼。 407 | 蓬莱文章建安骨,中间小谢又清发。 408 | 俱怀逸兴壮思飞,欲上青天览明月。 409 | 抽刀断水水更流,举杯销愁愁更愁。 410 | 人生在世不称意,明朝散发弄扁舟。 411 | 057岑参:走马川行奉送封大夫出师西征 412 | 君不见走马川行雪海边,平沙莽莽黄入天。 413 | 轮台九月风夜吼,一川碎石大如斗。 414 | 随风满地石乱走,匈奴草黄马正肥。 415 | 金山西见烟尘飞,汉家大将西出师。 416 | 将军金甲夜不脱,半夜军行戈相拨。 417 | 风头如刀面如割,马毛带雪汗气蒸。 418 | 五花连钱旋作冰,幕中草檄砚水凝。 419 | 虏骑闻之应胆慑,料知短兵不敢接。 420 | 车师西门伫献捷! 421 | 058岑参:轮台歌奉送封大夫出师西征 422 | 轮台城头夜吹角,轮台城北旄头落。 423 | 羽书昨夜过渠黎,单于已在金山西。 424 | 戍楼西望烟尘黑,汉兵屯在轮台北。 425 | 上将拥旄西出征,平明吹笛大军行。 426 | 四边伐鼓雪海涌,三军大呼阴山动。 427 | 虏塞兵气连云屯,战场白骨缠草根。 428 | 剑河风急雪片阔,沙口石冻马蹄脱。 429 | 亚相勤王甘苦辛,誓将报主静边尘。 430 | 古来青史谁不见,今见功名胜古人。 431 | 059岑参:白雪歌送武判官归京 432 | 北风卷地白草折,胡天八月即飞雪。 433 | 忽如一夜春风来,千树万树梨花开。 434 | 散入珠帘湿罗幕,狐裘不暖锦衾薄。 435 | 将军角弓不得控,都护铁衣冷犹著。 436 | 瀚海阑干百丈冰,愁云黪淡万里凝。 437 | 中军置酒饮归客,胡琴琵琶与羌笛。 438 | 纷纷暮雪下辕门,风掣红旗冻不翻。 439 | 轮台东门送君去,去时雪满天山路。 440 | 山回路转不见君,雪上空留马行处。 441 | 062杜甫:寄韩谏议 442 | 今我不乐思岳阳,身欲奋飞病在床。 443 | 美人娟娟隔秋水,濯足洞庭望八荒。 444 | 鸿飞冥冥日月白,青枫叶赤天雨霜。 445 | 玉京群帝集北斗,或骑麒麟翳凤凰。 446 | 芙蓉旌旗烟雾落,影动倒景摇潇湘。 447 | 星宫之君醉琼浆,羽人稀少不在旁。 448 | 似闻昨者赤松子,恐是汉代韩张良。 449 | 昔随刘氏定长安,帷幄未改神惨伤。 450 | 国家成败吾岂敢,色难腥腐餐枫香。 451 | 周南留滞古所惜,南极老人应寿昌。 452 | 美人胡为隔秋水,焉得置之贡玉堂? 453 | 065元结:石鱼湖上醉歌并序 454 | 漫叟以公田米酿酒,因休暇,则载酒于湖上, 455 | 时取一醉;欢醉中,据湖岸,引臂向鱼取酒, 456 | 使舫载之,遍饮坐者。意疑倚巴丘,酌於君山 457 | 之上,诸子环洞庭而坐,酒舫泛泛然,触波涛 458 | 而往来者,乃作歌以长之。 459 | 石鱼湖,似洞庭,夏水欲满君山青。 460 | 山为樽,水为沼,酒徒历历坐洲鸟。 461 | 长风连日作大浪,不能废人运酒舫。 462 | 我持长瓢坐巴丘,酌饮四座以散愁。 463 | 067韩愈:八月十五夜赠张功曹 464 | 纤云四卷天无河,清风吹空月舒波。 465 | 沙平水息声影绝,一杯相属君当歌。 466 | 君歌声酸辞且苦,不能听终泪如雨。 467 | 洞庭连天九嶷高,蛟龙出没猩鼯号。 468 | 十生九死到官所,幽居默默如藏逃。 469 | 下床畏蛇食畏药,海气湿蛰熏腥臊。 470 | 昨者州前槌大鼓,嗣皇继圣登夔皋。 471 | 赦书一日行万里,罪从大辟皆除死。 472 | 迁者追回流者还,涤瑕荡垢清朝班。 473 | 州家申名使家抑,坎轲只得移荆蛮。 474 | 判司卑官不堪说,未免捶楚尘埃间。 475 | 同时辈流多上道,天路幽险难追攀。 476 | 君歌且休听我歌,我歌今与君殊科。 477 | 一年明月今宵多,人生由命非由他。 478 | 有酒不饮奈明何! 479 | 071白居易:长恨歌 480 | 汉皇重色思倾国,御宇多年求不得。 481 | 杨家有女初长成,养在深闺人未识。 482 | 天生丽质难自弃,一朝选在君王侧。 483 | 回眸一笑百媚生,六宫粉黛无颜色。 484 | 春寒赐浴华清池,温泉水滑洗凝脂。 485 | 侍儿扶起娇无力,始是新承恩泽时。 486 | 云鬓花颜金步摇,芙蓉帐暖度春宵。 487 | 春宵苦短日高起,从此君王不早朝。 488 | 承欢侍宴无闲暇,春从春游夜专夜。 489 | 后宫佳丽三千人,三千宠爱在一身。 490 | 金星妆成娇侍夜,玉楼宴罢醉和春。 491 | 姊妹弟兄皆列士,可怜光彩生门户。 492 | 遂令天下父母心,不重生男重生女。 493 | 骊宫高处入青云,仙乐风飘处处闻。 494 | 缓歌慢舞凝丝竹,尽日君王看不足。 495 | 渔阳鼙鼓动地来,惊破霓裳羽衣曲。 496 | 九重城阙烟尘生,千乘万骑西南行。 497 | 翠华摇摇行复止,西出都门百馀里。 498 | 六军不发无奈何,宛转蛾眉马前死。 499 | 花钿委地无人收,翠翘金雀玉搔头。 500 | 君王掩面救不得,回看血泪相和流。 501 | 黄埃散漫风萧索,云栈萦纡登剑阁。 502 | 峨嵋山下少人行,旌旗无光日色薄。 503 | 蜀江水碧蜀山青,圣主朝朝暮暮情。 504 | 行宫见月伤心色,夜雨闻铃肠断声。 505 | 天旋地转回龙驭,到此踌躇不能去。 506 | 马嵬坡下泥土中,不见玉颜空死处。 507 | 君臣相顾尽沾衣,东望都门信马归。 508 | 归来池苑皆依旧,太液芙蓉未央柳。 509 | 芙蓉如面柳如眉,对此如何不泪垂! 510 | 春风桃李花开日,秋雨梧桐叶落时。 511 | 西宫南内多秋草,落叶满阶红不扫。 512 | 梨园子弟白发新,椒房阿监青娥老。 513 | 夕殿萤飞思悄然,孤灯挑尽未成眠。 514 | 迟迟钟鼓初长夜,耿耿星河欲曙天。 515 | 鸳鸯瓦冷霜华重,翡翠衾寒谁与共? 516 | 悠悠生死别经年,魂魄不曾来入梦。 517 | 临邛道士鸿都客,能以精诚致魂魄。 518 | 为感君王辗转思,遂教方士殷勤觅。 519 | 排空驭气奔如电,升天入地求之遍。 520 | 上穷碧落下黄泉,两处茫茫皆不见。 521 | 忽闻海上有仙山,山在虚无缥缈间。 522 | 楼阁玲珑五云起,其中绰约多仙子。 523 | 中有一人字太真,雪肤花貌参差是。 524 | 金阙西厢叩玉扃,转教小玉报双成。 525 | 闻道汉家天子使,九华帐里梦魂惊。 526 | 揽衣推枕起徘徊,珠箔银屏迤逦开。 527 | 云鬓半偏新睡觉,花冠不整下堂来。 528 | 风吹仙袂飘飘举,犹似霓裳羽衣舞。 529 | 玉容寂寞泪阑干,梨花一枝春带雨。 530 | 含情凝睇谢君王,一别音容两渺茫。 531 | 昭阳殿里恩爱绝,蓬莱宫中日月长。 532 | 回头下望人寰处,不见长安见尘雾。 533 | 唯将旧物表深情,钿合金钗寄将去。 534 | 钗留一股合一扇,钗擘黄金合分钿。 535 | 但教心似金钿坚,天上人间会相见。 536 | 临别殷勤重寄词,词中有誓两心知。 537 | 七月七日长生殿,夜半无人私语时。 538 | 在天愿作比翼鸟,在地愿为连理枝。 539 | 天长地久有时尽,此恨绵绵无绝期! 540 | 072白居易:琵琶行并序 541 | 元和十年,予左迁九江郡司马。明年秋,送客湓浦口,闻船中夜弹琵琶者,听其音 542 | ,铮铮然有京都声;问其人,本长安倡女,尝学琵琶於穆曹二善才。年长色衰,委 543 | 身为贾人妇。遂命酒,使快弹数曲,曲罢悯然。自叙少小时欢乐事,今漂沦憔悴, 544 | 转徙於江湖间。予出官二年恬然自安,感斯人言,是夕,始觉有迁谪意,因为长句 545 | 歌以赠之,凡六百一十六言,命曰琵琶行。 546 | 浔言江头夜送客,枫叶荻花秋瑟瑟。 547 | 主人下马客在船,举酒欲饮无管弦。 548 | 醉不成欢惨将别,别时茫茫江浸月。 549 | 忽闻水上琵琶声,主人忘归客不发。 550 | 寻声暗问弹者谁,琵琶声停欲语迟。 551 | 移船相近邀相见,添酒回灯重开宴。 552 | 千呼万唤始出来,犹抱琵琶半遮面。 553 | 转轴拨弦三两声,未成曲调先有情。 554 | 弦弦掩抑声声思,似诉平生不得志。 555 | 低眉信手续续弹,说尽心中无限事。 556 | 轻拢慢捻抹复挑,初为霓裳后六么。 557 | 大弦嘈嘈如急雨,小弦切切如私语。 558 | 嘈嘈切切错杂弹,大珠小珠落玉盘。 559 | 间关莺语花底滑,幽咽泉流水下滩。 560 | 水泉冷涩弦凝绝,凝绝不通声渐歇。 561 | 别有幽愁暗恨生,此时无声胜有声。 562 | 银瓶乍破水浆迸,铁骑突出刀枪鸣。 563 | 曲终收拨当心画,四弦一声如裂帛。 564 | 东船西舫悄无言,唯见江心秋月白。 565 | 沈吟放拨插弦中,整顿衣裳起敛容。 566 | 自言本是京城女,家在虾蟆陵下住。 567 | 十三学得琵琶成,名属教坊第一部。 568 | 曲罢曾教善才服,妆成每被秋娘妒。 569 | 五陵年少争缠头,一曲红绡不知数。 570 | 钿头银篦击节碎,血色罗裙翻酒污。 571 | 今年欢笑复明年,秋月春风等闲度。 572 | 弟走从军阿姨死,暮去朝来颜色故。 573 | 门前冷落车马稀,老大嫁作商人妇。 574 | 商人重利轻别离,前月浮梁买茶去。 575 | 去来江口守空船,绕船月明江水寒。 576 | 夜深忽梦少年事,梦啼妆泪红阑干。 577 | 我闻琵琶已叹息,又闻此语重唧唧。 578 | 同是天涯沦落人,相逢何必曾相识! 579 | 我从去年辞帝京,谪居卧病浔阳城。 580 | 浔阳地僻无音乐,终岁不闻丝竹声。 581 | 住近湓江地低湿,黄芦苦竹绕宅生。 582 | 其间旦暮闻何物?杜鹃啼血猿哀鸣。 583 | 春江花朝秋月夜,往往取酒还独倾。 584 | 岂无山歌与村笛,呕哑嘲哳难为听! 585 | 今夜闻君琵琶语,如听仙乐耳暂明。 586 | 莫辞更坐弹一曲,为君翻作琵琶行。 587 | 感我此言良久立,却坐促弦弦转急。 588 | 凄凄不似向前声,满座重闻皆掩泣。 589 | 座中泣下谁最多,江州司马青衫湿! 590 | 075李颀:古从军行 591 | 白日登山望烽火,黄昏饮马傍交河。 592 | 行人刁斗风沙暗,公主琵琶幽怨多。 593 | 野云万里无城郭,雨雪纷纷连大漠。 594 | 胡雁哀鸣夜夜飞,胡儿眼泪双双落。 595 | 闻道玉门犹被遮,应将性命逐轻车。 596 | 年年战骨埋荒外,空见葡萄入汉家。 597 | 076王维:洛阳女儿行 598 | 洛阳女儿对门居,才可容颜十五馀。 599 | 良人玉勒乘骢马,侍女金盘脍鲤鱼。 600 | 画阁朱楼尽相望,红桃绿柳垂檐向。 601 | 罗帷送上七香车,宝扇迎归九华帐。 602 | 狂夫富贵在青春,意气骄奢剧季伦。 603 | 自怜碧玉亲教舞,不惜珊瑚持与人。 604 | 春窗曙灭九微火,九微片片飞花琐。 605 | 戏罢曾无理曲时,妆成只是薰香坐。 606 | 城中相识尽繁华,日夜经过赵李家。 607 | 谁怜越女颜如玉,贫贱江头自浣纱! 608 | 077王维:老将行 609 | 少年十五二十时,步行夺得胡马骑。 610 | 射杀山中白额虎,肯数邺下黄须儿! 611 | 一身转战三千里,一剑曾当百万师。 612 | 汉兵奋迅如霹雳,虏骑崩腾畏蒺藜。 613 | 卫青不败由天幸,李广无功缘数奇。 614 | 自从弃置便衰朽,世事蹉跎成白首。 615 | 昔时飞箭无全目,今日垂杨生左肘。 616 | 路旁时卖故侯瓜,门前学种先生柳。 617 | 苍茫古木连穷巷,寥落寒山对虚牖。 618 | 誓令疏勒出飞泉,不似颍川空使酒。 619 | 贺兰山下阵如云,羽檄交驰日夕闻。 620 | 节使三河募年少,诏书五道出将军。 621 | 试拂铁衣如雪色,聊持宝剑动星文。 622 | 愿得燕弓射大将,耻令越甲鸣吾君。 623 | 莫嫌旧日云中守,犹堪一战取功勋! 624 | 080李白:长相思二首之一 625 | 长相思,在长安。 626 | 络纬秋啼金井阑,微霜凄凄簟色寒。 627 | 孤灯不明思欲绝,卷帷望月空长叹。 628 | 美人如花隔云端。 629 | 上有青冥之长天,下有渌水之波澜。 630 | 天长路远魂飞苦,梦魂不到关山难。 631 | 长相思,摧心肝! 632 | 081李白:长相思二首之二 633 | 日色已尽花含烟,月明欲素愁不眠。 634 | 赵瑟初停凤凰柱,蜀琴欲奏鸳鸯弦。 635 | 此曲有意无人传,愿随春风寄燕然。 636 | 忆君迢迢隔青天。 637 | 昔日横波目,今成流泪泉。 638 | 不信妾肠断,归来看取明镜前。 639 | 082李白:行路难三首之一 640 | 金樽清酒斗十千,玉盘珍羞值万钱。 641 | 停杯投箸不能食,拔剑四顾心茫然。 642 | 欲渡黄河冰塞川,将登太行雪满山。 643 | 闲来垂钓碧溪上,忽复乘舟梦日边。 644 | 行路难,行路难!多歧路,今安在? 645 | 长风破浪会有时,直挂云帆济沧海。 646 | 083李白:行路难三首之二 647 | 大道如青天,我独不得出。 648 | 羞逐长安社中儿,赤鸡白狗赌梨栗。 649 | 弹剑作歌奏苦声,曳裾王门不称情。 650 | 淮阴市井笑韩信,汉朝公卿忌贾生。 651 | 君不见,昔时燕家重郭隗,拥彗折节无嫌猜 652 | 剧辛乐毅感恩分,输肝剖胆效英才。 653 | 昭王白骨萦蔓草,谁人更扫黄金台? 654 | 行路难,归去来! 655 | 084李白:行路难三首之三 656 | 有耳莫洗颍川水,有口莫食首阳蕨。 657 | 含光混世贵无名,何用孤高比云月? 658 | 吾观自古贤达人,功成不退皆殒身。 659 | 子胥既弃吴江上,屈原终投湘水滨。 660 | 陆机雄才岂自保?李斯税驾苦不早。 661 | 华亭鹤唳讵可闻,上蔡苍鹰何足道! 662 | 君不见,吴中张翰称达生,秋风忽忆江东行。 663 | 且乐生前一杯酒,何须身后千载名! 664 | 085李白:将进酒 665 | 君不见,黄河之水天上来,奔流到海不复回。 666 | 君不见,高堂明镜悲白发,朝如青丝暮成雪。 667 | 人生得意须尽欢,莫使金樽空对月! 668 | 天生我材必有用,千金散尽还复来。 669 | 烹羊宰牛且为乐,会须一饮三百杯! 670 | 岑夫子,丹丘生,将进酒,君莫停! 671 | 与君歌一曲,请君为我侧耳听! 672 | 钟鼓馔玉不足贵,但愿长醉不愿醒! 673 | 古来圣贤皆寂寞,惟有饮者留其名! 674 | 陈王昔时宴平乐,斗酒十千恣欢谑。 675 | 主人何为言少钱?径须沽取对君酌。 676 | 五花马,千金裘,呼儿将出换美酒,与尔同消万古愁! 677 | 086杜甫:兵车行 678 | 车辚辚,马萧萧,行人弓箭各在腰。 679 | 耶娘妻子走相送,尘埃不见咸阳桥。 680 | 牵衣顿足拦道哭,哭声直上干云霄! 681 | 道旁过者问行人,行人但云点行频。 682 | 或从十五北防河,便至四十西营田。 683 | 去时里正与裹头,归来头白还戍边! 684 | 边亭流血成海水,武皇开边意未已。 685 | 君不闻,汉家山东二百州,千村万落生荆杞! 686 | 纵有健妇把锄犁,禾生陇亩无东西。 687 | 况复秦兵耐苦战,被驱不异犬与鸡。 688 | 长者虽有问,役夫敢申恨? 689 | 且如今年冬,未休关西卒。 690 | 县官急索租,租税从何出? 691 | 信知生男恶,反是生女好。 692 | 生女犹得嫁比邻,生男埋没随百草! 693 | 君不见,青海头,古来白骨无人收。 694 | 新鬼烦冤旧鬼哭,天阴雨湿声啾啾! 695 | 088杜甫:哀江头 696 | 少陵野老吞生哭,春日潜行曲江曲。 697 | 江头宫殿锁千门,细柳新蒲为谁绿? 698 | 忆昔霓旌下南苑,苑中景物生颜色。 699 | 昭阳殿里第一人,同辇随君侍君侧。 700 | 辇前才人带弓箭,白马嚼啮黄金勒。 701 | 翻身向天仰射云,一箭正坠双飞翼。 702 | 明眸皓齿今何在?血污游魂归不得! 703 | 清渭东流剑阁深,去住彼此无消息。 704 | 人生有情泪沾臆,江水江花岂终极? 705 | 黄昏胡骑尘满城,欲往城南望城北。 706 | 090唐玄宗:经邹鲁祭孔子而叹之 707 | 夫子何为者,栖栖一代中。 708 | 地犹鄹氏邑,宅即鲁王宫。 709 | 叹凤嗟身否?伤麟怨道穷。 710 | 今看两楹奠,当与梦时同。 711 | 091张九龄:望月怀远 712 | 海上生明月,天涯共此时。 713 | 情人怨遥夜,竟夕起相思! 714 | 灭烛怜光满,披衣觉露滋。 715 | 不堪盈手赠,还寝梦佳期。 716 | 092王勃:送杜少府之任蜀州 717 | 城阙辅三秦,风烟望五津。 718 | 与君离别意,同是宦游人。 719 | 海内存知己,天涯若比邻。 720 | 无为在歧路,儿女共沾巾。 721 | 094杜审言:和晋陵路丞早春游望 722 | 独有宦游人,偏惊物候新。 723 | 云霞出海曙,梅柳渡江春。 724 | 淑气催黄鸟,晴光转绿苹。 725 | 忽闻歌古调,归思欲沾巾。 726 | 095沈全期:杂诗 727 | 闻道黄龙戍,频年不解兵。 728 | 可怜闺里月,长在汉家营。 729 | 少妇今春意,良人昨夜情。 730 | 谁能将旗鼓,一为取龙城? 731 | 096宋之问:题大庾岭北驿 732 | 阳月南飞雁,传闻至此回。 733 | 我行殊未已,何日复归来? 734 | 江静潮初落,林昏瘴不开。 735 | 明朝望乡处,应见陇头梅。 736 | 097王湾:次北固山下 737 | 客路青山外,行舟绿水前。 738 | 潮平两岸阔,风正一帆悬。 739 | 海日生残夜,江春入旧年。 740 | 乡书何处达?归雁洛阳边。 741 | 098常建:题破山寺后禅院 742 | 清晨入古寺,初日照高林。 743 | 曲径通幽处,禅房花木深。 744 | 山光悦鸟性,潭影空人心。 745 | 万籁此俱寂,惟馀钟磬音。 746 | 099岑参:寄左省杜拾遗 747 | 联步趋丹陛,分曹限紫微。 748 | 晓随天仗入,暮惹御香归。 749 | 白发悲花落,青云羡鸟飞。 750 | 圣朝无阙事,自觉谏书稀。 751 | 100李白:赠孟浩然 752 | 吾爱孟夫子,风流天下闻。 753 | 红颜弃轩冕,白首卧松云。 754 | 醉月频中圣,迷花不事君。 755 | 高山安可仰,徒此挹清芬。 756 | 757 | 758 | 第一卷 第三章 759 | 760 | 唐诗300首 101-150 761 | 101李白:渡荆门送别 762 | 渡远荆门外,来从楚国游。 763 | 山随平野尽,江入大荒流。 764 | 月下飞天镜,云生结海楼。 765 | 仍怜故乡水,万里送行舟。 766 | 102李白:送友人 767 | 青山横北郭,白水绕东城。 768 | 此地一为别,孤蓬万里征。 769 | 浮云游子意,落日故人情。 770 | 挥手自兹去,萧萧班马鸣。 771 | 103李白:听蜀僧浚弹琴 772 | 蜀僧抱绿绮,西下峨眉峰。 773 | 为我一挥手,如听万壑松。 774 | 客心洗流水,馀响入霜钟。 775 | 不觉碧山暮,秋云暗几重。 776 | 104李白:夜泊牛渚怀古 777 | 牛渚西江夜,青天无片云。 778 | 登舟望秋月,空忆谢将军。 779 | 余亦能高咏,斯人不可闻。 780 | 明朝挂帆席,枫叶落纷纷。 781 | 106杜甫:春望 782 | 国破山河在,城春草木深。 783 | 感时花溅泪,恨别鸟惊心。 784 | 烽火连三月,家书抵万金。 785 | 白头搔更短,浑欲不胜簪。 786 | 107杜甫:春宿左省 787 | 花隐掖垣暮,啾啾栖鸟过。 788 | 星临万户动,月傍九霄多。 789 | 不寝听金钥,因风想玉珂。 790 | 明朝有封事,数问夜如何? 791 | 108杜甫:至德二载甫自京金光门出,问道归凤翔。乾元初从左拾遗移华州掾。与亲 792 | 故别,因出此门。有悲往事。 793 | 此道昔归顺,西郊胡正繁。 794 | 至今残破胆,应有未招魂。 795 | 近得归京邑,移官岂至尊? 796 | 无才日衰老,驻马望千门。 797 | 109杜甫:月夜忆舍弟 798 | 戍鼓断人行,秋边一雁声。 799 | 露从今夜白,月是故乡明。 800 | 有弟皆分散,无家问死生。 801 | 寄书长不达,况乃未休兵。 802 | 110杜甫:天末怀李白 803 | 凉风起天末,君子意如何? 804 | 鸿雁几时到,江湖秋水多。 805 | 文章憎命达,魑魅喜人过。 806 | 应共冤魂语,投诗赠汨罗。 807 | 111杜甫:奉济驿重送严公四韵 808 | 远送从此别,青山空复情。 809 | 几时杯重把,昨夜月同行。 810 | 列郡讴歌惜,三朝出入荣。 811 | 将村独归处,寂寞养残生。 812 | 112杜甫:别房太尉墓 813 | 他乡复行役,驻马别孤坟。 814 | 近泪无干土,低空有断云。 815 | 对棋陪谢傅,把剑觅徐君。 816 | 唯见林花落,莺啼送客闻。 817 | 113杜甫:旅夜书怀 818 | 细草微风岸,危樯独夜舟。 819 | 星垂平野阔,月涌大江流。 820 | 名岂文章著?官应老病休。 821 | 飘飘何所似,天地一沙鸥。 822 | 114杜甫:登岳阳楼 823 | 昔闻洞庭水,今上岳阳楼。 824 | 吴楚东南坼,乾坤日夜浮。 825 | 亲朋无一字,老病有孤舟。 826 | 戎马关山北,凭轩涕泗流。 827 | 116王维:山居秋暝 828 | 空山新雨后,天气晚来秋。 829 | 明月松间照,清泉石上流。 830 | 竹喧归浣女,莲动下渔舟。 831 | 随意春芳歇,王孙自可留。 832 | 117王维:归嵩山作 833 | 清川带长薄,车马去闲闲。 834 | 流水如有意,暮禽相与还。 835 | 荒城临古渡,落日满秋山。 836 | 迢递嵩高下,归来且闭关。 837 | 118王维:终南山 838 | 太乙近天都,连山接海隅。 839 | 白云回望合,青霭入看无。 840 | 分野中峰变,阴晴众壑殊。 841 | 欲投人处宿,隔水问樵夫。 842 | 119王维:酬张少府 843 | 晚年惟好静,万事不关心。 844 | 自顾无长策,空知返旧林。 845 | 松风吹解带,山月照弹琴。 846 | 君问穷通理,渔歌入浦深。 847 | 120王维:过香积寺 848 | 不知香积寺,数里入云峰。 849 | 古木无人径,深山何处钟? 850 | 泉声咽危石,日色冷青松。 851 | 薄暮空潭曲,安禅制毒龙。 852 | 122王维:汉江临眺 853 | 楚塞三湘接,荆门九派通。 854 | 江流天地外,山色有无中。 855 | 郡邑浮前浦,波澜动远空。 856 | 襄阳好风日,留醉与山翁。 857 | 123王维:终南别业 858 | 中岁颇好道,晚家南山陲。 859 | 兴来美独往,胜事空自知。 860 | 行到水穷处,坐看云起时。 861 | 偶然值林叟,谈笑无还期。 862 | 124孟浩然:望洞庭湖赠张丞相 863 | 八月湖水平,涵虚混太清。 864 | 气蒸云梦泽,波撼岳阳城。 865 | 欲济无舟楫,端居耻圣明。 866 | 坐观垂钓者,空有羡鱼情。 867 | 125孟浩然:与诸子登岘山 868 | 人事有代谢,往来成古今。 869 | 江山留胜迹,我辈复登临。 870 | 水落鱼梁浅,天寒梦泽深。 871 | 羊公碑字在,读罢泪沾襟。 872 | 126孟浩然:清明日宴梅道士房 873 | 林卧愁春尽,开轩览物华。 874 | 忽逢青鸟使,邀入赤松家。 875 | 丹灶初开火,仙桃正发花。 876 | 童颜若可驻,何惜醉流霞! 877 | 127孟浩然:岁暮归南山 878 | 北阙休上书,南山归敝庐。 879 | 不才明主弃,多病故人疏。 880 | 白发催年老,青阳逼岁除。 881 | 永怀愁不寐,松月夜窗墟。 882 | 128孟浩然:过故人庄 883 | 故人具鸡黍,邀我至田家。 884 | 绿树村边合,青山郭外斜。 885 | 开轩面场圃,把酒话桑麻。 886 | 待到重阳日,还来就菊花。 887 | 129孟浩然:秦中感秋寄远上人 888 | 一丘尝欲卧,三径苦无资。 889 | 北土非吾愿,东林怀我师。 890 | 黄金燃桂尽,壮志逐年衰。 891 | 日夕凉风至,闻蝉但益悲。 892 | 130孟浩然:宿桐庐江寄广陵旧游 893 | 山暝听猿愁,沧江急夜流。 894 | 风鸣两岸叶,月照一孤舟。 895 | 建德非吾土,维扬忆旧游。 896 | 还将两行泪,遥寄海西头。 897 | 131孟浩然:留别王侍御维 898 | 寂寂竟何待,朝朝空自归。 899 | 欲寻芳草去,惜与故人违。 900 | 当路谁相假,知音世所稀。 901 | 只应守寂寞,还掩故园扉。 902 | 132孟浩然:早寒江上有怀 903 | 木落雁南渡,北风江上寒。 904 | 我家襄水曲,遥隔楚云端。 905 | 乡泪客中尽,孤帆天际看。 906 | 迷津欲有问,平海夕漫漫。 907 | 133刘长卿:秋日登吴公台上寺远眺 908 | 古台摇落后,秋日望乡心。 909 | 野寺人来少,云峰水隔深。 910 | 夕阳依旧垒,寒磬满空林。 911 | 惆怅南朝事,长江独至今。 912 | 134刘常卿:送李中丞归汉阳别业 913 | 流落征南将,曾驱十万师。 914 | 罢归无旧业,老去恋明时。 915 | 独立三边静,轻生一剑知。 916 | 茫茫江汉上,日暮复何之。 917 | 135刘长卿:饯别王十一南游 918 | 望君烟水阔,挥手泪沾巾。 919 | 飞鸟没何处,青山空向人。 920 | 长江一帆远,落日五湖春。 921 | 谁见汀洲上,相思愁白苹? 922 | 136刘长卿:寻南溪常山道人隐居 923 | 一路经行处,莓苔见履痕。 924 | 白云依静渚,春草闭闲门。 925 | 过雨看松色,随山到水源。 926 | 溪花与禅意,相对亦忘言。 927 | 137刘长卿:新年作 928 | 乡心新岁切,天畔独潸然。 929 | 老至居人下,春归在客先。 930 | 岭猿同旦暮,江柳共风烟。 931 | 已似长沙傅,从今又几年? 932 | 138钱起:送僧归日本 933 | 上国随缘住,来途若梦行。 934 | 浮天沧海远,去世法舟轻。 935 | 水月通禅寂,鱼龙听梵声。 936 | 惟怜一灯影,万里眼中明。 937 | 139钱起:谷口书斋寄杨补阙 938 | 泉壑带茅茨,云霞生薜帷。 939 | 竹怜新雨后,山爱夕阳时。 940 | 闲鹭栖常早,秋花落更迟。 941 | 家童扫萝径,昨与故人期。 942 | 140韦应物:淮上喜会梁川故人 943 | 江汉曾为客,相逢每醉还。 944 | 浮云一别后,流水十年间。 945 | 欢笑情如旧,萧疏鬓已斑。 946 | 何因北归去,淮上对秋山。 947 | 141韦应物:赋得暮雨送李胄 948 | 楚江微雨里,建业暮钟时。 949 | 漠漠帆来重,冥冥鸟去迟。 950 | 海门深不见,浦树远含滋。 951 | 相送情无限,沾襟比散丝。 952 | 142韩翃:酬程延秋夜即事见赠 953 | 长簟迎风早,空城澹月华。 954 | 星河秋一雁,砧杵夜千家。 955 | 节候看应晚,心期卧亦赊。 956 | 向来吟秀句,不觉已鸣鸦。 957 | 143刘脊虚:阙题 958 | 道由白云尽,春与青溪长。 959 | 时有落花至,远隋流水香。 960 | 闲门向山路,深柳读书堂。 961 | 幽映每白日,清辉照衣裳。 962 | 144戴叔伦:江乡故人偶集客舍 963 | 天秋月又满,城阙夜千重。 964 | 还作江南会,翻疑梦里逢。 965 | 风枝惊暗鹊,露草覆寒虫。 966 | 羁旅长堪醉,相留畏晓钟。 967 | 145卢纶:李端公 968 | 故关衰草遍,离别正堪悲! 969 | 路出寒云外,人归暮雪时。 970 | 少孤为客早,多难识君迟。 971 | 掩泪空相向,风尘何处期? 972 | 146李益:喜见外弟又言别 973 | 十年离乱后,长大一相逢。 974 | 问姓惊初见,称名忆旧容。 975 | 别来沧海事,语罢暮天钟。 976 | 明日巴陵道,秋山又几重。 977 | 147司空曙:云阳馆与韩绅宿别 978 | 故人江海别,几度隔山川。 979 | 乍见翻疑梦,相悲各问年。 980 | 孤灯寒照雨,深竹暗浮烟。 981 | 更有明朝恨,离杯惜共传。 982 | 148司空曙:喜外弟卢纶见宿 983 | 静夜四无邻,荒居旧业贫。 984 | 雨中黄叶树,灯下白头人。 985 | 以我独沉久,愧君相访频。 986 | 平生自有分,况是蔡家亲! 987 | 149司空曙:贼平后送人北归 988 | 世乱同南去,时清独北还。 989 | 他乡生白发,旧国见青山。 990 | 晓月过残垒,繁星宿故关。 991 | 寒禽与衰草,处处伴愁颜。 992 | 150刘禹锡:蜀先主庙 993 | 天地英雄气,千秋尚凛然! 994 | 势分三足鼎,业复五铢钱。 995 | 得相能开国,生儿不象贤。 996 | 凄凉蜀故妓,来舞魏宫前。 997 | 998 | 999 | 第一卷 第四章 1000 | 1001 | 唐诗300首 151-200 1002 | 151张籍:没蕃故人 1003 | 前年伐月支,城下没全师。 1004 | 蕃汉断消息,死生长别离。 1005 | 无人收废帐,归马识残旗。 1006 | 欲祭疑君在,天涯哭此时。 1007 | 152白居易:赋得古原草送别 1008 | 离离原上草,一岁一枯荣。 1009 | 野火烧不尽,春风吹又生。 1010 | 远芳侵古道,晴翠接荒城。 1011 | 又送王孙去,萋萋满别情。 1012 | 153杜牧:旅宿 1013 | 旅馆无良伴,凝情自悄然。 1014 | 寒灯思旧事,断雁警愁眠。 1015 | 远梦归侵晓,家书到隔年。 1016 | 沧江好烟月,门系钓鱼船。 1017 | 154许浑:秋日赴阙题潼关驿楼 1018 | 红叶晚萧萧,长亭酒一瓢。 1019 | 残云归太华,疏雨过中条。 1020 | 树色随山迥,河声入海遥。 1021 | 帝乡明日到,犹自梦渔樵。 1022 | 155许浑:早秋 1023 | 遥夜泛清瑟,西风生翠萝。 1024 | 残萤栖玉露,早雁拂银河。 1025 | 高树晓还密,远山晴更多。 1026 | 淮南一叶下,自觉老烟波。 1027 | 156李商隐:蝉 1028 | 本以高难饱,徒劳恨费声。 1029 | 五更疏欲断,一树碧无情。 1030 | 薄宦梗犹泛,故园芜已平。 1031 | 烦君最相警,我亦举家清。 1032 | 157李商隐:风雨 1033 | 凄凉宝剑篇,羁泊欲穷年。 1034 | 黄叶仍风雨,青楼自管弦。 1035 | 新知遭薄俗,旧好隔良缘。 1036 | 心断新丰酒,销愁斗几千。 1037 | 158李商隐:落花 1038 | 高阁客竟去,小园花乱飞。 1039 | 参差连曲陌,迢递送斜晖。 1040 | 肠断未忍扫,眼穿仍欲归。 1041 | 芳心向春尽,所得是沾衣。 1042 | 159李商隐:凉思 1043 | 客去波平槛,蝉休露满枝。 1044 | 永怀当此节,倚立自移时。 1045 | 北斗兼春远,南陵寓使迟。 1046 | 天涯占梦数,疑误有新知。 1047 | 160李商隐:北青萝 1048 | 残阳西入崦,茅屋访孤僧。 1049 | 落叶人何在?寒云路几层? 1050 | 独敲初夜磬,闲倚一枝藤。 1051 | 世界微尘里,吾宁爱与憎。 1052 | 161温庭筠:送人东游 1053 | 荒戍落黄叶,浩然离故关。 1054 | 高风汉阳渡,初日郢门山。 1055 | 江上几人在?天涯孤棹还。 1056 | 何当重相见,樽酒慰离颜? 1057 | 162马戴:灞上秋居 1058 | 灞原风雨定,晚见雁行频。 1059 | 落叶他乡树,寒灯独夜人。 1060 | 空园白露滴,孤壁野僧邻。 1061 | 寄卧郊扉久,何年致此身? 1062 | 163马戴:楚江怀古 1063 | 露气寒光集,微阳下楚丘。 1064 | 猿啼洞庭树,人在木兰舟。 1065 | 广泽生明月,苍山夹乱流。 1066 | 云中君不见,竟夕自悲秋。 1067 | 164张乔:书边事 1068 | 调角断清秋,征人倚戍楼。 1069 | 春风对青冢,白日落梁州。 1070 | 大漠无兵阻,穷边有客游。 1071 | 蕃情似此水,长愿向南流。 1072 | 165崔涂:巴山道中除夜有怀 1073 | 迢递三巴路,羁危万里身。 1074 | 乱山残雪夜,孤独异乡春。 1075 | 渐与骨肉远,转於僮仆亲。 1076 | 那堪正飘泊,明日岁华新。 1077 | 167杜荀鹤:春宫怨 1078 | 早被婵娟误,欲妆临镜慵。 1079 | 承恩不在貌,教妾若为容。 1080 | 风暖鸟声碎,日高花影重。 1081 | 年年越溪女,相忆采芙蓉。 1082 | 168韦庄:章台夜思 1083 | 清瑟怨遥夜,绕弦风雨哀。 1084 | 孤灯闻楚角,残月下章台。 1085 | 芳草已云暮,故人殊未来。 1086 | 乡书不可寄,秋雁又南回。 1087 | 169僧皎然:寻陆鸿渐不遇 1088 | 移家虽带郭,野径入桑麻。 1089 | 近种篱边菊,秋来未著花。 1090 | 扣门无犬吠,欲去问西家。 1091 | 报到山中去,归来每日斜。 1092 | 170崔颢:黄鹤楼 1093 | 昔人已乘黄鹤去,此地空馀黄鹤楼。 1094 | 黄鹤一去不复返,白云千载空悠悠。 1095 | 晴川历历汉阳树,芳草萋萋鹦鹉洲。 1096 | 日暮乡关何处是,烟波江上使人愁。 1097 | 172祖咏:望蓟门 1098 | 燕台一去客心惊,箫鼓喧喧汉将营。 1099 | 万里寒光生积雪,三边曙色动危旌。 1100 | 沙场烽火侵胡月,海畔云山拥蓟城。 1101 | 少小虽非投笔吏,论功还欲请长缨。 1102 | 173李颀:送魏万之京 1103 | 朝闻游子唱骊歌,昨夜微霜初度河。 1104 | 鸿雁不堪愁里听,云山况是客中过。 1105 | 关城树色催寒近,御苑砧声向晚多。 1106 | 莫见长安行乐处,空令岁月易蹉跎。 1107 | 174崔曙:九日登望仙台呈刘明府 1108 | 汉文皇帝有高台,此日登临曙色开。 1109 | 三晋云山皆北向,二陵风雨自东来。 1110 | 关门令尹谁能识?河上仙翁去不回。 1111 | 且欲竟寻彭泽宰,陶然共醉菊花杯。 1112 | 176高适:送李少府贬峡中王少府贬长沙 1113 | 嗟君此别意何如?驻马衔杯问谪居。 1114 | 巫峡啼猿数行泪,衡阳归雁几封书。 1115 | 青枫江上秋帆远,白帝城边古木疏。 1116 | 圣代即今多雨露,暂时分手莫踌躇。 1117 | 177岑参:奉和中书舍人贾至早朝大明宫 1118 | 鸡鸣紫陌曙光寒,莺啭皇州春色阑。 1119 | 金阙晓钟开万户,玉阶仙仗拥千官。 1120 | 花迎剑佩星初落,柳拂旌旗露未干。 1121 | 独有凤凰池上客,阳春一曲和皆难。 1122 | 178王维:和贾舍人早朝大明宫之作 1123 | 绛帻鸡人送晓筹,尚衣方进翠云裘。 1124 | 九天阊阖开宫殿,万国衣冠拜冕旒。 1125 | 日色才临仙掌动,香烟欲傍衮龙浮。 1126 | 朝罢须裁五色诏,佩声归向凤池头。 1127 | 179王维:奉和圣制从蓬莱向兴庆阁道中留春雨中春望之作应制 1128 | 渭水自萦秦塞曲,黄山旧绕汉宫斜。 1129 | 銮舆迥出千门柳,阁道回看上苑花。 1130 | 云里帝城双凤阙,雨中春树万人家。 1131 | 为乘阳气行时令,不是宸游玩物华。 1132 | 181王维:酬郭给事 1133 | 洞门高阁霭馀辉,桃李阴阴柳絮飞。 1134 | 禁里疏钟官舍晚,省中啼鸟吏人稀。 1135 | 晨摇玉佩趋金殿,夕奉天书拜琐闱。 1136 | 强欲从君无那老,将因卧病解朝衣。 1137 | 182杜甫:蜀相 1138 | 丞相祠堂何处寻?锦官城外柏森森。 1139 | 映阶碧草自春色,隔叶黄鹂空好音。 1140 | 三顾频烦天下计,两朝开济老臣心。 1141 | 出师未捷身先死,长使英雄泪满襟! 1142 | 183杜甫:客至 1143 | 舍南舍北皆春水,但见群鸥日日来。 1144 | 花径不曾缘客扫,蓬门今始为君开。 1145 | 盘飧市远无兼味,樽酒家贫只旧醅。 1146 | 肯与邻翁相对饮,隔篱呼取尽馀杯! 1147 | 184杜甫:野望 1148 | 西山白雪三城戍,南浦清江万里桥。 1149 | 海内风尘诸弟隔,天涯涕泪一身遥。 1150 | 唯将迟暮供多病,未有涓埃答圣朝。 1151 | 跨马出郊时极目,不堪人事日萧条! 1152 | 185杜甫:闻官军收河南河北 1153 | 剑外忽传收蓟北,初闻涕泪满衣裳。 1154 | 却看妻子愁何在,漫卷诗书喜欲狂。 1155 | 白日放歌须纵酒,青春作伴好还乡! 1156 | 即从巴峡穿巫峡,便下襄阳向洛阳。 1157 | 186杜甫:登高 1158 | 风急天高猿啸哀,渚清沙白鸟飞回。 1159 | 无边落木萧萧下,不尽长江滚滚来。 1160 | 万里悲秋常作客,百年多病独登台。 1161 | 艰难苦恨繁霜鬓,潦倒新停浊酒杯。 1162 | 187杜甫:登楼 1163 | 花近高楼伤客心,万方多难此登临。 1164 | 锦江春色来天地,玉垒浮云变古今。 1165 | 北极朝庭终不改,西山寇盗莫相侵! 1166 | 可怜后主还祠庙,日暮聊为梁父吟。 1167 | 188杜甫:宿府 1168 | 清秋幕府井梧寒,独宿江城蜡炬残。 1169 | 永夜角声悲自语,中天月色好谁看? 1170 | 风尘荏苒音书绝,关塞萧条行陆难。 1171 | 已忍伶俜十年事,强移栖息一枝安。 1172 | 189杜甫:阁夜 1173 | 岁暮阴阳催短景,天涯霜雪霁寒霄。 1174 | 五更鼓角声悲壮,三峡星河影动摇。 1175 | 野哭千家闻战伐,夷歌数处起渔樵。 1176 | 卧龙跃马终黄土,人事音书漫寂寥。 1177 | 190杜甫:咏怀古迹五首之一 1178 | 支离东北风尘际,漂泊西南天地间。 1179 | 三峡楼台淹日月,五溪衣服共云山。 1180 | 羯胡事主终无赖,词客哀时且未还。 1181 | 庾信平生最萧瑟,暮年诗赋动江关。 1182 | 191杜甫:咏怀古迹五首之二 1183 | 摇落深知宋玉悲,风流儒雅亦吾师。 1184 | 怅望千秋一洒泪,萧条异代不同时。 1185 | 江山故宅空文藻,云雨荒台岂梦思! 1186 | 最是楚宫俱泯灭,舟人指点到今疑。 1187 | 192杜甫:咏怀古迹五首之三 1188 | 群山万壑赴荆门,生长明妃尚有村。 1189 | 一去紫台连朔漠,独留青冢向黄昏。 1190 | 画图省识春风面,环佩空归月下魂。 1191 | 千载琵琶作胡语,分明怨恨曲中论。 1192 | 193杜甫:咏怀古迹五首之四 1193 | 蜀主征吴幸三峡,崩年亦在永安宫。 1194 | 翠华想像空山里,玉殿虚无野寺中。 1195 | 古庙杉松巢水鹤,岁时伏腊走村翁。 1196 | 武侯祠屋常邻近,一体君臣祭祀同。 1197 | 194杜甫:咏怀古迹五首之五 1198 | 诸葛大名垂宇宙,宗臣遗像肃清高。 1199 | 三分割据纡筹策,万古云霄一羽毛。 1200 | 伯仲之间见伊吕,指挥若定失萧曹。 1201 | 运移汉祚终难复,志决身歼军务劳。 1202 | 195刘长卿:江州重别薛六柳八二员外 1203 | 生涯岂料承优诏?世事空知学醉歌。 1204 | 江上月明胡雁过,淮南木落楚山多。 1205 | 寄身且喜沧洲近,顾影无如白发何! 1206 | 今日龙钟人共老,愧君犹遣慎风波。 1207 | 196刘长卿:长沙过贾谊宅 1208 | 三年谪宦此栖迟,万古惟留楚客悲。 1209 | 秋草独寻人去后,寒林空见日斜时。 1210 | 汉文有道恩犹薄,湘水无情吊岂知? 1211 | 寂寂江山摇落处,怜君何事到天涯! 1212 | 197刘长卿:自夏口至鹦洲夕望岳阳寄源中丞 1213 | 汀洲无浪复无烟,楚客相思益渺然。 1214 | 汉口夕阳斜渡鸟,洞庭秋水远连天。 1215 | 孤城背岭寒吹角,独戍临江夜泊船。 1216 | 贾谊上书忧汉室,长沙谪去古今怜。 1217 | 198钱起:赠阙下裴舍人 1218 | 二月黄鹂飞上林,春城紫禁晓阴阴。 1219 | 长乐钟声花外尽,龙池柳色雨中深。 1220 | 阳和不散穷途恨,霄汉长怀捧日心。 1221 | 献赋十年犹未遇,羞将白发对华簪。 1222 | 199韦应物:寄李儋元锡 1223 | 去年花里逢君别,今日花开又一年。 1224 | 世事茫茫难自料,春愁黯黯独成眠。 1225 | 身多疾病思田里,邑有流亡愧俸钱。 1226 | 闻道欲来相问讯,西楼望月几回圆? 1227 | 200韩翃:同题仙游观 1228 | 仙台初见五城楼,风物凄凄宿雨收。 1229 | 山色遥连秦树晚,砧声近报汉宫秋。 1230 | 疏松影落空坛静,细草香闲小洞幽。 1231 | 何用别寻方外去,人间亦自有丹丘! 1232 | 1233 | 1234 | 第一卷 第五章 1235 | 1236 | 唐诗300首 201-250 1237 | 201皇甫冉:春思 1238 | 莺啼燕语报新年,马邑龙堆路几千。 1239 | 家住层城邻汉苑,心随明月到胡天。 1240 | 机中锦字论长恨,楼上花枝笑独眠。 1241 | 为问天戎窦车骑,何时返旆勒燕然? 1242 | 202卢纶:晚次鄂州 1243 | 云开远见汉阳城,犹是孤帆一日程。 1244 | 估客昼眠知浪静,舟人夜语觉潮生。 1245 | 三湘愁鬓逢秋色,万里归心对月明。 1246 | 旧业已随征战尽,更堪江上鼓鼙声。 1247 | 204刘禹锡:西塞山怀古 1248 | 王浚楼船下益州,金陵王气黯然收。 1249 | 千寻铁锁沈江底,一片降幡出石头。 1250 | 人世几回伤往事?山形依旧枕寒流。 1251 | 从今四海为家日,故垒萧萧芦荻秋。 1252 | 205元稹:遣悲怀三首之一 1253 | 谢公最小偏怜女,自嫁黔娄百事乖。 1254 | 顾我无衣搜荩箧,泥他沽酒拔金钗。 1255 | 野蔬充膳甘长藿,落叶添薪仰古槐。 1256 | 今日俸钱过十万,与君营奠复营斋。 1257 | 206元稹:遣悲怀三首之二 1258 | 昔日戏言身后事,今朝都到眼前来。 1259 | 衣裳已施行看尽,针线犹存未忍开。 1260 | 尚想旧情怜婢仆,也曾因梦送钱财。 1261 | 诚知此恨人人有,贫贱夫妻百事哀。 1262 | 208白居易:自河南经乱,关内阻饥,兄弟离散,各在一处。因望月有感,聊书所怀,寄上浮梁大兄,于潜七兄,乌江十五兄,兼示符离及下邽弟妹。 1263 | 时难年荒世业空,弟兄羁旅各西东。 1264 | 田园寥落干戈后,骨肉流离道路中。 1265 | 吊影分为千里雁,辞根散作九秋蓬。 1266 | 共看明月应垂泪,一夜乡心五处同。 1267 | 209李商隐:锦瑟 1268 | 锦瑟无端五十弦,一弦一柱思华年。 1269 | 庄生晓梦迷蝴蝶,望帝春心托杜鹃。 1270 | 沧海月明珠有泪,蓝田日暖玉生烟。 1271 | 此情可待成追忆,只是当时已惘然。 1272 | 210李商隐:无题 1273 | 昨夜星辰昨夜风,画楼西畔桂堂东。 1274 | 身无彩凤双飞翼,心有灵犀一点通。 1275 | 隔座送钩春酒暖,分曹射覆蜡灯红。 1276 | 嗟余听鼓应官去,走马兰台类转蓬。 1277 | 211李商隐:隋宫 1278 | 紫泉宫殿锁烟霞,欲取芜城作帝家。 1279 | 玉玺不缘归日角,锦帆应是到天涯。 1280 | 於今腐草无萤火,终古垂杨有暮鸦。 1281 | 地下若逢陈后主,岂宜重问后庭花? 1282 | 212李商隐:无题二首之一 1283 | 来是空言去绝踪,月斜楼上五更钟。 1284 | 梦为远别啼难唤,书被催成墨未浓。 1285 | 蜡照半笼金翡翠,麝熏微度绣芙蓉。 1286 | 刘郎已恨蓬山远,更隔蓬山一万重。 1287 | 213李商隐:无题二首之二 1288 | 飒飒东风细雨来,芙蓉塘外有轻雷。 1289 | 金蟾啮锁烧香入,玉虎牵丝汲井回。 1290 | 贾氏窥帘韩掾少,宓妃留枕魏王才。 1291 | 春心莫共花争发,一寸相思一寸灰。 1292 | 214李商隐:筹笔驿 1293 | 猿鸟犹疑畏简书,风云常为护储胥。 1294 | 徒令上将挥神笔,终见降王走传车。 1295 | 管乐有才原不忝,关张无命欲何如。 1296 | 他年锦里经祠庙,梁父吟成恨有馀。 1297 | 215李商隐:无题 1298 | 相见时难别亦难,东风无力百花残。 1299 | 春蚕到死丝方尽,蜡炬成灰泪始干。 1300 | 晓镜但愁云鬓改,夜吟应觉月光寒。 1301 | 蓬莱此去无多路,青鸟殷勤为探看。 1302 | 217李商隐:无题二首之一 1303 | 凤尾香罗薄几重,碧文圆顶夜深缝。 1304 | 扇裁月魄羞难掩,车走雷声语未通。 1305 | 曾是寂寥金烬暗,断无消息石榴红。 1306 | 斑骓只系垂杨岸,何处西南任好风? 1307 | 218李商隐:无题二首之二 1308 | 重帷深下莫愁堂,卧后清宵细细长。 1309 | 神女生涯原是梦,小姑居处本无郎。 1310 | 风波不信菱枝弱,月露谁教桂叶香? 1311 | 直道相思了无益,未妨惆怅是清狂。 1312 | 219温庭筠:利洲南渡 1313 | 澹然空水对斜晖,曲岛苍茫接翠微。 1314 | 波上马嘶看棹去,柳边人歇待船归。 1315 | 数丛沙草群鸥散,万顷江田一鹭飞。 1316 | 谁解乘舟寻范蠡,五湖烟水独忘机? 1317 | 220温庭筠:苏武庙 1318 | 苏武魂销汉使前,古祠高树两茫然。 1319 | 云边雁断胡天月,陇上羊归塞草烟。 1320 | 回日楼台非甲帐,去时冠剑是丁年。 1321 | 茂陵不见封侯印,空向秋波哭逝川。 1322 | 221薛逢:宫词 1323 | 十二楼中尽晓妆,望仙楼上望君王。 1324 | 锁衔金兽连环冷,水滴铜龙昼漏长。 1325 | 云髻罢梳还对镜,罗衣欲换更添香。 1326 | 遥窥正殿帘开处,袍裤宫人扫御床。 1327 | 222秦韬玉:贫女 1328 | 蓬门未识绮罗香,拟托良媒益自伤。 1329 | 谁爱风流高格调?共怜时世俭梳妆。 1330 | 敢将十指夸针巧,不把双眉斗画长。 1331 | 苦恨年年压金线,为他人作嫁衣裳。 1332 | 223沈全期:古意呈补阙乔知之 1333 | 卢家少妇郁金香,海燕双栖玳瑁梁。 1334 | 九月寒砧催木叶,十年征戍忆辽阳。 1335 | 白狼河北音书断,丹凤城南秋夜长。 1336 | 谁为含愁独不见,更教明月照流黄? 1337 | 224王维:鹿柴 1338 | 空山不见人,但闻人语响。 1339 | 返景入深林,复照青苔上。 1340 | 225王维:竹里馆 1341 | 独坐幽篁里,弹琴复长啸。 1342 | 深林人不知,明月来相照。 1343 | 226王维:送别 1344 | 山中相送罢,日暮掩柴扉。 1345 | 春草明年绿,王孙归不归? 1346 | 227王维:相思 1347 | 红豆生南国,春来发几枝? 1348 | 愿君多采撷,此物最相思。 1349 | 228王维:杂诗 1350 | 君自故乡来,应知故乡事。 1351 | 来日绮窗前,寒梅著花未? 1352 | 229裴迪:送崔九 1353 | 归山深浅去,须尽丘壑美。 1354 | 莫学武陵人,暂游桃源里。 1355 | 230祖咏:终南望馀雪 1356 | 终南阴岭秀,积雪浮云端。 1357 | 林表明霁色,城中增暮寒。 1358 | 231孟浩然:宿建德江 1359 | 移舟泊烟渚,日暮客愁新。 1360 | 野旷天低树,江清月近人。 1361 | 232孟浩然:春晓 1362 | 春眠不觉晓,处处闻啼鸟。 1363 | 夜来风雨声,花落知多少? 1364 | 233李白:夜思 1365 | 床前明月光,疑是地上霜。 1366 | 举头望明月,低头思故乡。 1367 | 234李白:怨情 1368 | 美人卷珠帘,深坐蹙蛾眉。 1369 | 但见泪痕湿,不知心恨谁? 1370 | 235杜甫:八阵图 1371 | 功盖三分国,名成八阵图。 1372 | 江流石不转,遗恨失吞吴。 1373 | 236王之涣:登鹳雀楼 1374 | 白日依山尽,黄河入海流。 1375 | 欲穷千里目,更上一层楼。 1376 | 237刘长卿:送灵澈 1377 | 苍苍竹林寺,杳杳钟声晚。 1378 | 荷笠带斜阳,青山独归远。 1379 | 238刘长卿:弹琴 1380 | 泠泠七弦上,静听松风寒。 1381 | 古调虽自爱,今人多不弹。 1382 | 239刘长卿:送上人 1383 | 孤云将野鹤,岂向人间住! 1384 | 莫买沃洲山,时人已知处。 1385 | 240韦应物:秋夜寄邱员外 1386 | 怀君属秋夜,散步咏凉天。 1387 | 空山松子落,幽人应未眠。 1388 | 241李端:听筝 1389 | 鸣筝金粟柱,素手玉房前。 1390 | 欲得周郎顾,时时误拂弦。 1391 | 242王建:新嫁娘 1392 | 三日入厨下,洗手作羹汤。 1393 | 未谙姑食性,先遣小姑尝。 1394 | 244柳宗元:江雪 1395 | 千山鸟飞绝,万径人踪灭。 1396 | 孤舟蓑笠翁,独钓寒江雪。 1397 | 245元稹:行宫 1398 | 寥落古行宫,宫花寂寞红。 1399 | 白头宫女在,闲坐说玄宗。 1400 | 246白居易:问刘十九 1401 | 绿蚁新醅酒,红泥小火炉。 1402 | 晚来天欲雪,能饮一杯无? 1403 | 247张祜:何满子 1404 | 故国三千里,深宫二十年。 1405 | 一声何满子,双泪落君前。 1406 | 248李商隐:登乐游原 1407 | 向晚意不适,驱车登古原。 1408 | 夕阳无限好,只是近黄昏。 1409 | 249贾岛:寻隐者不遇 1410 | 松下问童子,言师采药去。 1411 | 只在此山中,云深不知处。 1412 | 250李频:渡汉江 1413 | 岭外音书绝,经冬复立春。 1414 | 近乡情更怯,不敢问来人。 1415 | 1416 |    第一卷 第六章 1417 | 1418 | 唐诗300首 251-300 1419 | 251金昌绪:春怨 1420 | 打起黄莺儿,莫教枝上啼。 1421 | 啼时惊妾梦,不得到辽西。 1422 | 252西鄙人:哥舒歌 1423 | 北斗七星高,哥舒夜带刀。 1424 | 至今窥牧马,不敢过临洮。 1425 | 253崔颢:长干行二首之一 1426 | 君家何处住,妾住在横塘。 1427 | 停船暂借问,或恐是同乡。 1428 | 254崔颢:长干行二首之二 1429 | 家临九江水,来去九江侧。 1430 | 同是长干人,生小不相识。 1431 | 255李白:玉阶怨 1432 | 玉阶生白露,夜久侵罗袜。 1433 | 却下水晶帘,玲珑望秋月。 1434 | 256卢纶:塞下曲四首之一 1435 | 鹫翎金仆姑,燕尾绣蝥弧。 1436 | 独立扬新令,千营共一呼。 1437 | 257卢纶:塞下曲四首之二 1438 | 林暗草惊风,将军夜引弓。 1439 | 平明寻白羽,没在石棱中。 1440 | 258卢纶:塞下曲四首之三 1441 | 月黑雁飞高,单于夜遁逃。 1442 | 欲将轻骑逐,大雪满弓刀。 1443 | 259卢纶:塞下曲四首之四 1444 | 野幕蔽琼筵,羌戎贺劳旋。 1445 | 醉和金甲舞,雷鼓动山川。 1446 | 260李益:江南曲 1447 | 嫁得瞿塘贾,朝朝误妾期。 1448 | 早知潮有信,嫁与弄潮儿。 1449 | 261贺知章:回乡偶书 1450 | 少小离家老大回,乡音无改鬓毛衰。 1451 | 儿童相见不相识,笑问客从何处来? 1452 | 262张旭:桃花溪 1453 | 隐隐飞桥隔野烟,石矶西畔问渔船。 1454 | 桃花尽日随流水,洞在清溪何处边? 1455 | 263王维:九月九日忆山东兄弟 1456 | 独在异乡为异客,每逢佳节倍思亲。 1457 | 遥知兄弟登高处,遍插茱萸少一人。 1458 | 264王昌龄:芙蓉楼送辛渐 1459 | 寒雨连江夜入吴,平明送客楚山孤。 1460 | 洛阳亲友如相问,一片冰心在玉壶。 1461 | 265王昌龄:闺怨 1462 | 闺中少妇不知愁,春日凝妆上翠楼。 1463 | 忽见陌头杨柳色,悔教夫婿觅封侯。 1464 | 266王昌龄:春宫曲 1465 | 昨夜风开露井桃,未央前殿月轮高。 1466 | 平阳歌舞新承宠,帘外春寒赐锦袍。 1467 | 267王翰:凉州词 1468 | 葡萄美酒夜光杯,欲饮琵琶马上催。 1469 | 醉卧沙场君莫笑,古来征战几人回! 1470 | 268李白:送孟浩然之广陵 1471 | 故人西辞黄鹤楼,烟花三月下扬州。 1472 | 孤帆远影碧空尽,惟见长江天际流。 1473 | 269李白:下江陵 1474 | 朝辞白帝彩云间,千里江陵一日还。 1475 | 两岸猿声啼不住,轻舟已过万重山。 1476 | 270岑参:逢入京使 1477 | 故园东望路漫漫,双袖龙钟泪不干。 1478 | 马上相逢无纸笔,凭君传语报平安。 1479 | 271杜甫:江南逢李龟年 1480 | 岐王宅里寻常见,崔九堂前几度闻。 1481 | 正是江南好风景,落花时节又逢君。 1482 | 272韦应物:滁州西涧 1483 | 独怜幽草涧边生,上有黄鹂深树鸣。 1484 | 春潮带雨晚来急,野渡无人舟自横。 1485 | 273张继:枫桥夜泊 1486 | 月落乌啼霜满天,江枫渔火对愁眠。 1487 | 姑苏城外寒山寺,夜半钟声到客船。 1488 | 274韩翃:寒食 1489 | 春城无处不飞花,寒食东风御柳斜。 1490 | 日暮汉宫传蜡烛,轻烟散入五侯家。 1491 | 275刘方平:月夜 1492 | 更深月色半人家,北斗阑干南斗斜。 1493 | 今夜偏知春气暖,虫声新透绿窗纱。 1494 | 276刘方平:春怨 1495 | 纱窗日落渐黄昏,金屋无人见泪痕。 1496 | 寂寞空庭春欲晚,梨花满地不开门。 1497 | 277柳中庸:征人怨 1498 | 岁岁金河复玉关,朝朝马策与刀环。 1499 | 三春白雪归青冢,万里黄河绕黑山。 1500 | 278顾况:宫词 1501 | 玉楼天半起笙歌,风送宫嫔笑语和。 1502 | 月殿影开闻夜漏,水晶帘卷近秋河。 1503 | 279李益:夜上受降城闻笛 1504 | 回乐峰前沙似雪,受降城外月如霜。 1505 | 不知何处吹芦管,一夜征人尽望乡。 1506 | 280刘禹锡:乌衣巷 1507 | 朱雀桥边野草花,乌衣巷口夕阳斜。 1508 | 旧时王谢堂前燕,飞入寻常百姓家。 1509 | 281刘禹锡:春词 1510 | 新妆宜面下朱楼,深锁春光一院愁。 1511 | 行到中庭数花朵,蜻蜓飞上玉搔头。 1512 | 282白居易:后宫词 1513 | 泪湿罗巾梦不成,夜深前殿按歌声。 1514 | 红颜未老恩先断,斜倚薰笼坐到明。 1515 | 283张祜:赠内人 1516 | 禁门宫树月痕过,媚眼惟看宿鹭窠。 1517 | 斜拔玉钗灯影畔,剔开红焰救飞蛾。 1518 | 285张祜:集灵台二首之二 1519 | 虢国夫人承主恩,平明骑马入宫门。 1520 | 却嫌脂粉污颜色,淡扫蛾眉朝至尊。 1521 | 286张祜:题金陵渡 1522 | 金陵津渡小山楼,一宿行人自可愁。 1523 | 潮落夜江斜月里,两三星火是瓜州。 1524 | 287朱庆馀:宫词 1525 | 寂寂花时闭院门,美人相并立琼轩。 1526 | 含情欲说宫中事,鹦鹉前头不敢言。 1527 | 288朱庆馀:近试上张水部 1528 | 洞房昨夜停红烛,待晓堂前拜舅姑。 1529 | 妆罢低声问夫婿,画眉深浅入时无? 1530 | 289杜牧:将赴吴兴登乐游原 1531 | 清时有味是无能,闲爱孤云静爱僧。 1532 | 欲把一麾江海去,乐游原上望昭陵。 1533 | 290杜牧:赤壁 1534 | 折戟沈沙铁未销,自将磨洗认前朝。 1535 | 东风不与周郎便,铜雀春深销二乔。 1536 | 291杜牧:泊秦淮 1537 | 烟笼寒水月笼沙,夜泊秦淮近酒家。 1538 | 商女不知亡国恨,隔江犹唱《后庭花》。 1539 | 292杜牧:寄扬州韩绰判官 1540 | 青山隐隐水迢迢,秋尽江南草未凋。 1541 | 二十四桥明月夜,玉人何处教吹箫? 1542 | 293杜牧:遣怀 1543 | 落魄江湖载酒行,楚腰纤细掌中轻。 1544 | 十年一觉扬州梦,赢得青楼薄幸名。 1545 | 294杜牧:秋夕 1546 | 银烛秋光冷画屏,轻罗小扇扑流萤。 1547 | 天阶夜色凉如水,坐看牵牛织女星。 1548 | 295杜牧:赠别二首之一 1549 | 娉娉袅袅十三馀,豆蔻梢头二月初。 1550 | 春风十里扬州路,卷上珠帘总不如。 1551 | 296杜牧:赠别二首之二 1552 | 多情却似总无情,唯觉樽前笑不成。 1553 | 蜡烛有心还惜别,替人垂泪到天明。 1554 | 297杜牧:金谷园 1555 | 繁华事散逐香尘,流水无情草自春。 1556 | 日暮东风怨啼鸟,落花犹似坠楼人。 1557 | 298李商隐:夜雨寄北 1558 | 君问归期未有期,巴山夜雨涨秋池。 1559 | 何当共剪西窗烛,却话巴山夜雨时? 1560 | 299李商隐:寄令狐郎中 1561 | 嵩云秦树久离居,双鲤迢迢一纸笔。 1562 | 休问梁园旧宾客,茂陵秋雨病相如。 1563 | 300李商隐:为有 1564 | 为有云屏无限娇,凤城寒尽怕春宵。 1565 | 无端嫁得金龟婿,辜负香衾事早朝。 1566 | 301李商隐:隋宫 1567 | 乘兴南游不戒严,九重谁省谏书函? 1568 | 春风举国裁宫锦,半作障泥半作帆。 1569 | 302李商隐:瑶池 1570 | 瑶池阿母绮窗开,黄竹歌声动地哀。 1571 | 八骏日行三万里,穆王何事不重来? 1572 | 303李商隐:嫦娥 1573 | 云母屏风烛影深,长河渐落晓星沈。 1574 | 嫦娥应悔偷灵药,碧海青天夜夜心。 1575 | 304李商隐:贾生 1576 | 宣室求贤访逐臣,贾生才调更无伦。 1577 | 可怜夜半虚前席,不问苍生问鬼神! 1578 | 305温庭筠:瑶瑟怨 1579 | 冰簟银床梦不成,碧天如水夜云轻。 1580 | 雁声远过潇湘去,十二楼中月自明。 1581 | 306郑畋:马嵬坡 1582 | 玄宗回马杨妃死,云雨难忘日月新。 1583 | 终是圣明天子事,景阳宫井又何人? 1584 | 307韩偓:已凉 1585 | 碧阑干外绣帘垂,猩色屏风画折枝。 1586 | 八尺龙须方锦褥,已凉天气未寒时。 1587 | 308韦庄:金陵图 1588 | 江雨霏霏江草齐,六朝如梦鸟空啼。 1589 | 无情最是台城柳,依旧烟笼十里堤。 1590 | 309陈陶:陇西行 1591 | 誓扫匈奴不顾身,五千貂锦丧胡尘。 1592 | 可怜无定河边骨,犹是深闺梦里人! 1593 | 310张泌:寄人 1594 | 别梦依依到谢家,小廊回合曲阑斜。 1595 | 多情只有春庭月,犹为离人照落花。 1596 | 311无名氏:杂诗 1597 | 尽寒食雨草萋萋,著麦苗风柳映堤。 1598 | 等是有家归未得,杜鹃休向耳边啼。 1599 | 313王维:秋夜曲 1600 | 桂魄初生秋露微,轻罗已薄未更衣。 1601 | 银筝夜久殷勤弄,心怯空房不忍归! 1602 | 314王昌龄:长信怨 1603 | 奉帚平明金殿开,且将团扇共徘徊。 1604 | 玉颜不及寒鸦色,犹带昭阳日影来。 1605 | 315王昌龄:出塞 1606 | 秦时明月汉时关,万里长征人未还。 1607 | 但使龙城飞将在,不教胡马渡阴山! 1608 | 316王之涣:出塞 1609 | 黄河远上白云间,一片孤城万仞山。 1610 | 羌笛何须怨杨柳?春风不度玉门关。 1611 | 317李白:清平调三首之一 1612 | 云想衣裳花想容,春风拂槛露华浓。 1613 | 若非群玉山头见,会向瑶台月下逢。 1614 | 318李白:清平调三首之二 1615 | 一枝红艳露凝香,云雨巫山枉断肠。 1616 | 借问汉宫谁得似?可怜飞燕倚新妆。 1617 | 319李白:清平调三首之三 1618 | 名花倾国两相欢,常得君王带笑看。 1619 | 解释春风无限恨,沈香亭北倚阑干。 1620 | 320杜秋娘:金缕衣 1621 | 劝君莫惜金缕衣,劝君惜取少年时。 1622 | 花开堪折直须折,莫待无花空折枝! 1623 | 1624 | -------------------------------------------------------------------------------- /teacher/gendict/课文.txt: -------------------------------------------------------------------------------- 1 | 第一册 2 | 3 | 001一三五七九 4 | 一三五七九 5 | 6 | 002公鸡的尾巴弯 7 | 公鸡的尾巴弯。 8 | 鸭子的尾巴扁。 9 | 孔雀的尾巴最好看。 10 | 11 | 003秋天到了 12 | 天气凉了,树叶黄了,一片片叶子从树上落下来。 13 | 天空那么蓝,那么高。一群大雁往南飞,一会儿排成个“人”字,一会儿排成个“一”字。 14 | 啊!秋天来了! 15 | 16 | 004小猫种鱼 17 | 农民把玉米种在地里,到了秋天,收了很多玉米。 18 | 农民把花生种在地里,到了秋天,收了很多花生。 19 | 小猫看见了,把小鱼种在地里。他想,到了秋天,一定会收到很多小鱼。 20 | 21 | 005小山羊 22 | 小山羊和小鸡是朋友。小鸡请小山羊吃虫子。小山羊说:“谢谢你!我不吃虫子。” 23 | 24 | 006小小的船 25 | 弯弯的月儿小小的船。 26 | 小小的船儿两头尖。 27 | 我在小小的船里坐, 28 | 只看见闪闪的星星蓝蓝的天。 29 | 30 | 007蒲公英的种子 31 | 我是蒲公英的种子, 32 | 有一朵毛茸茸的小花。 33 | 微风轻轻一吹, 34 | 我离开了亲爱的妈妈。 35 | 飞呀飞呀, 36 | 飞到哪儿, 37 | 哪儿就是我的家。 38 | 39 | 008过桥 40 | 雷锋小时候上学要走过一座小桥。 41 | 有一天下大雨,雷锋和几个小同学一起上学去。他们走到桥边,看见河水漫过了小桥。 42 | 雷锋说:“来,我背你们过桥。” 43 | 雷锋把小同学一个一个地背过去。放学的时候,他又把小同学一个一个地背过来。 44 | 45 | 009小公鸡和小鸭子 46 | 小公鸡和小鸭子一块儿出去玩。 47 | 他们走进草丛里。小公鸡找到了许多虫子,吃得很欢。小鸭子捉不到虫子,急得直叫唤。小公鸡看见了,捉到虫子就给小鸭子吃。 48 | 他们走到小河边。小鸭子说:“公鸡弟弟,我到河里捉鱼给你吃。”小公鸡说:“我也去。” 49 | 小鸭子说:“不行,不行,你会淹死的!” 50 | 小公鸡不信,偷偷地跟在小鸭子后面,也下了水。 51 | 小鸭子正在水里捉鱼,忽然听见小公鸡喊救命。他飞快地游到小公鸡身边,让小公鸡爬到自己的背上。 52 | 小鸭子把小公鸡送上岸。小公鸡对小鸭子说:“鸭子哥哥,谢谢你。” 53 | 54 | 010春天 55 | 春天对冰雪说了什么,冰雪那么听话,都化了。 56 | 春天对小草说了什么, 小草那么听话,都绿了。 57 | 春天对花儿说了什么, 花儿那么听话,都开了。 58 | 59 | 011花园果园 60 | 我们村种了许多果树。春天,桃花开了,梨花开了,苹果花也开了。我们村成了花园。 61 | 秋天,桃子熟了,梨熟了,苹果也熟了。我们村成了果园。 62 | 63 | 012泉水小溪 64 | 泉水泉水你到哪里去? 65 | 我要流进小溪里。 66 | 溪水溪水你到哪里去? 67 | 我要流进江河里。 68 | 69 | 013乌鸦喝水 70 | 乌鸦口渴了,到处找水喝。 71 | 乌鸦看见一个瓶子,瓶子里有水。可是,瓶子里水不多,瓶口又小,乌鸦喝不着水。怎么办呢? 72 | 乌鸦看见旁边有许多小石子,想出办法来了。 73 | 乌鸦把小石子一个一个地放在瓶子里。瓶子里的水渐渐升高,乌鸦就喝着水了。 74 | 75 | 014小猴子下山 76 | 有一天,一只小猴子下山来。它走到一块玉米地里,看见玉米结得又大又多,非常高兴,就掰了一个,扛着往前走。 77 | 小猴子扛着玉米,走到一棵桃树下。它看见满树的桃子又大又红,非常高兴,就扔了玉米去摘桃子。 78 | 小猴子捧着几个桃子,走到一片瓜地里。它看见满地的西瓜又大又圆,非常高兴,就扔了桃子去摘西瓜。 79 | 小猴子抱着一个大西瓜往回走。走着走着,看见一只小兔蹦蹦跳跳的,真可爱。它非常高兴,就扔了西瓜去追小兔。 80 | 小兔跑进树林子,不见了。小猴子只好空着手回家去。 81 | 82 | 015司马光 83 | 古时候有个孩子,叫司马光。 84 | 有一回,他跟几个小朋友在花园里玩。花园里有假山,假山下面有一口大水缸,缸里装满了水。 85 | 有个小朋友爬到假山上去玩,一不小心,掉进了大水缸。 86 | 别的小朋友都慌了,有的吓哭了,有的叫着喊着,跑去找大人。 87 | 司马光没有慌,他举起一块石头,使劲砸那口缸,几下子就把缸砸破了。 88 | 缸里的水流出来了,掉进缸里的小朋友得救了。 89 | 90 | 016谜语 91 | 有时落在山腰,有时挂在树梢,有时像个圆盘,有时像把镰刀。 92 | 93 | 017春风吹 94 | 春风吹, 95 | 春风吹, 96 | 吹绿了柳树, 97 | 吹红了桃花。 98 | 吹来了燕子, 99 | 吹醒了青蛙。 100 | 春风轻轻地吹,春雨西西地下。 101 | 大家快来种蓖麻,大家快来种葵花。 102 | 103 | 018燕子飞回来了 104 | 春天到了,小燕子跟着妈妈从很远很远的南方飞回来。 105 | 飞呀,飞呀,她们飞过大海。小燕子往下一看,奇怪地问:“妈妈,海面上哪儿来那么多铁塔?”妈妈笑着说:“孩子,那是井架,工人在开采海底的石油呢。” 106 | 飞呀,飞呀,她们飞过高山。小燕子往下一看,奇怪地问:“妈妈,那火车为什么不冒烟呢?”妈妈笑着说:“孩子,那是电力机车。你看,车顶上还有电线呢。” 107 | 飞呀,飞呀,她们飞过田野,飞到去年住过的地方。小燕子奇怪地问:“妈妈,这里哪儿来那么多新房子?”妈妈笑着说:“孩子,农民过上好日子啦。你看,那写字的孩子不是京生吗?” 108 | 小燕子高兴地说:“妈妈,京生也爱学习了。”妈妈说:“是呀!农村的变化可真大啊!” 109 | 110 | 019两只小狮子 111 | 狮子妈妈生下了两只小狮子。 112 | 一只小狮子整天练习滚、扑、撕、咬,非常刻苦。另一只却懒洋洋地晒太阳,什么也不干。 113 | 一棵小树问懒狮子:“你怎么不学点儿本领啊?” 114 | 懒狮子抬起头来,慢吞吞地说:“我才不去吃那苦头呢!” 115 | 小树说:“那你以后怎样生活呢?” 116 | 懒狮子说:“我爸爸和妈妈是林中的大王,凭着他们的地位,我会活得很好!” 117 | 这话被狮子妈妈听到了,她对懒狮子说:“孩子,将来我们老了,不在了,你靠谁呢?你也应该学会生活的本领,做一只真正的狮子!” 118 | 119 | 020小白兔和小灰兔 120 | 老山羊在地里收白菜,小白兔和小灰兔来帮忙。 121 | 收完白菜,老山羊把一车白菜送给小灰兔。小灰兔收下了,说:“谢谢您!” 122 | 老山羊又把一车白菜送给小白兔。小白兔说:“我不要白菜,请您给我一些菜子吧。”老山羊送给小白兔一包菜子。 123 | 小白兔回到家里,把地翻松了,种上菜子。 124 | 过了几天,白菜长出来了。小白兔常常给白菜浇水,施肥,拔草,捉虫。白菜很快就长大了。 125 | 小灰兔把一车白菜拉回家里。他不干活了,饿了就吃老山羊送的白菜。 126 | 过了些日子,小灰兔把白菜吃完了,又到老山羊家里去要白菜。 127 | 这时候,他看见小白兔挑着一担白菜,给老山羊送来了。小灰兔很奇怪,问道:“小白兔,你的菜是哪儿来的?” 128 | 小白兔说:“是我自己种的。只有自己种,才有吃不完的菜。” 129 | 130 | 021王冕学画 131 | 古时候有个画家叫王冕。他小时候家里很穷,只念了三年书,就去给人家放牛。他一边放牛,一边找些书来读。 132 | 一个夏天的傍晚,王冕在湖边放牛。忽然乌云密布,下了一阵大雨。大雨过后,阳光照得满湖通红。湖里的荷花开得更鲜艳了,粉红的花瓣上清水滴滴,碧绿的荷叶上水珠滚来滚去。 133 | 王冕看得出了神,心里想,要是能把这美丽的荷花画下来,那多好哇! 134 | 王冕用平时省下来的钱买了画笔和颜料,又找来一些纸,照着湖里的荷花画。开始画得不像,可是他不灰心,天天画。后来,他画的荷花,就像刚从湖里采来的一样。 135 | 136 | 022小猫钓鱼 137 | 猫妈妈带着小花猫,到河边钓鱼。 138 | 一只蜻蜓飞来了,小花猫放下鱼竿,就去捉蜻蜓。蜻蜓飞走了,小花猫没捉着蜻蜓。回到河边一看,妈妈钓着了一条大鱼。 139 | 一只蝴蝶飞来了,小花猫放下鱼竿,就去捉蝴蝶。蝴蝶飞走了,小花猫没捉着蝴蝶。回到河边一看,妈妈又钓着了一条大鱼。 140 | 小花猫说:“真气人,鱼儿怎么不上我的钩呢?” 141 | 猫妈妈对小花猫说:“不是鱼儿不上钩。你一会儿捉蜻蜓,一会儿捉蝴蝶,怎么能钓着鱼呢?” 142 | 小花猫听了妈妈的话,就一心一意地钓鱼。蜻蜓又飞来了,小花猫就像没看见一样。不大一会儿,小花猫也钓着了一条大鱼。 143 | 144 | 145 | 023蔬菜 146 | 萝卜、莴笋、白菜、黄花菜、扁豆,都是蔬菜。这些蔬菜,有的吃根,有的吃茎,有的吃叶子,有的吃花,还有的吃果实。 147 | 148 | 024庄稼地好朋友 149 | 青蛙捉害虫。猫头鹰捉田鼠。青蛙和猫头鹰都是庄稼的好朋友。 150 | 七星瓢虫爱吃蚜虫。赤眼蜂能消灭螟虫。七星瓢虫和赤眼蜂也是庄稼地好朋友。 151 | 152 | 025浪花 153 | 我坐在沙滩上玩耍。浪花看见了,迈着轻轻的步子走来,悄悄地搔痒了我的小脚丫。笑得我眼泪都流出来了,它才哗哗哗地笑着跑回家。 154 | 一会儿,浪花又唱着笑着跑出来了。这次它给我捧来了雪白的贝壳、青青的小虾。我的小篮子都装不下啦。 155 | 哗哗哗,浪花跑来又跑去,像一个淘气的娃娃。 156 | 157 | 026跳伞 158 | 姐姐的胆子真大,敢从飞机上跳下! 159 | 蓝天上飘满了五彩的花朵,也不知道哪朵是姐姐的花。 160 | 161 | 027奇妙的“眼睛” 162 | 望远镜是天文学家的“眼睛”。天文学家有了它,可以看到遥远的星星。 163 | 显微镜是医生的“眼睛”。医生有了它,可以看见极小的病菌。 164 | 潜望镜是海军战士的“眼睛”。海军战士有了它,可以在潜水艇里监视海面上的敌人。 165 | 166 | 028羊妈妈收菜 167 | 羊妈妈带着小羊到菜园去收菜。 168 | 他们走到萝卜地里。羊妈妈拔了一个萝卜。小羊要吃萝卜叶子。羊妈妈说:“萝卜的根最好吃。” 169 | 他们走到白菜地里。羊妈妈拔了一棵小白菜。小羊要吃白菜的根。羊妈妈说:“白菜的叶子才好吃呢!” 170 | 他们走到西红柿地里。小羊要吃西红柿的叶子。羊妈妈说:“要吃西红柿的果实呀!” 171 | 172 | 029小八路 173 | 他是谁? 174 | 你看他身穿军装,头戴军帽,脚穿草鞋,胳膊上还有臂章。原来他是个小八路。 175 | 你看他长得多结实啊!他一定跟着毛主席跑过很多路,打过很多仗。他准是个勇敢的小八路。 176 | 你看他一有空就坐在石头上,掏出小本子写字,多么专心啊!他真是个爱学习的小八路。 177 | 178 | 030王二小 179 | 王二小是儿童团员。他常常一边放牛,一边给八路军放哨。 180 | 有一天,敌人来 “扫荡”,走到山口迷了路。敌人看见王二小在山坡上放牛,就叫他带路。 181 | 王二小装着听话的样子走在前面,把敌人带进了八路军的埋伏圈。 182 | 突然,四面八方响起了枪声。敌人知道上了当,就杀害了小英雄王二小。 183 | 正在这时候,八路军从山上冲下来,消灭了全部敌人。 184 | 185 | 031明明上学 186 | 早上,明明去上学。他走着走着,忽然听见蛐蛐的叫声。明明一听,就知道草丛里有一只好蛐蛐。 187 | 明明轻轻地走过去,扒开草一看,好大的一只蛐蛐。他用手一捂,没捂着。蛐蛐一跳,又钻进草丛里去了。明明追上去,扒开草仔细地找,扒来扒去,怎么也找不着。 188 | 这时候,小文在路上喊:“明明,还不快走,要迟到啦!”明明立刻从草丛里走出来,拍了拍身上的土,和小文一同往学校跑去。 189 | 他们刚走进教室,上课铃就响了。 190 | 明明看了看小文,笑了。 191 | 192 | 0311一只小羊羔 193 | 放学了,巴特在回家的路上,听见咩咩的叫声。他东找西找,在一条小沟里找到一只小羊羔。 194 | 是谁丢了羊羔呢?巴特抱着小羊羔,到处去打听。人家都说没有丢。 195 | 天黑了,巴特只好把小羊羔抱回家去。 196 | 第二天,巴特一早起来,就去看小羊羔,还给它奶喝。 197 | 巴特放学回来,妈妈说,小羊羔是牧场丢的。巴特顾不上吃饭,抱起小羊羔,飞快地向牧场跑去。 198 | 小羊羔又回到了羊妈妈身边。 199 | 200 | 032要下雨了 201 | 小白兔弯着腰在山坡上割草。天气很闷,小白兔直起身子,伸伸腰。 202 | 一只小燕子从他头上飞过。小白兔大声喊:“燕子,燕子,你为什么飞得这么低啊?” 203 | 燕子边飞边说:“要下雨了。空气很潮湿,虫子的翅膀沾了小水珠,飞不高。我正忙着捉虫子呢!” 204 | 是要下雨了吗?小白兔往前一看,那边池子里的小鱼都游到水面上来了。 205 | 小白兔跑过去问:“小鱼,小鱼,今天怎么有空出来啊?” 206 | 小鱼说:“要下雨了。水里闷得很,我们游到水面上透透气。小白兔,你快回家吧,小心淋着雨。” 207 | 小白兔连忙挎起篮子往家跑。他看见路边有一大群蚂蚁。小白兔把要下雨的消息告诉蚂蚁。一只大蚂蚁说:“是要下雨了,我们正忙着往高处搬家呢!” 208 | 小白兔加快步子往家跑。他一边跑一边喊:“妈妈,妈妈,要下雨了!” 209 | 哗,哗,哗,大雨下起来了! 210 | 211 | 033小壁虎借尾巴 212 | 小壁虎在墙角捉蚊子,一条蛇咬住了它的尾巴。小壁虎一挣,挣断尾巴逃走了。 213 | 没有尾巴多难看啊!小壁虎想,向谁去借一条尾巴呢? 214 | 小壁虎爬呀爬,爬到小河边。他看见小鱼在河里摇着尾巴游来游去。小壁虎说:“小鱼姐姐,您的尾巴借给我行吗?”小鱼说:“不行啊,我要用尾巴拨水呢。” 215 | 小壁虎爬呀爬,爬到大树上。他看见老黄牛甩着尾巴在树下吃草。小壁虎说:“牛伯伯,您把尾巴借给我行吗?”老黄牛说:“不行啊,我要用尾巴赶蝇子呢。” 216 | 小壁虎爬呀爬,爬到屋檐下。他看见燕子摆着尾巴在空中飞来飞去。小壁虎说:“燕子阿姨,您的尾巴借给我行吗?”燕子说:“不行啊,我要用尾巴掌握方向呢。” 217 | 小壁虎借不到尾巴,心里很难过。他爬呀爬,爬回家里找妈妈。 218 | 小壁虎把借尾巴的事告诉了妈妈。妈妈笑着说:“傻孩子,你转过身子看看。”小壁虎转身一看,高兴地叫起来:“我长出一条新尾巴啦!” 219 | 220 | 034三只白鹤 221 | 一天中午,三只白鹤在河里捉到了许多鱼。 222 | 他们吃得饱饱的,把剩下的一条大鱼埋在地里,留着明天吃。 223 | 第一只白鹤抬头看了看太阳,记住大鱼埋在太阳底下。 224 | 第二只白鹤抬头看了看天空,记住大鱼埋在白云下面。 225 | 第三只白鹤看了看河边的大柳树,记住大鱼埋在柳树旁边。 226 | 第二天,太阳刚刚升起,三只白鹤都醒来了。 227 | 第一只白鹤朝太阳飞去。第二只白鹤朝白云飞云。第三只白鹤飞到河边,落在大柳树旁边。 228 | 哪只白鹤能找到埋在地里的大鱼呢? 229 | 230 | 035咕咚 231 | 木瓜熟了。一个木瓜从高高的树上掉进湖里,“咕咚”! 232 | 兔子吓了一跳,拔腿就跑。小猴子看见了,问他为什么跑。兔子一边跑一边叫:“不好啦,‘咕咚’可怕极了!” 233 | 小猴子一听,就跟着跑起来。他一边跑一边大叫:“不好啦,不好啦,‘咕咚’来了,大家快跑哇!” 234 | 这一下可热闹了。狐狸呀,山羊啊,小鹿哇,一个跟着一个跑起来。大伙一边跑一边叫:“快逃命啊,‘咕咚’来了!” 235 | 大象看见了,也跟着跑起来。野牛拦住他,问:“‘咕咚’在哪里,你看见了?”大象说:“没看见,大伙都说‘咕咚’来了。”野牛拦住大伙问,大伙都说没看见。最后问兔子,兔子说:“是我听见的,‘咕咚’就在那边的湖里。” 236 | 兔子领着大家来到湖边。正好又有一个木瓜从高高的树上掉进湖里,“咕咚”! 237 | 大伙你看看我,我看看你,都笑了。 238 | 239 | 036吃水不忘挖井人 240 | 瑞金城外有个村子叫沙洲坝。毛主席在江西领导革命的时候,在那儿住过。 241 | 一天,毛主席看见一个老乡挑着浑浊的水往家里走,就问:“老乡,这水挑来做什么用呀?”老乡回答说:“吃呀!”毛主席疑惑地问:“水这么脏,能吃吗?”老乡苦笑着说:“没法子,再脏的水也得吃呀!”毛主席又问:“是从哪里挑的?”老乡回答:“从塘里挑的。”毛主席请老乡带他去看看。走了一阵,只见一个不大的水塘,杂草丛生,池水污浊。全村人洗衣、洗菜、吃水全在这里。毛主席关切地问:“能不能到别处挑水吃?”老乡摇摇头,说:“我们沙洲坝就是缺水呀!挑担水要走好几里路。”毛主席皱了皱眉头,若有所思地走了。 242 | 第二天,毛主席找来村里人一起商量挖水井的事。大家一起勘察水源,选择井位。当井位确定后,毛主席挽起衣袖,卷起裤腿,带头挖了起来。于是,大伙挖的挖,铲的铲,干得热火朝天。 243 | 在挖井的日子里,毛主席和临时中央政府的其他领导人,一有空就到工地参加劳动。经过十几天的奋战,水井挖成了,沙洲坝的人民终于喝上了清澈甘甜的井水。群众激动地说:“我们从来没有喝过这么甜的水,毛主席真是我们的大恩人哪!” 244 | 解放以后,沙洲坝人民在井旁立了一块石碑,上面刻着:“吃水不忘挖井人,时刻想念毛主席!” 245 | 246 | 247 | 037达尔文和小松鼠 248 | 一百多年前,英国有一位科学家,叫达尔文。达尔文小时候爱到野外去玩。天上的鸟, 249 | 地上的虫,水里的鱼,他都喜欢。他从来不捉小动物,而是观察他们怎样生活。 250 | 有一次,他又到树林里玩,看见树上有几只从来没见过的小鸟。他站住了,仰着头仔细观察,观察了好长时间。 251 | 那天她穿的是一件棕色粗糙的外衣`,站在那儿一动不动,像一根树干。一只小松鼠跑来了,顺着他的腿往上爬,一直爬到肩膀上。小松鼠坐在他的肩膀上,左看看,右看看,还翘着小尾巴,跟树上的妈妈打招呼呢。松鼠妈妈可急坏了。 252 | 它吱吱地叫着,好像在说:“傻孩子,你看错了,那不是大树,他会伤害你的。 253 | 254 | 038斧子的故事 255 | 从前,有一个穷孩子。一天,他上山去砍柴,走在一座独木桥上,不小心把斧子掉进河里。没有斧子怎么砍柴呢?他急得直哭。 256 | 突然,哗哗的山涧里走出来一位老爷爷。他捋捋白胡须关心地问:“谁家的孩子啊,哭得这么伤心?” 257 | 孩子说:“老爷爷,我的斧子掉进河里了,不能砍柴啦!” 258 | 老爷爷说:“孩子,你别哭,我来帮你捞。”说着钻进水里。不大一会儿,老爷爷钻出水面,手里举着一把金斧子,问:“这是你的斧子吗?” 259 | 孩子说:“这不是我的斧子。” 260 | 老爷爷又钻进水里。过了一会,他又举着一把银斧子,问:“这把斧子是你的吧?”孩子摇摇头,说:“这也不是我的斧子。” 261 | 老爷爷又钻进水里,捞起一把铁斧子,问:“这把斧子是你的吗?” 262 | 孩子高兴地说:“对,这是我的斧子。谢谢您,老爷爷!” 263 | 老爷爷微笑着说:“孩子,你很诚实。我把这两把斧子也送给你吧!” 264 | 孩子说:“老爷爷,不是我的东西,我不要。”说完,拿着自己的斧子走了。 265 | 老爷爷看着他的背影,微笑着点点头,不见了。 266 | 267 | 039植物妈妈有办法 268 | 孩子如果已经长大, 269 | 就得告别妈妈,四海为家。 270 | 牛马有脚,鸟有翅膀, 271 | 植物旅行又用什么办法? 272 | 蒲公英妈妈准备了降落伞, 273 | 把它送给自己的娃娃。 274 | 只要有风轻轻吹过, 275 | 孩子们就乘着风纷纷出发。 276 | 苍耳妈妈有个好办法, 277 | 她给孩子穿上带刺的铠甲。 278 | 只要挂住动物的皮毛, 279 | 孩子们就能去田野、山洼。 280 | 豌豆妈妈更有办法, 281 | 她让豆荚晒在太阳底下, 282 | 啪的一声,豆荚炸开, 283 | 孩子们就蹦着跳着离开妈妈。 284 | 植物妈妈的办法很多很多, 285 | 不信你就仔细观察。 286 | 那里有许许多多的知识, 287 | 粗心的小朋友却得不到它。 288 | 289 | 040秋天 290 | 天那么高,那么蓝。高高的蓝天上飘着几朵白云。 291 | 蓝天下是一眼望不到边的稻田。稻子熟了,黄澄澄的,像铺了一地金子。 292 | 稻田旁边有个池塘。池塘的边上有棵梧桐树。一片一片的黄叶从树上落下来。有的落到水里,小鱼游过去,藏在底下,把它当做伞。有的落在岸边,蚂蚁爬上去,来回跑着,把它当做运动场。 293 | 稻田那边飞来两只燕子,看见树叶往下落,一边飞一边叫,好像在说:“电报来了,催我们赶快到南方去呢!” 294 | 295 | 041温暖 296 | 天快亮了,周总理走出大会堂。他又工作了整整一夜。 297 | 周总理刚要上车,看见远处有一位清洁工人正在清扫街道。他走过去,紧紧握住工人的手,亲切的说:“同志,你辛苦了,人民感谢你。”清洁工人望着敬爱的周总理,激动得说不出话来。 298 | 一阵秋风吹过,树落下来几片黄叶。深秋的清晨是寒冷的,周总理却送来了春天般的温暖。 299 | 300 | 042诚实的孩子 301 | 列宁八岁的时候,有一天,跟爸爸到姑妈家去做客。 表兄弟表姐妹见到列宁都很高兴,拉着他一道去玩。他们在房间里捉迷藏。列宁不小心碰了桌子,桌子上的一只花瓶掉下来,打碎了。孩子们正玩得起劲,谁也没有注意,还是互相追赶着。姑妈听见声音,跑进来一看,花瓶碎了,就问:“是谁打碎的?”表兄弟表姐妹都说:“不是我!”列宁也低声说:“不是我。”姑妈笑着说:“那一定是花瓶自己打碎的。”大家都笑起来,只有列宁没有笑。 回到家里,列宁躺在床上不说话。妈妈问他为什么不愉快,列宁把打碎花瓶的事告诉了妈妈。妈妈叫他写信给姑妈,承认自己说了谎。过了几天,邮递员送来姑妈是回信。姑妈在信上说:“你做错了事能自己认错,是个诚实的孩子。” 302 | 303 | 043蓝树叶 304 | 美术课上,老师教同学们画风景画,要画上树、房子和小山。李丽画好了近处的房子、远处的小山。她正要画树,可是绿色铅笔找不到了。 305 | 李丽看看旁边的林园园已经把树画好了,树叶那么绿,真惹人爱。李丽小声对林园园说:“把绿铅笔借给我用一用行吗?”林园园吞吞吐吐地说:“我还没有画完呢。”李丽只好坐在那里看林园园画。 306 | 等她画完了,李丽说:“现在可以把绿铅笔借给我了吧?”林园园说:“我怕你把笔尖弄断了。”李丽说:“我小心一点儿。” 307 | 林园园从盒子里拿出绿铅笔,说:“你要注意,不要削,画的时候不要用力,不要画得太多!”李丽连忙说:“我只画树叶和小草。”林园园皱着眉头,说:“还要画小草?”李丽看了看林园园,没有接她的铅笔。李丽拿起自己的蓝铅笔,用心地画着一片片树叶。林园园看见这些蓝树叶,不由得脸红了。 308 | 309 | 310 | 044老师说他做得对 311 | 语文试卷发下来,同学们都在看自己的试卷,林拿到试卷一看,啊!一百分,心里高兴极了。他仔细一看,发现第二题的具字少了一横,怎么这样粗心呢?幸好老师没发现。怎么办呢?去不去找老师改分呢? 312 | 改分吧,我好不容易才得了一百分;不改吧,这分数是假的。想到这里,他决定做一个诚实的孩子。 313 | 于是林林来到办公室找老师改分。林林把试卷交给老师说:我这道题错了一个字,请你改一下分数吧! 314 | 老师接过试卷一看,果然具字少了一横,就把一百分改成九十九分。老师还竖起大拇指说:林林做得对,真是一个诚实的孩子。林林听了,心里比吃了蜜还甜。 315 | 316 | 045坐井观天 317 | 一只青蛙坐在井里,一只小鸟飞来,落在井沿上。 青蛙问小鸟:“你从哪儿飞来呀?” 318 | 小鸟回答说:“我从远处飞来。我在天空中飞了一百多里,口渴了,下来找点水喝。” 319 | 青蛙说:“朋友,别说大话了!天不过井口那么大,还用飞那么远吗?” 320 | 小鸟说:“你弄错了,天无边无际,大得很哪!” 321 | 青蛙笑了,说:“朋友,我天天坐在井里,一抬头就看见天。我不会弄错的。” 322 | 小鸟也笑了,说:“朋友,你是弄错了。不相信,你跳出井口来看一看吧。 323 | 324 | 046狼和小羊 325 | 狼来到小溪边,看见小羊正在那儿喝水。 326 | 狼非常想吃小羊,就故意找碴儿,说:“你把我喝的水弄脏了!你安的什么心?” 327 | 小羊吃了一惊,温和地说:“我怎么会把您喝的水弄脏呢?您站在上游,水是从您那儿流到我这儿来的,不是从我这儿流到您那儿去的。” 328 | 狼气冲冲地说:“就算这样吧,你总是个坏家伙!我听说,去年你在背地里说我的坏话!” 329 | 可怜的小羊喊道:“啊,亲爱的狼先生,那是不会有的事,去年我还没有生下来呐!” 330 | 狼不想再争辩了,龇着牙,逼近小羊,大声嚷道:“你这个小坏蛋!说我坏话的不是你就是你爸爸,反正都一样。”说着就往小羊身上扑去。 331 | 332 | 047骆驼和羊 333 | 骆驼长得高,羊长得矮。骆驼说:“长得高好。”羊说:“不对,长得矮才好呢。”骆驼说:“我可以做一件事,证明高比矮好。羊说:“我也可以做一件事,证明矮比高好。” 334 | 他们走到一个园子旁边。园子四面有围墙,里面种了很多树,茂盛的枝叶伸出墙外来。骆驼一抬头就吃到了树叶。羊抬起前腿,扒在墙上,脖子伸得老长,还是吃不着。骆驼说:“你看,这可以证明了吧,高比矮好。”羊摇了摇头,不肯认输。 335 | 他们俩又走了几步,看见围墙有个又窄又矮的门。羊大模大样地走进门去吃园子里的草。骆驼跪下前腿,低下头,往门里钻,怎么也钻不进去。羊说:“你看,这可以证明了吧,矮比高好。”骆驼摇了摇头,也不肯认输。 336 | 他们去找老牛评理。老牛说:“你们俩都只看到自己的长处,看不到自己的短处。这是不对的。” 337 | 338 | 048我要的是葫芦 339 | 从前,有个人种了一棵葫芦。细长的葫芦藤上长满了绿叶,开出了几朵雪白的小花。花谢以后,藤上挂了几个小葫芦。多么可爱的小葫芦哇!那个人每天都要去看几次。 [8] 340 | 有一天,他看见叶子上爬着一些蚜虫,心里想,有几个虫子怕什么!他盯着小葫芦自言自语地说:“我的小葫芦,快长啊,快长啊!长得赛过大南瓜才好呢!” 341 | 一个邻居看见了,对他说:“你别光盯着葫芦了,叶子上生了蚜虫,快治一治吧!”那个人感到很奇怪,他说:“什么?叶子上的虫还用治?我要的是葫芦。” 342 | 没过几天,叶子上的蚜虫更多了。小葫芦慢慢地变黄了,一个一个都落了。 343 | 344 | 049画鸡蛋 345 | 四百多年以前,有个意大利人叫达·芬奇。他是个著名的画家。 346 | 达·芬奇开始学画的时候,老师先让他画鸡蛋,画了一个又让画一个,他画得不耐烦了,就问老师:“老师,您天天要我画鸡蛋,这不是太简单了吗?”老师严肃地说:“你以为画鸡蛋很容易,这就错了,在一千个鸡蛋当中,没有形状完全相同的。每个鸡蛋从不同的角度去看,形状也不一样。我让你画鸡蛋,就是要训练你的眼力和绘画技巧,使你能看得准确,画得熟练。” 347 | 达·芬奇听从老师的话,用心画鸡蛋,画了一张又一张,每一张都画了许多形状不同的鸡蛋。 348 | 后来,达·芬奇无论画什么,都能画得又快又像。 349 | 350 | 050吃墨水 351 | 陈毅爷爷小时候非常喜欢读书。有一次,他正在看书,妈妈端来饼和芝麻酱,叫他蘸着吃。 352 | 他一边看书,一边吃饼。书桌上有一个大墨盒,他竟把饼蘸到墨盒里,一口一口吃得很香。 353 | 妈妈走进屋,看到他满嘴都是墨,吃惊地叫了起来。这时,他才发现蘸的不是芝麻酱,而是墨水。 354 | 妈妈一边责怪他,一边心疼地拉他去漱口。他却笑着说:“没关系!吃点墨水好哇,我肚子里的‘墨水’还太少呢!” 355 | 356 | 051补丁 357 | 毛主席生活非常俭朴,他的衣服、袜子很多都打了补丁。 358 | 刚进北京的时候,毛主席住在香山。有一天,他要接见一位客人。警卫员找了又找,也找不到一条不带补丁的裤子。 359 | 毛主席说:“有补丁不要紧,整齐干净就行。”他穿着带补丁的裤子接见了那位客人。 360 | 新中国成立以后,毛主席的生活仍然很俭朴。每次接见外宾,警卫员总要提醒他,坐沙发的时候要把腿收回来。 361 | 因为他的袜子大多是补过的,往外伸腿,袜子上的补丁就会露出来。 362 | 警卫员多次提出,要给毛主席添置一些衣物。毛主席说,国家还穷,不能带头浪费。 363 | 没条件讲究的时候不讲究,这一条好做到;有条件讲究的时候不讲究,这一条难做到。共产党人就是要做难做到的事。 364 | 365 | 052狐狸和乌鸦 366 | 乌鸦在大树上做了一个窝。大树底下有个洞,洞里住着狐狸。 367 | 有一天,乌鸦飞出去给它的孩子找东西吃。它找到一片肉,叼了回来,站在窝旁边的树枝上,心里很高兴。 368 | 这时候,狐狸也出来找吃的。它抬起头,看见乌鸦嘴里叼着一片肉,馋得直流口水。 369 | 狐狸想了想,就笑着对乌鸦说:“您好,亲爱的乌鸦!”乌鸦不做声。 370 | 狐狸又说:“亲爱的乌鸦,您的孩子好吗?”乌鸦看了狐狸一眼,还是不做声。 371 | 狐狸又说:“亲爱的乌鸦,您的羽毛真漂亮,麻雀比起您来可就差多了。您的嗓子真好,谁都爱听您唱歌,您就唱几句吧!” 372 | 乌鸦听了狐狸的话,得意极了,就唱起歌来。 373 | “哇……”乌鸦刚一张嘴,肉就掉下来了。狐狸叼起肉,钻到洞里去了。 374 | 375 | 053小马过河 376 | 马棚里住着一匹老马和一匹小马。 377 | 有一天,老马对小马说:“你已经长大了,能帮妈妈做点事吗?”小马连蹦带跳地说:“怎么不能?我很愿意帮您做事。”老马高兴地说:“那好哇,你把这半口袋麦子驮到磨坊去吧。” 378 | 小马驮起麦子,飞快地往磨坊跑去。跑着跑着,一条小河挡住了去路,河水哗哗地流着。小马为难了,心想:我能不能过去呢?如果妈妈在身边,问问她该怎么办,那多好哇! 379 | 他向四周望望,看见一头老牛在河边吃草。小马嗒嗒嗒跑过去,问道:“牛伯伯,请您告诉我,这条河,我能趟过去吗?”老牛说:“水很浅,刚没小腿,能趟过去。” 380 | 小马听了老牛的话,立刻跑到河边,准备趟过去。突然,从树上跳下一只松鼠,拦住他大叫:“小马,别过河,别过河,河水会淹死你的!”小马吃惊地问:“水很深吗?”松鼠认真地说:“深得很呢!昨天,我的一个伙伴就是掉进这条河里淹死的!” 381 | 小马连忙收住脚步,不知道怎么办才好。他叹了口气,说:“唉!还是回家问问妈妈吧!” 382 | 小马甩甩尾巴,跑回家去。妈妈问:“怎么回来啦?”小马难为情地说:“一条河挡住了,我……我过不去。”妈妈说:“那条河不是很浅吗?”小马说:“是啊!牛伯伯也这么说。可是松鼠说河水很深,还淹死过他的伙伴呢!”妈妈说:“那么河水到底是深还是浅?你仔细想过他们的话吗?”小马低下了头,说:“没……没想过。”妈妈亲切地对小马说:“孩子,光听别人说,自己不动脑筋,不去试试,是不行的。河水是深是浅,你去试一试就会明白了。” 383 | 小马跑到河边,刚刚抬起前蹄,松鼠又大叫起来:“怎么,你不要命啦!”小马说:“让我试试吧。”他下了河,小心地趟了过去。原来河水既不像老牛说的那样浅,也不像松鼠说的那样深。 384 | 385 | 054走山路 386 | 早晨一片雾,山里看不清路, 387 | 急坏了小猪、小鹿和小兔。 388 | 小兔领小猪,小猪拉小鹿,扯着藤,扶着树,一步一步走山路。 389 | 秋风婆婆来帮助,呼——呼—— 390 | 一下子吹散满天雾。 391 | 392 | 055美丽的公鸡 393 | 从前有一只公鸡,自以为很美丽,整天得意洋洋地唱: 394 | “公鸡公鸡真美丽,大红冠子花外衣,油亮脖子金黄脚,要比漂亮我第一。” 395 | 有一天,公鸡挺着胸脯,唱着歌,来到一棵大树下。他看见一只啄木鸟,说:“长嘴巴的啄木鸟,咱们比比谁美。”啄木鸟一面忙着一面说:“对不起,老树生了虫子,我要给他治病。”公鸡听了,唱着歌,大摇大摆地走了。 396 | 公鸡来到一个果园里,看见一只蜜蜂,说:“鼓眼睛的小蜜蜂,咱们比比谁美。”蜜蜂头也没抬地说:“对不起,果树开花了,我要采蜜去。”公鸡又唱着歌,大摇大摆地走了。 397 | 公鸡来到一块稻田边,看见一只青蛙,说:“大肚皮的青蛙,咱们比比谁美。”青蛙瞪着大眼睛说:“对不起,稻田里有害虫,我要捉害虫去。”公鸡见谁也不和他比美,只好往回走。 398 | 在路上,公鸡碰到一匹驮着粮食的老马,伤心地说:“老马伯伯,我去和啄木鸟、蜜蜂、青蛙比美,他们为什么都不理我呢?”老马说:“因为他们懂得美不美不光看外表,还要看能不能帮助人们做事。” 399 | 公鸡听了很惭愧,再也不去和谁比美了。他每天天不亮就“喔、喔、喔”地打鸣儿,一遍又一遍地催人们早起。 400 | 401 | 056精彩的马戏 402 | 昨天,妈妈带我去看了一场精彩的马戏。 403 | 先说猴子爬竿吧。猴子穿着衣服,打扮得像个小孩。它爬到高竿顶上,在上面倒竖蜻蜓,一双圆溜溜的眼睛好奇地瞅瞅观众。那顽皮的样子,逗得观众哈哈大笑。 404 | 黑熊踩木球也很好玩。笨重的黑熊爬到大木球上,身子直立起来,小心地移动着双脚,让木球滚到了跷跷板上。木球刚滚过中心点,跷跷板的那一头就掉下来了。你看那黑熊多紧张啊!观众又发出一阵哄笑。 405 | 山羊走钢丝,表演得也很出色。在细细的钢丝上,山羊就像在平地上一样,稳稳当当地走过来走过去。山羊还表演了它的绝技。钢丝上插着一块金属原板,只有碗口那么大。山羊小心地把四只脚都踩在木板上,身子弯得像一座拱桥。全场观众都为它喝彩。 406 | 还有小狗做算术,猴子骑车,马钻火圈,都挺有趣。马戏团的叔叔阿姨真有办法,能让动物听从他们的指挥。 407 | 408 | 057北京 409 | 北京是我国的首都,是一座美丽的城市。 410 | 天安门在北京城的中央,红墙、黄瓦,又庄严,又美丽。天安门前面是宽阔的广场。广场中间矗立着人民英雄纪念碑。 411 | 北京有许多又宽又长的柏油马路。道路两旁,绿树成阴,鲜花盛开。北京新建了许多立交桥。立交桥的四围有绿毯似的草坪和拼成图案的花坛。各种车辆在桥上桥下来来往往,川流不息。 412 | 北京有许多名胜古迹和风景优美的公园,还有许多新建的高楼大厦。站在高处一看,全城到处是绿树,到处是大楼。 413 | 北京真美啊!我们爱北京,我们爱祖国的首都! 414 | 415 | 058初冬 416 | 早上,白茫茫的一片大雾。 417 | 远处的塔、小山都望不见了。 418 | 近处的田野、树林像隔着一层纱,模模糊糊看不清。 419 | 太阳像个红球,慢慢地升起来,发出淡淡的光,一点儿也不耀眼。 420 | 地里的庄稼都收完了,人们正在园子里忙着收白菜。 421 | 雾慢慢地散了,太阳射出光芒来。 422 | 远处的塔、小山都望得见了。近处的田野、树林也看得清了。 423 | 柿子树上挂着许多大柿子,像一个一个的红灯笼。 424 | 树林里落了厚厚的一层黄叶。只有松树、柏树不怕冷,还是那么绿。 425 | 426 | 059蜘蛛 427 | 不知什么时候,蜘蛛在我家窗前的树杈上结了个网。我常常趴在窗台上,看蜘蛛怎样捉虫。 428 | 小飞虫碰到网上粘住了。蜘蛛很快地爬过去,一下子就把它逮住了。飞蛾投到网上,使劲想挣脱。 429 | 蜘蛛从尾部抽出丝来把它缠住。最后,飞蛾一动也不动了。 430 | 431 | 060动物过冬 432 | 早晨,小蚂蚁来到树林里找吃的。树林里变了样,满地是落叶。一阵风吹来。他感到有点儿冷。周围静极了,朋友们都到哪儿去了呢? 433 | 小蚂蚁忽然听到鸟叫声。他一抬头,看见喜鹊站在树梢上。小蚂蚁喊道:“喜鹊,你好,燕子、杜鹃、黄鹂他们都到哪儿去了?”喜鹊说:“天冷了,他们到南方过冬去了,明年春天才回来呢。”“你也去吗?”小蚂蚁问。喜鹊说:“我不去。我把窝垫得暖暖和和的,就在这儿过冬。” 434 | 青蛙听见小蚂蚁的声音,从池塘里跳上岸,说:“小蚂蚁,我正要跟你告别呢!”“怎么?”小蚂蚁问,“你也要到南方去?”“不,不,我要去睡觉了。”青蛙说。小蚂蚁看看天,问:“你怎么啦?太阳才升起来,你又要睡啦?”“我要冬眠了。整个冬天,我们青蛙都睡在洞里,不吃也不动,到明年春天再出来。”青蛙一边说,一边用脚刨土,一会儿就刨好了一个洞,“你看,冬天住在这个洞里,既不怕风,又不怕雪,暖暖和和的,真舒服!” 435 | 小蚂蚁想,冬天快到了,我也该准备过冬的食物啦! 436 | 437 | 061小蝌蚪找妈妈 438 | 池塘里有一群小蝌蚪,大大的脑袋,黑灰色的身子,甩着长长的尾巴,快活地游来游去。 439 | 小蝌蚪游哇游,过了几天,长出两条后腿。他们看见鲤鱼妈妈在教小鲤鱼捕食,就迎上去,问:“鲤鱼阿姨,我们的妈妈在哪里?”鲤鱼妈妈说:“你们的妈妈有四条腿,宽嘴巴。你们到那边去找吧!” 440 | 小蝌蚪游哇游,过了几天,长出两条前腿。他们看见一只乌龟摆动着四条腿在水里游,连忙追上去,叫着:“妈妈,妈妈!”乌龟笑着说:“我不是你们的妈妈。你们的妈妈头顶上有两只大眼睛,披着绿衣裳。你们到那边去找吧!” 441 | 小蝌蚪游哇游,过了几天,尾巴变短了。他们游到荷花旁边,看见荷叶上蹲着一只大青蛙,披着碧绿的衣裳,露着雪白的肚皮,鼓着一对大眼睛。 442 | 小蝌蚪游过去,叫着:“妈妈,妈妈!”青蛙妈妈低头一看,笑着说:“好孩子,你们已经长成青蛙了,快跳上来吧!”他们后腿一蹬,向前一跳,蹦到了荷叶上。 443 | 不知什么时候,小青蛙的尾巴已经不见了。他们跟着妈妈,天天去捉害虫。 444 | 445 | 062骄傲的孔雀 446 | 孔雀很美丽,可是很骄傲,只要看到谁长得漂亮,他就抖动羽毛,展开尾巴,炫耀自己的美丽。 447 | 有一天,孔雀昂着头,挺着胸脯,拖着美丽的长尾巴,沿着湖边散步。树上的花喜鹊很有礼貌地向他点头问好,他理也不理。 448 | 忽然,孔雀发现湖里有一只鸟,跟他一模一样,也十分漂亮。他立刻停住脚步,展开尾巴。美丽的尾巴抖动着,像一把五彩洒金的大扇子。 449 | 谁知湖里的那只鸟也停住脚步,展开尾巴。美丽的尾巴也抖动着,像一把五彩洒金的大扇子。 450 | 骄傲的孔雀有点儿生气了,他睁大了圆圆的眼睛,抖了抖头上的翎毛。湖里的那只鸟也睁大了圆圆的眼睛,抖了抖头上的翎毛。 451 | 骄傲的孔雀可真生气了,他昂着头,挺着胸脯,向前迈了一大步,没想到一下子掉进湖里了。 452 | 孔雀不会游泳,他在湖里挣扎了半天,好不容易抓住了树根,才爬上岸来。 453 | 他回头朝湖里看看,湖里的那只鸟,也浑身湿淋淋的,在发抖呢!孔雀这回可高兴了。 454 | 树上的花喜鹊格格地笑起来。孔雀看了花喜鹊一眼,不高兴地说:“丑喜鹊,你笑什么!” 455 | 花喜鹊拍拍翅膀,说:“骄傲的孔雀,湖里的那只鸟就是你自己的影子啊!你骄傲得连自己也不认识了!” 456 | 457 | 063丑小鸭 458 | 太阳暖烘烘的,鸭妈妈卧在窝里,等她的孩子出世。 459 | 一只只小鸭都从蛋壳里钻出来了,就剩下一个特别大的蛋。过了好几天,这个蛋才慢慢裂开,钻出一只又大又丑的鸭子。他的毛灰灰的,嘴巴大大的,身子瘦瘦的,大家都叫他“丑小鸭”。 460 | 丑小鸭来到世界上,除了鸭妈妈,谁都欺负他。哥哥、姐姐咬他,公鸡啄他,连养鸭的小姑娘也讨厌他。丑小鸭感到非常孤单,就钻出篱笆,离开了家。 461 | 丑小鸭来到树林里,小鸟讥笑他,猎狗追赶他。他白天只好躲起来,到了晚上才敢出来找吃的。 462 | 秋天到了,树叶黄了,丑小鸭来到湖边的芦苇里,悄悄地过日子。一天傍晚,一群天鹅从空中飞过。丑小鸭望着洁白美丽的天鹅,又惊奇又羡慕。 463 | 天越来越冷,湖面结了厚厚的冰,丑小鸭在冰上冻僵了,幸亏一位农夫看见了,把他带回家。 464 | 一天,丑小鸭出来散步,看见丁香开花了,知道春天来了。他扑扑翅膀,向湖边飞去,忽然看见镜子似的湖面上,映出一个漂亮的影子,雪白的羽毛,长长的脖子,美丽极了。这难道是自己的影子?啊,原来我不是丑小鸭,是一只漂亮的天鹅呀! 465 | 466 | 064曹冲称象 467 | 古时候有个大官叫曹操。别人送他一头大象,他很高兴,带着儿子和官员们一同去看。 468 | 大象又高又大,身子像一堵墙,腿像四根柱子。官员们一边看一边议论:“这么大的象,到底有多重呢?” 469 | 曹操问:“谁有办法把这头大象称一称?”有的说:“得造一杆大秤,砍一棵大树做秤杆。”有的说:“有了大秤也不行啊,谁有那么大的力气提得起这杆大秤呢?”曹操听了直摇头。 470 | 曹操的儿子曹冲才七岁,他站出来,说:“我有个办法。把大象赶到一艘大船上,看船身下沉多少,就沿着水面,在船舷上画一条线。再把大象赶上岸,往船上装石头,装到船下沉到画线的地方为止。然后称一称船上的石头。石头有多重,大象就有多重。” 471 | 曹操微笑着点一点头。他叫人照曹冲说的办法去做,果然称出了大象的重量。 472 | 473 | 065刻舟求剑 474 | 从前,有个人坐船过江,他一不小心,把挂在身上的宝剑掉进江里去了。 475 | 那个人一点儿也不着急,拿出小刀在船舷上刻了一个记号。 476 | 有人催他:“还不赶快捞!在船舷上刻记号有什么用啊?” 477 | 那个人不慌不忙,指了指刻的记号,说:“不用着急,宝剑是从这儿掉下去的,等船靠了岸,我就从这儿跳下去,准能把宝剑捞上来。” 478 | 479 | 066黄鹂和山雀 480 | 老黄鹂在树上搭了个窝,里面睡着一窝小黄鹂。老黄鹂站在窝边的树枝上。 481 | 海棠树上有一片嫩叶卷了起来。老黄鹂看见了,连忙飞过去,从那片卷着的叶子里,捉出一条黄绿色的小毛虫,飞了回来。小黄鹂都把脖子伸得长长的,张开黄黄的小嘴,叫着:“妈妈,给我吃,给我吃!”老黄鹂把小虫塞到一只小黄鹂的嘴里。那只小黄鹂吃的津津有味,问妈妈:“这是什么呀?真好吃!”老黄鹂说:“这是卷叶虫。这种害虫很狡猾。它吐出丝,把嫩叶卷起来,自己躲在里面吃叶肉。” 482 | 一只山雀飞来,落在旁边一棵树上,把一块树皮似的东西吞了下去。小黄鹂惊奇地叫起来:“山雀阿姨,您怎么吃树皮呀!” 483 | “孩子,你们不知道。这不是树皮,是梨椿象。它们专吸果汁,坏透了!”山雀说完,又衔了一个梨椿象,去喂她的孩子。 484 | 一个月过去了,小黄鹂和小山雀长大了。他们在枝叶茂盛的果树林里飞来飞去,跟着妈妈捕捉害虫。 485 | 秋天,果树上结满了果子。一阵风吹过,红通通的海棠,黄澄澄的梨,都轻轻地点头,在感谢黄鹂和山雀呢。 486 | 487 | 067我们也要当红军 488 | 雨过天晴。毛主席带着一支红军队伍,在泥泞的路上前进。 489 | 忽然从后边传来清脆的喊声:“ 红军叔叔,等一等!”毛主席停住脚,转过身,看见两个孩子正向队伍奔来。他们满头大汗,跑到毛主席面前,望着这位身材高大的红军首长,恳切地说:“伯伯, 我们也要当红军,收下我们吧!” 490 | 毛主席微笑着,上下打量着两个孩子。他们穿着破破烂烂的衣服,脚上穿着草鞋。一个孩子背着破草帽和小包袱。另一个孩子也背着小包袱,包袱上还绑着一双布鞋。毛主席知道他们是贫苦农民的孩子,点点头,答应了他们的要求。 491 | 一个红军战士转过脸来笑着,好像在说,欢迎你们,红军队伍就是你们的家。 492 | 493 | 068难忘的泼水节 494 | 火红火红的凤凰花开了,傣族人民一年一度的泼水节又到了。1961年的泼水节,傣族人民特别高兴,因为敬爱的周恩来总理和他们一起过泼水节。 495 | 那天早晨,人们敲起象脚鼓,从四面八方赶来了。为了欢迎周总理,人们在地上撒满了凤凰花的花瓣,好像铺上了鲜红的地毯。一条条龙船驶过江面,一串串花炮升上天空。人们欢呼着:“周总理来了!” 496 | 周总理身穿对襟白褂,咖啡色长裤,头上包着一条水红色头巾,笑容满面地来到人群中。他接过一只象脚鼓,敲着欢乐的鼓点,踩着凤凰花铺成的“地毯”,同傣族人民一起跳舞。 497 | 开始泼水了。周总理一手端着盛满清水的银碗,一手拿着柏树枝蘸了水,向人们泼洒,为人们祝福。傣族人民一边欢呼,一边向周总理泼水,祝福他健康长寿。 498 | 清清的水,泼呀,洒呀!周总理和傣族人民笑哇,跳哇,是那么开心! 499 | 多么幸福哇,1961年的泼水节! 500 | 多么令人难忘啊,1961年的泼水节! 501 | 502 | 069蜜蜂引路 503 | 1922年,列宁住在莫斯科附近的一座小山上。当地有个养蜂的人,列宁常常派人去请他谈天。 504 | 有一回,列宁想找那个人谈谈怎样养蜂。可是往常派去找他的人到莫斯科去了,别人都不知道他住在哪里,列宁就亲自去找。 505 | 列宁一边走一边看,发现路边的花丛里有许多蜜蜂。他仔细观察,只见那些蜜蜂采了蜜就飞进附近的一个园子,园子旁边有一所小房子。列宁走到那所房子跟前,敲了敲门,开门的果然就是养蜂的人。 506 | 养蜂的人看见列宁,惊讶地说:“您好,列宁同志,是谁把您领到这儿来的?”列宁笑着说:“我有向导,是您的蜜蜂把我领到这儿来的。” 507 | 508 | 070数星星得孩子 509 | 晚上,满天的星星像无数珍珠撒在碧玉盘里。一个孩子坐在院子里,靠着奶奶,仰起头,指着天空数星星。一颗,两颗,一直数到了几百颗。 510 | 奶奶笑着说:“傻孩子,又在数星星了。那么多星星,一闪一闪地乱动,眼都看花了,你能数得清吗?” 511 | 孩子说:“奶奶,能看得见,就能数得清。星星是在动,可不是乱动。您看,这颗星和那颗星,中间总是离那么远。” 512 | 爷爷走过来,说:“孩子,你看得很仔细。天上的星星是在动,可是看起来它们之间的距离好像是不变的。我们的祖先把它们分成一组一组的,还给起了名字。”爷爷停了停,指着北边的天空,说:“你看,那七颗星,连起来像一把勺子,叫北斗七星。勺口对着的那颗星,就是北极星。北斗七星总是绕着北极星转。”爷爷说的话是真的吗?这孩子一夜没睡好,几次起来看星星。他看清楚了,北斗七星果然绕着北极星慢慢地转动。 513 | 这个数星星的孩子名叫张衡,是汉朝人。他长大以后刻苦钻研天文,成了著名的天文学家。 514 | 515 | 071要是你在野外迷了路 516 | 要是你在野外迷了路, 517 | 可千万别慌张, 518 | 大自然有很多天然的指南针, 519 | 会帮助你辨别方向。 520 | 太阳是个忠实的向导, 521 | 它在天空给你指点方向: 522 | 中午的时候它在南边, 523 | 地上的树影正指着北方。 524 | 北极星是盏指路灯, 525 | 它永远高挂在北方。 526 | 要是你能认出它, 527 | 就不会在黑夜里乱闯。 528 | 要是碰上阴雨天, 529 | 大树也会来帮忙。 530 | 枝叶稠的一面是南方, 531 | 枝叶稀的一面是北方。 532 | 雪特别怕太阳, 533 | 沟渠里的积雪会给你指点方向。 534 | 看看哪边的雪化得快,哪边化得慢, 535 | 就可以分辨北方和南方。 536 | 要是你在野外迷了路, 537 | 可千万别慌张, 538 | 大自然有很多天然的指南针, 539 | 需要你仔细观察,多多去想。 540 | 541 | 072不懂就要问 542 | 孙中山小时候在私塾读书。那时侯上课,先生念,学生跟着念,咿咿呀呀,像唱歌一样。学生读熟了,先生就让他们一个一个地背诵。至于书里的意思,先生从来不讲。 543 | 一天,孙中山来到学校,照例把书放到先生面前,流利地背出昨天所学的功课。先生听了,连连点头。接着,先生在孙中山的书上又圈了一段。他念一句,叫孙中山念一句。孙中山会读了,就回到座位上练习背诵。孙中山读了几遍,就背下来了。可是,书里说的是什么意思,他一点儿也不懂。孙中山想,这样糊里糊涂地背,有什么用呢?于是,他壮着胆子站起来,问:“先生,您刚才让我背的这段书是什么意思?请您给我讲讲吧!” 544 | 这一问,把正在摇头晃脑高声念书的同学们吓呆了,课堂里霎时变得鸦雀无声。 545 | 先生拿着戒尺,走到孙中山跟前,厉声问道:“你会背了吗?” 546 | “会背了。”孙中山说着,就把那段书一字不漏地背了出来。 547 | 先生收起戒尺,摆摆手让孙中山坐下,说:“我原想,书中的道理,你们长大了自然会知道的。现在你们既然想听,我就讲讲吧!” 548 | 先生讲得很详细,大家听得很认真。 549 | 后来,有个同学问孙中山:“你向先生提出问题,不怕挨打吗?” 550 | 孙中山笑了笑,说:“学问学问,不懂就要问。为了弄清楚道理,就是挨打也值得。 551 | 552 | 073我的爸爸 553 | 我的爸爸李大钊离开我们已经几十年了,我永远不会忘记他对我的教育。 每逢看到孩子们学习,我就会想起爸爸说过的话:“小孩子做什么事情都不能三心二意,要学就学个踏实,要玩就玩个痛快。” 那是寒假里的一天,我在屋里写大字,外边下起了大雪。啊,我们又可以堆雪人打雪仗了。我想着想着,手里的笔就不听使唤了。爸爸正站在我旁边,他用手敲了敲我写的字。我仔细一看,有几个字写的东倒西歪的。我知道自己错了,脸上热辣辣的,就认真往下写。 我把写好的大字交给爸爸看,心里想:“爸爸一定要让我重写一遍。没想到爸爸看了,指着后边几个字对我说:“好,像这样写就对了!”又对我说:“叫你哥哥来,咱们到外边玩雪去!”爸爸带着我们到雪地里,跑呀跳呀,团雪球,打雪仗,还堆了个大雪人。我们一点儿不觉得冷,爸爸也像年轻了好几岁。 每逢听到孩子们唱歌,我就会想起爸爸第一次教我们唱《国际歌》的情景。 一个夏天的晚上,爸爸要教我们唱歌。他坐在风琴前面,让我们先唱一支学校里新教的歌。爸爸听我们唱完了,眉头一皱,说:“学校像美丽的花园,孩子们多么幸福,这不是撒谎吗?地主和资本家残酷地剥削农民和工人,许多孩子都吃不上饭,哪有什么美丽和幸福!”接着,他一边弹琴,一边用低沉的声音教我们唱《国际歌》。 554 | 555 | 074快乐的节日 556 | 小鸟在前面带路, 557 | 风啊抚摩着我们, 558 | 我们像春天一样, 559 | 来到花园里,来到草地上。 560 | 鲜艳的红领巾,美丽的衣裳,像朵朵花儿开放。 561 | 花儿向我们点头,小溪欢快地流淌。 562 | 他们向我们祝贺,向我们歌唱。 563 | 他们好像在说,这个世界上,有我们就更美丽,有我们就充满希望。 564 | 感谢亲爱地祖国,培养我们幸福成长。 565 | 我们像小鸟一样,等身上地羽毛丰满,就勇敢地向着天空飞翔,飞向我们地理想。 566 | 唱啊,跳啊, 567 | 敬爱的老师, 568 | 亲爱的伙伴, 569 | 我们一起度过这快乐的时光。 570 | 571 | 075黄山奇石 572 | 闻名中外的黄山风景区,在我国安徽省南部。那里景色秀丽神奇,尤其是那些怪石,有趣极了。 573 | 就说"仙桃石"吧,它好像从天上飞下来的一个大桃子,落在山顶的石盘上。 574 | 在一座陡峭的山峰上,有一只猴子。它两只胳膊抱着腿,一动不动的蹲在山头,望着翻滚的云海。这就是有趣的"猴子观海"。 575 | "仙人指路"就更有趣了!远远望去,真像一位仙人站在高高的山峰上,伸着手臂指向前方。 576 | 每当太阳升起,有座山峰上的几块巨石,就变成了一只金光闪闪的雄鸡。它伸着脖子,对着天都峰不住地啼叫。不用说,这就是著名的"金鸡叫天都"了。 577 | 黄山的奇石还有很多,像"天狗望月""狮子抢球""仙女弹琴"……那些叫不出名字的奇形怪状的岩石,正等你去给他们起名字呢! 578 | 579 | 076雷雨 580 | 满天的乌云,黑沉沉地压下来。树上的叶子一动不动,蝉一声也不叫。 581 | 忽然一阵大风,吹得树枝乱摆。一只蜘蛛从网上垂下来,逃走了。 582 | 闪电越来越亮,雷声越来越响。 583 | 哗,哗,哗,雨下起来了。 584 | 雨越下越大,往窗外望去,树哇,房子啊,都看不清了。 585 | 渐渐地,渐渐地,雷声小了,雨声也小了。 586 | 天亮起来了。打开窗户,清新的空气迎面扑来。 587 | 雨停了。太阳出来了。一条彩虹挂在天空。蝉叫了,蜘蛛又坐在网上。池塘里水满了,青蛙也叫起来了。 588 | 589 | 077日月潭 590 | 日月潭是我国台湾省最大的一个湖。它在台湾省中部的山区。那里群山环绕,树木茂盛,周围有许多名胜古迹。 591 | 日月潭很深,湖水碧绿。湖中央有个美丽的小岛,叫光华岛。小岛把湖水分成两半,北边像圆圆的太阳,叫日潭;南边像弯弯的月亮,叫月潭。 592 | 清晨,湖面上飘着薄薄的雾。天边的晨星和山上的点点灯光,隐隐约约地倒映在湖水中。 593 | 中午,太阳高照,整个日月潭的美景和周围的建筑,都清晰地展现在眼前。要是下起蒙蒙细雨,日月潭好像披上轻纱,周围的景物一片朦胧,就像童话中的仙境。 594 | 595 | 078回声 596 | 小河上有座石桥。半圆的桥洞和水里的倒影连起来,好像一个大月亮。 597 | 小青蛙跟着妈妈游到桥洞底下,看到周围美丽的景色,高兴得叫起来:“呱呱呱,多好看啊!”这时,不知哪儿有一只小青蛙也在叫起来:“呱呱呱,多好看啊!”小青蛙问:“你是谁?你在哪儿?” 598 | 那只看不见的小青蛙也在问:“你是谁?你在哪儿?” 599 | 小青蛙奇怪极了,他问妈妈:“桥洞里藏着一只小青蛙吧?他在学我说话哩。”妈妈笑着说:“孩子,跟我来!” 600 | 青蛙妈妈带着小青蛙跳到岸上。她捡起一颗石子,扔进河里,河水激起一圈圈波纹。波纹碰到河岸,又一圈圈地荡回来。 601 | 青蛙妈妈说:“孩子,你的叫声就像这水的波纹。水的波纹碰到河岸又荡回来。你在桥洞里叫,声音的波纹碰到桥洞的石壁,也要返回来。这样,你就听到自己的声音啊。”小青蛙高兴得一蹦老高,说:“妈妈,我明白了,这就是回声吧?”妈妈笑着点点头。 602 | 小青蛙又游回桥洞里,呱呱地叫个不停。桥洞里立刻响起一片呱呱的回声。小青蛙欢快地说:“多好玩啊!” 603 | 604 | 079看浪花 605 | 三个孩子光脚丫, 606 | 坐在海滩看浪花。 607 | 哗——哗—— 608 | 一束束浪花像问号, 609 | 在问孩子想什么? 610 | “我想让海水变淡水, 611 | 哗啦哗啦浇庄稼!” 612 | 哗——哗—— 613 | 一束束浪花像稻穗, 614 | 绿浪滚滚连天涯。 615 | “我想到海底去打猎, 616 | 用激光枪捕获大黑鲨!” 617 | 哗——哗—— 618 | 一束束浪花像马鬃, 619 | 万马奔腾甩尾巴。 620 | “我想到海底去采矿, 621 | 抱出万千金疙瘩!” 622 | 哗——哗—— 623 | 一束束浪花像彩绸, 624 | 万里海疆铺彩霞。 625 | 三个孩子看浪花, 626 | 说说笑笑忘了回家。 627 | 哗——哗—— 628 | 一束束浪花像小手, 629 | 抚摸孩子的小脚丫。 630 | 631 | 080葡萄沟 632 | 新疆吐鲁番有个地方叫葡萄沟。那里盛产水果。五月有杏子,七八月有香梨、蜜桃、沙果,到八九月份,人们最喜爱的葡萄成熟了。 633 | 葡萄种在山坡上。茂密的枝叶向四面展开,就像搭起了一个个绿色的凉棚。到了秋季,葡萄一大串一大串挂在绿叶底下,有红的、白的、紫的、暗红的、淡绿的,五光十色,美丽极了。要是这时你到葡萄沟去,热情好客的维吾尔族老乡,准会摘下最甜的葡萄,让你吃个够。 634 | 收下来的葡萄有的运到城市去,有的运到晾房里制成葡萄干。晾房修在山坡上,样子有点儿像碉堡。晾房的四壁留着许多小孔,里面有许多木架子。人们把成串的葡萄挂在架子上,利用流动的空气,使水分蒸发,晾成葡萄干。葡萄沟生产的葡萄干颜色鲜,味道甜,非常有名。 635 | 葡萄沟真是个好地方 636 | 637 | 081晨读 638 | 清晨,天气格外晴朗。温暖得阳光洒满山村。村头的场院里,一只老母鸡带着一群小鸡,悠闲地寻找食物。 639 | 几盆花草迎着朝阳,呈现出勃勃生机。 640 | 村里地三个小伙伴,又坐在磨台上读书了。看,坐在右边地那个小女孩读得多入神哪!铅笔放在身边, 641 | 两手捧着书,完全被课文吸引住了,连小鸡在她身边叽叽叫都没有觉察。 642 | 坐在当中戴红领巾得男孩,仰着头,正在高声背诵英语单词,旁边放着单词卡片。他背的熟,记得牢, 643 | 显出一副十分得意得样子。靠左边坐得小男孩,可能平时有些贪玩,弹弓经常装在书包里。 644 | 这会儿,他用书拖着下巴正在人真思索,是思索一道难题呢,还是思索今后应该怎样更专心地学习? 645 | 现在,他们已经懂得珍惜时间,用功读书。几年,十几年以后,他们一定会有出息,用智慧和勤劳,建设可爱地家乡。 646 | 647 | -------------------------------------------------------------------------------- /teacher/replace.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | 3 | var asmjs = fs.readFileSync("./target/asmjs-unknown-emscripten/release/teacher.js", "utf-8"); 4 | 5 | //注释掉两个 Module["arguments"]=arguments 6 | var new_content = asmjs.replace('Module["arguments"]=arguments', ''); 7 | new_content = new_content.replace('ENVIRONMENT_IS_WORKER=typeof importScripts==="function";', ''); 8 | new_content = new_content.replace('Module["arguments"]=arguments', ''); 9 | //处理字体需要加大内存(2的整数倍) 10 | new_content = new_content.replace('Module["TOTAL_STACK"]||5242880', 'Module["TOTAL_STACK"]||parseInt(5242880*4)'); 11 | new_content = new_content.replace('Module["TOTAL_MEMORY"]||16777216', 'Module["TOTAL_MEMORY"]||parseInt(16777216*4)'); 12 | 13 | fs.writeFileSync("../mpproj/teacher/pages/index/teacher.js", new_content); -------------------------------------------------------------------------------- /teacher/src/main.rs: -------------------------------------------------------------------------------- 1 | #![recursion_limit = "128"] 2 | extern crate bincode; 3 | use stdweb::Value; 4 | #[macro_use] 5 | extern crate serde_derive; 6 | extern crate bzip2; 7 | extern crate serde; 8 | 9 | #[macro_use] 10 | extern crate stdweb; 11 | mod platform; 12 | mod teacher; 13 | use stdweb::unstable::TryInto; 14 | mod pdollarplus; 15 | 16 | include!("mmp.rs"); 17 | 18 | fn main() { 19 | stdweb::initialize(); 20 | platform_init(); 21 | teacher::init(); 22 | stdweb::event_loop(); 23 | } 24 | -------------------------------------------------------------------------------- /teacher/src/mmp.rs: -------------------------------------------------------------------------------- 1 | //微信小程序实现 2 | use crate::platform::*; 3 | use base64::decode; 4 | use std::io::Write; 5 | use stdweb::web::ArrayBuffer; 6 | use std::collections::HashMap; 7 | use crate::teacher::Word; 8 | use bincode::deserialize; 9 | 10 | fn log(s: &str){ 11 | js!(console.log(@{s})); 12 | } 13 | 14 | fn current_timestamp() -> i64{ 15 | js!(return Date.now()).try_into().unwrap() 16 | } 17 | 18 | fn get_timezone_offset() -> i32{ 19 | js!(return new Date().getTimezoneOffset()/60;).try_into().unwrap() 20 | } 21 | 22 | //------注册事件------------- 23 | //查询字典 24 | fn register_query_dict_listener(callback: &'static Fn()){ 25 | js!(getApp().query_dict = @{callback}); 26 | } 27 | //页面加载完 28 | fn register_on_ready_listener(callback: &'static Fn()){ 29 | js!(getApp().on_ready = @{callback}); 30 | } 31 | //动画演示 32 | fn register_stroke_anim_listener(callback: &'static Fn()){ 33 | js!(getApp().stroke_anim = @{callback}); 34 | } 35 | //橡皮擦 36 | fn register_eraser_listener(callback: &'static Fn()){ 37 | js!(getApp().eraser = @{callback}); 38 | } 39 | //历史记录 40 | fn register_history_listener(callback: &'static Fn()){ 41 | js!(getApp().histories = @{callback}); 42 | } 43 | //内容输入框 44 | fn register_show_input(callback: &'static Fn()){ 45 | js!(getApp().show_input = @{callback}); 46 | } 47 | //内容选择 48 | fn register_show_choose(callback: &'static Fn()){ 49 | js!(getApp().show_choose = @{callback}); 50 | } 51 | //回退上一个字 52 | fn register_previous(callback: &'static Fn()){ 53 | js!(getApp().previous = @{callback}); 54 | } 55 | //搜索列表 56 | fn register_search_title(callback: &'static Fn(String)){ 57 | js!(getApp().search = @{callback}); 58 | } 59 | //----------触摸事件-------------- 60 | fn register_on_touchstart(callback: &'static Fn(f64, f64, f64, f64)){ 61 | js!(getApp().on_touchstart = @{callback};); 62 | } 63 | //反馈 64 | fn register_add_feedback(callback: &'static Fn()){ 65 | js!(getApp().add_feedback = @{callback}); 66 | } 67 | fn add_feedback(feedback:&str, callback: &'static Fn(bool)){ 68 | js!(getApp().page.addFeedback(@{feedback}, @{callback})); 69 | } 70 | 71 | fn register_on_touchmove(callback: &'static Fn(f64, f64, f64, f64)){ 72 | js!(getApp().on_touchmove = @{callback};); 73 | } 74 | fn register_on_touchend(callback: &'static Fn()){ 75 | js!(getApp().on_touchend = @{callback};); 76 | } 77 | fn register_on_touchcancel(callback: &'static Fn()){ 78 | js!(getApp().on_touchcancel = @{callback};); 79 | } 80 | //-------------------------------- 81 | //读取笔画数据 82 | fn load_strokes(callback: &mut FnMut(Option>)){ 83 | let data:String = js!(return getApp().globalData.strokes;).try_into().unwrap(); 84 | let data = decode(&data).unwrap(); 85 | let mut decompressor = bzip2::write::BzDecoder::new(vec![]); 86 | decompressor.write_all(&data).unwrap(); 87 | let data = decompressor.finish().unwrap(); 88 | callback(Some(data)); 89 | } 90 | 91 | //读取字典文件 92 | fn load_dict(callback: &'static Fn(Result, String>)){ 93 | let scb = move |value: Value| { 94 | match value{ 95 | Value::Undefined | Value::Null => callback(Err(format!("Undefined/Null {:?}", value))), 96 | Value::String(e) => callback(Err(e)), 97 | Value::Bool(b) => callback(Err(format!("Bool {}", b))), 98 | Value::Number(n) => callback(Err(format!("Number {:?}", n))), 99 | Value::Symbol(s) => callback(Err(format!("Symbol {:?}", s))), 100 | Value::Reference(n) => { 101 | let buffer:ArrayBuffer = n.try_into().unwrap(); 102 | let buffer = Vec::from(buffer); 103 | let data: HashMap = deserialize(&buffer).unwrap(); 104 | callback(Ok(data)); 105 | } 106 | }; 107 | }; 108 | js!{ 109 | var scb = @{scb}; 110 | //字典解压的完整文件路径 111 | var path = getApp().globalData.userDataPath+"DICT"; 112 | try{ 113 | scb(wx.getFileSystemManager().readFileSync(path)); 114 | }catch(e){ 115 | //下载字典 116 | wx.cloud.downloadFile({ 117 | fileID: "cloud://pub-ee5927.7075-pub-ee5927/DICT.zip", 118 | success: function(res){ 119 | //解压文件 120 | wx.getFileSystemManager().unzip({ 121 | zipFilePath:res.tempFilePath, 122 | //解压到userData根目录 123 | targetPath: getApp().globalData.userDataPath, 124 | success: function(){ 125 | scb(wx.getFileSystemManager().readFileSync(path)); 126 | }, 127 | fail: function(res){ 128 | console.log(res); 129 | scb("字典文件解压失败"); 130 | }, 131 | }); 132 | }, 133 | fail: function (res) { 134 | scb("字典下载失败"); 135 | } 136 | }); 137 | } 138 | }; 139 | } 140 | // fn load_dict(callback: &'static Fn(Result, String>)){ 141 | // let scb = move |value: Value| { 142 | // match value{ 143 | // Value::Undefined | Value::Null => callback(Err(format!("Undefined/Null {:?}", value))), 144 | // Value::String(e) => callback(Err(e)), 145 | // Value::Bool(b) => callback(Err(format!("Bool {}", b))), 146 | // Value::Number(n) => callback(Err(format!("Number {:?}", n))), 147 | // Value::Symbol(s) => callback(Err(format!("Symbol {:?}", s))), 148 | // Value::Reference(n) => { 149 | // let buffer:ArrayBuffer = n.try_into().unwrap(); 150 | // callback(Ok(Vec::from(buffer))); 151 | // } 152 | // }; 153 | // }; 154 | // js!{ 155 | // var scb = @{scb}; 156 | // var path = getApp().globalData.userDataPath+"DICT"; 157 | // try{ 158 | // scb(wx.getFileSystemManager().readFileSync(path)); 159 | // }catch(e){ 160 | // //下载字典 161 | // wx.cloud.downloadFile({ 162 | // fileID: "cloud://pub-ee5927.7075-pub-ee5927/DICT", 163 | // success: function(res){ 164 | // //复制文件 165 | // try{ 166 | // wx.getFileSystemManager().saveFileSync(res.tempFilePath, path); 167 | // scb(wx.getFileSystemManager().readFileSync(path)); 168 | // }catch(e){ 169 | // scb("字典读取失败:"+JSON.stringify(e)); 170 | // } 171 | // }, 172 | // fail: function (res) { 173 | // scb("字典下载失败:"+JSON.stringify(res)); 174 | // } 175 | // }); 176 | // } 177 | // }; 178 | // } 179 | 180 | //提示相关 181 | fn alert(title:&str, message: &str, callback: &'static Fn()){ 182 | js!{ 183 | getApp().page.showModal({ 184 | showCancel: false, 185 | confirmText: "确定", 186 | title: @{title}, 187 | content: @{message}, 188 | success: function(res) { 189 | @{callback}(); 190 | } 191 | }); 192 | }; 193 | } 194 | fn show_modal(title:&str, content: &str, show_cancel: bool, ok:&'static Fn(), cancel:&'static Fn()){ 195 | js!{ 196 | wx.showModal({ 197 | title: @{title}, 198 | content: @{content}, 199 | showCancel: @{show_cancel}, 200 | success: function(res) { 201 | if (res.confirm) { 202 | @{ok}(); 203 | } else if (res.cancel) { 204 | @{cancel}(); 205 | } 206 | } 207 | }); 208 | }; 209 | } 210 | 211 | //确认字符串数据 212 | fn confirm_str(title:&str, content: &str, val:&str, ok:&'static Fn(String), cancel:&'static Fn()){ 213 | js!{ 214 | var val = @{val}; 215 | wx.showModal({ 216 | title: @{title}, 217 | content: @{content}, 218 | showCancel: true, 219 | success: function(res) { 220 | if (res.confirm) { 221 | @{ok}(val); 222 | } else if (res.cancel) { 223 | @{cancel}(); 224 | } 225 | } 226 | }); 227 | }; 228 | } 229 | 230 | fn show_toast(title:&str, duration: i32, mask: bool, image: Option){ 231 | js!{ 232 | var image = @{image}; 233 | var data = { 234 | title: @{title}, 235 | icon: "none", 236 | duration: @{duration}, 237 | mask: @{mask}, 238 | }; 239 | if (image){ 240 | data.image = image; 241 | } 242 | wx.showToast(data); 243 | }; 244 | } 245 | 246 | fn show_loading(title:&str){ 247 | js!{ 248 | wx.showLoading({ 249 | title: @{title}, 250 | mask: true 251 | }); 252 | }; 253 | } 254 | 255 | fn hide_loading(){ 256 | js!{wx.hideLoading();}; 257 | } 258 | 259 | //显示输入对话框 260 | fn show_input(text: &str, placeholder:&str, callback: &'static Fn(String)){ 261 | js!{ 262 | getApp().page.setData({ inputPlaceholder:@{placeholder}, inputContent: @{text}, showInput: true, showCanvasPlace: true}); 263 | getApp().handle_input = @{callback}; 264 | }; 265 | } 266 | 267 | //显示选择对话框(列表1,当前项,列表2,当前项,callback(当前项1,当前项2)) 268 | fn show_choose(groups: Option>, groud_id:i32, names: Option>, name_id:i32, handle: Option<(&'static Fn(i32, i32), &'static Fn(i32, i32, i32, i32))>){ 269 | js!{ 270 | getApp().page.hideMenu(); 271 | getApp().page.setData({ 272 | exerciseValue:[@{groud_id}, @{name_id}], //当前选项 273 | showChoose: true, 274 | showCanvasPlace: true, }); 275 | }; 276 | if let Some(groups) = groups{ 277 | js!(getApp().page.setData({exerciseGroups: @{groups}})); 278 | } 279 | if let Some(names) = names{ 280 | js!(getApp().page.setData({exerciseNames: @{names}})); 281 | } 282 | if let Some(handle) = handle{ 283 | js!{ 284 | //绑定事件 285 | getApp().handle_choose = @{handle.0}; 286 | getApp().handle_choose_change = @{handle.1}; 287 | } 288 | } 289 | } 290 | 291 | //隐藏输入对话框 292 | fn hide_input(){ 293 | js!(getApp().page.setData({ showInput: false, showCanvasPlace: false})); 294 | } 295 | 296 | //显示练习记录 297 | fn show_history(history: History, index: i32){ 298 | js!{ 299 | var page = getApp().page; 300 | var history = @{history}; 301 | var index = @{index}; 302 | var text_array = history.text.split(""); 303 | page.setData({ 304 | showHistoryStroke: true, 305 | showCanvasPlace: true, 306 | historyStrokeText: text_array, 307 | }); 308 | getApp().handle_history = function(index){ 309 | //画笔画 310 | setTimeout(function(){ 311 | page.drawStrokes(history, index); 312 | }, 200); 313 | }; 314 | getApp().handle_history(0); 315 | }; 316 | } 317 | 318 | // //View相关 319 | // fn window_width() -> i32{ 320 | // js!(return wx.getSystemInfoSync().windowWidth;).try_into().unwrap() 321 | // } 322 | // fn window_height() -> i32{ 323 | // js!(return wx.getSystemInfoSync().windowHeight;).try_into().unwrap() 324 | // } 325 | 326 | fn show_custom_toast(title:String, image: String, duration: i32){ 327 | js!(clearTimeout(getApp().showToastTimeOut);); 328 | js!{ 329 | getApp().page.setData({ 330 | scoreToastAnimation: "showtoast "+@{duration}+"ms", 331 | hideScoreToast: false, 332 | scoreToastImage: @{image}, 333 | scoreToastText: @{title} 334 | }); 335 | getApp().showToastTimeOut = setTimeout(function(){ 336 | getApp().page.setData({ 337 | hideScoreToast: true 338 | }); 339 | }, @{duration}); 340 | }; 341 | } 342 | 343 | fn save_file(name:&str, content:Vec){ 344 | js!{ 345 | var path = getApp().globalData.userDataPath+@{name}; 346 | wx.getFileSystemManager().writeFile({ 347 | filePath: path, 348 | data: new Uint8Array(@{content}).buffer, 349 | success: function (res) { 350 | // console.log("文件保存成功", res); 351 | }, 352 | fail: function (res) { 353 | // console.log("文件保存失败!", res); 354 | } 355 | }); 356 | }; 357 | } 358 | 359 | fn read_file(name:&str, callback: &'static Fn(Result, String>)){ 360 | let cb = move |value:Value|{ 361 | match value{ 362 | Value::Undefined | Value::Null => callback(Err(format!("Undefined/Null {:?}", value))), 363 | Value::String(e) => callback(Err(e)), 364 | Value::Bool(b) => callback(Err(format!("Bool {}", b))), 365 | Value::Number(n) => callback(Err(format!("Number {:?}", n))), 366 | Value::Symbol(s) => callback(Err(format!("Symbol {:?}", s))), 367 | Value::Reference(n) => { 368 | let buffer:ArrayBuffer = n.try_into().unwrap(); 369 | callback(Ok(Vec::from(buffer))); 370 | } 371 | }; 372 | }; 373 | js!{ 374 | var cb = @{cb}; 375 | var path = getApp().globalData.userDataPath+@{name}; 376 | wx.getFileSystemManager().readFile({ 377 | filePath: path, 378 | success: function (res) { 379 | // console.log("文件读取成功", res); 380 | cb(res.data); 381 | }, 382 | fail: function (res) { 383 | // console.log("文件读取失败!", res); 384 | cb(res.errMsg); 385 | } 386 | }); 387 | }; 388 | } 389 | 390 | //存储相关 391 | fn set_storage(name: &str, content: Vec) -> Result<(), String>{ 392 | let result:Value = js!(try{ 393 | var content = @{content}; 394 | var name = @{name}; 395 | //console.log("set_storage>>>> 存储 ", name, content); 396 | // console.log("保存:", name, content, "类型:", typeof(content)); 397 | wx.setStorageSync(name, content); 398 | return null; 399 | }catch(e){ 400 | return e+""; 401 | } 402 | ).try_into().unwrap(); 403 | 404 | match result{ 405 | Value::String(s) => Err(s), 406 | _ => Ok(()) 407 | } 408 | } 409 | 410 | fn get_storage(name: &str) -> Result, String>{ 411 | let data:Value = js!( 412 | try { 413 | var name = @{name}; 414 | var data = wx.getStorageSync(name); 415 | //console.log("get_storage>>>> 读取 ", name, data); 416 | //Array转换成arrayBuffer 417 | if(data && data.length>0){ 418 | return new Uint8Array(data).buffer; 419 | }else{ 420 | return "数据为空!"; 421 | } 422 | } catch (e) { 423 | return e+""; 424 | } 425 | ).try_into().unwrap(); 426 | 427 | match data{ 428 | Value::Undefined | Value::Null => Err(format!("get_storage 调用失败/Undefined/Null: {:?}", data)), 429 | Value::String(e) => Err(format!("get_storage 调用失败/String: {}", e)), 430 | Value::Bool(b) => Err(format!("get_storage 调用失败: 布尔值 {}", b)), 431 | Value::Number(n) => Err(format!("get_storage 调用失败: Number {:?}", n)), 432 | Value::Symbol(n) => Err(format!("get_storage 调用失败: Symbol {:?}", n)), 433 | _ => { 434 | let buffer:ArrayBuffer = data.try_into().unwrap(); 435 | Ok(Vec::from(buffer)) 436 | } 437 | } 438 | } 439 | 440 | //动画相关 441 | fn set_timeout(tid:i32, callback: &'static Fn(), delay: u32){ 442 | js!{ 443 | var timeouts = getApp().timeouts; 444 | var tid = @{tid}; 445 | if (timeouts.has(tid)){//清空之前的动画 446 | clearTimeout(timeouts.get(tid)); 447 | } 448 | var timeout = setTimeout(@{callback}, @{delay}); 449 | timeouts.set(tid, timeout); 450 | }; 451 | } 452 | 453 | fn clear_timeout(tid: i32){ 454 | js!{ 455 | if (getApp().timeouts && getApp().timeouts.has(@{tid})){ 456 | clearTimeout(getApp().timeouts.get(@{tid})); 457 | } 458 | }; 459 | } 460 | 461 | //提示相关 462 | // fn alert(&self, title:&str, message: &str, ok: &'static Fn()); 463 | // fn show_modal(&self, title:&str, content: &str, show_cancel: bool, ok:&'static Fn(), cancel:&'static Fn()); 464 | // fn show_toast(&self, title:&str, duration: i32, mask: bool, image: Option, ); 465 | // fn show_loading(&self, title:&str); 466 | // fn hide_loading(&self); 467 | 468 | struct MMPCanvasContext{} 469 | 470 | impl CanvasContext for MMPCanvasContext{ 471 | fn set_fill_style_color(&self, color: &str) { 472 | js!(getApp().canvasContext.setFillStyle(@{color})); 473 | } 474 | fn fill_rect(&self, x: f64, y: f64, width: f64, height: f64) { 475 | js!(getApp().canvasContext.fillRect(@{x}, @{y}, @{width}, @{height})); 476 | } 477 | fn set_stroke_style_color(&self, color: &str) { 478 | js!(getApp().canvasContext.setStrokeStyle(@{color})); 479 | } 480 | fn set_line_width(&self, line_width: f64) { 481 | js!(getApp().canvasContext.setLineWidth(@{line_width})); 482 | } 483 | fn begin_path(&self) { 484 | js!(getApp().canvasContext.beginPath()); 485 | } 486 | fn move_to(&self, x: f64, y: f64) { 487 | js!(getApp().canvasContext.moveTo(@{x},@{y})); 488 | } 489 | fn line_to(&self, x: f64, y: f64) { 490 | js!(getApp().canvasContext.lineTo(@{x},@{y})); 491 | } 492 | fn stroke(&self) { 493 | js!(getApp().canvasContext.stroke()); 494 | } 495 | fn stroke_rect(&self, x: f64, y: f64, width: f64, height: f64) { 496 | js!(getApp().canvasContext.strokeRect(@{x}, @{y}, @{width}, @{height})); 497 | } 498 | fn fill_circle(&self, x: f64, y: f64, radius: f64) { 499 | js!{ 500 | getApp().canvasContext.save(); 501 | getApp().canvasContext.beginPath(); 502 | getApp().canvasContext.arc(@{x}, @{y}, @{radius}, 0.0, 360.0, false); 503 | getApp().canvasContext.fill(); 504 | getApp().canvasContext.restore(); 505 | } 506 | } 507 | 508 | fn rotate(&self, angle: f64) { 509 | js!(getApp().canvasContext.rotate(@{angle})); 510 | } 511 | fn set_line_dash(&self, segments: Vec) { 512 | js!(getApp().canvasContext.setLineDash(@{segments})); 513 | } 514 | fn save(&self) { 515 | js!(getApp().canvasContext.save()); 516 | } 517 | fn restore(&self) { 518 | js!(getApp().canvasContext.restore()); 519 | } 520 | fn scale(&self, x: f64, y: f64) { 521 | js!(getApp().canvasContext.scale(@{x}, @{y})); 522 | } 523 | fn translate(&self, x: f64, y: f64) { 524 | js!(getApp().canvasContext.translate(@{x}, @{y})); 525 | } 526 | fn draw_image(&self, path: &str, x: i32, y: i32, width: i32, height: i32) { 527 | js!{ 528 | getApp().canvasContext.drawImage(@{path},@{x}, @{y}, @{width}, @{height}); 529 | }; 530 | } 531 | fn draw_image_at(&self, path: &str, x: f64, y: f64) { 532 | js!{ getApp().canvasContext.drawImage(@{path},@{x}, @{y})}; 533 | } 534 | fn draw(&self, callback: &'static Fn()){ 535 | js!{ 536 | var cb = @{callback}; 537 | getApp().canvasContext.draw(false, function(e){ 538 | cb(); 539 | }) 540 | }; 541 | } 542 | 543 | fn set_font_size(&self, font_size:f64){ 544 | js!(getApp().canvasContext.setFontSize(@{font_size})); 545 | } 546 | fn fill_text(&self, text:&str, x:f64, y:f64){ 547 | js!(getApp().canvasContext.fillText(@{text}, @{x}, @{y})); 548 | } 549 | } 550 | 551 | struct IndexPage{ 552 | context: Box, 553 | } 554 | 555 | impl MainPage for IndexPage{ 556 | //获取画布 557 | fn canvas(&self) -> &Box{ 558 | &self.context 559 | } 560 | 561 | fn canvas_width(&self) -> f64{ 562 | js!( 563 | return getApp().page.data.renderSize; 564 | ).try_into() 565 | .unwrap() 566 | } 567 | fn canvas_height(&self) -> f64{ 568 | js!( 569 | return getApp().page.data.renderSize; 570 | ).try_into() 571 | .unwrap() 572 | } 573 | 574 | //设置显示的字符(页面标签) [//在小程序中,程序分包根据需要切换不同字体] 575 | fn set_character(&self, c: char){ 576 | let val = c.escape_unicode().to_string().replace("\\", "").replace("u{", "").replace("}", ""); 577 | let z = i64::from_str_radix(&format!("{}", val), 16).unwrap(); 578 | let class = if z<=28431{ "KaiTi_GB2312_0" }else{"KaiTi_GB2312_1"}; 579 | js!{ 580 | //置空、更新字体 581 | getApp().page.setData({ character: "", fontName: @{class}}); 582 | //更新文字 583 | getApp().page.setData({ character: @{format!("{}", c)}}); 584 | }; 585 | } 586 | 587 | //作业完成进度预览 588 | fn update_homework(&self, content:&str, index: i32){ 589 | let unicodes:Vec = content.chars().map(|c|{ 590 | c.escape_unicode().to_string().replace("\\", "").replace("u{", "").replace("}", "") 591 | }).collect(); 592 | 593 | js!{ 594 | var unicodes = @{unicodes}; 595 | var content = @{content}; 596 | var index = @{index}; 597 | var words = []; 598 | for (var i = 0; i < content.length; i++) { 599 | words.push({ id: 'x'+i+unicodes[i], style: index > i ? "a" : "", text: content.charAt(i) }); 600 | } 601 | //大概滚动到中间位置 602 | var i = index-5; 603 | if(i<0){ 604 | i = 0; 605 | } 606 | getApp().page.setData({ words: words, scrollId: 'x' + i + unicodes[i]}); 607 | }; 608 | } 609 | 610 | //笔刷按钮闪烁动画 611 | fn start_brush_blink(&self){ 612 | js!(getApp().page.setData({ brushDotHidden: false});); 613 | } 614 | fn stop_brush_blink(&self){ 615 | js!(getApp().page.setData({ brushDotHidden: true});); 616 | } 617 | } 618 | 619 | fn get_page_context() ->Box{ 620 | Box::new(IndexPage{context: Box::new(MMPCanvasContext{})}) 621 | } 622 | 623 | fn platform_init(){ 624 | js_serializable!( History ); 625 | js!(getApp().timeouts = new Map()); 626 | } -------------------------------------------------------------------------------- /teacher/src/pdollarplus.rs: -------------------------------------------------------------------------------- 1 | use std; 2 | use std::f64::consts::PI; 3 | //use std::time::{Duration, Instant}; 4 | /* 5 | $ P + Point-Cloud识别器是一款2-D手势识别器,专为基于手势的用户界面进行快速原型设计,尤其适用于视力不佳的人。 6 | $ P +提高了$ P Point-Cloud识别器的准确性。 7 | $ P +是通过仔细研究低视力人群的中风姿势表现而开发的,这为如何为所有用户提高$ P提供了见解。 8 | */ 9 | 10 | const NUM_POINTS: usize = 32; 11 | const ORIGIN: Point = Point { 12 | x: 0.0, 13 | y: 0.0, 14 | id: 0, 15 | angle: 0.0, 16 | }; 17 | 18 | #[derive(Debug, Clone, Serialize, Deserialize)] 19 | pub struct Point { 20 | pub x: f64, 21 | pub y: f64, 22 | pub id: usize, 23 | pub angle: f64, // normalized turning angle, $P+ 24 | } 25 | 26 | impl Point { 27 | pub fn new>(x: T, y: T, id: usize) -> Point { 28 | Point { 29 | x: x.into(), 30 | y: y.into(), 31 | id, 32 | angle: 0.0, 33 | } 34 | } 35 | 36 | pub fn with_angle>(x: T, y: T, id: usize, angle: f64) -> Point { 37 | Point { 38 | x: x.into(), 39 | y: y.into(), 40 | id, 41 | angle, 42 | } 43 | } 44 | } 45 | 46 | // 47 | // Result class 48 | // 49 | pub struct Result { 50 | pub name: String, 51 | pub score: f64, 52 | pub ms: f64, 53 | } 54 | 55 | impl Result { 56 | fn new(name: &str, score: f64, ms: f64) -> Result { 57 | // constructor 58 | Result { 59 | name: name.to_string(), 60 | score, 61 | ms, 62 | } 63 | } 64 | } 65 | 66 | #[derive(Debug, Clone)] 67 | pub struct PointCloud { 68 | name: String, 69 | pub points: Vec, 70 | } 71 | 72 | impl PointCloud { 73 | fn new(name: &str, points: Vec) -> PointCloud { 74 | let points = resample(points, NUM_POINTS); 75 | let points = scale(&points); 76 | let points = translate_to(&points, &ORIGIN); 77 | PointCloud { 78 | name: name.to_string(), 79 | points: compute_normalized_turning_angle(&points), 80 | } 81 | } 82 | } 83 | 84 | impl Default for PointCloud { 85 | fn default() -> PointCloud { 86 | PointCloud { 87 | name: String::new(), 88 | points: vec![], 89 | } 90 | } 91 | } 92 | 93 | pub struct PDollarPlusRecognizer { 94 | point_clouds: Vec, 95 | } 96 | 97 | impl PDollarPlusRecognizer { 98 | pub fn new() -> PDollarPlusRecognizer { 99 | PDollarPlusRecognizer { 100 | point_clouds: vec![], 101 | } 102 | } 103 | 104 | pub fn recognize(&self, points: Vec) -> Result { 105 | //let t0 = Instant::now(); 106 | let points = translate_to(&scale(&resample(points, NUM_POINTS)), &ORIGIN); 107 | let points = compute_normalized_turning_angle(&points); // $P+ 108 | 109 | let mut b = std::f64::MAX; 110 | let mut u = -1; 111 | for i in 0..self.point_clouds.len() { 112 | // for each point-cloud template 113 | let d = cloud_distance(&points, &self.point_clouds[i].points) 114 | .min(cloud_distance(&self.point_clouds[i].points, &points)); // $P+ 115 | if d < b { 116 | b = d; // best (least) distance 117 | u = i as i32; // point-cloud index 118 | } 119 | } 120 | 121 | //let t1 = duration_to_milis(&t0.elapsed()); 122 | let t1 = 0.0; 123 | 124 | if u == -1 { 125 | Result::new("No match.", -1.0, t1) 126 | } else { 127 | Result::new( 128 | &self.point_clouds[u as usize].name, 129 | b, // $P+ 130 | t1, 131 | ) 132 | } 133 | } 134 | 135 | pub fn add_gesture(&mut self, name: &str, points: Vec) -> usize { 136 | //println!("add_gesture name={}", name); 137 | self.point_clouds.push(PointCloud::new(name, points)); 138 | let mut num = 0; 139 | for i in 0..self.point_clouds.len() { 140 | if self.point_clouds[i].name == name { 141 | num += 1; 142 | } 143 | } 144 | num 145 | } 146 | 147 | pub fn clear_gestures(&mut self) { 148 | self.point_clouds.clear(); 149 | } 150 | 151 | pub fn _point_clouds(&self) -> &Vec { 152 | &self.point_clouds 153 | } 154 | } 155 | 156 | fn cloud_distance(pts1: &Vec, pts2: &Vec) -> f64 { 157 | // revised for $P+ 158 | let mut matched = vec![false; pts1.len()]; // pts1.length == pts2.length 159 | let mut sum = 0.0; 160 | for i in 0..pts1.len() { 161 | let mut index = -1; 162 | let mut min = std::f64::MAX; 163 | for j in 0..pts1.len() { 164 | let d = distance_with_angle(&pts1[i], &pts2[j]); 165 | if d < min { 166 | min = d; 167 | index = j as i32; 168 | } 169 | } 170 | matched[index as usize] = true; 171 | sum += min; 172 | } 173 | for j in 0..matched.len() { 174 | if !matched[j] { 175 | let mut min = std::f64::MAX; 176 | for i in 0..pts1.len() { 177 | let d = distance_with_angle(&pts1[i], &pts2[j]); 178 | if d < min { 179 | min = d; 180 | } 181 | } 182 | sum += min; 183 | } 184 | } 185 | return sum; 186 | } 187 | 188 | fn distance_with_angle(p1: &Point, p2: &Point) -> f64 { 189 | // $P+ 190 | let dx = p2.x - p1.x; 191 | let dy = p2.y - p1.y; 192 | let da = p2.angle - p1.angle; 193 | (dx * dx + dy * dy + da * da).sqrt() 194 | } 195 | 196 | fn compute_normalized_turning_angle(points: &Vec) -> Vec { 197 | // $P+ 198 | let mut newpoints = vec![]; 199 | newpoints.push(Point::new(points[0].x, points[0].y, points[0].id)); // first point 200 | for i in 1..points.len() - 1 { 201 | let dx = (points[i + 1].x - points[i].x) * (points[i].x - points[i - 1].x); 202 | let dy = (points[i + 1].y - points[i].y) * (points[i].y - points[i - 1].y); 203 | let dn = distance(&points[i + 1], &points[i]) * distance(&points[i], &points[i - 1]); 204 | let cosangle = (-1.0f64).max(1.0f64.min((dx + dy) / dn)); // ensure [-1,+1] 205 | let angle = cosangle.acos() / PI; // normalized angle 206 | newpoints.push(Point::with_angle( 207 | points[i].x, 208 | points[i].y, 209 | points[i].id, 210 | angle, 211 | )); 212 | } 213 | newpoints.push(Point::new( 214 | // last point 215 | points[points.len() - 1].x, 216 | points[points.len() - 1].y, 217 | points[points.len() - 1].id, 218 | )); 219 | newpoints 220 | } 221 | 222 | fn translate_to(points: &Vec, pt: &Point) -> Vec { 223 | // translates points' centroid 224 | let c = centroid(points); 225 | let mut newpoints = vec![]; 226 | for point in points { 227 | let qx = point.x + pt.x - c.x; 228 | let qy = point.y + pt.y - c.y; 229 | newpoints.push(Point::new(qx, qy, point.id)); 230 | } 231 | newpoints 232 | } 233 | 234 | fn centroid(points: &Vec) -> Point { 235 | let mut x = 0.0; 236 | let mut y = 0.0; 237 | for point in points { 238 | x += point.x; 239 | y += point.y; 240 | } 241 | x /= points.len() as f64; 242 | y /= points.len() as f64; 243 | Point::new(x, y, 0) 244 | } 245 | 246 | fn scale(points: &Vec) -> Vec { 247 | let mut min_x = std::f64::MAX; 248 | let mut max_x = std::f64::MIN; 249 | let mut min_y = std::f64::MAX; 250 | let mut max_y = std::f64::MIN; 251 | for i in 0..points.len() { 252 | min_x = min_x.min(points[i].x); 253 | min_y = min_y.min(points[i].y); 254 | max_x = max_x.max(points[i].x); 255 | max_y = max_y.max(points[i].y); 256 | } 257 | let size = (max_x - min_x).max(max_y - min_y); 258 | let mut new_points = vec![]; 259 | for i in 0..points.len() { 260 | let qx = (points[i].x - min_x) / size; 261 | let qy = (points[i].y - min_y) / size; 262 | new_points.push(Point::new(qx, qy, points[i].id)); 263 | } 264 | new_points 265 | } 266 | 267 | pub fn resample(mut points: Vec, n: usize) -> Vec { 268 | let len = path_length(&points) / (n as f64 - 1.0); // interval length 269 | let mut dist = 0.0; 270 | let mut new_points = vec![points[0].clone()]; 271 | 272 | let mut i = 1; 273 | while i < points.len() { 274 | if points[i].id == points[i - 1].id { 275 | let d = distance(&points[i - 1], &points[i]); 276 | if (dist + d) >= len { 277 | let qx = points[i - 1].x + ((len - dist) / d) * (points[i].x - points[i - 1].x); 278 | let qy = points[i - 1].y + ((len - dist) / d) * (points[i].y - points[i - 1].y); 279 | let q = Point::new(qx, qy, points[i].id); 280 | new_points.push(q.clone()); // append Point::new 'q' 281 | points.insert(i, q); // insert 'q' at position i in points s.t. 'q' will be the next i 282 | dist = 0.0; 283 | } else { 284 | dist += d; 285 | } 286 | } 287 | i += 1; 288 | } 289 | if new_points.len() == n as usize - 1 { 290 | // somtimes we fall a rounding-error short of adding the last point, so add it if so 291 | new_points.push(Point::new( 292 | points[points.len() - 1].x, 293 | points[points.len() - 1].y, 294 | points[points.len() - 1].id, 295 | )); 296 | } 297 | 298 | //println!("resample之后:{:?}", new_points); 299 | 300 | new_points 301 | } 302 | 303 | // length traversed by a point path 304 | fn path_length(points: &Vec) -> f64 { 305 | let mut d = 0.0; 306 | for i in 1..points.len() { 307 | if points[i].id == points[i - 1].id { 308 | d += distance(&points[i - 1], &points[i]); 309 | } 310 | } 311 | d 312 | } 313 | 314 | pub fn distance(p1: &Point, p2: &Point) -> f64 { 315 | // Euclidean distance between two points 316 | let dx = p2.x - p1.x; 317 | let dy = p2.y - p1.y; 318 | (dx * dx + dy * dy).sqrt() 319 | } 320 | 321 | // pub fn duration_to_milis(duration: &Duration) -> f64 { 322 | // duration.as_secs() as f64 * 1000.0 + duration.subsec_nanos() as f64 / 1_000_000.0 323 | // } 324 | -------------------------------------------------------------------------------- /teacher/src/platform.rs: -------------------------------------------------------------------------------- 1 | //系统功能接口 2 | //页面、UI的API接口 3 | use crate::pdollarplus::Point; 4 | 5 | pub trait CanvasContext { 6 | fn set_fill_style_color(&self, color: &str); 7 | fn fill_rect(&self, x: f64, y: f64, width: f64, height: f64); 8 | fn set_stroke_style_color(&self, color: &str); 9 | fn set_line_width(&self, line_width: f64); 10 | fn begin_path(&self); 11 | fn move_to(&self, x: f64, y: f64); 12 | fn line_to(&self, x: f64, y: f64); 13 | fn stroke(&self); 14 | fn stroke_rect(&self, x: f64, y: f64, width: f64, height: f64); 15 | fn fill_circle(&self, x: f64, y: f64, radius: f64); 16 | fn draw_image(&self, path: &str, x: i32, y: i32, width: i32, height: i32); 17 | fn draw_image_at(&self, path: &str, x: f64, y: f64); 18 | fn set_line_dash(&self, segments: Vec); 19 | fn save(&self); 20 | fn restore(&self); 21 | fn scale(&self, x: f64, y: f64); 22 | fn translate(&self, x: f64, y: f64); 23 | fn rotate(&self, angle: f64); 24 | fn draw(&self, callback: &'static Fn()) { 25 | callback(); 26 | } 27 | fn set_font_size(&self, font_size:f64); 28 | fn fill_text(&self, text:&str, x:f64, y:f64); 29 | } 30 | 31 | pub trait MainPage { 32 | //获取画布 33 | fn canvas(&self) -> &Box; 34 | fn canvas_width(&self) -> f64; 35 | fn canvas_height(&self) -> f64; 36 | //设置显示的字符(页面标签) [//在小程序中,程序分包根据需要切换不同字体] 37 | fn set_character(&self, c: char); 38 | //作业完成进度预览 39 | fn update_homework(&self, content: &str, index: i32); 40 | 41 | //笔刷按钮闪烁动画 42 | fn start_brush_blink(&self); 43 | fn stop_brush_blink(&self); 44 | } 45 | 46 | #[derive(Clone, Serialize, Deserialize, Debug)] 47 | pub struct History { 48 | pub date: String, 49 | pub text: String, 50 | pub strokes: Vec>>, //存储每个字得笔画 51 | pub scores: Vec, //存储每个字得得分 52 | pub avg: String, //平均分 53 | } 54 | -------------------------------------------------------------------------------- /teacher/src/teacher.rs: -------------------------------------------------------------------------------- 1 | use crate::pdollarplus::{resample, PDollarPlusRecognizer, Point}; 2 | use crate::platform::*; 3 | use bincode::{deserialize, serialize}; 4 | use chrono::offset::FixedOffset; 5 | use chrono::{DateTime, NaiveDateTime}; 6 | use std::cell::RefCell; 7 | use std::collections::HashMap; 8 | use std::io::Write; 9 | //图标集 https://www.iconfinder.com/icons/1054952/chart_graph_trends_icon 10 | 11 | const KEY_INPUTS: &str = "inputs"; 12 | const KEY_HOMEWORK: &str = "homework"; 13 | const KEY_HISTORY: &str = "history"; 14 | const KEY_CHOOSE: &str = "choose"; 15 | use crate::log; 16 | 17 | static POEMS: &[u8] = include_bytes!("../POEMS"); 18 | static ARTICLS: &[u8] = include_bytes!("../ARTICLS"); 19 | // static PINYIN: &[u8] = include_bytes!("../PINYIN"); 20 | 21 | 22 | const DELAY_ANIM:u32 = 30; //动画模式 23 | const DELAY_IDLE:u32 = 9000; //空闲模式 24 | 25 | thread_local! { 26 | static CONTROLLER: RefCell = RefCell::new(Controller::new()); 27 | } 28 | 29 | #[derive(Clone, Serialize, Deserialize, Debug)] 30 | pub struct Word { 31 | pub strokes: String, 32 | pub pinyin: String, 33 | pub radicals: String, 34 | pub explanation: String, 35 | } 36 | 37 | //保存的练习记录 38 | #[derive(Serialize, Deserialize, Debug)] 39 | pub struct Homework { 40 | group: i32, //分组:0自定义,1古诗,2课文 41 | title: String, //古诗、课文对应的标题(索引) 42 | content: String, //练习内容 43 | progress: usize, //练习进度 44 | } 45 | 46 | pub struct Controller { 47 | pinyin: HashMap, 48 | page: Box, 49 | poems: HashMap, 50 | poems_map: Vec<(String, String)>, //Vec<(Name, Key)> 51 | articls: HashMap, 52 | articls_map: Vec<(String, String)>, //Vec<(Name, Key)> 53 | strokes_map: HashMap>>, 54 | dict: Option>, 55 | stroke_anim: Vec, //当前动画的指示器,每当新的笔画开始,数组清空,每一帧的时候放入一个当前笔画的点,直到数组长度和当前笔画点数相等。 56 | pub character: usize, //当前第几个字 57 | drawing_ch: Option, //当前绘制的字 58 | strokes: Vec>, 59 | stroke_index: usize, 60 | all_user_strokes: Vec>>, //用户所有字的笔画数据 61 | all_user_strokes_score: Vec, //用户每个字的得分 62 | user_strokes: Vec>, //当前字用户的笔画 63 | stroke_scores: Vec, //当前字的笔画得分 64 | writing: bool, //正在写入 65 | complete: bool, //当前文字已写完, 66 | pub homework: Vec, 67 | pub homework_str: String, 68 | error_icon: Option, 69 | last_point: Option<(f64, f64)>, //draw()方法正在执行 70 | delay: u32, //连续绘制间隔 71 | stroke_animation: Option, //笔画动画是否在执行 0-错误提示动画, 1-整字动画 72 | last_render_time: i64, 73 | 74 | /* 75 | 更新逻辑: 76 | 默认帧率 1FPS 77 | 切换字符、笔画演示、错误提示、用户触摸(start,touchmove) 时, 帧率切为20FPS (间隔50ms) 78 | 触摸结束(touchend,touchcancel)、动画演示结束、错误提示结束 时,帧率降低为 1FPS (间隔1000ms) 79 | */ 80 | } 81 | 82 | impl Controller { 83 | pub fn new() -> Controller{ 84 | //反序列化 85 | let poems: HashMap = deserialize(POEMS).unwrap(); 86 | //提取所有古诗的名字列表,以及对应的key 87 | let mut keys: Vec = poems.keys().map(|s| String::from(s.as_str())).collect(); 88 | keys.sort(); 89 | let poems_map = keys 90 | .iter() 91 | .map(|s| (s.split("-").last().unwrap().to_string(), s.clone())) 92 | .collect(); 93 | 94 | //提取所有文章的名字列表,以及对应的key 95 | //解压 96 | let mut decompressor = bzip2::write::BzDecoder::new(vec![]); 97 | decompressor.write_all(&ARTICLS).unwrap(); 98 | let slice = decompressor.finish().unwrap(); 99 | let articls: HashMap = deserialize(&slice).unwrap(); 100 | let mut keys: Vec = articls.keys().map(|s| String::from(s.as_str())).collect(); 101 | keys.sort(); 102 | let articls_map = keys 103 | .iter() 104 | .map(|s| (s.split("-").last().unwrap().to_string(), s.clone())) 105 | .collect(); 106 | 107 | //------------ 拼音列表 -------------------- 108 | //解压 109 | // let mut decompressor = bzip2::write::BzDecoder::new(vec![]); 110 | // decompressor.write_all(&PINYIN).unwrap(); 111 | // let slice = decompressor.finish().unwrap(); 112 | // let pinyin: HashMap = deserialize(&slice).unwrap(); 113 | let pinyin = HashMap::new(); 114 | 115 | Controller { 116 | pinyin: pinyin, 117 | page: crate::get_page_context(), 118 | poems, 119 | poems_map, 120 | articls, 121 | articls_map, 122 | strokes_map: HashMap::new(), 123 | dict: None, 124 | stroke_anim: vec![], 125 | character: 0, 126 | stroke_index: 0, 127 | strokes: vec![], 128 | user_strokes: vec![], 129 | all_user_strokes: vec![], 130 | all_user_strokes_score: vec![], 131 | writing: false, 132 | complete: false, 133 | homework: vec![], 134 | homework_str: String::new(), 135 | delay: 1000, 136 | drawing_ch: None, 137 | stroke_scores: vec![], 138 | error_icon: None, 139 | last_point: None, 140 | stroke_animation: None, 141 | last_render_time: 0 142 | } 143 | } 144 | 145 | //立即绘制并开始以指定的时间间隔连续绘制 146 | fn reset_delay(&mut self, delay:u32, render:bool){ 147 | if self.delay != delay || render{ 148 | self.delay = delay; 149 | crate::clear_timeout(0); 150 | self.render(); 151 | } 152 | } 153 | 154 | fn on_ready(&mut self) { 155 | //js!(console.log("on_ready>>>", new Date(), Date.now())); 156 | crate::show_loading("加载笔画"); 157 | //加载笔画 158 | crate::load_strokes(&mut |data| { 159 | let decoded: HashMap>> = 160 | deserialize(data.as_ref().unwrap()).unwrap(); 161 | 162 | self.strokes_map = decoded; 163 | //加载练习内容 164 | self.load_homework(); 165 | }); 166 | } 167 | 168 | fn load_homework(&mut self) { 169 | //js!(console.log("load_homework>>>", new Date(), Date.now())); 170 | //读取被保存的练习内容 171 | let homework: Homework = if let Ok(saved) = &crate::get_storage(KEY_HOMEWORK) { 172 | deserialize(&saved).unwrap() 173 | } else { 174 | let mut keys: Vec = self 175 | .articls 176 | .keys() 177 | .map(|s| String::from(s.as_str())) 178 | .collect(); 179 | keys.sort(); 180 | Homework { 181 | group: 2, 182 | title: keys[0].clone(), 183 | content: self.articls.get(&keys[0]).unwrap().clone(), 184 | progress: 0, 185 | } 186 | }; 187 | //设置练习内容显示文本 188 | self.set_homework(&homework.content); 189 | //加载笔画 190 | self.create_strokes(); 191 | crate::hide_loading(); 192 | } 193 | 194 | //更新动画 195 | pub fn update(&mut self){ 196 | // log("update>>>"); 197 | if let Some(anim_type) = self.stroke_animation{ 198 | let anim_len = self.stroke_anim.len(); 199 | if anim_len < self.strokes[self.stroke_index].len() { 200 | //添加下一个笔画点 201 | self.stroke_anim 202 | .push(self.strokes[self.stroke_index][anim_len].clone()); 203 | self.stroke_anim 204 | .push(self.strokes[self.stroke_index][anim_len + 1].clone()); 205 | } else { 206 | self.stroke_anim.clear(); 207 | //如果是整笔动画演示, 每个笔画结束以后自动切换到下一笔画 208 | if anim_type==1 && self.stroke_index < self.strokes.len() - 1 { 209 | self.stroke_index += 1; 210 | } else { 211 | //动画结束 212 | if anim_type==1 { 213 | self.page.stop_brush_blink(); 214 | //恢复到第一笔 215 | self.stroke_index = 0; 216 | } 217 | //如果是单笔动画演示, 笔画结束以后清空动画 218 | //self.animating = false; 219 | // log(&format!("第{}笔动画结束", self.stroke_index)); 220 | //log("笔画动画结束,切换为慢速帧率."); 221 | 222 | self.stroke_animation = None; 223 | 224 | //如果没有触摸,恢复慢速动画 225 | if !self.writing{ 226 | self.reset_delay(DELAY_IDLE, true); //切换到慢速帧率 227 | } 228 | } 229 | } 230 | } 231 | } 232 | 233 | //绘制 234 | pub fn render(&mut self) { 235 | //log("render.."); 236 | self.last_render_time = crate::current_timestamp(); 237 | let page = &self.page; 238 | let context = page.canvas(); 239 | 240 | let (width, _height) = (page.canvas_width(), page.canvas_height()); 241 | 242 | //--------------------- 画拼音 ---------------------------------- 243 | if let Some(pinyin) = self.pinyin.get(&self.homework[self.character]){ 244 | context.set_font_size(20.0); 245 | context.set_fill_style_color("#959595"); 246 | context.fill_text(pinyin, 120.0, 20.0); 247 | } 248 | 249 | //------------------ 绘制用户的笔画 ----------------------------- 250 | context.set_stroke_style_color("#333"); 251 | context.set_fill_style_color("#333"); 252 | let line_width = width * 0.035; 253 | context.set_line_width(line_width); 254 | 255 | for points in &self.user_strokes { 256 | let slen = points.len(); 257 | if slen > 1 { 258 | context.fill_circle(points[0].x, points[0].y, line_width / 2.0); 259 | } 260 | 261 | context.begin_path(); 262 | context.move_to(points[0].x, points[0].y); 263 | for point in points { 264 | context.line_to(point.x, point.y); 265 | } 266 | let len = points.len(); 267 | context.stroke(); 268 | 269 | if slen > 1 { 270 | context.fill_circle(points[len - 1].x, points[len - 1].y, line_width / 2.0); 271 | } 272 | } 273 | 274 | //--------------------- 画笔动画 -------------------------- 275 | context.set_stroke_style_color("#000088"); 276 | context.begin_path(); 277 | context.set_line_dash(vec![]); 278 | context.set_line_width(1.0); 279 | context.save(); 280 | //测试笔画 281 | //笔画路径 282 | //原始宽高 900x900, dx=180,dy=85 283 | //计算比例 284 | let scale = width as f64 / 1000.0; 285 | //platform.translate(scale*88.0, scale*48.0); 286 | context.scale(scale, scale); 287 | 288 | //------------ 正确笔画 ------------------------------ 289 | /* 290 | context.begin_path();// 291 | let strokes:&Vec> = self.strokes_map.get(&self.homework[self.character]).unwrap(); 292 | for points in strokes{ 293 | // if points.len()>6{ 294 | // platform.stroke_rect(points[6][0] as f64, points[6][1] as f64, (10) as f64, (10)as f64); 295 | // } 296 | context.move_to(points[0].0 as f64, points[0].1 as f64); 297 | for i in 1..points.len(){ 298 | context.line_to(points[i].0 as f64, points[i].1 as f64); 299 | } 300 | } 301 | for points in &self.strokes{ 302 | context.move_to(points[0].x, points[0].y); 303 | for i in 1..points.len(){ 304 | context.line_to(points[i].x, points[i].y); 305 | } 306 | } 307 | context.stroke(); 308 | */ 309 | //------------------------------------------------------ 310 | 311 | //如果需要,绘制错误提示 312 | if let Some(pos) = &self.error_icon { 313 | context.draw_image_at("/static/icons/pen.png", pos.x + 20.0, pos.y - 30.0); 314 | } 315 | 316 | //绘制画笔 317 | if self.stroke_animation.is_some(){ 318 | if self.stroke_anim.len() > 0 { 319 | context.draw_image_at( 320 | "/static/icons/hand.png", 321 | self.stroke_anim.last().unwrap().x, 322 | //self.stroke_anim.last().unwrap().y - platform.brush_height(), 323 | self.stroke_anim.last().unwrap().y + 10.0, 324 | ); 325 | } 326 | } 327 | 328 | context.restore(); 329 | // if !self.render{ 330 | 331 | // } 332 | //self.render = true; 333 | context.draw(&||{ 334 | CONTROLLER.with(|ctrl| { 335 | //下一帧 336 | let ctrl = ctrl.borrow_mut(); 337 | crate::set_timeout( 338 | 0, 339 | &|| { 340 | CONTROLLER.with(|c| { 341 | c.borrow_mut().next_frame(); 342 | }); 343 | }, 344 | ctrl.delay, 345 | ); 346 | }); 347 | }); 348 | } 349 | 350 | fn next_frame(&mut self){ 351 | self.update(); 352 | self.render(); 353 | } 354 | 355 | pub fn set_homework(&mut self, content: &str) { 356 | let content = String::from(content.trim()); 357 | //选择一个支持的字符 358 | let mut index = -1; 359 | for (i, ch) in content.chars().enumerate() { 360 | if self.strokes_map.contains_key(&ch) { 361 | index = i as i32; 362 | break; 363 | } 364 | } 365 | if index == -1 { 366 | //没有找到文字! 367 | if content.len() == 0 { 368 | crate::alert("提示", "请输入要练习的文字!", &|| {}); 369 | } 370 | } else { 371 | self.complete = false; 372 | self.character = index as usize; 373 | self.stroke_index = 0; 374 | self.stroke_anim.clear(); 375 | self.stroke_scores.clear(); 376 | self.user_strokes.clear(); 377 | self.all_user_strokes = vec![vec![]; content.len()]; 378 | self.all_user_strokes_score = vec![0.0; content.len()]; 379 | self.homework = content.chars().collect(); 380 | self.homework_str = content; 381 | self.stroke_animation = None; 382 | self.create_strokes(); 383 | 384 | self.page 385 | .update_homework(&self.homework_str, self.character as i32); 386 | } 387 | //保存历史记录 388 | let _ = crate::set_storage( 389 | KEY_HOMEWORK, 390 | serialize(&Homework { 391 | group: 0, //0自定义 392 | title: "自定义".into(), 393 | content: self.homework_str.clone(), 394 | progress: 0, 395 | }) 396 | .unwrap(), 397 | ); 398 | } 399 | 400 | //创建笔画数组 401 | pub fn create_strokes(&mut self) { 402 | //js!(console.log("create_strokes>>>", new Date(), Date.now())); 403 | //self.platform.log(&format!("create_strokes character={}", self.character)); 404 | let ch = self.homework[self.character]; 405 | self.drawing_ch = Some(ch); 406 | 407 | let strokes: &Vec> = self.strokes_map.get(&ch).unwrap(); 408 | //self.platform.log(&format!("一共{}笔", strokes.len())); 409 | self.strokes.clear(); 410 | for i in 0..strokes.len() { 411 | //self.platform.log(&format!("第{}笔 {:?}", i, strokes[i])); 412 | self.strokes.push(resample( 413 | strokes[i] 414 | .iter() 415 | .map(|p| Point::new(p.0, p.1, i + 1)) 416 | .collect(), 417 | 50, 418 | )); 419 | } 420 | 421 | //设置显示的字符 422 | self.page.set_character(ch); 423 | //js!(console.log("set_character ok.", new Date(), Date.now())); 424 | } 425 | 426 | fn clear_error_stroke(&mut self, remove_score: bool) { 427 | //删除当前笔画得分 428 | if remove_score { 429 | self.stroke_scores.remove(self.stroke_index); 430 | } 431 | //清空当前错误的笔画 432 | self.user_strokes.remove(self.stroke_index); 433 | //显示错误图标 434 | self.error_icon = Some(self.strokes[self.stroke_index][0].clone()); 435 | //笔画提示 436 | log("笔画错误,切换到动画模式 reset_delay(50)."); 437 | self.stroke_animation = Some(0); //笔画错误动画 438 | self.reset_delay(DELAY_ANIM, false); 439 | } 440 | 441 | //开/关 笔画演示控制 442 | pub fn stroke_anim(&mut self) { 443 | //如果正在错误图示,不进行操作 444 | if let Some(anim_type) = self.stroke_animation{ 445 | if anim_type == 0{ 446 | return; 447 | } 448 | 449 | self.page.stop_brush_blink(); 450 | //结束动画 451 | self.stroke_anim.clear(); 452 | self.stroke_animation = None; 453 | //重新渲染 454 | //log("关闭动画演示,切换为慢速帧率."); 455 | self.reset_delay(DELAY_IDLE, true); 456 | self.stroke_index = 0; 457 | }else{ 458 | self.page.start_brush_blink(); 459 | //清空用户笔画 460 | self.user_strokes.clear(); 461 | self.stroke_animation = Some(1); 462 | //切换到第1笔动画 463 | self.stroke_index = 0; 464 | self.stroke_anim.clear(); 465 | //开始动画 466 | self.reset_delay(DELAY_ANIM, false); 467 | } 468 | } 469 | 470 | //擦除/重写 471 | fn rewrite(&mut self) { 472 | self.stroke_index = 0; 473 | self.stroke_anim.clear(); 474 | self.stroke_scores.clear(); 475 | self.user_strokes.clear(); 476 | //log("rewrite,切换为慢速帧率."); 477 | self.reset_delay(DELAY_IDLE, true); 478 | } 479 | 480 | /** 481 | * 低于50分不通过。 482 | * 笔画差距超过16不通过。 483 | */ 484 | fn calculate_score(&mut self) { 485 | self.writing = false; 486 | // self.platform.log("计算当前笔画得分..."); 487 | 488 | let mut recognizer = PDollarPlusRecognizer::new(); 489 | 490 | //笔画少于2点重写 491 | if self.user_strokes[self.stroke_index].len() > 2 { 492 | //将当前笔画加入识别器 493 | recognizer.add_gesture("stroke", self.strokes[self.stroke_index].clone()); 494 | //识别用户当前笔画 495 | let result = recognizer.recognize(self.user_strokes[self.stroke_index].clone()); 496 | // self.platform.log_div(&format!( 497 | // "笔画得分:{} > {}分", 498 | // result.name, result.score 499 | // )); 500 | self.stroke_scores.push(result.score); 501 | 502 | //笔画距离超过4.5的不通过 503 | if self.stroke_scores[self.stroke_index] < 4.5 { 504 | //切换到下一笔画 505 | self.stroke_index += 1; 506 | //如果“笔画错误”处于显示中,将其隐藏 507 | if self.error_icon.is_some() { 508 | self.error_icon = None; 509 | } 510 | 511 | //检查是否写完 512 | if self.user_strokes.len() == self.strokes.len() { 513 | //检查整个汉字是否正确 514 | recognizer.clear_gestures(); 515 | let mut points = vec![]; 516 | for stroke in &self.strokes { 517 | points.append(&mut stroke.clone()); 518 | } 519 | //self.platform.log(&format!("原始:{:?}", points)); 520 | recognizer.add_gesture(&self.homework[self.character].to_string(), points); 521 | 522 | let mut user_points = vec![]; 523 | for i in 0..self.user_strokes.len() { 524 | for point in &self.user_strokes[i] { 525 | user_points.push(point.clone()); 526 | } 527 | } 528 | //self.platform.log(&format!("用户:{:?}", user_points)); 529 | let result = recognizer.recognize(user_points); 530 | // self.platform 531 | // .log(&format!("整字识别结果:{}", result.score)); 532 | 533 | let mut total_score = 0.0; 534 | for score in &self.stroke_scores { 535 | total_score += score; 536 | } 537 | // self.platform 538 | // .log_div(&format!("整字得分:{}/{}", result.score, total_score)); 539 | self.stroke_scores.clear(); 540 | //log("笔画完成,整字完成,切换为慢速帧率."); 541 | self.reset_delay(DELAY_IDLE, false); 542 | 543 | 544 | //整字得分大于xx分,重写 2.7~6.5 分别代表 10.0~6.2分, 最终整篇计算平均分 8.5~9.0(3星),7.5~8.5(2星),6.0~7.5(1星) 545 | if result.score > 6.5 { 546 | //提示用户重写 547 | crate::alert("哎呦", "字写得太丑了,重新写吧!", &|| { 548 | CONTROLLER.with(|c| { 549 | c.borrow_mut().rewrite(); 550 | }); 551 | }); 552 | return; 553 | } else { 554 | //将当前字的笔画数据保存到数组 555 | self.all_user_strokes[self.character] = self.user_strokes.clone(); 556 | 557 | //提示用户单字得分 558 | //6.5-2.7 = 3.8 559 | //得分=result.score-2.7; 560 | let mut num = result.score - 2.7; 561 | if num < 0.0 { 562 | num = 0.0; 563 | } 564 | let score = 10.0 - num; 565 | //保存得分到数组 566 | self.all_user_strokes_score[self.character] = score; 567 | 568 | //切换到下一个字 569 | if self.next_character(1) { 570 | crate::show_loading("保存记录"); 571 | //完成作业 572 | self.page 573 | .update_homework(&self.homework_str, self.character as i32); 574 | 575 | //计算平均分 576 | let sum: f64 = self.all_user_strokes_score.iter().sum(); 577 | let avg = sum / self.all_user_strokes_score.len() as f64; 578 | 579 | //格式化时间 580 | let timestamp = crate::current_timestamp(); 581 | //new Date().getTimezoneOffset()/60 582 | let timezone_offset = crate::get_timezone_offset(); 583 | let naive = NaiveDateTime::from_timestamp(timestamp / 1000, 0); 584 | //3600为1小时 585 | let datetime: DateTime = DateTime::from_utc( 586 | naive, 587 | FixedOffset::west(timezone_offset * 3600), 588 | ); 589 | //let newdate = datetime.format("%Y-%m-%d %H:%M:%S"); 590 | //保存练习记录(1条) 591 | let history = History { 592 | avg: format!("{:.1}", avg), 593 | scores: self.all_user_strokes_score.clone(), 594 | date: format!("{}", datetime.format("%Y-%m-%d %H:%M")), 595 | text: self.homework_str.clone(), 596 | strokes: self.all_user_strokes.clone(), 597 | }; 598 | 599 | //保存历史记录 600 | let _ = serialize(&history) 601 | .and_then(|data| Ok(crate::save_file(KEY_HISTORY, data))); 602 | //重新开始 603 | let new_str = self.homework_str.clone(); 604 | self.set_homework(&new_str); 605 | crate::hide_loading(); 606 | //刷新 607 | self.reset_delay(DELAY_IDLE, true); 608 | crate::alert("恭喜", "完成任务了!", &|| {}); 609 | } else { 610 | // 不是最后一个字,提示用户得分!! 611 | let star = if score >= 8.5 { 612 | 3 613 | } else if score >= 7.5 { 614 | 2 615 | } else { 616 | 1 617 | }; 618 | 619 | //提示用户得星 620 | crate::show_custom_toast( 621 | format!("{:.1}分", score), 622 | String::from(match star { 623 | 3 => "/static/star_3.png", 624 | 2 => "/static/star_2.png", 625 | _ => "/static/star_1.png", 626 | }), 627 | 1000, 628 | ); 629 | } 630 | } 631 | }else{ 632 | //log("笔画完成,整字未完成,切换为慢速帧率."); 633 | self.reset_delay(DELAY_IDLE, false); 634 | } 635 | } else { 636 | self.clear_error_stroke(true); 637 | } 638 | } else { 639 | log("笔画太短!"); 640 | self.clear_error_stroke(false); 641 | } 642 | } 643 | 644 | /** 645 | * step: 0 不变,1下一个字符,2上一个字符 646 | */ 647 | pub fn next_character(&mut self, step: i32) -> bool { 648 | if step == 0 { 649 | return false; 650 | } 651 | if step > 0 && self.character >= self.homework.len() { 652 | self.complete = true; 653 | return true; 654 | } 655 | if step < 0 && self.character == 0 { 656 | self.complete = false; 657 | return true; 658 | } 659 | if step > 0 { 660 | self.character += 1; 661 | } else { 662 | self.character -= 1; 663 | } 664 | { 665 | let mut ch = self.homework.get(self.character); 666 | //跳过标点符号 667 | while !ch.is_none() && self.strokes_map.get(&ch.unwrap()).is_none() { 668 | // log(&format!("跳过{}", ch.unwrap())); 669 | 670 | if step > 0 { 671 | self.character += 1; 672 | } else { 673 | self.character -= 1; 674 | } 675 | if self.character < self.homework.len() { 676 | ch = Some(&self.homework[self.character]); 677 | } else { 678 | ch = None; 679 | } 680 | } 681 | if ch.is_none() { 682 | //|| self.strokes_map.get(&ch.unwrap()).is_none() 683 | self.complete = true; 684 | return true; 685 | } 686 | } 687 | 688 | //下一个字 689 | self.stroke_index = 0; 690 | self.create_strokes(); 691 | self.user_strokes.clear(); 692 | self.error_icon = None; 693 | //关闭动画 694 | if self.stroke_animation.is_some() { 695 | self.stroke_animation = None; 696 | } 697 | 698 | //清空笔画 699 | //log("下一个字,切换为慢速帧率."); 700 | self.reset_delay(DELAY_IDLE, true); 701 | // log("已切换到下一个字"); 702 | self.page 703 | .update_homework(&self.homework_str, self.character as i32); 704 | false 705 | } 706 | 707 | pub fn on_pointer_down( 708 | &mut self, 709 | client_x: f64, 710 | client_y: f64, 711 | _offset_x: f64, 712 | _offset_y: f64, 713 | ) { 714 | //log(&format!("on_pointer_down {},{}", client_x, client_y)); 715 | if self.stroke_animation.is_some() { 716 | // log("on_pointer_down>正在动画,不处理"); 717 | return; 718 | } 719 | if self.complete { 720 | // log("on_pointer_down>已完成,不处理"); 721 | return; 722 | } 723 | //创建新的笔画 724 | self.user_strokes 725 | .push(vec![Point::new(client_x, client_y, self.stroke_index + 1)]); 726 | self.writing = true; 727 | } 728 | 729 | pub fn on_pointer_up(&mut self) { 730 | if self.writing { 731 | self.calculate_score(); 732 | } 733 | if self.stroke_animation.is_none(){ 734 | //log("on_pointer_up,切换为慢速帧率."); 735 | self.reset_delay(DELAY_IDLE, false); 736 | } 737 | } 738 | 739 | pub fn on_pointer_move( 740 | &mut self, 741 | client_x: f64, 742 | client_y: f64, 743 | _offset_x: f64, 744 | _offset_y: f64, 745 | ) { 746 | //log(&format!("on_pointer_move {},{}", client_x, client_y)); 747 | if let Some((x1, y1)) = self.last_point{ 748 | let (x2,y2) = (client_x, client_y); 749 | let distance = (((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))).sqrt(); 750 | if distance<5.0{ 751 | //log("距离小于5.0"); 752 | return; 753 | } 754 | } 755 | if self.writing { 756 | self.last_point = Some((client_x, client_y)); 757 | //加入画点 758 | self.user_strokes[self.stroke_index].push(Point::new( 759 | client_x, 760 | client_y, 761 | self.stroke_index + 1, 762 | )); 763 | // if crate::current_timestamp() - self.last_render_time >= 35{ 764 | //self.reset_delay(DELAY_IDLE, true); 765 | // } 766 | self.reset_delay(DELAY_ANIM, false); 767 | }else{ 768 | //log(&format!("on_pointer_move 没有writing,不处理 {},{}", client_x, client_y)); 769 | } 770 | } 771 | } 772 | 773 | //检查字典是否已下载 774 | pub fn check_dict() { 775 | let loaded = CONTROLLER.with(|c| { 776 | c.borrow().dict.is_some() 777 | }); 778 | //检查字典是否加载 779 | if loaded { 780 | search_dict(); 781 | } else { 782 | //读取字典 783 | crate::show_loading("加载字典"); 784 | crate::load_dict(&|data| { 785 | crate::hide_loading(); 786 | match data { 787 | Err(err) => crate::alert("提示", &format!("{:?}", err), &|| {}), 788 | Ok(data) => { 789 | //保存 790 | CONTROLLER.with(|c| { 791 | c.borrow_mut().dict = Some(data); 792 | }); 793 | search_dict(); 794 | } 795 | } 796 | }); 797 | // crate::load_dict(&|data| { 798 | // crate::hide_loading(); 799 | // match data { 800 | // Err(err) => crate::alert("提示", &format!("{:?}", err), &|| {}), 801 | // Ok(data) => { 802 | // //保存 803 | // let decoded: HashMap> = deserialize(&data).unwrap(); 804 | // CONTROLLER.with(|c| { 805 | // c.borrow_mut().dict = Some(decoded); 806 | // }); 807 | // search_dict(); 808 | // } 809 | // } 810 | // }); 811 | } 812 | } 813 | 814 | //读取保存的选择内容 815 | fn get_choose_index() -> Vec{ 816 | match crate::get_storage(KEY_CHOOSE) { 817 | Ok(choose) => deserialize(&choose).unwrap_or(vec![0, 0]), 818 | Err(err) => { 819 | log(&format!("KEY_CHOOSE读取失败 {:?}", err)); 820 | vec![0, 0] 821 | } 822 | } 823 | } 824 | 825 | //根据练习内容的分组类型,读取分组的文章标题列表 826 | fn get_choose_names(group_index:i32) -> Vec{ 827 | CONTROLLER.with(|ctrl| { 828 | let ctrl = ctrl.borrow(); 829 | if group_index == 0 { 830 | //读取课文 831 | ctrl.articls_map.iter().map(|v| v.0.clone()).collect() 832 | } else { 833 | //读取古诗 834 | ctrl.poems_map.iter().map(|v| v.0.clone()).collect() 835 | } 836 | }) 837 | } 838 | 839 | //查询字典 840 | fn search_dict() { 841 | CONTROLLER.with(|ctrl| { 842 | let ctrl = ctrl.borrow(); 843 | let ch = format!("{}", ctrl.homework[ctrl.character]); 844 | if let Some(word) = ctrl.dict.as_ref().unwrap().get(&ch) { 845 | let title = format!("“{}”的字意", ch); 846 | let content = format!( 847 | "{}\r\n笔画:{} 部首:{}\r\n{}", 848 | word.pinyin, word.strokes, word.radicals, word.explanation 849 | ); 850 | crate::show_modal(&title, &content, false, &|| {}, &|| {}); 851 | } else { 852 | crate::alert("提示", "没有这个字", &|| {}); 853 | } 854 | }); 855 | } 856 | 857 | pub fn init(){ 858 | 859 | crate::register_add_feedback(&||{ 860 | crate::show_input("", "笔画错误可在此填写", &|result| { 861 | if result.trim().len() == 0 { 862 | crate::show_toast("请输入反馈内容", 1000, false, None); 863 | return; 864 | } 865 | 866 | crate::confirm_str("提交确认", "确定要提交反馈内容吗?", &result, &|result:String|{ 867 | crate::show_loading("正在提交"); 868 | crate::add_feedback(result.trim(), &|success|{ 869 | crate::hide_loading(); 870 | if success{ 871 | crate::show_toast("提交成功", 1500, false, None); 872 | }else{ 873 | crate::show_modal("提示", "提交失败", false, &|| {}, &|| {}); 874 | } 875 | }); 876 | }, &||{ 877 | 878 | }); 879 | }); 880 | }); 881 | 882 | crate::register_query_dict_listener(&|| { 883 | check_dict(); 884 | }); 885 | 886 | crate::register_previous(&|| { 887 | CONTROLLER.with(|c| { 888 | let is_first = c.borrow_mut().next_character(-1); 889 | if is_first { 890 | crate::alert("提示", "已经到第一个字了", &|| {}); 891 | } 892 | }); 893 | }); 894 | 895 | crate::register_stroke_anim_listener(&|| { 896 | CONTROLLER.with(|c| { 897 | c.borrow_mut().stroke_anim(); 898 | }); 899 | }); 900 | 901 | crate::register_on_touchstart(&|client_x: f64, 902 | client_y: f64, 903 | offset_x: f64, 904 | offset_y: f64| { 905 | CONTROLLER.with(|c| { 906 | c.borrow_mut().on_pointer_down(client_x, client_y, offset_x, offset_y); 907 | }); 908 | }); 909 | 910 | crate::register_on_touchmove(&|client_x: f64, 911 | client_y: f64, 912 | offset_x: f64, 913 | offset_y: f64| { 914 | CONTROLLER.with(|c| { 915 | c.borrow_mut().on_pointer_move(client_x, client_y, offset_x, offset_y); 916 | }); 917 | }); 918 | 919 | crate::register_history_listener(&|| { 920 | //读取历史记录 921 | crate::show_loading("正在加载"); 922 | crate::read_file(KEY_HISTORY, &|res| { 923 | crate::hide_loading(); 924 | if let Ok(data) = res { 925 | match deserialize(&data) { 926 | Ok(history) => { 927 | crate::show_history(history, 0); 928 | } 929 | Err(err) => { 930 | log(&format!("历史记录读取失败 {:?}", err)); 931 | crate::show_toast("读取失败", 1000, false, None); 932 | } 933 | } 934 | } else { 935 | crate::alert("提示", "暂无练习记录", &|| {}); 936 | //crate::show_toast("暂无记录", 1000, false, None); 937 | } 938 | }); 939 | }); 940 | 941 | crate::register_show_input(&|| { 942 | let input: String = match &crate::get_storage(KEY_INPUTS) { 943 | Ok(saved) => deserialize(&saved).unwrap(), 944 | Err(err) => { 945 | log(&format!( 946 | ">>>>>>>>register_show_input get_storage {:?}", 947 | err 948 | )); 949 | String::new() 950 | } 951 | }; 952 | crate::show_input(&input, "输入练习内容", &|result| { 953 | crate::hide_input(); 954 | if result.trim().len() == 0 { 955 | return; 956 | } 957 | //保存输入历史和作业内容 958 | if let Err(err) = crate::set_storage(KEY_INPUTS, serialize(&result).unwrap()) { 959 | log(&format!("inputs保存失败!{:?}", err)); 960 | } 961 | CONTROLLER.with(|c| { 962 | c.borrow_mut().set_homework(&result); 963 | }); 964 | }); 965 | }); 966 | 967 | crate::register_search_title(&|text|{ 968 | //读取保存得选项记录 969 | let mut choose = get_choose_index(); 970 | let names: Vec = get_choose_names(choose[0]); 971 | for j in 0..names.len(){ 972 | if names[j].contains(&text){ 973 | choose[1] = j as i32; 974 | break; 975 | } 976 | } 977 | crate::show_choose(None, choose[0], None, choose[1], None); 978 | }); 979 | 980 | crate::register_show_choose(&|| { 981 | //读取保存得选项记录 982 | let choose = get_choose_index(); 983 | 984 | let groups = vec!["课文".into(), "古诗".into()]; 985 | 986 | let names: Vec = get_choose_names(choose[0]); 987 | 988 | crate::show_choose( 989 | Some(groups), 990 | choose[0], 991 | Some(names), 992 | choose[1], 993 | //选择完成 994 | Some(( 995 | &|group_id, name_id| { 996 | CONTROLLER.with(|c| { 997 | let mut ctrl = c.borrow_mut(); 998 | //设置选择的练习内容 999 | let homework = if group_id == 0 { 1000 | ctrl.articls 1001 | .get(&ctrl.articls_map[name_id as usize].1) 1002 | .unwrap() 1003 | .clone() 1004 | } else { 1005 | ctrl.poems 1006 | .get(&ctrl.poems_map[name_id as usize].1) 1007 | .unwrap() 1008 | .clone() 1009 | }; 1010 | ctrl.set_homework(&homework); 1011 | }); 1012 | 1013 | //保存选择内容 1014 | let _ = serialize(&vec![group_id, name_id]) 1015 | .and_then(|data| Ok(crate::set_storage(KEY_CHOOSE, data))); 1016 | }, 1017 | &|old_group_id, _old_name_id, new_group_id, new_name_id| { 1018 | let groups: Vec = vec!["课文".into(), "古诗".into()]; 1019 | 1020 | let names = if old_group_id == new_group_id { 1021 | None 1022 | } else { 1023 | Some(get_choose_names(new_group_id)) 1024 | }; 1025 | crate::show_choose(Some(groups), new_group_id, names, new_name_id, None); 1026 | //保存选择内容 1027 | let _ = serialize(&vec![new_group_id, new_name_id]) 1028 | .and_then(|data| Ok(crate::set_storage(KEY_CHOOSE, data))); 1029 | }, 1030 | )), 1031 | ); 1032 | }); 1033 | 1034 | crate::register_on_touchend(&|| { 1035 | CONTROLLER.with(|c| { 1036 | c.borrow_mut().on_pointer_up(); 1037 | }); 1038 | }); 1039 | 1040 | crate::register_on_touchcancel(&|| { 1041 | CONTROLLER.with(|c| { 1042 | c.borrow_mut().on_pointer_up(); 1043 | }); 1044 | }); 1045 | 1046 | crate::register_on_ready_listener(&|| { 1047 | CONTROLLER.with(|c| { 1048 | c.borrow_mut().on_ready(); 1049 | }); 1050 | }); 1051 | 1052 | crate::register_eraser_listener(&|| { 1053 | CONTROLLER.with(|c| { 1054 | let mut ctrl = c.borrow_mut(); 1055 | if ctrl.stroke_animation.is_some() || ctrl.user_strokes.len() == 0 { 1056 | //提示橡皮擦出文字 1057 | crate::show_toast("橡皮擦", 1000, false, None); 1058 | } else { 1059 | ctrl.rewrite(); 1060 | } 1061 | }); 1062 | }); 1063 | } -------------------------------------------------------------------------------- /teacher/src/web.rs: -------------------------------------------------------------------------------- 1 | //网页实现 2 | --------------------------------------------------------------------------------