├── .gitignore
├── .npmignore
├── README.md
├── artwork
├── icon1_1.png
├── icon1_2.png
├── icon2.png
├── icon_400x400.png
└── markppt.psd
├── bin
└── cli.js
├── examples
├── gulpeol
│ ├── bug
│ │ ├── close.png
│ │ ├── gulp-plugins.png
│ │ ├── notification.png
│ │ ├── reference.png
│ │ └── thanks.png
│ └── gulp-eol-bug.md
├── kidjs
│ └── kidjs.md
└── mytalk
│ ├── Desert.jpg
│ └── talk.md
├── index.js
├── package.json
├── screenshots
├── 2015-04-10 23.17.37.png
├── 2015-04-11 02.09.47.png
├── 20150901233430.png
├── 20150901233453.png
├── 20150901234930.png
└── 20150901235103.png
└── web
├── ppt.hbs
└── ppt_
├── animate.min.css
├── arrow_up.png
├── censorship.worker.js
├── highlight.pack.js
├── highlight.railscasts.css
├── icon_400x400.png
├── jquery.min.js
├── jquery.waitforimages.min.js
├── marked.min.js
├── oops.md
├── ppt.css
├── ppt.js
├── purify.min.js
└── randomColor.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | tmp
3 | examples/**/ppt_
4 | examples/**/*.html
5 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | tmp
2 | examples/**/ppt_
3 | examples/**/*.html
4 | examples/gulpeol
5 | artwork
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # markppt
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | ## 一篇markdown,一份ppt。
12 |
13 | - 一个读取markdown文件,生成网页slides/ppt的工具
14 | - 很多时候,我们用markdown来书写我们的人生
15 | - 很多时候,我们需要有一份ppt来向世界分享观点
16 | - 网页实现,处处发布,随机背景色,css3动画切换
17 | - 超响应式布局,自动缩放,不再畏惧屏幕尺寸
18 | - 智能无缝分页匹配,无需更改markdown原文
19 |
20 | 点击查看演示
21 |
22 | - [node.js技术交流会 (dark)](http://fritx.github.io/markppt/nodejs-talk/)
23 | - [gulp-eol bug之总结 (bright)](http://fritx.github.io/markppt/gulpeol/gulp-eol-bug.html)
24 | - [My Talk (bright)](http://fritx.github.io/markppt/mytalk/talk.html)
25 | - [Kid.js (light)](http://fritx.github.io/markppt/kidjs/kidjs.html)
26 |
27 | ```plain
28 | $ npm i -g markppt # 从npm安装
29 | $ markppt mytalk/talk.md # markdown路径
30 | $ markppt mytalk/talk.md --theme=light # 指定css主题
31 | $ markppt mytalk/talk.md --theme=bright # 默认取dark
32 | $ markppt mytalk/talk.md --color=green # 指定主色调
33 | ```
34 |
35 | 将会在[原目录](https://github.com/fritx/markppt/tree/master/examples/mytalk/)
36 |
37 | ```plain
38 | - mytalk/
39 | - Desert.jpg
40 | - talk.md
41 | ```
42 |
43 | 生成`ppt_`文件夹,和一份`talk.html`,打开即可[浏览ppt](http://fritx.github.io/markppt/mytalk/talk.html)
44 |
45 | ```plain
46 | - mytalk/
47 | - ppt_/ (√)
48 | - Desert.jpg
49 | - talk.md
50 | - talk.html (√)
51 | ```
52 |
53 | 常见问题解答
54 |
55 | - [运行无报错输出,但是打开html空白 #8](https://github.com/fritx/markppt/issues/8)
56 |
57 | 高级功能:支持url参数指定任意md路径(自带内容审查机制,不合规则跳转Oops..)
58 |
59 | ```sh
60 | $ markppt index.md --arbitrary # index.md为默认页面 文件不存在也ok
61 | # 然后可指定任意md路径,如 http://xxx/?url=xxx/talk.md
62 | # 或其他绝对路径,如 http://xxx/?url=https://raw.githubusercontent.com/fritx/markppt/dev/examples/mytalk/talk.md
63 | # 或 http://xxx/?url=https://fastly.jsdelivr.net/gh/fritx/markppt@dev/examples/mytalk/talk.md
64 | ```
65 |
--------------------------------------------------------------------------------
/artwork/icon1_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/artwork/icon1_1.png
--------------------------------------------------------------------------------
/artwork/icon1_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/artwork/icon1_2.png
--------------------------------------------------------------------------------
/artwork/icon2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/artwork/icon2.png
--------------------------------------------------------------------------------
/artwork/icon_400x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/artwork/icon_400x400.png
--------------------------------------------------------------------------------
/artwork/markppt.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/artwork/markppt.psd
--------------------------------------------------------------------------------
/bin/cli.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | var minimist = require('minimist')
3 | var markppt = require('../')
4 |
5 | var args = minimist(process.argv.slice(2))
6 | var file = args._[0]
7 |
8 | if (!file) {
9 | console.error('filename required.')
10 | return
11 | }
12 |
13 | // todo: 更多选项及较好的传递方式
14 | markppt.build(file, {
15 | arbitrary: args['arbitrary'],
16 | color: args['color'],
17 | theme: args['theme']
18 | })
19 |
--------------------------------------------------------------------------------
/examples/gulpeol/bug/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/examples/gulpeol/bug/close.png
--------------------------------------------------------------------------------
/examples/gulpeol/bug/gulp-plugins.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/examples/gulpeol/bug/gulp-plugins.png
--------------------------------------------------------------------------------
/examples/gulpeol/bug/notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/examples/gulpeol/bug/notification.png
--------------------------------------------------------------------------------
/examples/gulpeol/bug/reference.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/examples/gulpeol/bug/reference.png
--------------------------------------------------------------------------------
/examples/gulpeol/bug/thanks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/examples/gulpeol/bug/thanks.png
--------------------------------------------------------------------------------
/examples/gulpeol/gulp-eol-bug.md:
--------------------------------------------------------------------------------
1 | # gulp-eol bug修复之总结
2 |
3 | *2014-09-06*
4 |
5 | ## 背景
6 |
7 | [gulp-eol][1]是我之前写的一个gulp插件,主要用于统一文件的换行符。
8 |
9 | 今早打开github,发现一俄国人跑来我这开[issue][2],说是复制/转移文件时,插件失效了,还贴出了他的gulpfile。
10 |
11 |
12 |
13 | 下午happy完回来,发现是自己程序的bug,修复后发布,并告知事主[@truetamtam][3]确认,tam很快说问题解决了,皆大欢喜。
14 |
15 | ## 我想说
16 |
17 | 凡事都应**以小见大**,这样才能进步成长。我列出了7点,不多。
18 |
19 | ### 1. 粗心大意
20 |
21 | 此bug乃低级错误:
22 |
23 | ```js
24 | str = str.replace(/\r?\n/g, eol);
25 | if (append && !(
26 | new RegExp(eol + '$').test(str))
27 | ) {
28 | // this statement should be always executed
29 | // but not remained here
30 | file.contents = new Buffer(str + eol);
31 | }
32 | ```
33 |
34 | 我错将一个关键的赋值逻辑放入了`if(){}`中,加之测试覆盖不全,导致bug埋藏许久。
35 |
36 | ### 2. 心存感激
37 |
38 | 整个issue下来,共6次发言,我和tam各3次。我们的发言基本上都带有感谢或友好。虽然这大多时候只是一种礼节,但我相信大家都是一样,发自内心地享受友爱和互助。
39 |
40 | 我甚至在[代码更新][4]中“慷慨激昂”地道谢:
41 |
42 |
43 |
44 | ### 3. 明于展示
45 |
46 | > Talk is cheap, show me the code!
47 |
48 | 相信大家都知道这句it界的名言,口说无凭,很多时候我们需要用代码、用实例来说明问题。在这一点上,我和tam都是做的不错的:
49 |
50 | - 问题提出时,他贴上了gulpfile,便于我对环境的了解
51 | - bug初步确定时,我给出了简短的源码注解(同1.),表达了自己的判断
52 |
53 | ### 4. 巧于引用
54 |
55 |
56 |
57 | bug修复后,在提交描述中提及issue的编号,如"#1",issue页会及时地追加一条标签。虽然这只是github一个简单的功能,但它发挥着关键作用:
58 |
59 | - 通知:及时明确地展示提交描述
60 | - 关联:精确链接到具体的代码改动
61 | - 简明:就具体的代码改动,你已无需额外发言阐述
62 |
63 | 另外,我用了"for #1",而不是"fix #1"。因为此bug与事主的实例并无绝对联系,当时只是初步判定,用"for"可以在引用issue的同时,不close掉它。
64 |
65 | ### 5. 堪称典范
66 |
67 | > 整个issue下来,共6次发言,我和tam各3次
68 |
69 | 是的,加上3次操作,共9步,让我们来回顾一下:
70 |
71 | 1. tam:提出问题,贴出实例
72 | 1. 我:表示迟点回应,感谢
73 | 1. 我:(发现有bug,贴上bug标签)
74 | 1. 我:表示已有初步判定,贴出注解,预告更新,感谢
75 | 1. tam:酷,感谢
76 | 1. 我:(提交更新,引用issue)
77 | 1. 我:告知已发布,要求确认
78 | 1. tam:表示确认,感谢
79 | 1. tam:(关闭issue)
80 |
81 |
82 |
83 | ---
84 |
85 | 别看这区区小issue,它包括了扼要的表达、精准的操作,包括了:
86 |
87 | 1. 提出议题,描述问题
88 | 1. 初步回应
89 | 1. 问题分类确定
90 | 1. 症结确定和描述
91 | 1. 预告更新
92 | 1. 更新提交和描述
93 | 1. 更新告知,要求确认
94 | 1. 问题解决确认
95 | 1. 关闭议题
96 |
97 | 这简直就是issue的标杆、模板与典范。感谢tam的配合。
98 |
99 | ### 6. 猜想成立
100 |
101 | 之前接触grunt/gulp这批新兴的构建工具,见识了琳琅满目的插件,加之web开发者的冲劲有目共睹,有了以下猜想:
102 |
103 | - 复制/编译/压缩/测试,还有什么gulp不能做?
104 | - gulp能做很多,将存在不少未开发甚至未知的插件
105 | - 发现并开发出来,有类似需求的人会主动来前来使用
106 |
107 | 短短几行代码,gulp-eol写好发布,未作任何推广,自己没用几次,几个月后竟有人“自投罗网”。事实证明,我的猜想是对的。
108 |
109 |
110 |
111 | ### 7. 关于github
112 |
113 | 在同学之中,[我在github](https://github.com/fritx)上的活跃度和“功绩”应属最佳。这得益于web开发者(尤其是web前端)一贯的开源氛围。
114 |
115 | 以前是我找老外,提issue,现在也逐渐变成了他们找我。非常享受跟他们一起交流学习。当然,与国人、同学也是一样。
116 |
117 | github能给你以“虚荣”:
118 |
119 | - “嘿,npm排行第2的aysnc库,我可是[top6/89][5]的贡献者。”
120 | - “用过zepto?” “不但用过,还参与开发,[top68/151][6]。”
121 |
122 | github虽不是全部,但也是一种角度。据我所知,不少it公司,包括我们公司,都非常重视应聘者的github。多点使用github,尽可能开采它的功能吧。Just for fun!
123 |
124 | ## 结语
125 |
126 | 想提升**吹牛技艺**的可以联系本人。
127 |
128 | 注意,全文并未提及“装B”二字。
129 |
130 | [1]: https://github.com/fritx/gulp-eol
131 | [2]: https://github.com/fritx/gulp-eol/issues/1
132 | [3]: https://github.com/truetamtam
133 | [4]: https://github.com/fritx/gulp-eol/commit/86018672a37cfaa49ebb7f7c20bf9136b0add43a
134 | [5]: https://github.com/caolan/async/graphs/contributors
135 | [6]: https://github.com/madrobby/zepto/graphs/contributors
--------------------------------------------------------------------------------
/examples/kidjs/kidjs.md:
--------------------------------------------------------------------------------
1 | # kid.js
2 |
3 | > Another Browser-side Module Loader.
4 |
5 | Source Code: [fritx/kid.js](https://github.com/fritx/kid.js)
6 |
7 | ## Kid.js vs Sea.js vs Require.js
8 |
9 | | | Kid.js | Sea.js | Require.js |
10 | | :---: | :---: | :---: | :---: |
11 | | Style | \- | CMD | AMD |
12 | | IE Comp | IE9+ | IE5.5+ | IE6+ |
13 | | Symbol | `kid` | `seajs` | `require` |
14 | | Size | <1K | 6.8K | 15.2K |
15 | | Sandbox | No | Yes | Yes |
16 | | Dep Repack | No | Yes | Yes |
17 |
18 | Kid.js implements only dynamically loading, no AMD/CMD.
19 |
20 | ## Usage
21 |
22 | ```js
23 | kid.config({
24 | base: 'scripts/',
25 | alias: {
26 | 'underscore': ['underscore.js', 'underscore.string.js'],
27 | 'jquery': 'jquery/2.0.0/jquery.js',
28 | 'jquery.cookie': 'jquery.cookie/index.js'
29 | }
30 | });
31 |
32 | // they work asynchronously
33 |
34 | kid.use(['jquery', 'jquery.cookie'], function () {
35 | console.log($);
36 | console.log($.cookie);
37 | });
38 |
39 | kid.use(['underscore'], function () {
40 | console.log(_);
41 | console.log(_.string);
42 | });
43 | ```
44 |
45 | Also see [examples/](https://github.com/fritx/kid.js/tree/master/examples)
46 |
--------------------------------------------------------------------------------
/examples/mytalk/Desert.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/examples/mytalk/Desert.jpg
--------------------------------------------------------------------------------
/examples/mytalk/talk.md:
--------------------------------------------------------------------------------
1 | # Talk
2 |
3 | *Date*
4 |
5 | ## Heading 1
6 |
7 | Paragraph 1
8 |
9 | Paragraph 1-1
10 |
11 | ## Heading 2
12 |
13 | 
14 |
15 | Paragraph 2
16 |
17 | ## Heading 3
18 |
19 | Paragraph 3
20 |
21 | - Item 3-1
22 | - Item 3-2
23 | - Item 3-3
24 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs-extra')
2 | var path = require('path')
3 | var Handlebars = require('handlebars')
4 |
5 | exports.build = build
6 |
7 | function build (file, opt) {
8 | if (!opt.theme) opt.theme = 'dark'
9 |
10 | var basename = path.basename(file) // => index.md
11 | var baseseg = basename.split('.')[0] // => index
12 | opt.url = basename
13 |
14 | var source = fs.readFileSync(path.join(__dirname, './web/ppt.hbs'), {encoding: 'utf8'})
15 | var template = Handlebars.compile(source, {noEscape: true})
16 | var out = template({'opt': JSON.stringify(opt)})
17 |
18 | var dir = path.dirname(file)
19 | fs.copySync(path.resolve(__dirname, 'web', 'ppt_'), path.resolve(dir, 'ppt_'))
20 | fs.writeFileSync(path.resolve(dir, baseseg + '.html'), out) // => index.html
21 | }
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "markppt",
3 | "version": "0.1.3",
4 | "description": "一篇markdown,一份ppt。",
5 | "license": "MIT",
6 | "files": ["bin", "web"],
7 | "keywords": [
8 | "ppt",
9 | "slides",
10 | "markdown",
11 | "markppt"
12 | ],
13 | "repository": "git@github.com:fritx/markppt.git",
14 | "main": "index.js",
15 | "bin": {
16 | "markppt": "bin/cli.js"
17 | },
18 | "scripts": {
19 | "prepublishOnly": "dos2unix bin/**"
20 | },
21 | "dependencies": {
22 | "fs-extra": "^0.23.1",
23 | "handlebars": "^4.7.8",
24 | "minimist": "^1.1.3"
25 | },
26 | "devDependencies": {
27 | "dos2unix-cli": "^1.0.1"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/screenshots/2015-04-10 23.17.37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/screenshots/2015-04-10 23.17.37.png
--------------------------------------------------------------------------------
/screenshots/2015-04-11 02.09.47.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/screenshots/2015-04-11 02.09.47.png
--------------------------------------------------------------------------------
/screenshots/20150901233430.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/screenshots/20150901233430.png
--------------------------------------------------------------------------------
/screenshots/20150901233453.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/screenshots/20150901233453.png
--------------------------------------------------------------------------------
/screenshots/20150901234930.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/screenshots/20150901234930.png
--------------------------------------------------------------------------------
/screenshots/20150901235103.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fritx/markppt/7a5a8ca50855eae949a992c6688a9173956cc37c/screenshots/20150901235103.png
--------------------------------------------------------------------------------
/web/ppt.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
"+(escaped?code:escape(code,true))+"\n
"}return''+(escaped?code:escape(code,true))+"\n
\n"};Renderer.prototype.blockquote=function(quote){return"\n"+quote+"\n"};Renderer.prototype.html=function(html){return html};Renderer.prototype.heading=function(text,level,raw){return"
"+text+"
\n"};Renderer.prototype.table=function(header,body){return""+text+"
"};Renderer.prototype.br=function(){return this.options.xhtml?""+escape(e.message+"",true)+""}throw e}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,sanitizer:null,mangle:true,smartLists:false,silent:false,highlight:null,langPrefix:"lang-",smartypants:false,headerPrefix:"",renderer:new Renderer,xhtml:false};marked.Parser=Parser;marked.parser=Parser.parse;marked.Renderer=Renderer;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;marked.parse=marked;if(typeof module!=="undefined"&&typeof exports==="object"){module.exports=marked}else if(typeof define==="function"&&define.amd){define(function(){return marked})}else{this.marked=marked}}).call(function(){return this||(typeof window!=="undefined"?window:global)}()); -------------------------------------------------------------------------------- /web/ppt_/oops.md: -------------------------------------------------------------------------------- 1 | # Oops.. 2 | 3 | Something goes wrong. 4 | -------------------------------------------------------------------------------- /web/ppt_/ppt.css: -------------------------------------------------------------------------------- 1 | .animated { 2 | -webkit-animation-duration: .5s; 3 | animation-duration: .5s; 4 | } 5 | 6 | /* 7 | 改自 gitter.im scroller效果 8 | https://cdn02.gitter.im/_s/543e5ec/styles/router-app.css 9 | */ 10 | /* ::-webkit-scrollbar{width:9px} 11 | ::-webkit-scrollbar-track{background-color:rgba(100,100,100,.1)} 12 | ::-webkit-scrollbar-thumb{-webkit-border-radius:6px;border-radius:6px;background:rgba(100,100,100,.2);margin-right:1px;-webkit-transition:opacity 300ms ease-in-out;transition:opacity 300ms ease-in-out} 13 | :hover::-webkit-scrollbar-thumb{background:rgba(100,100,100,.4);margin-right:1px;-webkit-transition:opacity 300ms ease-in-out;transition:opacity 300ms ease-in-out} 14 | ::-webkit-scrollbar-thumb:window-inactive{background:rgba(0,0,0,.1)} 15 | */ 16 | /* touch箭头提示 */ 17 | @-webkit-keyframes ani_arrow { 18 | 0% { 19 | opacity: 0; 20 | -webkit-transform: translateY(10px); 21 | transform: translateY(10px); 22 | } 23 | 40% { 24 | opacity: 1; 25 | -webkit-transform: translateY(4px); 26 | transform: translateY(4px); 27 | } 28 | 100% { 29 | opacity: 0; 30 | -webkit-transform: translateY(-4px); 31 | transform: translateY(-4px); 32 | } 33 | } 34 | @-moz-keyframes ani_arrow { 35 | 0% { 36 | opacity: 0; 37 | -webkit-transform: translateY(10px); 38 | transform: translateY(10px); 39 | } 40 | 40% { 41 | opacity: 1; 42 | -webkit-transform: translateY(4px); 43 | transform: translateY(4px); 44 | } 45 | 100% { 46 | opacity: 0; 47 | -webkit-transform: translateY(-4px); 48 | transform: translateY(-4px); 49 | } 50 | } 51 | @-ms-keyframes ani_arrow { 52 | 0% { 53 | opacity: 0; 54 | -webkit-transform: translateY(10px); 55 | transform: translateY(10px); 56 | } 57 | 40% { 58 | opacity: 1; 59 | -webkit-transform: translateY(4px); 60 | transform: translateY(4px); 61 | } 62 | 100% { 63 | opacity: 0; 64 | -webkit-transform: translateY(-4px); 65 | transform: translateY(-4px); 66 | } 67 | } 68 | @keyframes ani_arrow { 69 | 0% { 70 | opacity: 0; 71 | -webkit-transform: translateY(10px); 72 | transform: translateY(10px); 73 | } 74 | 40% { 75 | opacity: 1; 76 | -webkit-transform: translateY(4px); 77 | transform: translateY(4px); 78 | } 79 | 100% { 80 | opacity: 0; 81 | -webkit-transform: translateY(-4px); 82 | transform: translateY(-4px); 83 | } 84 | } 85 | .arrow { 86 | z-index: 9; 87 | position: absolute; 88 | width: 50px; 89 | height: 30px; 90 | } 91 | .arrow:before { 92 | width: 21px; 93 | height: 12px; 94 | content: ''; 95 | position: absolute; 96 | left: 15px; 97 | top: 8px; 98 | background-image: url(arrow_up.png); 99 | background-repeat: no-repeat; 100 | background-size: cover; 101 | opacity: 0; 102 | -webkit-animation: ani_arrow 1.2s ease-in 0s infinite; 103 | animation: ani_arrow 1.2s ease-in 0s infinite 104 | } 105 | .arrow.bottom { 106 | bottom: 4px; 107 | left: 50%; 108 | margin-left: -25px; 109 | } 110 | .arrow.right { 111 | right: 4px; 112 | top: 50%; 113 | margin-top: -15px; 114 | -webkit-transform-origin: top; 115 | transform-origin: top; 116 | -webkit-transform: rotate(-90deg); 117 | transform: rotate(-90deg); 118 | } 119 | 120 | html, body { 121 | margin: 0; 122 | padding: 0; 123 | width: 100%; 124 | height: 100%; 125 | overflow: hidden; 126 | position: relative; 127 | background-color: #f8f8f8; 128 | color: #fff; 129 | } 130 | .light { 131 | color: #000; 132 | } 133 | img { 134 | max-width: 100%; 135 | /* 暂时应对某些图片在dark下看不清 +arbitrary没支持指定light */ 136 | background-color: rgba(255,255,255,.5); 137 | } 138 | a { 139 | color: rgb(160,230,255); 140 | } 141 | .light a { 142 | color: rgb(30,80,170); 143 | } 144 | * { 145 | -ms-box-sizing: border-box; 146 | -o-box-sizing: border-box; 147 | -moz-box-sizing: border-box; 148 | -webkit-box-sizing: border-box; 149 | box-sizing: border-box; 150 | } 151 | 152 | pre { 153 | word-break: break-all; 154 | } 155 | code { 156 | background: #232323; 157 | color: #e6e1dc; 158 | -webkit-border-radius: 6px; /* 同scroller圆角 */ 159 | border-radius: 6px; 160 | padding: 4px 6px; 161 | margin: 0 2px; 162 | } 163 | pre code, pre code.hljs { 164 | display: block; 165 | overflow-x: auto; 166 | padding: .5em; 167 | margin: 0; 168 | } 169 | 170 | body>main { 171 | display: block; 172 | position: relative; 173 | width: 100%; 174 | height: 100%; 175 | } 176 | 177 | section { 178 | display: block; 179 | position: absolute; 180 | top: 0; 181 | bottom: 0; 182 | left: 0; 183 | right: 0; 184 | visibility: hidden; 185 | font-family: "Microsoft Yahei"; 186 | font-size: 175%; 187 | word-break: break-word; 188 | } 189 | 190 | section>div { 191 | -webkit-transform-origin: top; 192 | transform-origin: top; 193 | padding: 1px; /* hack */ 194 | /*box-sizing: content-box;*/ 195 | width: 100%; 196 | } 197 | 198 | /* 微信分享holder */ 199 | body>img { 200 | position: absolute; 201 | left: -9999px; 202 | top: -999px; 203 | } 204 | -------------------------------------------------------------------------------- /web/ppt_/ppt.js: -------------------------------------------------------------------------------- 1 | ;(function(){ 2 | 3 | // 使用visibility属性 实现占位 4 | $.fn.vshow = function(){ 5 | return $(this).css('visibility', 'visible') 6 | } 7 | $.fn.vhide = function(){ 8 | return $(this).css('visibility', 'hidden') 9 | } 10 | 11 | var isDev = /[\?&]dev/.test(location.search) 12 | var isTouch = 'ontouchmove' in document 13 | 14 | var current = 0 // 当前页码 15 | var total // 总页数 16 | var opt // 自定义选项 17 | var $main, $secs 18 | var loaded = [] 19 | 20 | var ppt = window.ppt = {} 21 | ppt.setup = setup 22 | 23 | function onerror(err) { 24 | console.error('ppt onerror', err) 25 | let searchParams = new URLSearchParams() 26 | searchParams.set('url', 'ppt_/oops.md') 27 | location.search = searchParams.toString() 28 | } 29 | 30 | function setup(options) { 31 | opt = options 32 | var url = opt.url 33 | if (opt.arbitrary) { 34 | url = new URL(location.href).searchParams.get('url') || url 35 | } 36 | $.ajax({ 37 | type: 'GET', 38 | url: url, 39 | error: function(err){ 40 | onerror(err) 41 | }, 42 | success: function(text){ 43 | text = text.trim() // 移除前后的空白/异常字符 44 | var worker 45 | if (opt.arbitrary) { 46 | // xxx: hacking `