Markdown 2 - simon9k/stackedit GitHub Wiki
- https://moodle.org/, 一个网上教育的网站,提供opensource的网校解决方案(Moodle是一个课程管理系统。一个利用健全的教育原则)
- prototype是提供一种动态方式,改变object的定义,包括为object提供新的property/function;这种动态的方式,是JS面向对象的方式,为复杂的系统开发提供了手段。注意这里this的用法,代表了这个object
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
}
Person.prototype.name = function() {
return this.firstName + " " + this.lastName;
};
- 对页面的各种元素,进行了object化,这样可以通过编程方式,灵活设置它们的属性/style/响应函数等
- public/res/layout.js
- 下面方法,给answer Input增加lisener
// 获取文档中的所有元素的列表
var elements = document.getElementsByTagName('button');
// 将bluify作为元素的点击监听函数,当元素被点击时,就会变成蓝色
for(var i=0 ; i<elements.length ; i++){
elements[i].addEventListener('click', bluify, false);
- 藏:永久保存+使用者看不见
- MD文件是要下载到客户端的,即使在“答题”阶段,也是先下载到browser中,再由browser解析生成html展示出来。那么browers即包含有answer,并可以加以利用;所以,判题等过程,也是由整个web页完成,而非MD生成的html独立完成;所以,不必在生成的html中插入JScript,和answer,而是在主页中增加处理功能,现有设计的<@>方式已经可以实现藏的功能。
- MD文件中已经保存了answer,需要每次运行考试前,进行answer提取,用以进行答题判定;
- 国际教育领域,比如是google homework的用户,可能对该系统更感兴趣;
- UUID生成https://github.com/broofa/node-uuid
function generateUUID(){
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (d + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c=='x' ? r : (r&0x7|0x8)).toString(16);
});
return uuid;
};
- Extentions/answearConverter.js:编写,实现插入"答题框/答案";
- 试题预览模式:做题(做题目状态:可填写/无答案),批改(不可修改,显示对错/正确答案),答案(不可编辑,正确答案突出显示在输入框中)
- 存在问题:如果进行答题/批改,就改变了MD输出文件的状态,如果载进行MD文件编辑,对应的预览又该如何变化?
- C#web:展示MD文件,客户端convert,然后check,上传结果
- RegExp:使用行内函数来修改匹配的字符,可以用来将答案提出,并形成input,该项任务是OK的;
- input:格式化(宽度/输入控制等),采用预先设定CSS+自定义?
- 需要多种答案:数字/整数/block大段文字
- 如何简化编写是要点
- 答案的编号
- jmcmanus/pagedown-extra是stackedit基础项目;
- extentions/santinizer.js 通过whitelist控制转换为安全的HTML,在此增加'input'后,输入框可以显示出来了
// Safe Block Elements - HTML5
var blockElements = _.extend({}, optionalEndTagBlockElements, makeMap("address,article," +
"aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," +
"h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));
- extention的hook机制还不了解
- 学习RegExp
- 改编emailConverter.js:可以成功实现新的替换,但是如果插入的是,将不会出现在最终生成的html中,应该是被拦截了;
-
return text.replace(/<(mailto\:)?([^\s>]+@[^\s>]+\.\S+?)>/g, function(match, mailto, email) {其中的math/mailto/email几个参数在哪里定义和赋值的?看不懂:这是String.replace的一种应用方式,即用函数来替换,本身这里的RegExp有多个可保留的子匹配项(一个正则表达式模式使用括号,将导致相应的子匹配被记住)
- 参考“developer-guider.md中段落: PageDown events
onPagedownConfigure(editor) - 参考其它extention
- 整个在做作业时,类似google codelab (讲解)中一步步完成题目
-
实现一个小的extention
-
添加button
-
引出preview窗体
-
变更整体布局
-
嵌入到Csharp project中
-
how to load default welcome MD file by
fileMgr.js(loaded the "WELCOME.md")
...
"text!WELCOME.md"
], function($, _, constants, core, utils, storage, settings, eventMgr, fileSystem, FileDescriptor, welcomeContent) {
...
if(fileDesc === undefined) {
var fileSystemSize = _.size(fileSystem);
if(fileSystemSize === 0) {
// If fileSystem empty create one file
fileDesc = fileMgr.createFile(constants.WELCOME_DOCUMENT_TITLE, welcomeContent);
}
- core.js 中的,"text!html/bodyViewer.html"等,引出了相关页面:/public/res/html/bodyViewer.html
- res/main.js
- rangy: 一个选中处理的框架
- core.js: 这看来是一个关键,editor.js的上一层,一直困惑如何调用editor的在这里;
- Node server.js:
- require package,cluster/http/https, and app,注:443port,是https主端口
- app,针对当前web应用的代码在此包中执行
- 生成https/http server:如果是https,还是会同时生成http服务器;
- 整体框架如此,服务器就生成了,下一步要研究./app/index.js, 这是node包app的主运行js
- ./app/index.js, Express框架
- 这是服务端框架
- ejs.all,.use,.get,.post等,其实都是route,
- res.renderDebug, 是本应用特别的对respond.render的再次封装;由于每一次http请求的响应都是新生成的对象,说以要每次都对该次的res重新生成该function
- app.engine('html', require('ejs').renderFile);渲染引擎是html的,不是其它非标准带嵌入代码的框架;
- 下一步则是研究editor.html即可
- editor.html (全部是客户端JS)
- 其中window.baseDir,window.require,是在本文件无显示(var)定义的全局变量,同时赋值了;
- /(?|&)debug($|&)/, 是一个正则表达式,也是一个对象,自己直接可以调用正则表达式对象的方法test(),用以验证表达式是否包含相关字符串;
- location.search 属性是一个可读可写的字符串,可设置或返回当前 URL 的查询部分(问号 ? 之后的部分)。
- 根据requierJS规范,在定义了window.require={}后,require.js的引用代码根据相关配置,开始执行;
- require.baseUrl如何指向public目录还是没有搞清楚(没有../指向当前editor的上级目录,以及public这个下级目录;应该是
app.use(serveStatic(__dirname + '/../public'));实现指定该目录(这是服务器端实现) - 果然,根据上述分析:1.纯html;2.纯JS(采用客户端requireJS);3.指定目录需要手动调整(即将editor.html拷贝到/public/目录下,4.单击editor.html,即可成功打开正常运行
- 根据window.require的赋值,deps说明要先载入main.js
- NPM:安装nodejs同时自动附带安装;在下载stackeditor项目后,在项目目录下执行NPM,将会根据pakage.json自动下载依赖项目,如下:
Which version of the package is installed?
If there is no package.json file in the local directory, the latest version of the package is installed.
If there is package.json file, the latest version satisfying the semver rule declared in package.json for that package (if there is any) is installed.
- stackedit 采用express这样的web framework,如果不准备用JS的服务端(nodejs或者express),可了解其基本知识后,引导到web页面的加载启动,以便仅了解页面JS的功能实现机制
- node server.js: server.js中
var app = require('./app');,直接指到'./app/index.js - packadge.json: 表示stackeditor本身也可以作为包,为其它项目所用? 那么其中的
"main": "res/main.js"所指定的目录不太对啊,没有完整的路径,应该是"./public/res/main.js",这个要继续研究。 - 本地安装的stackeditor(可以成功启动web服务的)与本git项目中的文档目录结构有差异,比如多了一个"node_modules",这个应该是采用NMP下载下来的,这一块还是比较混乱,对整个管理架构不了解(安装/部署/调试)。
- stakeditor本身以包形式提供整体解决方案,如果是这样,改编应用的方式将大变,不用再参考其演示web去实现,而是可以直接引用该包,利用包释放出来的功能,实现MD的编辑等;当然这个包是node的,除非要采用node服务器端,:(((
- NMP/bower, stackedit,都可以安装,还没成功,回头看看是什么
从NPM网站上found stackedit,不知道这个package是如何运作的。
https://www.npmjs.com/package/stackedit
用NMP安装stackedit成功的,应该是,在执行C:\inetpub>npm install stackedit后,C:\inetpub>node_modules目录生成了,package.json中dependence都在下面,并且,发现C:\inetpub\node_modules\stackedit目录,下面的内容和github上一致。
bower安装失败,应该是由于没有以管理员方式运行,下载了,但是无法创建目录进行存储;
stackedit应该是NPM(有package.json)和bower都采用了,原因如下:
为什么有很多项目 bower 和 npm 都用呢,那是因为要用 bower 管理前端的包,而用 npm 去管理一些后端的包和构建工具,例如,yeoman,grunt,gulp,jshint 等等等等。
- CJS vs AMD:
- NodeJS符合CJS,偏重服务端,有明确的export等指示,比较传统和清晰;
- requireJS是推荐AMD的,偏重浏览器端,相对抽象一点,不过关于所谓全局require,局部require的混淆,我是觉得稍微有点晕;
- 两种规范目的是解决松耦合包的管理/加载
- stackedit/app/index.js,还是应该认真研究
// Serve landing.html in /
app.get('/', function(req, res) {
res.renderDebug('landing.html');
});
// Serve editor.html in /viewer
app.get('/editor', function(req, res) {
res.renderDebug('editor.html');
});
- AMD Patten,读起来费劲,说明水平真的菜菜
- staskeditor是如何构建editor页面的,研究该页面如何构造实现相应功能,也就可以参考如何改造;对于需要服务端完成的功能,如PDF等,可以暂不考虑实现;
- public/res/layout.js,对editor窗体的整体控制,在这里
- editor.html中设定了baseUrl, debug or !debug, 分别对应到(public/)res or res-min,查阅两个目录大小,res-min目录仅4M,而res高达70M,这应该是minify的效果。奇怪的是pubic目录没有明确指定,而editor.html和require.js并不在同一个目录,困惑是如何引导到public/res,res-min的?
- editor.html的code明确指定了main.js
window.require = {
baseUrl: window.baseDir,
deps: ['main']
};
- 最简单的extension可以参考实现:public/res/extensions/emailConverter.js
- 重新安装stackeditor,用debug方式访问
- 编写js包,用requireJS管理,optimization,访问
- 采用nodejs:可以跨平台,提供了JS为基础的服务器;
- 采用npm:管理需要的第三方资源;如果其他人要fork等,即可以方便的自动下载相关资源;
- requireJS:实现复杂的package管理;本身构成复杂,各个package功能划分开,一个优秀的架构;
- requireJS:提供minify等功能
- 在这些架构下:开发(code/debug),发布,测试,运行,变更,等全方面都考虑到了;
- 从server.js开始,看看服务端启动,再到主页,了解主页的加载以及实现
- anatomy of an HTTP Transaction: 一个httpserver,提供若干框架功能,如request/respond/err/pipe等的处理,有点CGI的味道
- 自带profiler的应用,以发现系统瓶颈(某某函数占用99%系统CPU资源)
- 从server.js->./app/index.js(采用express框架)->./view/editor.html,希望规避掉nodejs/express等框架,直接到页面的实现,这个页面仅看见requireyJS的script,看来又得学习requirey了,它用来装载复杂的js实现:(
- requireJS研究:服务端(nodejs),web端都可以
- 通过homework关键字search,发现不少相关管理website,app,但是在作业方面,停留在Download/upload files阶段;
- stackedit的难度越来越大,随着深入一点学习发现,每一个点都扩展成一个大面:(
- 从NodeJS开始,了解系统启动运行机制
- 用c#实现RegEpr的答案机制
- gulp是一个杂务处理工具,帮助打包/压缩/更新依赖/发布等系统维护工作;
- Ace是本项目的基础实现(editor的),以便在editor过程中就可以代码highlight/格式化等,这个是个github编辑器没有的,马克飞象有;
- pagedown是本项目的基础,Markdown convertor (editor&convert)的实现;
- 整个应用的UI框架,由UILayout实现
- 如何扩展功能(加入Answer)
- 如何嵌入到大系统中
- 系统概要设计(quiz)
- 下载nodeJS(.msi)安装 (npm安装目录加入到path中,可以全局命令行模式下运行)
- 安装git(官网下载安装,否则安装gulp要失败。nodeJS采用git来下载东东)
- 安装bower (npm install -g bower)
C:\inetpub\stackedit-master>npm install -g bower
C:\Users\simon9k\AppData\Roaming\npm\bower -> C:\Users\simon9k\AppData\Roaming\npm\node_modules\bower\bin\bower
C:\Users\simon9k\AppData\Roaming\npm
`-- [email protected]
命令行是用管理员运行的,这样才可以成功创建相关目录,否则安装会失败。 bower 安装很顺利好像下载很快,不想前面安装gulp,很慢
- 安装相关包
bower install
也比较顺利,下载了一段时间,不过总是不断滚动提示,最后显示安装成功一堆包。 bower命令应该在相应项目文件下运行(以便打开包说明.json文件,以此确认需下载包)
bower crel#8dbda04b129fc0aec01a2a080d1cab26816e11c1 install crel#8dbda04b12
bower MutationObservers#~0.2.1 install MutationObservers#0.2.4
bower to-markdown#jquery install to-markdown#28ffe20ede
bower yaml.js#~0.1.4 install yaml.js#0.1.6
bower requirejs#~2.1.11 install requirejs#2.1.22
bower alertify.js#fc2e06fa39873363dda199204b8544119ab060bf install alertify.js#fc2e06fa39
bower google-diff-match-patch-js#~1.0.0 install google-diff-match-patch-js#1.0.0
bower js-sequence-diagrams#c59e2e39d9185e9291f37b73fc596eba5ed33650 install js-sequence-diagrams#c59e2e39d9
bower FileSaver#* install FileSaver#1.3.3
bower monetizejs#~0.2.0 install monetizejs#0.2.0
bower bootstrap-tour#~0.7.1 install bootstrap-tour#0.7.3
bower requirejs-text#~2.0.10 install requirejs-text#2.0.15
bower flowchart#751717d3db6437def9a5f8b1cb73e8bb81b5833a install flowchart#751717d3db
bower prism#a12e8692b5f660a0123a06f74935f75386a93042 install prism#a12e8692b5
bower pagedown-extra#ea782c3d11eb78f57d00aa819527338996a70721 install pagedown-extra#ea782c3d11
bower rangy#~1.2.3 install rangy#1.2.3
bower require-css#0.1.5 install require-css#0.1.5
bower xregexp#300157f34b39b15b7b0dba7608955945d53e61b9 install xregexp#300157f34b
bower WeakMap#0.2.4 install WeakMap#0.2.4
bower waitForImages#~1.4.2 install waitForImages#1.4.2
bower jsondiffpatch#fb9dddf7cd076d8ec89d376c0e9de9223e9888f9 install jsondiffpatch#fb9dddf7cd
bower jgrowl#~1.2.10 install jgrowl#1.2.13
bower require-less#0.1.2 install require-less#0.1.2
bower raphael#~2.1.2 install raphael#2.1.4
bower mousetrap#~1.4.4 install mousetrap#1.4.6
bower underscore#1.5.1 install underscore#1.5.1
bower jquery#2.0.3 install jquery#2.0.3
bower bootstrap#3.0.3 install bootstrap#3.0.3
bower hammerjs#~1.0.10 install hammerjs#1.0.11
bower google-code-prettify#~1.0.0 install google-code-prettify#1.0.5
bower stacktrace#~0.6.2 install stacktrace#0.6.4
bower MathJax#2.6.1 install MathJax#2.6.1
- 启动服务器
set port=80
node server.js
应该在server.js文件所属文件夹下运行