nattoppet 2.1.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,30 +0,0 @@
1
- \NeedsTeXFormat{LaTeX2e}
2
- \ProvidesClass{myarticle}[Article class of ylxdzsw's favor]
3
-
4
- \DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
5
- \ProcessOptions
6
-
7
- \LoadClass[a4paper, 11pt]{article}
8
-
9
- \RequirePackage[left=1.1in,right=1.1in,top=1in,bottom=1in]{geometry}
10
- \RequirePackage[utf8]{inputenc}
11
-
12
- \makeatletter
13
- \def\@maketitle{%
14
- \newpage
15
- \null
16
- \begin{center}%
17
- \let \footnote \thanks
18
- {\LARGE \@title \par}%
19
- \vskip 1.5em%
20
- {\large
21
- \lineskip .5em%
22
- \begin{tabular}[t]{c}%
23
- \@author\quad\textbar\quad\@date
24
- \end{tabular}\par}%
25
- \end{center}%
26
- \par
27
- \vskip 1.5em}
28
- \makeatother
29
-
30
- \endinput
package/compiler.js DELETED
@@ -1,120 +0,0 @@
1
- 'use strict'
2
-
3
- const vm = require("vm")
4
-
5
- const pattern = /^(?:\[(.+?)\]([:=])|\[mixin\] (.+?)\n)/m
6
-
7
- const tokenize = (str, rpath=x=>x) => {
8
- const tokens = []
9
-
10
- while (true) {
11
- const m = str.match(pattern)
12
- if (!m) {
13
- if (str) tokens.push({ type: 'text', content: str })
14
- break
15
- }
16
-
17
- if (m.index > 0) {
18
- tokens.push({ type: 'text', content: str.substring(0, m.index) })
19
- }
20
-
21
- if (m[3]) {
22
- tokens.push({ type: 'mixin', path: m[3] })
23
- str = str.substring(m.index + m[0].length)
24
- continue
25
- }
26
-
27
- const name = m[1]
28
- const type = m[2] == ':' ? 'ref' : 'fn'
29
- str = str.substring(m.index + m[0].length)
30
-
31
- const p1 = str.indexOf('\n\n')
32
- const p2 = str.search(pattern)
33
- const p = p1 >= 0 && p2 >= 0 ? Math.min(p1+1, p2) :
34
- p1 < 0 && p2 < 0 ? str.length : Math.max(p1+1, p2)
35
-
36
- const content = str.substring(0, p).trim()
37
- str = str.substring(p)
38
-
39
- tokens.push({ type, name, content })
40
- }
41
-
42
- for (let i = 0; i < tokens.length; i++) if (tokens[i].type == 'mixin') {
43
- const fs = require('fs')
44
- const path = rpath(tokens[i].path)
45
- const stat = fs.statSync(path)
46
- if (stat.isDirectory()) { // include before and after
47
- const before = tokenize(fs.readFileSync(path + '/before.ymd', 'utf8'), rpath)
48
- const after = tokenize(fs.readFileSync(path + '/after.ymd', 'utf8'), rpath)
49
- tokens.splice(i, 1, ...before)
50
- tokens.push(...after)
51
- } else {
52
- const mixins = tokenize(fs.readFileSync(path, 'utf8'), rpath)
53
- tokens.splice(i, 1, ...mixins)
54
- }
55
- i -= 1 // revisit i since we replaced it
56
- }
57
-
58
- return tokens
59
- }
60
-
61
- const interpret = (str, env, defs) => {
62
- const p1 = str.search(/^ /m)
63
- const p2 = str.search(/\[(.+?)\]/)
64
- if (p1 < 0 && p2 < 0) return str
65
-
66
- if (p2 < 0 || (p1 >= 0 && p1 < p2)) {
67
- const head = str.substring(0, p1)
68
- str = str.substring(p1+2)
69
- let p = str.indexOf('\n\n')
70
- if (p < 0) p = str.length
71
- return head + '<p>' + interpret(str.substring(0, p), env, defs) + '</p>' + interpret(str.substring(p+1), env, defs)
72
- }
73
-
74
- const name = str.match(/\[(.+?)\]/)[1]
75
- const i = defs.findIndex(x => x.name == name)
76
- if (i < 0) throw `definition ${name} not found`
77
-
78
- const def = defs[i]
79
- switch (def.type) {
80
- case 'fn':
81
- env.remaining = str.substring(p2 + name.length + 2)
82
- env.interpret = str => { // a "scoped" interpret function capable for interpreting substrings. We preserve the "remaining" property outside.
83
- const remaining = env.remaining
84
- const result = interpret(str, env, defs) // We gaved full defs available on the call site (dynamic scoping) as the text to be interpreted is part of the call site text.
85
- env.remaining = remaining
86
- return result
87
- }
88
- const result = vm.runInContext('{' + def.content + '}', env)
89
- return str.substring(0, p2) + result + interpret(env.remaining, env, defs)
90
- case 'ref':
91
- return str.substring(0, p2) +
92
- interpret(def.content, env, defs.slice(i+1)) + // However for ref we use lexical scoping. Exclude self to prevent recusion
93
- interpret(str.substring(p2 + name.length + 2), env, defs)
94
- default: throw 'unknown defs type'
95
- }
96
- }
97
-
98
- exports.compile = (str, locals={}) => {
99
- const env = vm.createContext(locals)
100
- for (const k in env) if (typeof(env[k]) == 'function')
101
- env[k] = env[k].bind(env)
102
-
103
- let tokens = tokenize(str, env.rpath)
104
- let output = ''
105
- while (true) {
106
- const token = tokens.shift()
107
- if (!token) return output
108
- if (token.type == 'text') {
109
- output += interpret(token.content, env, tokens)
110
- }
111
- }
112
- }
113
-
114
- /*
115
- TODO:
116
- 1. support first-class markdown-like nestable lists
117
- 2. cleanup the spaces, carefully define when to trim
118
- 3. require a newline before indent to open paragraph?
119
- 4. provide relative path resolution inside mixins
120
- */
package/koa/before.ymd DELETED
@@ -1,12 +0,0 @@
1
- <!doctype html>
2
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
3
- <meta name="author" content="ylxdzsw@gmail.com">
4
- <meta charset="utf-8">
5
- <title>[title] | ylxdzsw's blog</title>
6
-
7
- [require](@std/koa/koa.less)
8
-
9
- <section id="title">
10
- <h1>[title]</h1>
11
-
12
- [eval*] this.sections = []
package/koa/koa.less DELETED
@@ -1,179 +0,0 @@
1
- html {
2
- font-family: serif;
3
- font-size: 18px;
4
- line-height: 1.5;
5
- width: 100%;
6
- height: 100%;
7
-
8
- background: white;
9
- color: #33333d;
10
-
11
- @media (max-width: 625px) {
12
- font-size: 16px;
13
- text-align: justify;
14
- hyphens: auto;
15
- }
16
- }
17
-
18
- body {
19
- height: 100%;
20
- width: 100%;
21
- padding: 0;
22
- margin: 0;
23
- overflow-y: scroll;
24
- }
25
-
26
- a {
27
- color: #027AD2;
28
- }
29
-
30
- section {
31
- min-height: 50%;
32
- padding: 150px 10vw;
33
-
34
- @media (max-width: 625px) {
35
- padding: 25px 1.25rem;
36
- }
37
-
38
- &:nth-child(2n-1) {
39
- background: #fbfbfb;
40
- box-shadow: inset 0 1px 0 0 white;
41
- }
42
-
43
- &:not(:last-child) {
44
- border-bottom: 1px solid #eee;
45
- }
46
- }
47
-
48
- pre {
49
- background: white;
50
- border-top: 1px solid #eee;
51
- border-bottom: 1px solid #eee;
52
- padding: 25px;
53
- font-size: .8rem;
54
- text-align: left;
55
- overflow-x: auto;
56
- }
57
-
58
- code {
59
- font-family: monospace;
60
- }
61
-
62
- h2 {
63
- margin-top: 40px;
64
- font-size: 2rem;
65
- }
66
-
67
- h3 {
68
- margin-top: 80px;
69
- font-size: 1.2rem;
70
- }
71
-
72
- h4 {
73
- margin-top: 40px;
74
- font-size: 1rem;
75
- }
76
-
77
- ul li {
78
- font-size: .9rem;
79
- }
80
-
81
- p {
82
- text-indent: 2rem;
83
- }
84
-
85
- #title {
86
- padding: 0;
87
- height: 100%;
88
- text-align: center;
89
- position: relative;
90
-
91
- @media (max-width: 625px) {
92
- height: 40vh;
93
- }
94
-
95
- h1 {
96
- position: absolute;
97
- top: 45%;
98
- width: 100%;
99
- transform: translateY(-50%);
100
- margin: 0;
101
-
102
- font-size: 6rem;
103
- font-weight: normal;
104
-
105
- @media (max-width: 625px) {
106
- font-size: 3rem;
107
- }
108
- }
109
- }
110
-
111
- #nav {
112
- position: fixed;
113
- top: 35px;
114
- right: 30px;
115
- z-index: 5;
116
-
117
- @media (max-width: 625px) {
118
- top: 15px;
119
- right: 10px;
120
- }
121
-
122
- #nav-icon {
123
- position: absolute;
124
- top: 0;
125
- right: 0;
126
- padding: 6px;
127
- background: rgba(255,255,255,.9);
128
- border-radius: 2px;
129
- border: 1px solid transparent;
130
- font-size: 0;
131
- z-index: 4;
132
- }
133
-
134
- #nav-menu {
135
- display: none;
136
- position: relative;
137
- top: 35px;
138
- right: 0;
139
- margin: 0;
140
- border: 1px solid #efefef;
141
- border-bottom: 1px solid #ddd;
142
- border-radius: 2px;
143
- padding: 25px;
144
- background: rgba(255,255,255,.95);
145
- box-shadow: 0 1px 3px 0 #eee;
146
- z-index: 3;
147
-
148
- li {
149
- list-style: none;
150
-
151
- a {
152
- display: block;
153
- text-decoration: none;
154
- padding: 3px 0;
155
- color: inherit;
156
- font-size: 1rem;
157
-
158
- &:hover {
159
- text-decoration: underline;
160
- }
161
- }
162
- }
163
- }
164
-
165
- &:hover {
166
- ul {
167
- display: block;
168
- }
169
-
170
- #nav-icon {
171
- border: 1px solid #efefef;
172
- border-bottom: none;
173
- }
174
-
175
- #nav-menu {
176
- display: block;
177
- }
178
- }
179
- }
package/native/Cargo.toml DELETED
@@ -1,13 +0,0 @@
1
- [package]
2
- name = "nattoppet_native"
3
- version = "0.1.0"
4
- edition = "2021"
5
-
6
- [dependencies]
7
- web-view = { version = "0.7", features = ["edge"] }
8
-
9
- [target.'cfg(windows)'.build-dependencies]
10
- winres = "0.1"
11
-
12
- [package.metadata.winres]
13
- ProductName = "A nattoppet native app"
package/native/build.rs DELETED
@@ -1,12 +0,0 @@
1
- #[cfg(windows)]
2
- extern crate winres;
3
-
4
- #[cfg(windows)]
5
- fn main() {
6
- let mut res = winres::WindowsResource::new();
7
- res.set_icon("../icon.ico");
8
- res.compile().unwrap();
9
- }
10
-
11
- #[cfg(not(windows))]
12
- fn main() {}
@@ -1,22 +0,0 @@
1
- #![windows_subsystem = "windows"]
2
-
3
- use web_view::*;
4
-
5
- fn main() {
6
- static HTML_CONTENT: &str = include_str!("../target/bundle.html");
7
-
8
- web_view::builder()
9
- .title("Nattoppet Native")
10
- .content(Content::Html(HTML_CONTENT))
11
- .size(600, 480)
12
- .resizable(false)
13
- .debug(cfg!(debug_assertions))
14
- .user_data(())
15
- .invoke_handler(handler)
16
- .run()
17
- .unwrap();
18
- }
19
-
20
- fn handler(webview: &mut WebView<()>, arg: &str) -> WVResult {
21
- Ok(())
22
- }
package/nattoppet-dev.js DELETED
@@ -1,58 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- 'use strict'
4
-
5
- const file = process.argv[2]
6
-
7
- if (process.argv.length != 3 || file == "--help")
8
- return console.log("Usage: nattoppet-dev [file]")
9
-
10
- const fs = require('fs')
11
- const cp = require('child_process')
12
- const http = require('http')
13
-
14
- let content = "start watching..."
15
- let busy = 0
16
- let queued = false
17
- let lastevent = Date.now()
18
-
19
- const done = () => {
20
- busy = (busy + 1) % 3
21
- !busy && queued && start(queued = false)
22
- }
23
-
24
- const start = (init=false) => {
25
- const child = cp.spawn(__dirname + '/nattoppet.js', [file, '--dev'])
26
- let buffer = ''
27
- child.stdout.on('data', chunk => buffer += chunk)
28
- child.on('close', code => {
29
- if (code == 0) {
30
- console.log(init ? "rendered" : "updated")
31
- content = buffer
32
- } else
33
- console.error("failed") // todo: print time
34
- done()
35
- })
36
- setTimeout(done, 500)
37
- busy++
38
- }
39
-
40
- fs.watch(file).addListener("change", () => {
41
- if (Date.now() - lastevent < 50) return // hard throttle, not even queue it
42
- lastevent = Date.now()
43
- if (busy) return queued = true // soft throttle, queue at most one task
44
- start()
45
- })
46
-
47
- http.createServer((req, res) => {
48
- res.writeHead(200, { 'Content-Type': 'text/html' })
49
- res.end(content)
50
- }).listen(3939)
51
-
52
- const browser = process.env.BROWSER || ({ darwin: 'open', win32: 'start', win64: 'start' })[process.platform] || 'xdg-open'
53
-
54
- browser.includes('chrom')
55
- ? cp.exec(`${browser} --app=http://127.0.0.1:3939`)
56
- : cp.exec(`${browser} http://127.0.0.1:3939`)
57
-
58
- start(true)
@@ -1,49 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- 'use strict'
4
-
5
- const fs = require('fs')
6
- const cp = require('child_process')
7
- const path = require('path')
8
-
9
- const init = () => {
10
- fs.mkdirSync('native')
11
- fs.mkdirSync('native/src')
12
- fs.mkdirSync('native/target')
13
- fs.copyFileSync(path.join(__dirname, 'native', 'src', 'main.rs'), 'native/src/main.rs')
14
- fs.copyFileSync(path.join(__dirname, 'native', 'build.rs'), 'native/build.rs')
15
- fs.copyFileSync(path.join(__dirname, 'native', 'Cargo.toml'), 'native/Cargo.toml')
16
- }
17
-
18
- const bundle = () => {
19
- const child = cp.spawnSync(__dirname + '/nattoppet.js', [process.argv[3]])
20
- if (child.stderr.length) {
21
- console.error(child.stderr.toString())
22
- }
23
- fs.writeFileSync('native/target/bundle.html', child.stdout)
24
- }
25
-
26
- const build = () => {
27
- bundle()
28
- const child = cp.spawn('cargo', ['build', '--release'], { cwd: 'native' })
29
- child.stdout.pipe(process.stdout)
30
- child.stderr.pipe(process.stderr)
31
- child.on('exit', (code) => {
32
- if (code != 0) {
33
- console.error("Cargo exit with code: " + code)
34
- } else {
35
- console.log("building finished. Check native/target/release/")
36
- }
37
- })
38
- }
39
-
40
- const help = () => {
41
- console.log("Usage: nattoppet-native [init|bundle|build]")
42
- }
43
-
44
- switch (process.argv[2]) {
45
- case 'init': return init()
46
- case 'bundle': return bundle()
47
- case 'build': return build()
48
- default: return help()
49
- }
package/nattoppet.js DELETED
@@ -1,26 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- 'use strict'
4
-
5
- const fs = require('fs')
6
- const path = require('path')
7
- const stdlib = require('./stdlib')
8
- const compiler = require('./compiler')
9
- const minifier = require('html-minifier')
10
-
11
- const file = process.argv[2] || 0
12
- const dir = file ? path.dirname(path.resolve(file)) : process.cwd()
13
- const str = fs.readFileSync(file, 'utf8')
14
- const env = { ...stdlib, base_dir: dir }
15
- const raw = compiler.compile(str, env)
16
- const out = process.argv.includes('--dev', 1) ? raw : minifier.minify(raw, {
17
- collapseWhitespace: true,
18
- removeAttributeQuotes: true,
19
- removeComments: true,
20
- removeRedundantAttributes: true,
21
- removeOptionalTags: true,
22
- minifyCSS: true,
23
- minifyJS: true,
24
- })
25
-
26
- process.stdout.write(out)
package/ppt/before.ymd DELETED
@@ -1,8 +0,0 @@
1
- <!doctype html>
2
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
3
- <meta name="author" content="ylxdzsw@gmail.com">
4
- <meta charset="utf-8">
5
- <title>[title] | ylxdzsw's blog</title>
6
-
7
- [require](@std/ppt/ppt.less)
8
- [require](@std/ppt/ppt.coffee)
package/ppt/ppt.coffee DELETED
@@ -1,61 +0,0 @@
1
- # events: click, delay, sim
2
- # time-for-delay: short, long
3
- # fx: slide, fade, fx-[color]
4
- # time-for-fx: fast, slow
5
-
6
- init = ->
7
- scens = [].slice.call document.querySelectorAll '.scen'
8
- current = scens[0]
9
- timeline = 0
10
- clickListener = ->
11
-
12
- enter = (x) ->
13
- x.classList.add 'active'
14
- fx ++timeline, [].slice.call x.querySelectorAll '.click, .delay, .sim'
15
-
16
- inview = (x) ->
17
- { top, height } = do x.getBoundingClientRect
18
- top <= innerHeight / 2 <= top + height
19
-
20
- update = ->
21
- if not inview current
22
- for x in scens
23
- if inview x
24
- for e in document.querySelectorAll('.active')
25
- e.classList.remove 'active'
26
- enter x
27
- current = x
28
- break
29
-
30
- fx = (t, [head, tail...]) ->
31
- if not head?
32
- return
33
-
34
- cb = ->
35
- if t isnt timeline
36
- return
37
- head.classList.add 'active'
38
- fx t, tail
39
-
40
- if head.classList.contains 'click'
41
- clickListener = cb
42
- else if head.classList.contains 'delay'
43
- if head.classList.contains 'long'
44
- setTimeout cb, 800
45
- else if head.classList.contains 'short'
46
- setTimeout cb, 200
47
- else
48
- setTimeout cb, 400
49
- else if head.classList.contains 'sim'
50
- do cb
51
-
52
- enter current
53
- addEventListener 'click', -> do clickListener
54
- addEventListener 'scroll', update
55
- addEventListener 'resize', update
56
- setInterval update, 2000
57
-
58
- if document.readyState == 'loading'
59
- document.addEventListener 'DOMContentLoaded', init
60
- else
61
- do init