-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patheditor.html
170 lines (142 loc) · 6.33 KB
/
editor.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Your nxtx document</title>
<style>
html, body {
padding: 0;
height: 100%;
}
a {
color: #1A237E;
word-break: break-all;
text-decoration: none;
}
textarea {
padding: 5px;
width: calc(100% - 12px);
height: 100%;
display: inline-block;
}
.textarea {
margin: 20px 30px;
flex: 45%;
}
.flex {
display: flex;
height: 100%;
overflow-y: scroll;
}
.root {
flex: 55%;
display: inline-block;
overflow-y: scroll;
}
@media print {
.root, .flex {
overflow-y: visible;
}
}
#errorlabel {
background: rgba(244,67,54,0.6);
color: white;
font-family: monospace;
}
</style>
<link rel="stylesheet" href="https://nxtxorg.github.io/paper-css/paper.min.css">
<script src="https://nxtxorg.github.io/nxtx/build/nxtx.min.js"></script>
<script src="https://nxtxorg.github.io/loading/build/loading.min.js"></script>
<script src="https://nxtxorg.github.io/debug-render-time/build/debug-render-time.min.js"></script>
</head>
<body>
<div class="flex">
<div class="textarea no-print">
<textarea id="code">
\load:nxtxorg:package(list-of-contents)
\load:nxtxorg:package(bibliography)
\load:nxtxorg:package(acronyms)
\load:nxtxorg:package(styling)
\load:nxtxorg:package(layout)
\load:nxtxorg:package(plot)
\load:nxtxorg:package(basic-formatting)
\title(NxTx Demo)
\set-google-font-family('Merriweather', 'mono')
\ac:define(AST, 'Abstract Syntax Tree')
\ac:define(DOM, 'Document Object Model')
\loc-print
\chapter(Two-pass rendering)
NxTx utilises two-pass rendering to provide enough flexibility to support needed things, such as list of contents.
\section(First pass)
First pass executes the preprocessors invoked in the document source code. The return values from these preprocessors replaces the invocation node if no command is registered to the same name.
\section(Second pass)
Second pass renders the nodes in document \ac(AST). \ac(DOM) elements, such as \text:tt(#text) \text:tt(img) nodes, are placed directly on the \dquote(paper) and commands are executed and their return values are then placed in the document. The NxTx rendering engine automatically detects when the \dquote(paper) has overflown and insert a new piece a paper, and moves the element that is out of bounds to the new page.
\chapter(Concurrency)
All preprocessors that are in the same paragraph are executed in concurrently using \text:tt(Promise.all). The same applies to all commands used in the same paragraph. This is useful for quickly loading the packages needed for a document, as all the packages are fetched at the same time insted of one by one.
\chapter(Commands)
Commands are executed recursively; if they return a command node (or an array containing command nodes), those nodes are executed as well and the return value replaces the executed node. Commands typically return a string or a \ac(DOM) element, but can also return arrays of these.
\section(Syntax)
In NxTx, commands are invoked similarly to LaTeX; starting with a backslash (\text:tt(\)) followed by the name of the command and then the input arguments, enclosed in parentheses.
Example: \text:tt("\text:tt('Hello World')")
The NxTx language does not contain syntax for defining commands, nor is it planned. Instead ES/JS is used, as that seemed more fitting than the (La)TeX approach. JavaScript is a (debately) nice, turing complete programming language that runs (fast) in the browser. Why not use this fitting tool?
\chapter(Preprocessors)
Preprocessors are invoked in exactly the same way as commands. Both a command and a preprocessor can be registered to the same name. The difference between the two is that preprocessors are executed during the first pass of rendering a document, and commands in the second. The return value from preprocessors are only used if no command is registered to the same name, and is not rendered straight away, but instead replaces the invocation node in the AST.
\chapter(Packages)
NxTx comes as a barebones parser and renderer, the rest is up to packages! Packages can contain a number of preprocessors and commands that extend the rendering capabilities of NxTx. This architecture allows for only downloading/using the packages needed to render your document.
Packages
\section(Package demos)
Here are some demos of some packages
\subsection(Plot package)
\plot({
y:{
values:[3,45,6,34,4,5,5,4,35,34]
},
lines:[
{
x:[0,100],
y:[0,100]
}
]
})
</textarea>
</div>
<div class="root">
<span id="paper" class="A4 nxtx-root"></span>
</div>
</div>
<script defer>
const error = document.getElementById('errorlabel');
const code = document.getElementById('code');
const paper = document.getElementById('paper');
const tryRender = async codeValue => {
try {
await nxtx.render(codeValue, paper);
error.innerText = '';
} catch (e) {
// console.error(`Syntax error at line ${e.location.start.line} column ${e.location.start.column}:\n${e.message}`);
// if (error.location) error.innerText = `Syntax error at line ${e.location.start.line} column ${e.location.start.column}:\n${e.message}`;
}
};
let renderScheduled = false;
let unrenderedInputs = 0;
const flush = async () => {
const codeValue = code.value;
unrenderedInputs = 0;
console.clear();
await tryRender(codeValue);
renderScheduled = false;
if (unrenderedInputs) schedule();
};
const schedule = () => {
if (!renderScheduled) {
renderScheduled = true;
setTimeout(flush, 600);
}
};
const input = () => ++unrenderedInputs && schedule();
// editor.on('change', input);
code.addEventListener('input', input);
tryRender(code.value);
</script>
</body>
</html>