Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/keenwrite.git
M .gitattributes
2626
*.ttf binary
2727
*.ods binary
28
*.pdf binary
2829
2930
bin/linux-x64.warp-packer binary
M .gitignore
1818
keenwrite.build_artifacts.txt
1919
todo
20
tokens/
2120
A COPYRIGHT.md
1
KeenWrite, a free, cross-platform desktop text editor.
2
Copyright (C) 2025  White Magic Software, Ltd.
3
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, see <https://www.gnu.org/licenses/>.
16
117
M LICENSE.md
1
# License
1
# GNU GENERAL PUBLIC LICENSE
22
3
Copyright 2023 White Magic Software, Ltd.
3
Version 2, June 1991
44
5
All rights reserved.
5
    Copyright (C) 1989, 1991 Free Software Foundation, Inc.  
6
    <https://fsf.org/>
67
7
Redistribution and use in source and binary forms, with or without
8
modification, are permitted provided that the following conditions are met:
8
    Everyone is permitted to copy and distribute verbatim copies
9
    of this license document, but changing it is not allowed.
910
10
* Redistributions of source code must retain the above copyright
11
  notice, this list of conditions and the following disclaimer.
11
## Preamble
1212
13
* Redistributions in binary form must reproduce the above copyright
14
  notice, this list of conditions and the following disclaimer in the
15
  documentation and/or other materials provided with the distribution.
13
The licenses for most software are designed to take away your freedom
14
to share and change it. By contrast, the GNU General Public License is
15
intended to guarantee your freedom to share and change free
16
software--to make sure the software is free for all its users. This
17
General Public License applies to most of the Free Software
18
Foundation's software and to any other program whose authors commit to
19
using it. (Some other Free Software Foundation software is covered by
20
the GNU Lesser General Public License instead.) You can apply it to
21
your programs, too.
1622
17
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
When we speak of free software, we are referring to freedom, not
24
price. Our General Public Licenses are designed to make sure that you
25
have the freedom to distribute copies of free software (and charge for
26
this service if you wish), that you receive source code or can get it
27
if you want it, that you can change the software or use pieces of it
28
in new free programs; and that you know you can do these things.
29
30
To protect your rights, we need to make restrictions that forbid
31
anyone to deny you these rights or to ask you to surrender the rights.
32
These restrictions translate to certain responsibilities for you if
33
you distribute copies of the software, or if you modify it.
34
35
For example, if you distribute copies of such a program, whether
36
gratis or for a fee, you must give the recipients all the rights that
37
you have. You must make sure that they, too, receive or can get the
38
source code. And you must show them these terms so they know their
39
rights.
40
41
We protect your rights with two steps: (1) copyright the software, and
42
(2) offer you this license which gives you legal permission to copy,
43
distribute and/or modify the software.
44
45
Also, for each author's protection and ours, we want to make certain
46
that everyone understands that there is no warranty for this free
47
software. If the software is modified by someone else and passed on,
48
we want its recipients to know that what they have is not the
49
original, so that any problems introduced by others will not reflect
50
on the original authors' reputations.
51
52
Finally, any free program is threatened constantly by software
53
patents. We wish to avoid the danger that redistributors of a free
54
program will individually obtain patent licenses, in effect making the
55
program proprietary. To prevent this, we have made it clear that any
56
patent must be licensed for everyone's free use or not licensed at
57
all.
58
59
The precise terms and conditions for copying, distribution and
60
modification follow.
61
62
## TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
63
64
**0.** This License applies to any program or other work which
65
contains a notice placed by the copyright holder saying it may be
66
distributed under the terms of this General Public License. The
67
"Program", below, refers to any such program or work, and a "work
68
based on the Program" means either the Program or any derivative work
69
under copyright law: that is to say, a work containing the Program or
70
a portion of it, either verbatim or with modifications and/or
71
translated into another language. (Hereinafter, translation is
72
included without limitation in the term "modification".) Each licensee
73
is addressed as "you".
74
75
Activities other than copying, distribution and modification are not
76
covered by this License; they are outside its scope. The act of
77
running the Program is not restricted, and the output from the Program
78
is covered only if its contents constitute a work based on the Program
79
(independent of having been made by running the Program). Whether that
80
is true depends on what the Program does.
81
82
**1.** You may copy and distribute verbatim copies of the Program's
83
source code as you receive it, in any medium, provided that you
84
conspicuously and appropriately publish on each copy an appropriate
85
copyright notice and disclaimer of warranty; keep intact all the
86
notices that refer to this License and to the absence of any warranty;
87
and give any other recipients of the Program a copy of this License
88
along with the Program.
89
90
You may charge a fee for the physical act of transferring a copy, and
91
you may at your option offer warranty protection in exchange for a
92
fee.
93
94
**2.** You may modify your copy or copies of the Program or any
95
portion of it, thus forming a work based on the Program, and copy and
96
distribute such modifications or work under the terms of Section 1
97
above, provided that you also meet all of these conditions:
98
99
  
100
**a)** You must cause the modified files to carry prominent notices
101
stating that you changed the files and the date of any change.
102
103
  
104
**b)** You must cause any work that you distribute or publish, that in
105
whole or in part contains or is derived from the Program or any part
106
thereof, to be licensed as a whole at no charge to all third parties
107
under the terms of this License.
108
109
  
110
**c)** If the modified program normally reads commands interactively
111
when run, you must cause it, when started running for such interactive
112
use in the most ordinary way, to print or display an announcement
113
including an appropriate copyright notice and a notice that there is
114
no warranty (or else, saying that you provide a warranty) and that
115
users may redistribute the program under these conditions, and telling
116
the user how to view a copy of this License. (Exception: if the
117
Program itself is interactive but does not normally print such an
118
announcement, your work based on the Program is not required to print
119
an announcement.)
120
121
These requirements apply to the modified work as a whole. If
122
identifiable sections of that work are not derived from the Program,
123
and can be reasonably considered independent and separate works in
124
themselves, then this License, and its terms, do not apply to those
125
sections when you distribute them as separate works. But when you
126
distribute the same sections as part of a whole which is a work based
127
on the Program, the distribution of the whole must be on the terms of
128
this License, whose permissions for other licensees extend to the
129
entire whole, and thus to each and every part regardless of who wrote
130
it.
131
132
Thus, it is not the intent of this section to claim rights or contest
133
your rights to work written entirely by you; rather, the intent is to
134
exercise the right to control the distribution of derivative or
135
collective works based on the Program.
136
137
In addition, mere aggregation of another work not based on the Program
138
with the Program (or with a work based on the Program) on a volume of
139
a storage or distribution medium does not bring the other work under
140
the scope of this License.
141
142
**3.** You may copy and distribute the Program (or a work based on it,
143
under Section 2) in object code or executable form under the terms of
144
Sections 1 and 2 above provided that you also do one of the following:
145
146
  
147
**a)** Accompany it with the complete corresponding machine-readable
148
source code, which must be distributed under the terms of Sections 1
149
and 2 above on a medium customarily used for software interchange; or,
150
151
  
152
**b)** Accompany it with a written offer, valid for at least three
153
years, to give any third party, for a charge no more than your cost of
154
physically performing source distribution, a complete machine-readable
155
copy of the corresponding source code, to be distributed under the
156
terms of Sections 1 and 2 above on a medium customarily used for
157
software interchange; or,
158
159
  
160
**c)** Accompany it with the information you received as to the offer
161
to distribute corresponding source code. (This alternative is allowed
162
only for noncommercial distribution and only if you received the
163
program in object code or executable form with such an offer, in
164
accord with Subsection b above.)
165
166
The source code for a work means the preferred form of the work for
167
making modifications to it. For an executable work, complete source
168
code means all the source code for all modules it contains, plus any
169
associated interface definition files, plus the scripts used to
170
control compilation and installation of the executable. However, as a
171
special exception, the source code distributed need not include
172
anything that is normally distributed (in either source or binary
173
form) with the major components (compiler, kernel, and so on) of the
174
operating system on which the executable runs, unless that component
175
itself accompanies the executable.
176
177
If distribution of executable or object code is made by offering
178
access to copy from a designated place, then offering equivalent
179
access to copy the source code from the same place counts as
180
distribution of the source code, even though third parties are not
181
compelled to copy the source along with the object code.
182
183
**4.** You may not copy, modify, sublicense, or distribute the Program
184
except as expressly provided under this License. Any attempt otherwise
185
to copy, modify, sublicense or distribute the Program is void, and
186
will automatically terminate your rights under this License. However,
187
parties who have received copies, or rights, from you under this
188
License will not have their licenses terminated so long as such
189
parties remain in full compliance.
190
191
**5.** You are not required to accept this License, since you have not
192
signed it. However, nothing else grants you permission to modify or
193
distribute the Program or its derivative works. These actions are
194
prohibited by law if you do not accept this License. Therefore, by
195
modifying or distributing the Program (or any work based on the
196
Program), you indicate your acceptance of this License to do so, and
197
all its terms and conditions for copying, distributing or modifying
198
the Program or works based on it.
199
200
**6.** Each time you redistribute the Program (or any work based on
201
the Program), the recipient automatically receives a license from the
202
original licensor to copy, distribute or modify the Program subject to
203
these terms and conditions. You may not impose any further
204
restrictions on the recipients' exercise of the rights granted herein.
205
You are not responsible for enforcing compliance by third parties to
206
this License.
207
208
**7.** If, as a consequence of a court judgment or allegation of
209
patent infringement or for any other reason (not limited to patent
210
issues), conditions are imposed on you (whether by court order,
211
agreement or otherwise) that contradict the conditions of this
212
License, they do not excuse you from the conditions of this License.
213
If you cannot distribute so as to satisfy simultaneously your
214
obligations under this License and any other pertinent obligations,
215
then as a consequence you may not distribute the Program at all. For
216
example, if a patent license would not permit royalty-free
217
redistribution of the Program by all those who receive copies directly
218
or indirectly through you, then the only way you could satisfy both it
219
and this License would be to refrain entirely from distribution of the
220
Program.
221
222
If any portion of this section is held invalid or unenforceable under
223
any particular circumstance, the balance of the section is intended to
224
apply and the section as a whole is intended to apply in other
225
circumstances.
226
227
It is not the purpose of this section to induce you to infringe any
228
patents or other property right claims or to contest validity of any
229
such claims; this section has the sole purpose of protecting the
230
integrity of the free software distribution system, which is
231
implemented by public license practices. Many people have made
232
generous contributions to the wide range of software distributed
233
through that system in reliance on consistent application of that
234
system; it is up to the author/donor to decide if he or she is willing
235
to distribute software through any other system and a licensee cannot
236
impose that choice.
237
238
This section is intended to make thoroughly clear what is believed to
239
be a consequence of the rest of this License.
240
241
**8.** If the distribution and/or use of the Program is restricted in
242
certain countries either by patents or by copyrighted interfaces, the
243
original copyright holder who places the Program under this License
244
may add an explicit geographical distribution limitation excluding
245
those countries, so that distribution is permitted only in or among
246
countries not thus excluded. In such case, this License incorporates
247
the limitation as if written in the body of this License.
248
249
**9.** The Free Software Foundation may publish revised and/or new
250
versions of the General Public License from time to time. Such new
251
versions will be similar in spirit to the present version, but may
252
differ in detail to address new problems or concerns.
253
254
Each version is given a distinguishing version number. If the Program
255
specifies a version number of this License which applies to it and
256
"any later version", you have the option of following the terms and
257
conditions either of that version or of any later version published by
258
the Free Software Foundation. If the Program does not specify a
259
version number of this License, you may choose any version ever
260
published by the Free Software Foundation.
261
262
**10.** If you wish to incorporate parts of the Program into other
263
free programs whose distribution conditions are different, write to
264
the author to ask for permission. For software which is copyrighted by
265
the Free Software Foundation, write to the Free Software Foundation;
266
we sometimes make exceptions for this. Our decision will be guided by
267
the two goals of preserving the free status of all derivatives of our
268
free software and of promoting the sharing and reuse of software
269
generally.
270
271
**NO WARRANTY**
272
273
**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
274
WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
275
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
276
OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY
277
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
278
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
279
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
280
PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
281
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
282
283
**12.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
284
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
285
AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU
286
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
287
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
288
PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
289
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
290
FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF
291
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
292
DAMAGES.
293
294
END OF TERMS AND CONDITIONS
295
28296
M README.md
3737
Using Java, first follow these one-time setup steps:
3838
39
1. Download the *Full version* of the Java Runtime Environment, [JRE 23](https://bell-sw.com/pages/downloads).
39
1. Download the *Full version* of the Java Runtime Environment, [JRE 24](https://bell-sw.com/pages/downloads).
4040
   * JavaFX, which is bundled with BellSoft's *Full version*, is required.
4141
1. Install the JRE (include JRE's `bin` directory in the `PATH` environment variable).
M build.gradle
1010
  dependencies {
1111
    classpath 'org.owasp:dependency-check-gradle:10.0.3'
12
    classpath "com.github.spotbugs.snom:spotbugs-gradle-plugin:6.0.19"
12
    classpath "com.github.spotbugs.snom:spotbugs-gradle-plugin:6.3.0"
1313
  }
1414
}
1515
1616
plugins {
1717
  id 'application'
1818
  id 'org.openjfx.javafxplugin' version '0.1.0'
1919
  id 'com.palantir.git-version' version '3.1.0'
20
  id 'com.github.spotbugs' version '6.0.9'
21
  id 'com.jaredsburrows.license' version '0.9.8'
20
  id 'com.github.spotbugs' version '6.3.0'
2221
}
2322
...
6160
6261
def moduleSecurity = [
62
  '--enable-native-access=javafx.graphics',
63
  '--sun-misc-unsafe-memory-access=allow',
6364
  '--add-opens=javafx.graphics/javafx.scene=ALL-UNNAMED',
6465
  '--add-opens=javafx.controls/javafx.scene.control=ALL-UNNAMED',
6566
  '--add-opens=javafx.controls/javafx.scene.control.skin=ALL-UNNAMED',
6667
  '--add-opens=javafx.graphics/javafx.scene.text=ALL-UNNAMED',
6768
  '--add-opens=javafx.graphics/com.sun.javafx.css=ALL-UNNAMED',
69
  '--add-opens=javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED',
6870
  '--add-opens=javafx.graphics/com.sun.javafx.text=ALL-UNNAMED',
6971
  '--add-exports=javafx.base/com.sun.javafx.event=ALL-UNNAMED',
...
100102
  // JavaFX
101103
  implementation 'org.controlsfx:controlsfx:11.2.2'
102
  implementation 'org.fxmisc.richtext:richtextfx:0.11.5'
104
  implementation 'org.fxmisc.richtext:richtextfx:0.11.6'
103105
  implementation 'org.fxmisc.flowless:flowless:0.7.4'
104106
  implementation 'org.fxmisc.wellbehaved:wellbehavedfx:0.3.3'
...
114116
  implementation "com.vladsch.flexmark:flexmark-ext-tables:${v_flexmark}"
115117
  implementation "com.vladsch.flexmark:flexmark-ext-typographic:${v_flexmark}"
118
  implementation "com.vladsch.flexmark:flexmark-ext-footnotes:${v_flexmark}"
116119
117120
  // YAML
118
  implementation 'org.yaml:snakeyaml:2.4'
121
  implementation 'org.yaml:snakeyaml:2.5'
119122
  implementation "com.fasterxml.jackson.core:jackson-core:${v_jackson}"
120123
  implementation "com.fasterxml.jackson.core:jackson-databind:${v_jackson}"
121124
  implementation "com.fasterxml.jackson.core:jackson-annotations:${v_jackson}"
122125
  implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${v_jackson}"
123126
124127
  // HTML parsing and rendering
125
  implementation 'org.jsoup:jsoup:1.18.3'
126
  implementation 'org.xhtmlrenderer:flying-saucer-core:9.11.2'
128
  implementation 'org.jsoup:jsoup:1.21.2'
129
  implementation 'org.xhtmlrenderer:flying-saucer-core:10.0.0'
127130
128131
  // R
...
150153
  implementation 'org.ahocorasick:ahocorasick:0.6.3'
151154
  implementation 'com.github.albfernandez:juniversalchardet:2.5.0'
152
  implementation 'jakarta.validation:jakarta.validation-api:3.1.0'
155
  implementation 'jakarta.validation:jakarta.validation-api:3.1.1'
153156
  implementation 'org.greenrobot:eventbus-java:3.3.1'
154157
155158
  // Logging.
156159
  implementation 'org.slf4j:slf4j-api:2.1.0-alpha1'
157
  implementation 'org.slf4j:slf4j-nop:2.0.16'
160
  implementation 'org.slf4j:slf4j-nop:2.0.17'
158161
159162
  // Command-line parsing
...
171174
    }
172175
  }
176
177
  // Required to satisfy SpotBugs missing class warnings.
178
  implementation 'org.jspecify:jspecify:1.0.0'
179
  implementation 'com.google.errorprone:error_prone_annotations:2.41.0'
173180
174181
  testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${v_junit}"
M container/Containerfile
3232
WORKDIR $DOWNLOAD_DIR
3333
34
# Many fonts may be downloaded using Google's download URL. Example:
35
# https://fonts.google.com/download?family=Roboto%20Mono
34
# Define font list to avoid duplication
35
ENV FONTS_LIST="andada-pro archivo-narrow arimo carlito courier-prime \
36
  inconsolata inter libre-baskerville libre-franklin niconne nunito \
37
  open-sans-emoji pt-mono pt-sans pt-serif roboto roboto-mono source-serif-4 \
38
  snickles tw-kai underwood"
3639
37
# Fonts are repacked with minimal file set, flat directory, and license.
38
ADD "https://fonts.keenwrite.com/download/andada-pro.zip" ./
39
ADD "https://fonts.keenwrite.com/download/archivo-narrow.zip" ./
40
ADD "https://fonts.keenwrite.com/download/carlito.zip" ./
41
ADD "https://fonts.keenwrite.com/download/courier-prime.zip" ./
42
ADD "https://fonts.keenwrite.com/download/inconsolata.zip" ./
43
ADD "https://fonts.keenwrite.com/download/libre-baskerville.zip" ./
44
ADD "https://fonts.keenwrite.com/download/niconne.zip" ./
45
ADD "https://fonts.keenwrite.com/download/nunito.zip" ./
46
ADD "https://fonts.keenwrite.com/download/open-sans-emoji.zip" ./
47
ADD "https://fonts.keenwrite.com/download/pt-mono.zip" ./
48
ADD "https://fonts.keenwrite.com/download/pt-sans.zip" ./
49
ADD "https://fonts.keenwrite.com/download/pt-serif.zip" ./
50
ADD "https://fonts.keenwrite.com/download/roboto.zip" ./
51
ADD "https://fonts.keenwrite.com/download/roboto-mono.zip" ./
52
ADD "https://fonts.keenwrite.com/download/source-serif-4.zip" ./
53
ADD "https://fonts.keenwrite.com/download/underwood.zip" ./
40
# Download fonts
41
RUN mkdir -p "$FONTS_DIR" && \
42
  for font in $FONTS_LIST; do \
43
    wget "https://fonts.keenwrite.com/download/${font}.zip"; \
44
  done
5445
5546
# Typesetting software
56
ADD "http://lmtx.pragma-ade.nl/install-lmtx/context-$CONTEXT_ARCH.zip" "context.zip"
47
ADD "http://lmtx.pragma-ade.nl/install-lmtx/context-${CONTEXT_ARCH}.zip" "context.zip"
5748
5849
# ########################################################################
...
8778
  echo "PS1='\\u@typesetter:\\w\\$ '" >> $PROFILE && \
8879
  unzip -d $CONTEXT_HOME $DOWNLOAD_DIR/context.zip && \
89
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/andada-pro.zip "*.otf" && \
90
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/archivo-narrow.zip "*.otf" && \
91
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/carlito.zip "*.ttf" && \
92
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/courier-prime.zip "*.ttf" && \
93
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/libre-baskerville.zip "*.ttf" && \
94
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/inconsolata.zip "*.ttf" && \
95
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/niconne.zip "*.ttf" && \
96
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/nunito.zip "*.ttf" && \
97
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/open-sans-emoji.zip "*.ttf" && \
98
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/pt-mono.zip "*.ttf" && \
99
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/pt-sans.zip "*.ttf" && \
100
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/pt-serif.zip "*.ttf" && \
101
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/roboto.zip "*.ttf" && \
102
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/roboto-mono.zip "*.ttf" && \
103
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/source-serif-4.zip "*.otf" && \
104
  unzip -j -o -d $FONTS_DIR $DOWNLOAD_DIR/underwood.zip "*.ttf" && \
80
  for font in $FONTS_LIST; do \
81
    unzip -j -o -d $FONTS_DIR "$DOWNLOAD_DIR/${font}.zip" '*.ttf' '*.otf'; \
82
  done && \
10583
  fc-cache -f -v && \
106
  mkdir -p tex && \
10784
  sh install.sh && \
10885
  rm -rf \
...
11592
    $CONTEXT_HOME/tex/texmf-context/doc && \
11693
  mkdir -p $CONTEXT_HOME/tex/texmf-fonts/tex/context/user && \
117
  ln -s $CONTEXT_HOME/tex/texmf-fonts/tex/context/user $HOME/fonts && \
118
  source $PROFILE \
94
  ln -s $CONTEXT_HOME/tex/texmf-fonts/tex/context/user $HOME/.fonts && \
95
  source $PROFILE && \
11996
  mtxrun --generate && \
12097
  find \
M container/README.md
2626
    git push --tags
2727
28
1. Ensure the personal access token exists:
28
1. Ensure the host path file exists; it must include remote server name:
2929
30
    test -f tokens/release.pat && echo "exists"
30
    test -f host-path.txt && echo "exists"
3131
3232
1. Create the release and release notes via the web.
...
5757
1. Compute the SHA:
5858
59
    sha256sum *exe | cut -f1 -d' '
59
    sha256sum *setup.exe | cut -f1 -d' '
6060
6161
1. Edit `src/main/resources/com/keenwrite/messages.properties`.
62
1. Set `Wizard.typesetter.container.version` to the new container version.
62
1. Set `Wizard.typesetter.container.version` to the new executable version.
6363
1. Set `Wizard.typesetter.container.checksum` to the Windows version checksum.
6464
1. Set `Wizard.typesetter.container.image.version` to the new image version.
M container/manage.sh
194194
  # Use array to properly handle empty mount options
195195
  local mount_args=()
196
  [[ -n "${mount_source}" ]] && mount_args+=(${mount_source})
197
  [[ -n "${mount_target}" ]] && mount_args+=(${mount_target})
198
  [[ -n "${mount_images}" ]] && mount_args+=(${mount_images})
199
  [[ -n "${mount_fonts}"  ]] && mount_args+=(${mount_fonts})
200
201
  # Ensure directories exist and log creation
202
  for mount in "${mount_args[@]}"; do
203
    # Extract host path from mount string (format: -v /host:/container)
204
    host_path=$(echo "${mount}" | sed 's/^-v \([^:]*\):.*$/\1/')
196
  [[ -n "${mount_source}" ]] && \
197
    read -ra source_parts <<< "${mount_source}" && \
198
    mount_args+=("${source_parts[@]}")
199
  [[ -n "${mount_target}" ]] && \
200
    read -ra target_parts <<< "${mount_target}" && \
201
    mount_args+=("${target_parts[@]}")
202
  [[ -n "${mount_images}" ]] && \
203
    read -ra images_parts <<< "${mount_images}" && \
204
    mount_args+=("${images_parts[@]}")
205
  [[ -n "${mount_fonts}" ]] && \
206
    read -ra fonts_parts <<< "${mount_fonts}" && \
207
    mount_args+=("${fonts_parts[@]}")
205208
206
    [[ ! -d "$host_path" ]] && \
207
      $log "Create directory: $host_path" && \
208
      mkdir -p "$host_path"
209
  done
209
  # Create host directories for mount points
210
  [[ -n "${ARG_MOUNTPOINT_SOURCE}" && ! -d "${ARG_MOUNTPOINT_SOURCE}" ]] && \
211
    mkdir -p "${ARG_MOUNTPOINT_SOURCE}"
212
  [[ -n "${ARG_MOUNTPOINT_TARGET}" && ! -d "${ARG_MOUNTPOINT_TARGET}" ]] && \
213
    mkdir -p "${ARG_MOUNTPOINT_TARGET}"
214
  [[ -n "${ARG_MOUNTPOINT_IMAGES}" && ! -d "${ARG_MOUNTPOINT_IMAGES}" ]] && \
215
    mkdir -p "${ARG_MOUNTPOINT_IMAGES}"
216
  [[ -n "${ARG_MOUNTPOINT_FONTS}"  && ! -d "${ARG_MOUNTPOINT_FONTS}" ]]  && \
217
    mkdir -p "${ARG_MOUNTPOINT_FONTS}"
210218
211219
  ${CONTAINER_EXE} run \
A docs/01-introduction.md
1
# Introduction
2
3
{{app.title}} is a free desktop editor that transforms Markdown documents into
4
beautifully typeset PDF files. Whether you're crafting technical documentation,
5
reports, academic papers, or creative content, {{app.title}} combines the
6
simplicity and readability of Markdown with high-quality publishing
7
capabilities.
8
9
## Rethink
10
11
The core philosophy behind {{app.title}} may require shifting how you think
12
about writing documents. Unlike traditional word processors that mix content
13
and styling, {{app.title}} aims to completely separate what is written from how
14
it appears. You write in plain text and instruct the computer to typset the
15
document into print-ready PDF files. This approach allows for:
16
17
* **Rebranding** -- Corporations can redesign documents in weeks, not years
18
* **Consistency** -- Ensure uniform, high-quality output across documents
19
* **Future-proof** -- Plain-text files will be readable long after proprietary formats go obsolete
20
* **Version control** -- Plain text works seamlessly with version control systems
21
* **Reproducibility** -- Generate the same output using different systems
22
* **Focus** -- Write without distraction from formatting concerns
23
24
## Reflow
25
26
Learning how {{app.title}} converts plain text into PDF can help understand its
27
usage.
28
29
The original intent of Markdown was to simplify writing web pages. As such,
30
there are numerous tools to convert Markdown to HTML. {{app.title}} goes one
31
step further and converts Markdown to XHTML, which is a *well-formed* version
32
of HTML and also a type of XML. The typesetting system can transform XML
33
documents, and therefore XHTML documents, into typesetting instructions. Those
34
instructions add styling (colours, fonts, layout, etc.) to the final output
35
document.
36
37
In a nutshell: **Markdown → XHTML → TeX → PDF**
38
39
This chain allows separating content (the Markdown source) from presentation
40
(a TeX typesetting system), allowing the two to vary independently.
41
Incidentally, it also allows publishing the same content to the web, styled
42
using cascading stylesheets.
43
44
## Features
45
46
{{app.title}} has numerous tools to assist with document creation.
47
48
### Writing and editing
49
50
Built-in features to help write and edit documents include:
51
52
* **User-defined variables** for consistency, with autocomplete
53
* **Spell checking** to catch typos as you type
54
* **Document outline** for easy navigation in long documents
55
* **File manager** to view related files within the editor
56
* **Word count** and document statistics
57
58
### Export formats
59
60
{{app.title}} provides multiple export formats from Markdown:
61
62
* **PDF files** typeset using the ConTeXt typesetting system
63
* **XHTML files** for publishing to the web
64
* **Markdown** with variables interpolated and substituted
65
66
### Advanced capabilities
67
68
Beyond basic document creation, {{app.title}} includes:
69
70
* **Data visualization** through R integration
71
* **Diagram generation** supporting PlantUML, Mermaid, and other text formats
72
* **Variable interpolation** enables a single source of truth for content
73
* **Internationalization** with font handling for multiple languages
74
* **Mathematical** equations and formulas rendered beautifully
75
76
### User interface
77
78
The user interface has:
79
80
* **Dark mode** and other skin customizations
81
* **Multi-document editing** with detachable tabs
82
* **Live preview** showing formatted output as you write
83
* **Distraction-free** settings when you need to focus
84
85
## Target users
86
87
{{app.title}} is designed for anyone who needs to produce high-quality
88
documents while maintaining control over content and presentation:
89
90
* **Technical writers** creating documentation, user manuals, and specifications
91
* **Researchers and academics** writing papers with mathematical content
92
* **Authors** producing books and long-form content
93
94
## Quick start
95
96
The easiest way to begin using {{app.title}}:
97
98
1. **Download** the application from [keenwrite.com](https://keenwrite.com).
99
1. **Run** the application (no installation necessary).
100
1. **Create** your first document by clicking **File → New**.
101
1. **Start writing** in Markdown format.
102
1. **Preview** your work in the preview tab.
103
1. **Export** to PDF when ready.
104
105
To generate PDF files, you'll also need:
106
107
* The theme pack to apply a look and feel
108
* ConTeXt typesetting system (can be installed automatically)
109
110
If you have opted to download the Java version of {{app.title}}, see
111
[@sec:java-runtime-environment] for installation instructions.
112
113
## Document structure
114
115
This manual is organized to support both newcomers and experienced users
116
seeking specific information. You can read the manual sequentially to build
117
expertise gradually, or jump to specific chapters as needed.
118
119
## Getting help
120
121
When you need assistance or encounter challenges, multiple resources are
122
available to help. If you encounter issues or need assistance:
123
124
* Check the **Troubleshooting** chapter for common problems and solutions
125
* Visit the **Screenshots** chapter to see the interface in action
126
* Consult the **Command-line reference** for automation tasks
127
* Review the **Architecture** chapter if you're interested in extending {{app.title}}
128
129
The remaining chapters will guide you through installation, basic usage, and
130
gradually introduce advanced features.
131
1132
A docs/02-installation.md
1
# Installation
2
3
This chapter covers installing the application and its dependencies, including
4
the typesetting software required for PDF generation. Generating PDF files
5
requires the following components:
6
7
* {{app.title}} binary
8
* {{app.title}} theme pack
9
* ConTeXt typesetting system
10
11
The easiest way to get started is to download a {{app.title}} binary for your
12
operating system, run it, then launch the guided wizard as per [@sec:wizard].
13
The wizard will download and install all necessary components.
14
15
{{app.title}} binaries are self-installing, except for the Java archive
16
(`.jar`) version. Installing the Java archive version is useful for platforms
17
that don't have prebult {{app.title}} binaries. The Java archive version is
18
described in [@sec:java-runtime-environment].
19
20
## Wizard
21
22
Launch the wizard as follows:
23
24
1. [Download](https://keenwrite.com) {{app.title}}.
25
1. Start {{app.title}}.
26
1. Click **File → Export As → PDF**.
27
28
The installation wizard installs a container manager and typesetter container
29
image. The container image is a self-contained operating system that includes
30
the typesetting software, theme pack, and fonts. Using a container reduces the
31
number of manual installation steps.
32
33
## Java Runtime Environment
34
35
Using the Java archive version of {{app.title}} requires the following:
36
37
* `{{install.java}}` file.
38
* Java Runtime Environment (JRE) **{{version.java}}** with JavaFX.
39
* {{app.title}} launch script.
40
41
Software developers may choose to use the Java Development Kit (JDK)
42
**{{version.java}}**.
43
44
### Download {{app.title}}
45
46
[Download](https://keenwrite.com/) the Java archive version of {{app.title}}.
47
48
On Windows:
49
50
1. Create `C:\Users\%USERNAME%\keenwrite`.
51
1. Save `{{install.java}}` into the new directory.
52
53
### JRE with JavaFX
54
55
Install a JRE **{{version.java}}** version that bundles JavaFX.
56
57
1. Visit the BellSoft's Liberica JDK [download page](https://bell-sw.com/pages/downloads/#jdk-24).
58
1. Select the JDK corresponding to **{{version.java}}**.
59
1. Scroll down to the desired operating system.
60
1. Optionally, change the target CPU architecture.
61
1. Set **Package** to: `Full JRE`.
62
1. Download the `.zip` or `.tar.gz` file.
63
64
After downloading the *full* JRE, install it and make sure Java can be found
65
when run. On Unix systems, my preferred installation method follows:
66
67
1. Edit `$HOME/.bashrc`.
68
1. Add `export JAVA_HOME="/opt/jre"`.
69
1. Add `export PATH="${PATH}:{{install.path.unix.bin}}:${JAVA_HOME}/bin"`.
70
1. Save the file.
71
1. Install into `/opt/jre-{{version.java}}-full` and link to `/opt/jre`:
72
    ``` bash
73
    sudo su -
74
    cd /opt
75
    JAVA_DIR="jre-{{version.java}}-full"
76
    mkdir "${JAVA_DIR}"
77
    tar xf bellsoft-jre{{version.java}}-linux-amd64-full.tar.gz \
78
      -C "${JAVA_DIR}" --strip-components=1
79
    ln -sf "${JAVA_DIR}" jre
80
    ```
81
82
Pointing the symbolic link `/opt/jre` to `/opt/jre-{{version.java}}-full`
83
enables upgrading the JRE without having to update the `.bashrc` for each
84
new version.
85
86
### Unix launch script
87
88
On Unix-based systems (Linux, macOS, FreeBSD, alpine, etc.), install the
89
launch script as follows:
90
91
1. Open a terminal.
92
1. Download the launcher script into `{{install.path.unix.bin}}`.
93
94
   ``` bash
95
   wget --quiet --content-on-error \
96
     "{{install.url.unix.launcher}}"
97
   ```
98
99
1. Make the script executable.
100
101
   ``` bash
102
   chmod +x "{{install.unix.java}}"
103
   ```
104
105
1. Download or move the `.jar` file into `{{install.path.unix.bin}}`.
106
107
Provided `{{install.path.unix.bin}}` is part of the `PATH` environment
108
variable, {{app.title}} can be run by typing `{{install.unix.java}}` and
109
pressing [⏎ Enter]{.kbd}.
110
111
### Windows launch script
112
113
On Windows-based systems, install the launch script as follows:
114
115
1. Browse to the [launcher script]({{install.url.windows.script}}).
116
1. Right-click anywhere on the page.
117
1. Click **Save Page As** (or similar).
118
1. Browse to `C:\Users\%USERNAME%\keenwrite`.
119
1. Confirm saving the file.
120
1. Rename the file from `.bat.txt` to `.bat`, if necessary.
121
122
The Java version of {{app.title}} is installed.
123
124
## ConTeXt LMTX
125
126
For users who prefer more control over the installation process, manually
127
download and configure the typesetting software as follows:
128
129
1. Start {{app.title}}.
130
1. Click **File → Export As → PDF**.
131
1. Note the following details (e.g., Windows x86 64-bit):
132
    * operating system name;
133
    * instruction set; and
134
    * architecture.
135
1. Click the [install page](https://wiki.contextgarden.net/Introduction/Installation) link in the dialog.
136
1. Download the archive file for your operating system and architecture.
137
138
Follow the steps that apply to the computer's operating system:
139
140
* [Unix](#unix) (includes macOS, FreeBSD, Linux, and similar)
141
* [Windows](#windows) (includes Windows 7, Windows 10, and similar)
142
143
### Unix
144
145
On Linux, macOS, FreeBSD, and similar systems, replace `context-linux-64.zip`
146
with the version appropriate to your operating system and CPU architecture.
147
Proceed:
148
149
1. Open a terminal.
150
1. Run the following commands:
151
152
   ``` bash
153
   sudo su -
154
   export CONTEXT_FILE="context-linux-64.zip"
155
   export CONTEXT_DIR="/opt/context"
156
   mkdir -p "${CONTEXT_DIR}"
157
   cd "${CONTEXT_DIR}"
158
   wget "https://lmtx.pragma-ade.nl/install-lmtx/${CONTEXT_FILE}"
159
   unzip "${CONTEXT_FILE}"
160
   rm "${CONTEXT_FILE}"
161
   chmod +x install.sh
162
   ./install.sh
163
   exit
164
   echo export CONTEXT_HOME=\"${CONTEXT_DIR}\" >> ${HOME}/.bashrc
165
   echo PATH="\"\${PATH}:\${CONTEXT_HOME}/tex/texmf-linux-64/bin\"" \
166
     >> ${HOME}/.bashrc
167
   source ${HOME}/.bashrc
168
   ```
169
170
ConTeXt is installed; jump to [@sec:verification].
171
172
### Windows
173
174
On a Windows operating system, install the typesetting software as follows:
175
176
1. Extract the `.zip` file into `C:\Users\%USERNAME%\AppData\Local\context` (the "root" directory).
177
1. Run **install.bat** to download and install the software.
178
   * If prompted, click **Run** (or click **More info** first).
179
1. Download [localpath.bat]({{install.url.windows.path}}).
180
1. Save the file to the typesetting software's "root" directory.
181
1. Rename the file from `.bat.txt` to `.bat`, if necessary.
182
1. Run `localpath.bat` (to set and save the `PATH` environment variable).
183
184
ConTeXt is installed.
185
186
### Verification
187
188
After completing the installation process, verify that the typesetting software
189
has been installed correctly as follows:
190
191
1. Open a new terminal or command prompt.
192
1. Type: `context --version`
193
1. Press [⏎ Enter]{.kbd}.
194
195
If version information is displayed then the software is installed correctly.
196
197
## Theme packs
198
199
Theme packs define the visual appearance and styling of typeset documents.
200
Installing and configuring theme packs is essential for producing high-quality
201
PDF files. Each theme has its own requirements.
202
203
### Install theme pack
204
205
Install and configure the theme pack as follows:
206
207
1. Download the [theme-pack.zip](https://gitlab.com/DaveJarvis/keenwrite-themes/-/releases/permalink/latest/downloads/theme-pack.zip) archive.
208
1. Extract the archive.
209
   - On Unix, use `{{install.config.unix}}/`.
210
   - On Windows, use `{{install.config.win}}\`.
211
1. Start {{app.title}}, if not already running.
212
1. Click **Edit → Preferences**.
213
1. Click **Typesetting**.
214
1. Click **Browse** beside **Themes**.
215
1. Navigate to the `themes` directory.
216
   - On Unix, `{{install.config.unix}}/themes/`.
217
   - On Windows, `{{install.config.win}}\themes\`.
218
1. Click **Open**.
219
1. Click **OK**.
220
221
The theme pack is installed.
222
223
### Configure theme
224
225
Once a theme pack is installed, additional configuration may be required based
226
on the theme's formatting needs. Configure individual themes based on their
227
specific requirements. For example, the _Boschet_ theme requires downloading
228
and installing specific font families, which include:
229
230
* [Inconsolata]({{fonts.url}}/inconsolata.zip)
231
* [Libre Baskerville]({{fonts.url}}/libre-baskerville.zip)
232
* [Niconne]({{fonts.url}}/niconne.zip)
233
* [Open Sans Emoji]({{fonts.url}}open-sans-emoji.zip)
234
* [Source Serif 4]({{fonts.url}}/source-serif-4.zip)
235
* [TW Kai]({{fonts.url}}/tw-kai.zip)
236
* [Underwood Quiet Tab]({{fonts.url}}/underwood.zip)
237
238
See your operating system instructions for how to install a font.
239
240
When running ConTeXt within the typesetter container image, all fonts are
241
included.
242
243
## Run
244
245
Running {{app.title}} will depend on the operating system and installation
246
method. [@tbl:install-app-launchers] lists the executable file name used to
247
start the application.
248
249
| Operating System | Method       | Launcher file name |
250
|------------------|--------------|-----------------|
251
| Unix             | Binary       | `{{install.unix.native}}` |
252
| Unix             | Java archive | `{{install.unix.java}}`   |
253
| macOS            | Binary       | `{{install.mac.native}}`  |
254
| macOS            | Java archive | `{{install.mac.java}}`    |
255
| Windows          | Binary       | `{{install.win.native}}`  |
256
| Windows          | Java archive | `{{install.win.java}}`    |
257
258
:: {{app.title}} launchers {#tbl:install-app-launchers}
259
1260
A docs/03-quick-start.md
1
# Overview
2
3
This chapter describes how to basic editing functionality.
4
5
## First document
6
7
Create and open a document as follows:
8
9
1. Start {{app.title}}.
10
1. Click **File → Save As** to save the untitled file.
11
1. Set the file name to: `metadata.yaml`
12
1. Save the (empty) file.
13
1. Click **File → Open** to load the variable definition file.
14
1. Change **Source Files** to **Variable Files** to list variable definition files.
15
1. Browse to and select the `.yaml` file.
16
1. Click **Open**.
17
18
The variable definitions appear in the variable definition tab under the heading of **Variables**.
19
20
## Basic syntax
21
22
The editor supports standard Markdown features listed in [@tbl:markdown-syntax-basic]. While editing, try the toolbar icons to see how formatting appears in the preview tab.
23
24
| Style              | Syntax                        |
25
|--------------------|-------------------------------|
26
| **Bold**           | `**strong**`                  |
27
| *Italic*           | `*emphasis*` or `_emphasis_`  |
28
| ~~Struck text~~    | `~~struck~~`                  |
29
| Horizontal rule    | `---` on an empty line        |
30
| Unordered lists    | `- item` or `* item`          |
31
| Ordered lists      | `1. item`                     |
32
| Inline `code`      | `` `code` ``                  |
33
| Links              | `[label](url)`                |
34
| Images             | `![alt text](resource)`       |
35
| Blockquotes        | `> quoted text`               |
36
| Headings           | `#`, `##`, `###`              |
37
38
:: Basic Markdown syntax {#tbl:markdown-syntax-basic}
39
40
Remember that most of these items are suggestions to the presentation layer.
41
How they may appear in the final document may differ from what you anticipate.
42
43
## Preview
44
45
The preview tab updates in real time as you type. For example, if your variable file contains:
46
47
```yaml
48
novel:
49
  title: "Diary of {{novel.author}}"
50
  author: "Anne Frank"
51
```
52
53
Then typing:
54
55
```
56
The novel *{{novel.title}}* is a widely read book.
57
```
58
59
Will render as:
60
61
> The novel *Diary of Anne Frank* is a widely read book.
62
63
To autocomplete variable names:
64
65
1. Create a new file.
66
1. Type in a partial variable value, such as `Dia`.
67
1. Press [Ctrl+Space]{.kbd} (hold down the [Control]{.kbd} key and tap [Space]{.kbd}).
68
69
The editor inserts:
70
71
```
72
{{novel.title}}
73
```
74
75
And the preview tab shows:
76
77
> Diary of Anne Frank
78
79
## Export
80
81
To export your document as a PDF:
82
83
1. Click **File → Export As → PDF**.
84
1. Select a theme from the drop-down list.
85
1. Click **OK** or press [⏎ Enter]{.kbd}.
86
1. Choose a file name and location.
87
1. Click **Save**.
88
89
The document will be typeset using ConTeXt and saved as a PDF. You can view it in any PDF reader.
90
91
To combine multiple documents into one PDF:
92
93
1. Click **File → Export As → Joined PDF**.
94
1. Or press [Ctrl+Shift+p]{.kbd}.
95
196
A docs/04-variables.md
1
# Variables
2
3
Variables are placeholders for values that can be defined once and reused
4
throughout the document. When the document is built, each variable is replaced
5
with its corresponding value.
6
7
## File format
8
9
YAML (meaning, *YAML Ain't Markup Language*) is a plain-text format used for
10
storing structured data. It's commonly used in configuration files due to its
11
readability and simplicity. YAML files allow encoding key-value pairs within
12
a nested hierarchy.
13
14
Any number of variables can be defined, in any order:
15
16
``` yaml
17
key_1: Value 1
18
key_2: Value 2
19
```
20
21
A variable's value can reference other variables by enclosing the referenced
22
key in double curly braces (`{{ }}`)---also known as "moustache"
23
notation---wrapped in quotation marks:
24
25
``` yaml
26
key: Value
27
key_1: "{{key}} 1"
28
key_2: "{{key}} 2"
29
```
30
31
Variables can be nested to group related information:
32
33
``` yaml
34
document:
35
  title: Document Title
36
  author: Author Name
37
  isbn: 978-3-16-148410-0
38
```
39
40
Reference nested keys using a period, such as:
41
42
``` yaml
43
novel:
44
  author: Author Name
45
copyright:
46
  owner: "{{novel.author}}"
47
```
48
49
## Usage
50
51
The preview tab updates as you type. Imagine a variable file contains:
52
53
``` yaml
54
novel:
55
  title: "Diary of {{novel.author}}"
56
  author: "Anne Frank"
57
```
58
59
Then typing:
60
61
```
62
The novel *{{novel.title}}* is a widely read book.
63
```
64
65
Displays in the preview pane as:
66
67
> The novel *Diary of Anne Frank* is a widely read book.
68
69
## Autocomplete
70
71
Typing variable names is laborious. To autocomplete variable names:
72
73
1. Type in a partial variable value, such as `Dia`.
74
1. Press [Ctrl+Space]{.kbd} (hold down the [Control]{.kbd} key and tap [Space]{.kbd}).
75
76
The editor inserts:
77
78
```
79
{{novel.title}}
80
```
81
82
And the preview tab shows:
83
84
> Diary of Anne Frank
85
186
A docs/05-metadata.md
1
# Metadata
2
3
Metadata is information about a document such as title, author keywords,
4
copyright date, ISBN, and more. Most systems require coupling metadata directly
5
to the source document. {{app.title}} fetches reads metadata from the variable
6
definitions file instead. This allows reusing the same metadata across
7
documents.
8
9
Metadata can be inserted into the output document either through the document
10
properties in the user interface or via the command line.
11
12
## Document properties
13
14
Metadata can be mapped in the user preferences, shown in [@fig:gui-metadata].
15
When the document is exported, the document metadata variables are added to the
16
`<head>` tag as `<meta>` tags.
17
18
![Metadata screenshot](images/screenshots/09.png)
19
20
:: Document metadata preferences {#fig:gui-metadata}
21
22
The **Key** column lists metadata names and the **Value** column lists the
23
metadata content for each corresponding **Key**. The content may include
24
references to variable definitions. When the document is typeset, the values
25
for the variables will be substituted upon export. When exporting to XHTML
26
format, the header will include the keys and values as `<meta>` tags. For
27
example:
28
29
``` html
30
<head>
31
  <title>Document Title</title>
32
  <meta content="science, nature" name="keywords"/>
33
  <meta content="Penn Surnom" name="author"/>
34
  <meta content="4311" name="count"/>
35
</head>
36
```
37
38
## Command-line
39
40
Recall the document metadata from earlier:
41
42
``` yaml
43
document:
44
  title: Document Title
45
  author: Author Name
46
```
47
48
These data can be provided via command-line arguments as follows:
49
50
``` bash
51
keenwrite.bin \
52
  -i "01-introduction.md" \
53
  -v "metadata.yaml" \
54
  --metadata="title={{document.title}}" \
55
  --metadata="author={{document.author}}"
56
```
57
58
The resulting XHTML document will resemble:
59
60
``` html
61
<head>
62
  <title>Document Title</title>
63
  <meta content="Author Name" name="author"/>
64
  <meta content="1234" name="count"/>
65
</head>
66
```
67
68
We'll take a deeper look at command-line usages in
69
[@cha:command-line-interface].
70
71
## Special fields
72
73
Certain metadata keys have special handling and formatting rules when documents
74
are exported to different formats. When exporting the document, note the
75
following special metadata:
76
77
* **count** -- Document word count, always included.
78
* **author** -- Included as PDF metadata.
79
* **keywords** -- Included as PDF metadata.
80
* **document.title** -- Populates the `<title>` tag, not a `<meta>` tag.
81
82
Except for **count**, all of these metadata variables can be customized.
83
84
Some themes, such as *Handrit*, have additional metadata that may be included
85
in the final document automatically. *Handrit*, in particular, has a way to
86
pass in a pseudonym (or by-line) for publishing manuscripts under a pseudonym.
87
188
A docs/06-basic-markdown.md
1
# Basic Markdown
2
3
This section outlines the basic Markdown syntax supported by {{app.title}},
4
including paragraphs, headers, lists, links, and more. Countless Markdown
5
syntax resources exist, so only a brief refresher is provided.
6
7
## Paragraphs
8
9
Paragraphs are created by separating blocks of text with one or more blank
10
lines.
11
12
``` markdown
13
This is the first paragraph.
14
15
This is the second paragraph.
16
```
17
18
Without a blank line, the prose will be typeset as a single paragraph.
19
20
## Headers
21
22
Headers are created using one or more hash (`#`) symbols followed by a space
23
and the header text. The number of hash symbols indicates the level of the
24
header. While not strictly necessary, adding a blank line after a header can
25
make the document easier to read in its plain-text format.
26
27
``` markdown
28
# Header level 1
29
30
## Header level 2
31
32
### Header level 3
33
```
34
35
In technical documents, try to limit subheading levels to maintain clarity;
36
usually, three levels are sufficient.
37
38
## Lists
39
40
Ordered lists use numbers followed by a period and a space. Unordered lists
41
use asterisks (`*`), plus signs (`+`), or hyphens (`-`) followed by a space.
42
43
### Ordered list
44
45
My preference is to use `1.` for each ordered item and let the computer
46
renumber them because it makes adding and removing items faster, and
47
guarantees that there will never be a number skipped.
48
49
``` markdown
50
1. First item
51
1. Second item
52
1. Third item
53
```
54
55
### Unordered list
56
57
My preference is to use `*` for the first level of unordered items.
58
59
``` markdown
60
* Item one
61
* Item two
62
* Item three
63
```
64
65
## Links
66
67
Create links using square brackets for the link text followed by parentheses
68
for the URL.
69
70
``` markdown
71
[Download](https://keenwrite.com)
72
```
73
74
## Tables
75
76
Tables use pipes (`|`) to indicate separate columns and hyphens (`-`) to mark
77
the header row. Markdown does not define a syntax for table footers.
78
79
``` markdown
80
| Column A | Column B | Column C |
81
|----------|----------|----------|
82
| Value 1  | Value 2  | Value 3  |
83
| Value 4  | Value 5  | Value 6  |
84
```
85
86
Table cell justification can be suggested using a colon (`:`) on the left,
87
right, or both sides (centering) of the header separator line.
88
89
``` markdown
90
| Column A   | Column B  |  Column C |
91
|:-----------|:---------:|----------:|
92
| Value 1    |  Value 2  |   Value 3 |
93
| Value 4    |  Value 5  |   Value 6 |
94
```
95
96
The colon location is a hint to the presentation layer, which has the
97
freedom to ignore it.
98
199
A docs/07-advanced-markdown.md
1
# Extended Markdown
2
3
This chapter covers advanced formatting features that enhance document
4
structure and presentation. These features help create professional documents
5
with rich content organization, proper cross-referencing, and typographic
6
excellence.
7
8
## Fenced divs
9
10
Fenced divs are transformed into XHTML `div` elements. They allow semantic
11
organization and styling beyond standard Markdown.
12
13
### Basic syntax
14
15
A fenced div starts with at least three colons (`:::`), followed by one or more
16
spaces, and then any word. Content follows immediately on the next line.
17
Fences must be terminated with at least three colons alone on a line. For
18
example:
19
20
``` markdown
21
::: name
22
Content
23
:::
24
```
25
26
The output resembles:
27
28
``` html
29
<div class="name">
30
<p>Content</p>
31
</div>
32
```
33
34
### Extended syntax
35
36
Fenced divs have an extended syntax for more influence over the presentation.
37
The syntax allows for a unique identifier (marked with a hash, `#`), multiple
38
classes (each starting with a period, `.`), and key-value pairs (of the form
39
`name=value`):
40
41
``` markdown
42
::: {#poem-01 .stanza author="Emily Dickinson" year=1890}
43
Because I could not stop for Death --
44
He kindly stopped for me --
45
The Carriage held but just Ourselves --
46
And Immortality.
47
:::
48
```
49
50
This produces:
51
52
``` html
53
<div id="poem-01" class="stanza" data-author="Emily Dickinson" data-year="1890">
54
<p>Because I could not stop for Death –
55
He kindly stopped for me –
56
The Carriage held but just Ourselves –
57
And Immortality.</p>
58
</div>
59
```
60
61
While this syntax is not standard Markdown (i.e., CommonMark), it is supported
62
by many tools, including pandoc.
63
64
### Nested syntax
65
66
Fenced blocks may be nested to create hierarchical document structures:
67
68
``` markdown
69
::: poem
70
:::::: stanza
71
Because I could not stop for Death --
72
He kindly stopped for me --
73
The Carriage held but just Ourselves --
74
And Immortality.
75
::::::
76
:::
77
```
78
79
This produces nested `div` elements:
80
81
``` html
82
<div class="poem"><div class="stanza">
83
<p>Because I could not stop for Death –
84
He kindly stopped for me –
85
The Carriage held but just Ourselves –
86
And Immortality.</p>
87
</div></div>
88
```
89
90
Such nesting can help with complex presentation logic.
91
92
## Code blocks
93
94
In technical documentation, source code snippets help explain algorithms.  An
95
example snippet syntax is given in the following quintessential BASIC program:
96
97
    ``` basic
98
    10 print "hi"
99
    20 goto 10
100
    ```
101
102
The word `basic` suggests that the presentation layer colourise the syntax
103
according to the rules of the BASIC programming language. Code blocks are also
104
used to draw diagrams using text-based syntaxes. See [@sec:text-diagrams] for
105
details.
106
107
## Inline classes
108
109
Inline classes can be assigned to words or phrases. This allows presentation
110
logic to stylize words based on their classification. The general form of
111
inline classes follows:
112
113
``` markdown
114
[word]{.class}
115
```
116
117
For example:
118
119
``` markdown
120
[radiation]{.glossary .warning}
121
```
122
123
The given example outputs the following XHTML:
124
125
``` html
126
<span class="glossary warning">radiation</span>
127
```
128
129
Note the semantic `warning` class instead of a direct colour class such
130
as `red`. This allows the colour to be changed at the presentation layer
131
without the class name becoming stale.
132
133
## Captions and cross-references
134
135
Captions provide context and descriptions for tables, figures, equations, and
136
so forth. Cross-references allow linking to captioned items throughout the
137
document.
138
139
### Caption syntax
140
141
A caption *must* start with a double colon (`::`) and *must* be separated by a
142
blank line from the item it describes.
143
144
For images:
145
146
``` markdown
147
![image title](https://example.com/image.png)
148
149
:: Figure caption text
150
```
151
152
For tables:
153
154
``` markdown
155
| a | b | c |
156
|---|---|---|
157
| 1 | 2 | 3 |
158
| 4 | 5 | 6 |
159
160
:: Table caption text
161
```
162
163
For equations:
164
165
``` markdown
166
$$E = mc^2$$
167
168
:: Equation caption text
169
```
170
171
Note that this syntax is not supported by any other Markdown tool.
172
173
### Cross-references
174
175
Cross-references use anchor type names and unique identifiers such as:
176
177
- `{#type-name:id}` -- defines an anchor name
178
- `[@type-name:id]` -- references the anchor
179
180
Example image with cross-reference:
181
182
``` markdown
183
There is no cuter animal than the one in [@fig:animal].
184
185
![image title](https://placecats.com/500/300)
186
187
:: World's cutest animal {#fig:animal}
188
```
189
190
Anchors can include any type name and identifier, such as:
191
192
``` markdown
193
{#fig:cats}
194
{#图版:猫}
195
{#eq:mass-energy}
196
{#eqn:laplace}
197
```
198
199
### Predefined type names
200
201
To simplify writing captions and references, predefined type names correspond
202
to labels commonly used in documents. [@tbl:type-names] lists predefined
203
cross-reference type names along with their associated labels. Labels are
204
inserted into the document automatically.
205
206
| Type name                        | Label        |
207
|----------------------------------|--------------|
208
| algorithm, alg                   | Algorithm    |
209
| equation, eqn, eq                | Equation     |
210
| figure, fig                      | Figure       |
211
| formula                          | Formula      |
212
| listing, list, lst, source, src  | Listing      |
213
| lyric                            | Lyrics       |
214
| music, score                     | Score        |
215
| table, tbl, tab                  | Table        |
216
217
:: Cross-reference types and labels {#tbl:type-names}
218
219
You may add your own labels as follows:
220
221
1. Edit `xml-references.tex` in the `xhtml` theme subdirectory.
222
1. Insert a new line within the `ReferenceLabels` data set:
223
224
   ``` tex
225
   \setdataset[ReferenceLabels][en][
226
     typename=label,
227
   ]
228
   ```
229
1. Ensure there's a trailing comma (`,`).
230
1. Save the file.
231
232
## Quotation marks
233
234
{{app.title}} integrates KeenQuotes, a library for curling straight quotes in
235
both British and American English, with a high degree of
236
accuracy. To achieve this, all straight quotes are examined throughout the
237
document and, based on context, emitted as a particular entity encoding.
238
239
Understanding quotation mark encoding helps ensure proper typography in both
240
digital and print formats. Different encoding options provide flexibility for
241
various output requirements. [@tbl:quote-encoding] lists available encoding
242
choices.
243
244
| Option   | Encoding   | Description                                 |
245
|----------|------------|---------------------------------------------|
246
| regular  |            | Do not encode                               |
247
| apos     | `&apos;`   | Curled when typeset to PDF                  |
248
| aposhex  | `&#x27;`   | Apostrophe's numeric value                  |
249
| quote    | `&rsquo;`  | Right single quotation mark                 |
250
| quotehex | `&#8217;`  | Right single quotation mark's numeric value |
251
| modifier | `&#x2bc;`  | The modifier letter apostrophe              |
252
253
:: Single straight quote encoding options {#tbl:quote-encoding}
254
255
When typesetting to PDF, only the semantically correct `&apos;` value will be
256
curled. Authors may enter quotation marks by hand (`“”`), which will typeset as
257
expected.
258
259
### History
260
261
The origins of quotation marks trace back to scholarly annotation practices in
262
Ancient Greece. Greek scribes used marginal symbols like the diplé (`⟩`) to
263
highlight notable passages. A variant, the diplé periestigmene (`⸖`)—a diplé
264
accompanied by dots—was used by scholars to indicate disagreement with earlier
265
interpretations. These marks laid the groundwork for distinguishing quoted
266
text.
267
268
By the seventeenth century, quotation marks appeared regularly in printed
269
texts. Western European typographers in the nineteenth century adopted the
270
convention of turning quotation mark pairs outward, creating the familiar
271
"double curved" style.
272
273
Early mechanical typewriters lacked many punctuation marks. Straight single and
274
double quotes served multiple roles: quotation marks, apostrophes, feet and
275
inches, and mathematical primes. Computer character sets later codified
276
straight quotes (such as ASCII character 34, `"`), creating ongoing
277
typographical challenges.
278
279
Modern standards recommend using the right single quotation mark (`’`) for
280
apostrophes, though this creates semantic ambiguity since the same character
281
also closes dialogue. Consider the sentence:
282
283
> Ambiguity lurks in \"\'cause the horses\'\".
284
285
The meaning of `'cause` (*because* vs. *induce*) determines whether to use an
286
opening quote or apostrophe; historical decisions still impact modern
287
typography.
288
289
## Summary
290
291
[@tbl:markdown-extended-syntax] summarizes the syntaxes described in this
292
chapter.
293
294
| Syntax                 | Meaning                   | Marks                 |
295
|------------------------|---------------------------------------------------|
296
| `::: name` ¶ `:::`     | Fenced div                  | Triple colons       |
297
| ` ``` name` ¶ ` ``` `  | Code block                  | Triple backticks    |
298
| `[word]{.class}`       | Inline class                | Brackets and braces |
299
| `{#type:id}`           | Cross-reference definition  | Braces and hash     |
300
| `[@type:id]`           | Cross-reference anchor link | Brackets and at     |
301
302
:: Extended syntax {#tbl:markdown-extended-syntax}
303
304
Note that the pilcrow (`¶`) means that the opener is separated from its closer
305
by one or more blank lines (i.e., paragraphs).
306
1307
A docs/08-images.md
1
# Images
2
3
This chapter covers how to insert and manage document images. You can embed
4
standard images, create text-based diagrams, and---as we'll see
5
later---integrate plots from R.  The application supports various image formats
6
and provides flexible path resolution for both local and remote images.
7
8
## Inserting images
9
10
Insert an image into your Markdown document using the following syntax:
11
12
``` markdown
13
![image description](path)
14
```
15
16
Replace `image description` with a descriptive caption for the image and `path`
17
with either a local file path or URL where the image is located.
18
19
For example, to embed a local image file named `chart.png` located in the same
20
directory as your document, you could write:
21
22
``` markdown
23
![Sales Chart](chart.png)
24
```
25
26
To embed an image from a remote server, use its URL:
27
28
``` markdown
29
![Company Logo](https://keenwrite.com/images/logo/title.svg)
30
```
31
32
The application will display the image in the preview tab upon download.
33
34
## Image server
35
36
By default, all text diagrams are sent to [Kroki](https://kroki.io) for
37
conversion into SVG images. A network connection is required to render all text
38
diagrams. There is a configuration option to change servers and Kroki is
39
open-source software, so it is possible to keep all source diagrams on premises
40
by setting up a locally hosted image server.
41
42
## Text diagrams
43
44
{{app.title}} distinguishes between diagrams and source code listings by
45
prefixing diagrams with a `diagram-` prefix, such as:
46
47
    ``` diagram-plantuml
48
    @startuml
49
    Alice -> Bob: Hello
50
    @enduml
51
    ```
52
53
This has a few benefits. First, it allows rendering diagram types using a
54
service without having to codify all possible diagram types. Second, when a new
55
type of diagram is added, it's available immediately without needing to upgrade
56
the text editor. Third, it clearly distinguishes between a code block to be
57
rendered visually and one to be listed as verbatim source code.
58
59
Typically, source code is presented in code blocks that include the language
60
name so that syntax highlighting can be applied:
61
62
    ``` c
63
    main() {
64
        printf( "hello, world" );
65
    }
66
    ```
67
68
### Mermaid
69
70
GitHub created a *de facto* standard that prevents parsers from dynamically
71
distinguishing between a diagram to render and source code to list. The
72
following code block could be either a source code listing or a pie chart:
73
74
    ``` mermaid
75
    pie
76
        title Turkish Empire Proportions, 1789
77
        "Asia" : 66
78
        "Africa" : 20
79
        "Europe" : 14
80
    ```
81
82
While tagging the block as `mermaid-lang` could help, it creates a special case
83
that needs to be programmed into Markdown parsers. (Having both `c-lang` and
84
`c` is redundant.) The `diagram-` prefix side-steps the issue while keeping
85
true to the human-readability nature of Markdown. For this reason, using
86
`mermaid` alone for a fenced code block will show the source code rather than
87
draw a diagram.
88
89
## Image paths
90
91
Image file discovery enables flexible and intelligent handling of image links
92
within documents. It supports both remote and local image sources, and attempts
93
to resolve incomplete or relative paths.
94
95
### Resolution strategy
96
97
The algorithm follows a multi-step process to determine the file to display:
98
99
1. **Remote URLs** -- If the image reference begins with a remote protocol
100
(e.g., `http://`, `https://`), it is accepted as valid and used directly.
101
1. **Fully qualified paths** -- If the image refers to a specific file
102
path on the local system and the file is readable, it is used as-is.
103
1. **Relative paths** -- For unqualified links, the system checks if the image
104
exists relative to the base directory of the current document. If not found,
105
and there's no extension, all common image file name extensions (e.g., `.svg`,
106
`.png`, `.jpg`) are tried.
107
108
If the image cannot be resolved through any of the above methods, an error is
109
logged to indicate the missing file.
110
111
### Resolution example
112
113
A document that includes `![Logo](company-logo)` is resolved as follows:
114
115
1. If `company-logo` is a remote URL, try to fetch it.
116
1. Look for a local file named `company-logo`.
117
1. Look for a file named `company-logo` in a specified images directory.
118
1. Look for `company-logo.png`, `company-logo.jpg`, etc.
119
1. Use the first valid readable matching file found.
120
1. Log an error if the file cannot be found.
121
1122
A docs/09-exporting.md
1
# Exporting documents
2
3
{{app.title}} can convert Markdown documents to XHTML, PDF, and plain text
4
formats. The application has conveniences for concatenating multiple files
5
together prior to typesetting.
6
7
## Collating
8
9
When exporting multiple documents, the application uses an alphanumeric sorting
10
algorithm to determine the order files are concatenated prior to processing.
11
This files are collated in a natural order that honours both alphabetic and
12
numeric sequences within file names.
13
14
Consider the following file names:
15
16
```
17
chapter_1.md
18
chapter_2a.md
19
chapter_3.md
20
chapter_10.md
21
```
22
23
Without alphanumeric sorting, `chapter_10.md` would incorrectly appear before
24
`chapter_2a.md` in a standard alphabetic sort because the computer would
25
otherwise compare the _text_ `1` vs. `2` rather than the _numbers_ `10` vs. `2`.
26
27
## Batch Processing
28
29
The application can process a single document or multiple documents. Batch
30
processing automatically discovers and processes additional files based on the
31
actively edited file's location and extension.
32
33
### Single document export
34
35
Export a single document as follows:
36
37
1. Open the document to export.
38
1. Click **File → Export As → PDF** (or type [Ctrl+p]{.kbd}).
39
1. Select a theme from the drop-down list.
40
1. Set the output file name.
41
1. Click **Save**.
42
43
The document is exported.
44
45
### Multi-document export
46
47
Export multiple documents into a single, concatenated file:
48
49
1. Open any document in the directory containing files to export.
50
1. Click **File → Export As → Joined PDF** (or type [Ctrl+Shift+p]{.kbd}).
51
1. Select a theme from the drop-down list.
52
1. Set the output file name.
53
1. Click **Save**.
54
55
The application searches recursively through the directory hierarchy starting
56
from the actively edited file's location. All files with the same extension are
57
discovered, sorted using the alphanumeric algorithm, and concatenated prior
58
to exporting.
59
60
If the first file processed contains numeric digits in its name, only files
61
containing numeric digits will be included in the export. If the first file
62
contains no digits, all matching files are processed in alphabetical order.
63
64
### Chapter ranges
65
66
Chapter ranges can be restrict exporting to specific chapters.  The range
67
specification supports several formats:
68
69
* Individual chapters: `1,3,5` exports only chapters 1, 3, and 5.
70
* Range: `1-5` exports chapters 1 through 5, inclusive.
71
* Starting range: `-5` exports chapters 1 through 5.
72
* Open-ended range: `3-` exports chapter 3 and all subsequent chapters.
73
* Multiple ranges: `1,3-7,10-` exports chapter 1, chapters 3 through 7, and chapter 10 onwards.
74
75
## XHTML exports
76
77
The application produces standards-compliant XHTML documents that can be viewed
78
in web browsers or further processed. XHTML export features include:
79
80
* Document metadata is added to the `<head>` tag as `<meta>` tags
81
* Diagrams and visualizations are embedded as `<image>` elements
82
* Cross-references and internal links are preserved
83
* Mathematical expressions can be output in multiple formats
84
85
Mathematical expressions in XHTML exports can be rendered as:
86
87
* TeX notation for processing by KaTeX or MathJax; or
88
* SVG images for direct display without requiring additional libraries.
89
90
## PDF exports
91
92
PDF exports use the ConTeXt typesetting system to produce high-quality output.
93
Mathematical expressions are rendered directly by TeX-based software, ensuring
94
optimal typography for technical content.  Before exporting to PDF format, be
95
sure to have installed the theme pack and ConTeXt. See [@cha:installation] for
96
details.
97
98
## Theme selection
99
100
Themes control the visual appearance of exported PDF documents, including
101
fonts, spacing, colours, and layout. The application includes several predefined
102
themes, each optimized for different document types and purposes.
103
104
Some themes include:
105
106
* ***Boschet*** -- Based on Baskerville font with elegant styling.
107
* ***Handrit*** -- Double-spaced manuscript format using a courier font.
108
* ***Tarmes*** -- Based on Times Roman font with minimal styling.
109
* ***TeXomus*** -- A format suitable for technical documentaion.
110
111
Theme selection is available during PDF export through the theme drop-down menu
112
in the export dialog. Each theme may have specific font requirements that must
113
be installed separately.
114
115
Create themes by copying and modifying existing ones (e.g., *TeXomus* or
116
*Tarmes*).
117
1118
A docs/10-themes.md
1
# Themes
2
3
Themes in {{app.title}} define the visual appearance and layout of typeset PDF
4
documents. They control elements fonts, spacing, colours, page dimensions, and
5
structural formatting. Users can achieve high-quality outputs without modifying
6
document content. Themes are based on ConTeXt setups and can be selected during
7
PDF export to match different document purposes, such as manuscripts, user
8
manuals, or wills.
9
10
## Customization
11
12
Users may define unique document appearances by creating new theme setups. This
13
involves structuring a theme directory with required files to integrate with
14
the application's typesetting process.
15
16
All themes must have:
17
18
* a separate directory;
19
* a main entry point;
20
* a reference to XHTML setups; and
21
* a properties file.
22
23
For example, a new theme named "dīvus" would have the following file structure,
24
relative to the themes directory:
25
26
```
27
dīvus/
28
├── main.tex
29
├── xhtml.tex
30
└── theme.properties
31
```
32
33
### Theme directory
34
35
The theme directory organizes all files for a single theme. For consistency,
36
the theme directory name:
37
38
* must not include spaces;
39
* must a sibling directory of all other themes;
40
* should be lowercase; and
41
* should be a single word (Latin works well).
42
43
### Entry point
44
45
The theme's main entry point defines how the document is presented during
46
typesetting. The main entry point, `main.tex`, is passed to the typesetting
47
software by the editor immediately prior to typesetting. The purpose of the
48
entry point is to import all the other files that define how the document is to
49
be presented.
50
51
Minimally, the file must include the XHTML setups file, which may be
52
accomplished with the following line:
53
54
``` tex
55
\input xhtml
56
```
57
58
### XHTML setups
59
60
XHTML setups map document elements to typesetting commands. To typeset the
61
document, the editor first converts the content into a data format known as
62
XHTML. Using XHTML allows mapping common document elements to commands that the
63
typesetting software can execute to format the output document.
64
65
A file named `xhtml.tex` must exist alongside the main file (that is, in the
66
same directory). The file must contain the following:
67
68
``` tex
69
\usesubpath[../xhtml]
70
\input ../xhtml/setups
71
```
72
73
These commands instruct the typesetter to import instructions from the `xhtml`
74
directory, which must exist in the parent directory. The XHTML setups are
75
responsible for translating XML elements from the XHTML document into ConTeXt
76
macros.
77
78
### Properties file
79
80
The `theme.properties` files identify a theme's name to the application. This
81
file allows the editor to display a drop-down having user-friendly names.  The
82
format of the file follows:
83
84
``` properties
85
name=Theme Name
86
```
87
88
The `name` is the key that the editor uses and the `Theme Name` is the value
89
that the theme's author may assign. For the dīvus example, the file would
90
resemble:
91
92
    name=Dīvus
93
94
For consistency, the theme name:
95
96
* should use title case (start words with an uppercase letter);
97
* should be short (will be truncated to 20 characters);
98
* must be uniquely named; and
99
* must not contain punctuation (letters and numbers only).
100
101
If a theme does not contain this file, the theme will be unavailable for users
102
to select when exporting.
103
104
## Text replacement
105
106
Sometimes we want to bend typography to our will. {{app.title}} themes
107
provide a mechanism to leverage the power of TeX to change the typesetting
108
for particular words without adding hints to the source document. This
109
truly exhibits the power of moving presentation logic elsewhere.
110
111
Lua is a programming language that is tightly integrated with ConTeXt. Here's
112
an example of using Lua to create a list of replacements:
113
114
``` lua
115
\startluacode
116
userdata = userdata or {}
117
118
userdata.TextReplacements = {
119
  [1] = { "a.m.", "\\cap{am}" },
120
  [2] = { "TeX", "\\TeX{}" },
121
}
122
\stopluacode
123
```
124
125
This will replace `a.m.` with its small caps version and all occurrences of
126
`TeX` with its iconic lowered-E formatting. Replacements are case-sensitive.
127
Most themes, including *Boschet*, list replacement rules in a file called
128
`replace.tex` located in the theme's subdirectory.
129
130
## Resources
131
132
Styling themes with ConTeXt macros is beyond this manual's scope. Refer to the
133
theme source code for examples. Additionally, the following links are
134
excellent resources for support:
135
136
* [ConTeXt Mailing List](https://mailman.ntg.nl/mailman/listinfo/ntg-context)
137
* [TeX Stack Exchange](https://tex.stackexchange.com/questions/tagged/context)
138
139
See [@cha:typesetting-resources] for a library of books on ConTeXt.
140
1141
A docs/11-math.md
1
# Math
2
3
Mathematical expressions are typeset using TeX notation, a powerful system
4
developed by Dr. Donald E. Knuth for producing documents with complex
5
mathematical and scientific content. In TeX, you write plain text commands that
6
describe the structure and formatting of your document, and then compile them
7
to generate the final output.
8
9
{{app.title}} supports only plain TeX, allowing usage of either ConTeXt or
10
LaTeX.
11
12
## TeX notation
13
14
All TeX commands start with a backslash (`\`), followed by the name of the
15
command, and often use braces (`{}`) for any arguments.
16
17
Some simple mathematical elements using standard TeX syntax include:
18
19
* Fractions: `\fraction{numerator}{denominator}` (or `\frac{}{}`)
20
* Square roots: `\sqrt{expression}`
21
* Superscripts: `x^2`
22
* Subscripts: `x_1`
23
* Greek letters: `\alpha`, `\beta`, `\gamma`, etc.
24
* Integrals: `\int`
25
* Summations: `\sum`
26
* Limits: `\lim_{x \to 0}`
27
28
More complex expressions combine these elements:
29
30
``` tex
31
\sum_{n=1}^{\infty} \frac{1}{n^2} = \frac{\pi^2}{6}
32
33
:: Basel problem
34
```
35
36
Produces:
37
38
$$\sum_{n=1}^{\infty} \frac{1}{n^2} = \frac{\pi^2}{6}$$
39
40
:: Basel problem {#eqn:matter}
41
42
When exported to XHTML, mathematical expressions can be output as TeX notation
43
or SVG images. Using TeX notation allows rendering the mathematics using a
44
JavaScript library such as KaTeX or MathJax. When exported to PDF, the
45
typesetting system renders expressions directly.
46
47
## Sigil syntax
48
49
A sigil is a special symbol used to mark or identify different types of
50
elements, much like how medieval magicians and alchemists used them to
51
represent spirits, forces, or intentions. Rooted in occult traditions, sigils
52
served as visual signatures—condensed symbols encoding names, ideas, or goals
53
in a hidden or abstract form.
54
55
Mathematical expressions must be enclosed within sigils. Spaces are not
56
allowed after the opening sigil or before the closing one.
57
58
## Inline expressions
59
60
Enclose inline TeX code inside single dollar sign sigils (`$`):
61
62
``` tex
63
The quadratic formula is $x=\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$.
64
```
65
66
Outputs an equation within a sentence:
67
68
> The quadratic formula is $x=\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$.
69
70
## Standalone expressions
71
72
Enclose standalone TeX code inside double dollar sign sigils (`$$`):
73
74
``` tex
75
$$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$
76
```
77
78
Outputs a lone paragraph:
79
80
> $$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$
81
82
The assigned equation reference number will differ, of course.
83
184
A docs/12-r.md
1
# R
2
3
This chapter describes how to use R within the application to add dynamic
4
content to documents. It covers integration basics, environment setup, creating
5
visualizations, working with external data, and using YAML variables in R code.
6
7
## Integration
8
9
R integration allows embedding R code directly into documents for dynamic
10
content generation, such as statistical analysis and data plots. The
11
application supports R Markdown (`.Rmd`) files, where R code can be executed
12
inline or in chunks to produce results, including numerical outputs and
13
visualizations. KeenWrite's R integration is largely compatible with the
14
syntax for pandoc / knitr.
15
16
## Environment
17
18
Setting up the R environment involves configuring scripts and directories to
19
load custom functions and manage file locations. This ensures R code runs
20
smoothly within the application.
21
22
### Bootstrapping
23
24
A bootstrap script loads custom R libraries or functions at startup. Complete
25
the following steps to call an R function from your own library:
26
27
1. Click **File → New** to create a new file.
28
1. Click **File → Save As**.
29
1. Browse to your home directory.
30
1. Set **Name** to: `library.R`.
31
1. Click **Save**.
32
1. Set the contents to:
33
34
    ``` r
35
    sum <- function( a, b ) {
36
      a + b
37
    }
38
    ```
39
40
1. Click the **Save** icon.
41
1. Click **R → Script**.
42
1. Set the **R Startup Script** contents to:
43
44
   ``` r
45
   source( 'library.R' );
46
   ```
47
48
1. Click **OK**.
49
1. Create a new file.
50
1. Set the contents to:
51
52
   ``` r
53
   `r#sum( 5, 5 )`
54
   ```
55
56
1. Save the file as `math.R`.
57
58
The preview tab shows the result of calling the `sum` function:
59
60
> 10.0
61
62
This shows how the bootstrap script can load `library.R`, which defines a `sum`
63
function that is called by name in the Markdown document.
64
65
### Working directory
66
67
The working directory determines where R searches for source files. Accomplish
68
this as follows:
69
70
1. Click **R → Directory**.
71
1. Set **Directory** to a different directory.
72
1. Click **OK**.
73
1. Create the directory if it does not exist.
74
1. Move `library.R` into the directory.
75
1. Append a new function to `library.R` as follows:
76
77
   ``` r
78
   mul <- function( a, b ) {
79
     a * b
80
   }
81
   ```
82
83
1. Click **R → Script**.
84
1. Set the **R Startup Script** contents to:
85
86
   ``` r
87
   setwd( v$application$r$working$directory );
88
   source( "library.R" );
89
   ```
90
91
1. Change `math.Rmd` to:
92
93
   ``` r
94
   `r#mul( 5, 5 )`
95
   ```
96
97
1. Close the file `math.Rmd`.
98
1. Confirm saving the file when prompted.
99
1. Re-open `math.Rmd`.
100
101
The preview tab shows:
102
103
> 25.0
104
105
Calling `setwd` using `v$application$r$working$directory` changes the working
106
directory where the R engine searches for source files.
107
108
## Data visualizations
109
110
Data plots can be generated using R. First, create a new file:
111
112
1. Start the application.
113
1. Click **File → New** to create a new file.
114
1. Click **File → Save As**.
115
1. Set **Name** to: `plot.Rmd`
116
1. Click **Save**.
117
118
Setting the file name extension tells the application what processor to use
119
when transforming the contents. To insert visual content, such as a plot, use
120
the knitr-compatible syntax of ` ```{r}` and ` ``` ` to enclose multi-line R
121
snippets:
122
123
    ```{r}
124
    x <- seq( 0, 2 * pi, length.out=100 )
125
    y <- sin( x )
126
    plot( x, y, type="l" )
127
    ```
128
129
## Variable definitions
130
131
Variables provide a way to define reusable values that can be referenced
132
dynamically within R code. To see how variable definitions work in R, try the
133
following:
134
135
1. Create a new file.
136
1. Change the contents to (use spaces to indent, not tabs):
137
138
   ``` yaml
139
   project:
140
     title: Project Title
141
     author: Author Name
142
   ```
143
144
1. Save the file as `definitions.yaml`.
145
1. Click **File → Open**.
146
1. Set **Source Files** to **Variable Files**.
147
1. Select `definitions.yaml`.
148
1. Click **Open**.
149
1. Open `math.Rmd` if it is not already open.
150
1. Type: `je`
151
1. Press [Ctrl+Space]{.kbd}.
152
153
The editor inserts the following text (matches `je` against Pro**je**ct):
154
155
``` r
156
`r#x( v$project$title )`
157
```
158
159
The preview tab shows:
160
161
> 25.0
162
163
This is because the application inserts variable reference names based on the
164
type of file being edited. By default, the R engine does not have a function
165
named `x` defined. The `x` function performs fail-safe string conversions.
166
167
Continue as follows:
168
169
1. Click **R → Script**.
170
1. Append the following:
171
172
   ``` r
173
   x <- function( s ) {
174
     tryCatch( {
175
       r = eval( parse( text = s ) )
176
177
       ifelse( is.atomic( r ), r, s );
178
     },
179
     warning = function( w ) { s },
180
     error = function( e ) { s } )
181
   }
182
   ```
183
184
1. Click **OK**.
185
1. Close and re-open `math.Rmd`.
186
187
The preview tab shows:
188
189
> 25.0
190
>
191
> Project Title
192
193
The `x` function attempts to evaluate the expression defined by the variable.
194
This means that the variables can also include expressions that R is capable of
195
evaluating.
196
197
Externally defined variables are assigned to the `v` object in R code.  This
198
allows dereferencing them using a `$`-separated string. The moustache and
199
dot-separated notation also works (e.g., `{{project.title}}`), but better to be
200
consistent.
201
202
## Comma-separated values
203
204
Many R functions are included, like one that converts comma-separated values to
205
tables. Consider travel fares saved as `fares.csv` alongside the main document:
206
207
``` csv
208
Distance, "Fare ($)"
209
26.7,         73.75
210
16.4,         56.00
211
32.7,         83.25
212
77.0,        190.50
213
```
214
215
Call `csv2md` using a path relative to the R working directory, such as:
216
217
``` r
218
`r# csv2md( '../docs/fares.csv' );`
219
220
:: Taxi fares vs. distance
221
```
222
223
Convert the document from R Markdown to Markdown from the command line:
224
225
``` bash
226
keenwrite.bin \
227
  --r-script="${HOME}/writing/R/bootstrap.R" \
228
  --r-dir="${HOME}/writing/R" \
229
  -i 00.Rmd \
230
  -o 00.md
231
```
232
233
The output file, `00.md`, contains the result from running the function:
234
235
``` markdown
236
|Distance| Fare ($)|
237
|:---|---:|
238
|26.7| 73.75|
239
|16.4| 56.00|
240
|32.7| 83.25|
241
|77|190.50|
242
|Totals|481.65|
243
244
:: Taxi fares vs. distance
245
```
246
247
By isolating the data to an external file, it is possible to update the file
248
and rebuild the document to insert the latest values.
249
1250
A docs/13-gui.md
1
# Graphical user interface
2
3
This chapter covers customizing the graphical user interface (GUI).
4
5
## Skins
6
7
A skin defines the visual style of the application. Skins, which use a syntax
8
based on cascading style sheets, configure the user interface colours, fonts,
9
spacing, highlights, drop-shadows, gradients, and so forth. See the [W3C CSS
10
tutorial](https://www.w3.org/Style/Examples/011/firstcss).
11
12
### Order
13
14
The order that stylesheets are applied dictates how styles get overriden. The
15
application loads and applies stylesheets in the following order:
16
17
1. **scene.css** -- Defines toolbar styling.
18
1. **markdown.css** -- Defines text editor styling.
19
1. **skins/skin_name.css** -- Main application chrome, extensible.
20
1. **custom.css** -- User-defined preferences.
21
22
### Customization
23
24
This section walks through creating and applying a custom skin step-by-step, to
25
personalize the application's appearance. Create a custom skin as follows:
26
27
1. Start the application.
28
1. Click **File → New** to create a new file.
29
1. Click **File → Save As** to rename the file.
30
1. Save the file as `custom.css`.
31
1. Change the content to the following:
32
33
   ``` css
34
   .root {
35
     -fx-base: rgb( 30, 30, 30 );
36
     -fx-background: -fx-base;
37
   }
38
   ```
39
40
Apply the skin as follows:
41
42
1. Click **Edit → Preferences** to open the preferences dialog.
43
1. Click **Skins** to view the available options.
44
1. Click **Browse** to select a custom file.
45
1. Browse to and select `custom.css`, created previously.
46
1. Click **Open**.
47
1. Click **Apply**.
48
49
The user interface immediately changes to a dark mode. Continue:
50
51
1. Click **OK** to close the dialog.
52
1. Change the **rgb** numbers in **custom.css** from `30` to `60`.
53
1. Click **File → Save** to save the CSS file.
54
55
The user interface immediately changes colour.
56
57
### Classes
58
59
For more control, this section explains how to use pre-existing skin templates with defined classes, making it easier to tweak the GUI. Accomplish this as follows:
60
61
1. Visit the [skin]({{skins.url.main}}) repository directory
62
1. Click one of the files (e.g., `haunted_grey.css`).
63
1. Click **Raw**.
64
1. Copy the entire text.
65
1. Return to `custom.css`.
66
1. Delete the contents.
67
1. Paste the copied text.
68
1. Save the file.
69
70
To see how the CSS styles are applied to the text editor, open
71
[markdown.css]({{skins.url.markdown}}), which is also in the repository.
72
73
### Modena
74
75
The basic look used by the application is _Modena Light_. Typically we only
76
need to override a few classes to completely change the application's look and
77
feel. For a full listing of available styles see the OpenJDK's [Modena CSS
78
file](https://github.com/openjdk/jfx/blob/master/modules/javafx.controls/src/main/resources/com/sun/javafx/scene/control/skin/modena/modena.css).
79
80
### JavaFX CSS
81
82
JavaFX CSS has styling capabilities beyond regular CSS. The [Java CSS Reference
83
Guide](https://openjfx.io/javadoc/21/javafx.graphics/javafx/scene/doc-files/cssref.html)
84
shows differences between JavaFX CSS and W3C CSS. The guide covers functions
85
for manipulating colours and gradients using existing colour definitions.
86
87
### RichTextFX
88
89
The application uses RichTextFX to render the text editor. Styling various text
90
editor classes can require using the prefix `-rtfx` instead of the regular
91
JavaFX `-fx`.
92
93
## Fonts
94
95
The preview tab uses two categories of fonts: regular and monospace.
96
97
### Regular font
98
99
To change the regular preview font, complete the following steps:
100
101
1. Click **Edit → Preferences**.
102
1. Click **Fonts**.
103
1. Click **Change** under **Preview Font** for the **Preview tab font name**.
104
1. Find the font name by typing or scrolling.
105
1. Click the desired font family.
106
1. Click **OK**.
107
1. Click **Apply**.
108
109
The regular preview font is changed.
110
111
### Monospace font
112
113
To change the monospace preview font, complete the following steps:
114
115
1. Click **Edit → Preferences**.
116
1. Click **Fonts**.
117
1. Click **Change** under **Preview Font** for the **Monospace font name**.
118
1. Find the font name by typing or scrolling.
119
1. Click the desired font family.
120
1. Click **OK**.
121
1. Click **Apply**.
122
123
The monospace font is changed.
124
125
## Internationalization
126
127
Internationalization support is essential for editing and previewing text in
128
multiple languages. Both fonts and language must be set for non-Latin-based
129
text. [@tbl:editor-font-families] lists example Chinese-Japanese-Korean (CJK)
130
font settings for the editor and preview tabs.
131
132
| Tab     | Font Family       | Language           |
133
| ------- | ----------------- | ------------------ |
134
| Editor  | Noto Sans CJK KR  | Korean             |
135
| Editor  | Noto Sans CJK JP  | Japanese           |
136
| Editor  | Noto Sans CJK HN  | Chinese            |
137
| Editor  | Noto Sans CJK SC  | Simplified Chinese |
138
| Preview | Noto Serif CJK KR | Korean             |
139
| Preview | Noto Serif CJK JP | Japanese           |
140
| Preview | Noto Serif CJK HN | Chinese            |
141
| Preview | Noto Serif CJK SC | Simplified Chinese |
142
143
:: Editor and preview tab font families {#tbl:editor-font-families}
144
145
### Editor font
146
147
Follow these steps to change the editor font:
148
149
1. Click **Edit → Preferences**.
150
1. Click **Fonts**.
151
1. Click **Change** under **Editor Font**.
152
1. Find the font name by typing or scrolling.
153
1. Click the desired font family.
154
1. Click **OK**.
155
1. Click **Apply**.
156
157
The text editor font is changed.
158
159
Note the following:
160
161
* Install the desired fonts (restart the application).
162
* Enter font name directly if it cannot be selected.
163
164
### Language Settings
165
166
Language settings control the locale used by the application, which is important when using CJK fonts or other locale-specific features.
167
168
Change the locale as follows:
169
170
1. Click **Edit → Preferences**.
171
1. Click **Language**.
172
1. Select a value for **Locale**.
173
1. Click **Apply**.
174
175
The language is set.
176
1177
A docs/14-cli.md
1
# Command-line interface
2
3
This chapter covers how to use the application from the command line to convert
4
Markdown files to various output formats. Without specifying any command-line
5
arguments, the application will launch a graphical user interface.
6
7
## Common arguments
8
9
The most frequently used command-line arguments include:
10
11
* `-h` -- displays all command-line arguments, then exits.
12
* `-i` -- sets the input file name, must be a full path.
13
* `-o` -- sets the output file name, can be a relative path.
14
* `-s` -- sets a variable name and value at build time (dynamic data).
15
16
Setting a variable name on the command line useful, for example, to pass in a
17
product guide version number.
18
19
## Example usage
20
21
The following invocations will convert `01.md` into the respective file
22
formats, determined by the file name extension. In the first case, it will
23
become an XHTML page. In the second case, it will become a plain-text document
24
with all variables interpolated and replaced.
25
26
``` bash
27
keenwrite.bin \
28
  -i "${HOME}/document/01.md" \
29
  -o document.xhtml
30
31
keenwrite.bin \
32
  -i "${HOME}/document/01.md" \
33
  -o document.txt \
34
  -v "${HOME}/document/variables.yaml"
35
```
36
37
The following invocation will convert `01.Rmd` to a PDF file and replace
38
the metadata using values from the variable definitions file.
39
40
``` bash
41
keenwrite.bin \
42
  -i "${HOME}/document/01.Rmd" \
43
  -o document.pdf \
44
  --image-dir="${HOME}/document/images" \
45
  -v "${HOME}/document/variables.yaml" \
46
  --metadata="title={{book.title}}" \
47
  --metadata="author={{book.author}}" \
48
  --r-dir="${HOME}/document/R" \
49
  --r-script="${HOME}/document/R/bootstrap.R" \
50
  --theme-dir="{{install.config.unix}}/themes/boschet"
51
```
52
53
Directory or file names containing spaces must be quoted. For example, on
54
Windows:
55
56
``` bash
57
keenwrite.bin -i "C:\Users\My Documents\01.Rmd" -o document.pdf
58
```
59
160
A docs/15-troubleshooting.md
1
# Troubleshooting
2
3
This chapter addresses common issues that may arise while using {{app.title}}.
4
When problems occur, the status bar displays a brief summary of a problem.
5
Detailed information is available through the log viewer.
6
7
## Log
8
9
The application maintains a list of error messages to help diagnose issues.
10
11
Click **View → Log** (or press [F12]{.kbd}) to open the log view.
12
13
The log window shows various types of information:
14
15
* Error messages that indicate specific problems
16
* Warning messages about potential issues
17
* Information about file operations and processing
18
* System events and application state changes
19
20
When reporting issues or seeking help, the log information can provide valuable
21
context about what the application was doing when problems occurred.
22
23
## Container
24
25
If you encounter the following error (or similar) on Windows:
26
27
> Error: unable to load machine config file: "json: cannot unmarshal
28
> string into Go struct field MachineConfig.ImagePath of type define.VMFile"
29
30
Complete the following steps to remove obsolete containers:
31
32
1. Stop {{app.title}}.
33
1. Uninstall podman.
34
1. Delete `C:\Users\%USERNAME%\.config\containers\`.
35
1. Delete `C:\Users\%USERNAME%\AppData\Roaming\containers\`.
36
1. Open a command prompt.
37
1. Run:
38
   ``` dos
39
   wsl -l -v
40
   wsl --unregister podman-machine-default
41
   podman -v
42
   podman machine reset -f
43
   ```
44
1. Reboot.
45
1. Start {{app.title}}.
46
1. Retry exporting as a PDF file.
47
48
Note that downloading the typesetter image can take several minutes and does
49
not show a progress indicator. Be patient.
50
51
## SVG compatibility
52
53
Vector graphics files created in certain applications may encounter
54
compatibility issues when embedded in documents. These problems typically
55
manifest as rendering failures, missing content, or incorrectly displayed
56
graphics.
57
58
When referencing a vector graphic using Markdown, the status bar may show the
59
following error:
60
61
> The current document is unable to create an element of the requested type (namespace: http://www.w3.org/2000/svg, name: flowRoot).
62
63
This error occurs due to a version mismatch of the `flowRoot` element that
64
Inkscape creates. Resolve the issue by changing the SVG version number as
65
follows:
66
67
1. Edit the vector graphics file using any text editor.
68
1. Find `version="1.1"`.
69
1. Change the version to: `version="1.2"`.
70
1. Save the file.
71
72
The SVG will now appear inside the application; however, the text may appear as black blocks.
73
74
### Black blocks
75
76
Depending on how text is added to a vector graphic in Inkscape, the text may be
77
inserted within an element called a `flowRoot`. Although `flowRoot` is
78
recognized, the contents may not be fully interpreted, resulting in black
79
blocks being drawn instead of text, as shown in [@fig:blocked-text].
80
81
![Black text](images/blocked-text)
82
83
:: Blocked text {#fig:blocked-text}
84
85
Resolve the issue by "unflowing" all text elements as follows:
86
87
1. Start Inkscape.
88
1. Load the SVG file.
89
1. Select all the text elements.
90
1. Click **Text → Unflow**.
91
92
The text may change size and position; recreate the text without dragging using
93
the text tool. After all the text areas have been recreated, continue as
94
follows:
95
96
1. Click **Edit → XML Editor**.
97
1. Expand the **XML Editor** to see more elements.
98
1. Delete all elements named `svg:flowRoot`.
99
1. Save the file.
100
101
When the illustration is reloaded, the black blocks will have disappeared, but
102
the text elements may ignore any assigned colour.
103
104
### Blackened text
105
106
When an SVG `style` attribute contains a reference to `-inkscape-font-specification`, all values that follow said reference are ignored. This results in black text, shown in [@fig:black-text].
107
108
![Black text](images/black-text)
109
110
:: Blackened text {#fig:black-text}
111
112
Resolve the issue of colourless text as follows:
113
114
1. Open the SVG file in a plain-text editor.
115
1. Remove all references `-inkscape-font-specification:'<FONT>';`, including the trailing (or leading) semicolon.
116
1. Save the file.
117
118
[@fig:resolved-text] shows colours having reappeared after reloading.
119
120
![Resolved text](images/resolved-text)
121
122
:: Resolved text {#fig:resolved-text}
123
1124
A docs/16-oss.md
1
# Open-source software
2
3
{{app.title}} is free, open-source software.
4
5
## License
6
7
Copyright &copy; 2025 White Magic Software, Ltd.
8
9
This program is free software; you can redistribute it and/or modify it under
10
the terms of the GNU General Public License as published by the Free Software
11
Foundation; either version 2 of the License, or (at your option) any later
12
version.
13
14
This program is distributed in the hope that it will be useful, but WITHOUT ANY
15
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
16
PARTICULAR PURPOSE. See the GNU General Public License for more details.
17
18
You should have received a copy of the GNU General Public License along with
19
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
20
Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
22
The full text of the GPLv2 license can be found at:
23
[https://www.gnu.org/licenses/old-licenses/gpl-2.0.html](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html)
24
25
## Software architecture
26
27
[@fig:architecture] illustrates the software's high-level application
28
architecture. The processing pipeline transforms textual content through
29
multiple stages to produce the final document. Each processor in the
30
chain receives a document from its predecessor. This allows each
31
processor to handle a single responsibility, such as curling quotation
32
marks, replacing variable names, or inserting a caret position.
33
34
![architecture](images/architecture/architecture)
35
36
:: Software architecture {#fig:architecture}
37
38
* The **"Today"** section shows a single flow where a user writes in Markdown,
39
which is then processed and converted into a final HTML output. This is
40
typical of most conversion programs written today: they can only handle a
41
single type of input and a single type of output.
42
43
* The **"Proposed"** section shows that the architecture can be updated to
44
handle a wider range of input formats, all feeding into a more flexible
45
*Processor Chain*. The two-way arrow indicates that the output from one
46
processing pass can be be fed back into the next process.
47
48
* The **"Example Processing Combination"** section provides a detailed look at
49
how the system could handle multiple, complex inputs and outputs
50
simultaneously. It shows how different data formats (XML, YAML, JSON, etc.)
51
are processed through dedicated processors (XSLT Processor, R Processor,
52
etc.) to produce a variety of outputs (R Markdown, Markdown, HTML5),
53
demonstrating a more robust and interconnected system.
54
155
A docs/17-appendix.md
1
::: appendices
2
3
# Screenshots
4
5
This section provides application screenshots.
6
7
## PDF themes
8
9
The background of [@fig:screenshot-pdf-themes] depicts a novel being edited.
10
Note the following:
11
12
* PDF icon in the upper-left
13
* Novel metadata as integrated variables towards the top-left
14
* Theme selection dialog in the upper-middle
15
* Multiple styles (*Boschet*, *Handrit*, and *Tarmes*)
16
* Variations in page numbers
17
* Preferences dialog in the middle
18
19
![PDF themes](images/screenshots/08.png)
20
21
:: PDF Themes {#fig:screenshot-pdf-themes}
22
23
## Dockable tabs
24
25
[@fig:screenshot-outline] shows a document outline opened and docked in
26
the bottom-left corner:
27
28
![Document outline](images/screenshots/04.png)
29
30
:: Document outline {#fig:screenshot-outline}
31
32
## Variables
33
34
A diagram that includes variables is shown in [@fig:screenshot-diagram-genealogy].
35
36
![Family tree diagram screenshot](images/screenshots/05.png)
37
38
:: Family tree diagram {#fig:screenshot-diagram-genealogy}
39
40
## Equations
41
42
[@fig:screenshot-tex] shows TeX equations in a detached preview tab:
43
44
![TeX equations screenshot](images/screenshots/03.png)
45
46
:: TeX equations {#fig:screenshot-tex}
47
48
## Internationalization
49
50
[@fig:screenshot-locale] shows a poem with locale settings:
51
52
![Korean poem screenshot](images/screenshots/02.png)
53
54
:: Locale settings {#fig:screenshot-locale}
55
56
# Typesetting resources
57
58
Documents that introduce the typesetting system:
59
60
* [What is ConTeXt?](https://www.pragma-ade.com/general/manuals/what-is-context.pdf)
61
* [A not so short introduction to ConTeXt](https://github.com/contextgarden/not-so-short-introduction-to-context)
62
* [Dealing with XML in ConTeXt MKIV](https://pragma-ade.com/general/manuals/xml-mkiv.pdf)
63
* [Typographic Programming](https://www.pragma-ade.com/general/manuals/style.pdf)
64
65
The [documentation library](https://wiki.contextgarden.net/Documentation) includes the following gems:
66
67
* [ConTeXt Manual](https://www.pragma-ade.nl/general/manuals/ma-cb-en.pdf)
68
* [ConTeXt command reference](https://www.pragma-ade.nl/general/qrcs/setup-en.pdf)
69
* [METAFUN Manual](https://www.pragma-ade.nl/general/manuals/metafun-p.pdf)
70
* [It's in the Details](https://www.pragma-ade.nl/general/manuals/details.pdf)
71
* [Fonts out of ConTeXt](https://www.pragma-ade.com/general/manuals/fonts-mkiv.pdf)
72
73
Expert-level documentation includes the [LuaTeX Reference Manual](https://www.pragma-ade.nl/general/manuals/luatex.pdf).
74
75
# Acknowledgments
76
77
{{app.title}} sits on the shoulders of a great many developers, including:
78
79
* Dr. Donald E. Knuth, [TeX](https://ctan.org/tex-archive/systems/knuth/dist/tex?lang=en)
80
* Hans Hagen, [ConTeXt](https://www.pragma-ade.com/)
81
* James Gosling, [Java](https://www.java.com/)
82
* Karl Tauber, [Markdown Writer FX](https://github.com/JFormDesigner/markdown-writer-fx)
83
184
A docs/18-licenses.md
1
## Third-party libraries
2
3
{{app.title}} ships with the libraries listed in the following subsections.
4
5
### flexmark-java
6
- **Version:** 0.64.8
7
- [Maven](https://mvnrepository.com/artifact/com.vladsch.flexmark/flexmark/0.64.8)
8
- **License(s):** [BSD-2-Clause]( http://opensource.org/licenses/BSD-2-Clause)
9
- **Developers:** Vladimir Schneider
10
11
### ControlsFX
12
- **Version:** 11.2.2
13
- [Homepage](http://www.controlsfx.org/) | [Source](https://github.com/controlsfx/controlsfx) | [Maven](https://mvnrepository.com/artifact/org.controlsfx/controlsfx/11.2.2)
14
- **License(s):** [BSD-3-Clause](http://www.opensource.org/licenses/bsd-license.php)
15
- **Developers:** Jonathan Giles
16
17
### RichTextFX
18
- **Version:** 0.11.6
19
- [Homepage](https://github.com/FXMisc/RichTextFX/#richtextfx) | [Source](scm:git@github.com:FXMisc/RichTextFX.git) | [Maven](https://mvnrepository.com/artifact/org.fxmisc.richtext/richtextfx/0.11.6)
20
- **License(s):** [BSD-2-Clause](http://opensource.org/licenses/BSD-2-Clause), [GPL-2.0-only](http://www.gnu.org/software/classpath/license.html)
21
- **Developers:** Jordan Martinez, Jurgen Doll, Tomas Mikula
22
23
### WellBehavedFX
24
- **Version:** 0.3.3
25
- [Homepage](http://www.fxmisc.org/wellbehaved/) | [Source](scm:git@github.com:FXMisc/WellBehavedFX.git) | [Maven](https://mvnrepository.com/artifact/org.fxmisc.wellbehaved/wellbehavedfx/0.3.3)
26
- **License(s):** [BSD-2-Clause](http://opensource.org/licenses/BSD-2-Clause)
27
- **Developers:** Tomas Mikula
28
29
### JavaFX Swing
30
- **Version:** 24.0.2
31
- [Homepage](https://openjdk.java.net/projects/openjfx/) | [Maven](https://mvnrepository.com/artifact/org.openjfx/javafx-swing/24.0.2)
32
- **License(s):** [GPL-2.0-with-classpath-exception]( https://openjdk.java.net/legal/gplv2+ce.html)
33
- **Developers:** Abhinay Agarwal, Eugene Ryzhikov
34
35
### JavaFX Media
36
- **Version:** 24.0.2
37
- [Homepage](https://openjdk.java.net/projects/openjfx/) | [Maven](https://mvnrepository.com/artifact/org.openjfx/javafx-media/26-ea+3)
38
- **License(s):** [GPL-2.0-with-classpath-exception]( https://openjdk.java.net/legal/gplv2+ce.html)
39
40
### PreferencesFX
41
- **Version:** 11.17.0
42
- [Homepage](https://github.com/dlsc-software-consulting-gmbh/PreferencesFX) | [Source](https://github.com/dlsc-software-consulting-gmbh/PreferencesFX) | [Maven](https://mvnrepository.com/artifact/com.dlsc.preferencesfx/preferencesfx-core/11.17.0)
43
- **License(s):** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt)
44
- **Developers:** Dirk Lemmermann, Dieter Holz, François Martin, Marco Sanfratello
45
46
### FontAwesomeFX
47
- **Version:** 8.9
48
- [Source](https://bitbucket.org/Jerady/fontawesomefx/)
49
- **License(s):** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt)
50
- **Developers:** Jens Deters
51
52
### TiwulFX Dock
53
- **Version:** 0.5
54
- [Homepage](https://github.com/panemu/tiwulfx-dock) | [Source](https://panemu@github.com/panemu/tiwulfx-dock.git) | [Maven](https://mvnrepository.com/artifact/com.panemu/tiwulfx-dock/0.5)
55
- **License(s):** [MIT](https://github.com/panemu/tiwulfx-dock/blob/main/LICENSE)
56
- **Developers:** Amrullah Syadzili
57
58
### SnakeYAML
59
- **Version:** 2.5
60
- [Homepage](https://bitbucket.org/snakeyaml/snakeyaml) | [Source](https://bitbucket.org/snakeyaml/snakeyaml/src) | [Maven](https://mvnrepository.com/artifact/org.yaml/snakeyaml/2.5)
61
- **License(s):** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
62
- **Developers:** Alexander Maslov, Andrey Somov
63
64
### Jackson Core
65
- **Version:** 2.19.2
66
- [Homepage](https://github.com/FasterXML/jackson-core) | [Source](https://github.com/FasterXML/jackson-core) | [Maven](https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core/2.19.2)
67
- **License(s):** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt)
68
- **Developers:** Tatu Saloranta
69
70
### Jackson Databind
71
- **Version:** 2.19.2
72
- [Homepage](https://github.com/FasterXML/jackson) | [Source](https://github.com/FasterXML/jackson-databind) | [Maven](https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind/2.19.2)
73
- **License(s):** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt)
74
- **Developers:** Tatu Saloranta
75
76
### Jackson Dataformat-YAML
77
- **Version:** 2.19.2
78
- [Homepage](https://github.com/FasterXML/jackson-dataformats-text) | [Maven](https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.19.2)
79
- **License(s):** [Apache-2.0]( https://www.apache.org/licenses/LICENSE-2.0.txt)
80
- **Developers:** Tatu Saloranta
81
82
### jsoup
83
- **Version:** 1.21.2
84
- [Homepage](https://jsoup.org/) | [Source](https://github.com/jhy/jsoup) | [Maven](https://mvnrepository.com/artifact/org.jsoup/jsoup/1.21.2)
85
- **License(s):** [MIT](https://jsoup.org/license)
86
- **Developers:** Jonathan Hedley
87
88
### Flying Saucer Core
89
- **Version:** 10.0.0
90
- [Maven](https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-core/10.0.0)
91
- **License(s):** [LGPL-2.1-or-later](https://www.gnu.org/licenses/lgpl-3.0.html)
92
- **Developers:** Patrick Wright, Peter Brant
93
94
### Apache Commons Compress
95
- **Version:** 1.28.0
96
- [Homepage](https://commons.apache.org/proper/commons-compress/) | [Source](https://gitbox.apache.org/repos/asf?p=commons-compress.git) | [Maven](https://mvnrepository.com/artifact/org.apache.commons/commons-compress/1.28.0)
97
- **License(s):** [Apache-2.0]( https://www.apache.org/licenses/LICENSE-2.0.txt)
98
- **Developers:** Christian Grobmeier, Damjan Jovanovic, Emmanuel Bourg, Gary Gregory, Julius Davies, Peter Alfred Lee, Rob Tompkins, Sebastian Bazley, Stefan Bodewig, Torsten Curdt
99
100
### Apache Commons VFS
101
- **Version:** 2.10.0
102
- [Homepage](https://commons.apache.org/proper/commons-vfs/) | [Maven](https://mvnrepository.com/artifact/org.apache.commons/commons-vfs2/2.10.0)
103
- **License(s):** [Apache-2.0]( https://www.apache.org/licenses/LICENSE-2.0.txt)
104
- **Developers:** Adam Murdoch, Bernd Eckenfels, Gary Gregory, James Carman, James Strachan, Joerg Schaible, Mario Ivankovits, Rahul Akolkar, Ralph Goers
105
106
### Plexus Common Utilities
107
- **Version:** 4.0.2
108
- [Homepage](https://codehaus-plexus.github.io/plexus-utils/) | [Source](https://github.com/codehaus-plexus/plexus-utils/tree/plexus-utils-4.0.2/) | [Maven](https://mvnrepository.com/artifact/org.codehaus.plexus/plexus-utils/4.0.2)
109
- **License(s):** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt)
110
- **Developers:** Andreas Gudian, Andrew Williams, Ben Walding, Brett Porter, Carlos Sanchez, Dan Diephouse, Emmanuel Venisse, Gabriel Belingueres, Guillaume Nodet, Hervé Boutemy, James Taylor, Jason van Zyl, Joakim Erdfelt, John Casey, Karl Heinz Marbaise, Kasper Nielsen, Kenney Westerhof, Konrad Windszus, Kristian Rosenvold, Mark Wilkinson, Michael Osipov, Michal Maczka, Oleg Gusakov, Olivier Lamy, Pete Kazmier, Rahul Thakur, Slawomir Jaranowski, Sylwester Lachiewicz, Trygve Laugstøl, Vincent Siveton
111
112
### Renjin
113
- **Version:** 3.5-beta76
114
- [Maven](https://mvnrepository.com/artifact/org.renjin/renjin-script-engine/3.5-beta76)
115
- **License(s):** [GPL-2.0-or-later](https://opensource.org/license/gpl-2-0)
116
- **Developers:** Alex Bertram
117
118
### RJson
119
- **Version:** 0.2.15-renjin-21
120
- [Maven](https://mvnrepository.com/artifact/org.renjin.cran/rjson/0.2.15-renjin-21)
121
- **License(s):** [Apache-2.0]( http://www.apache.org/licenses/LICENSE-2.0.txt)
122
- **Developers:** Alex Couture-Beil 
123
124
### EchoSVG
125
- **Version:** 2.2
126
- [Homepage](https://github.com/css4j/echosvg/wiki) | [Maven](https://mvnrepository.com/artifact/io.sf.carte/echosvg-awt-util/2.2)
127
- **License(s):** [Apache-2.0]( http://www.apache.org/licenses/LICENSE-2.0.txt)
128
- **Developers:** Carlos Amengual
129
130
### Aho-Corasick
131
- **Version:** 0.6.3
132
- [Homepage](https://github.com/robert-bor/aho-corasick) | [Source](scm:git://github.com/robert-bor/aho-corasick) | [Maven](https://mvnrepository.com/artifact/org.ahocorasick/ahocorasick/0.6.3)
133
- **License(s):** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
134
- **Developers:** Daniel Beck, Dave Jarvis, Robert Bor
135
136
### JUniversalChardet
137
- **Version:** 2.5.0
138
- [Homepage](https://github.com/albfernandez/juniversalchardet) | [Source](git@github.com:albfernandez/juniversalchardet.git) | [Maven](https://mvnrepository.com/artifact/com.github.albfernandez/juniversalchardet/2.5.0)
139
- **License(s):** [MPL-1.1](https://www.mozilla.org/en-US/MPL/1.1/), [GPL-3.0-only](http://www.gnu.org/licenses/gpl.txt), [LGPL-3.0-only](http://www.gnu.org/licenses/lgpl.txt)
140
- **Developers:** Alberto Fernández, Shy Shalom, Kohei Taketa
141
142
### Jakarta Validation API
143
- **Version:** 3.1.1
144
- [Homepage](https://beanvalidation.org) | [Source](https://github.com/jakartaee/validation) | [Maven](https://mvnrepository.com/artifact/jakarta.validation/jakarta.validation-api/3.1.1)
145
- **License(s):** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
146
- **Developers:** Emmanuel Bernard, Guillaume Smet, Gunnar Morling, Hardy Ferentschik
147
148
### EventBus
149
- **Version:** 3.3.1
150
- [Homepage](https://greenrobot.org/eventbus/) | [Source](https://github.com/greenrobot/EventBus) | [Maven](https://mvnrepository.com/artifact/org.greenrobot/eventbus-java/3.3.1)
151
- **License(s):** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt)
152
- **Developers:** Markus Junginger
153
154
### picocli
155
- **Version:** 4.7.7
156
- [Homepage](https://picocli.info) | [Source](https://github.com/remkop/picocli/tree/master) | [Maven](https://mvnrepository.com/artifact/info.picocli/picocli/4.7.7)
157
- **License(s):** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
158
- **Developers:** Remko Popma
159
160
### JSpecify annotations
161
- **Version:** 1.0.0
162
- [Homepage](http://jspecify.org/) | [Source](https://github.com/jspecify/jspecify/) | [Maven](https://mvnrepository.com/artifact/org.jspecify/jspecify/1.0.0)
163
- **License(s):** [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
164
- **Developers:** Kevin Bourrillion
165
166
### Java Image Scaling
167
- **Version:** 0.8.7
168
- [Source](https://github.com/mortennobel/java-image-scaling)
169
- **License(s):** [BSD-3-Clause](http://www.opensource.org/licenses/bsd-license.php)
170
- **Developers:** Morten Nobel-Jørgensen
171
172
### File Preferences
173
- [Homepage](https://www.davidc.net/programming/java/java-preferences-using-file-backing-store)
174
- **License(s):** [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/)
175
- **Developers:** David Croft
176
177
### SLF4J API Module
178
- **Version:** 2.1.0-alpha1
179
- [Homepage](http://www.slf4j.org) | [Maven](https://mvnrepository.com/artifact/org.slf4j/slf4j-api/2.1.0-alpha1)
180
- **License(s):** [MIT]( http://www.opensource.org/licenses/mit-license.php)
181
- **Developers:** Ceki Gülcü
182
183
### SLF4J NOP Provider
184
- **Version:** 2.0.17
185
- [Homepage](http://www.slf4j.org) | [Maven](https://mvnrepository.com/artifact/org.slf4j/slf4j-nop/2.0.17)
186
- **License(s):** [MIT]( https://opensource.org/license/mit)
187
- **Developers:** Ceki Gülcü
188
189
:::
1190
M docs/README.md
33
The following documents have additional details about using the editor:
44
5
* [cmd.md](cmd.md) -- Command-line argument usage
6
* [div.md](div.md) -- Syntax for annotated text (fenced divs)
7
* [i18n.md](i18n.md) -- Internationalization features
8
* [r.md](r.md) -- R functions within R Markdown documents
9
* [samples](samples) -- Example documents
10
* [skins.md](skins.md) -- User interface customization
11
* [svg.md](svg.md) -- Resolve issues with some SVG files
12
* [metadata.md](metadata.md) -- Document metadata
13
* [references.md](references.md) -- Captions and cross-references
14
* [typesetting.md](typesetting.md) -- Document typesetting
15
* [variables.md](variables.md) -- Variable definitions and interpolation
5
* [Introduction](01-introduction.md) -- Getting started with KeenWrite
6
* [Variables](02-variables.md) -- Variable definitions and interpolation
7
* [Metadata](03-metadata.md) -- Document metadata
8
* [Command-line](04-cmd.md) -- Command-line argument usage
9
* [Diagrams](05-diagram.md) -- Creating diagrams and flowcharts
10
* [SVG](06-svg.md) -- Resolve issues with some SVG files
11
* [Screenshots](08-screenshots.md) -- Application screenshots
12
* [R Integration](09-r.md) -- R functions within R Markdown documents
13
* [Typesetting](10-typesetting.md) -- Document typesetting
14
* [Custom Typesetting](11-typesetting-custom.md) -- Advanced typesetting customization
15
* [Skins](12-skins.md) -- User interface customization
16
* [Fenced Divs](13-div.md) -- Syntax for annotated text (fenced divs)
17
* [Quotes](14-quotes.md) -- Quotes and citations
18
* [Internationalization](15-i18n.md) -- Internationalization features
19
* [References](16-references.md) -- Captions and cross-references
20
* [Samples](samples) -- Example documents
1621
1722
# Contributions
18
19
* [credits.md](credits.md) -- Thanks to authors of contributing projects
20
* [licenses](licenses) -- Third-party licenses
23
* [Credits](17-credits.md) -- Thanks to authors of contributing projects
24
* [Licenses](licenses) -- Third-party licenses
2125
2226
A docs/build.sh
1
#!/usr/bin/env bash
2
3
readonly SCRIPT_SRC="$(dirname "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}")"
4
readonly SCRIPT_DIR="$(cd "${SCRIPT_SRC}" >/dev/null 2>&1 && pwd)"
5
6
#keenwrite.bin \
7
java -jar /tmp/keenwrite.jar \
8
  $1 \
9
  --debug \
10
  --all \
11
  --chapters="1-" \
12
  -i 01-introduction.md \
13
  -o user-manual.pdf \
14
  --variables=$(pwd)/metadata.yaml \
15
  --set="version.java=$(cat ../java.version)" \
16
  --metadata="title={{document.title}}" \
17
  --metadata="subtitle={{document.subtitle}}" \
18
  --metadata="copyright={{document.copyright}}" \
19
  --metadata="version=$(git describe --tags --abbrev=0)" \
20
  --theme-dir="$HOME/dev/java/keenwrite/themes/texomus"
21
122
D docs/cmd.md
1
# Command-line arguments
2
3
The application may be run from the command-line to convert Markdown and
4
R Markdown files to a variety of output formats. Without specifying any
5
command-line arguments, the application will launch a graphical user interface.
6
7
## Common arguments
8
9
The most common command-line arguments to use include:
10
11
* `-h` -- displays all command-line arguments, then exits.
12
* `-i` -- sets the input file name, must be a full path.
13
* `-o` -- sets the output file name, can be a relative path.
14
* `-s` -- sets a variable name and value at build time (dynamic data).
15
16
## Example usage
17
18
On Linux, simple usages include:
19
20
    keenwrite.bin -i $HOME/document/01.md -o document.xhtml
21
22
    keenwrite.bin -i $HOME/document/01.md -o document.md \
23
      -v $HOME/document/variables.yaml
24
25
That command will convert `01.md` into the respective file formats. In
26
the first case, it will become an HTML page. In the second case, it will
27
become a Markdown document with all variables interpolated and replaced.
28
29
A more complex example follows:
30
31
    keenwrite.bin -i $HOME/document/01.Rmd -o document.pdf \
32
      --image-dir=$HOME/document/images -v $HOME/document/variables.yaml \
33
      --metadata="title={{book.title}}" --metadata="author={{book.author}}" \
34
      --r-dir=$HOME/document/r --r-script=$HOME/document/r/bootstrap.R \
35
      --theme-dir=$HOME/document/themes/boschet
36
37
That command will convert `01.Rmd` to `document.pdf` and replace the metadata
38
using values from the variable definitions file.
39
40
Directory names containing spaces must be quoted. For example, on Windows:
41
42
    keenwrite.bin -i "C:\Users\My Documents\01.Rmd" -o document.pdf
43
441
D docs/credits.md
1
# Credits
2
3
Using libraries from:
4
5
* Tomas Mikula: [RichTextFX](https://github.com/TomasMikula/RichTextFX), [WellBehavedFX](https://github.com/TomasMikula/WellBehavedFX), [Flowless](https://github.com/TomasMikula/Flowless), and [UndoFX](https://github.com/TomasMikula/UndoFX)
6
* Jens Deters: [FontAwesomeFX](https://bitbucket.org/Jerady/fontawesomefx)
7
* Dieter Holz: [PreferencesFX](https://github.com/dlsc-software-consulting-gmbh/PreferencesFX)
8
* David Croft: [File Preferences](http://www.davidc.net/programming/java/java-preferences-using-file-backing-store)
9
* Alex Bertram: [Renjin](https://www.renjin.org/)
10
* Vladimir Schneider: [flexmark](https://github.com/vsch/flexmark-java)
11
* Alberto Fernández, Shy Shalom, Kohei Taketa: [juniversalchardet](https://github.com/takscape/juniversalchardet)
12
* Morten Nobel-Jørgensen: [Java Image Scaling](https://github.com/mortennobel/java-image-scaling)
13
14
Inspired by:
15
16
* Karl Tauber: [Markdown Writer FX](https://github.com/JFormDesigner/markdown-writer-fx)
171
D docs/development/proguard/README.md
1
From https://github.com/greenrobot/EventBus#r8-proguard
2
3
	-keepattributes *Annotation*
4
	-keepclassmembers class * {
5
			@org.greenrobot.eventbus.Subscribe <methods>;
6
	}
7
	-keep enum org.greenrobot.eventbus.ThreadMode { *; }
8
	 
91
D docs/diagram.md
1
# Introduction
2
3
From a high level, the application architecture for converting Markdown documents is captured in the following figure:
4
5
``` diagram-graphviz
6
digraph {
7
  node [fontname = "Noto Sans" fontsize=6 height=.25 penwidth=.5];
8
  edge [fontname = "Noto Sans" fontsize=6  penwidth=.5 arrowsize=.5];
9
  node [shape=box color="{{keenwrite.palette.primary.light}}" fontcolor="{{keenwrite.palette.primary.dark}}"]
10
  edge [color="{{keenwrite.palette.grayscale.light}}" fontcolor="{{keenwrite.palette.grayscale.dark}}"]
11
12
  {{keenwrite.classes.processors.variable.definition}} ->   {{keenwrite.classes.processors.markdown}} [xlabel="{{keenwrite.graph.label.chain.next}}  "]
13
  {{keenwrite.classes.processors.markdown}} -> {{keenwrite.classes.processors.preview}} [xlabel="{{keenwrite.graph.label.chain.next}}  "]
14
  {{keenwrite.classes.processors.markdown}} -> Extensions [label="  contains"]
15
16
Extensions -> FencedBlockExtension
17
Extensions -> CaretExtension
18
Extensions -> ImageLinkExtension
19
Extensions -> TeXExtension
20
}
21
```
22
23
An extension is an addition to the Markdown parser, flexmark-java, that is used when converting the document's abstract syntax tree into an HTML document. The {{keenwrite.classes.processors.markdown}} contains both prepackaged and custom extensions.
241
D docs/diagram.yaml
1
---
2
keenwrite:
3
  classes:
4
    processors:
5
      markdown: MarkdownProcessor
6
      variable:
7
        definition: DefinitionProcessor
8
      preview: PreviewProcessor
9
  palette:
10
    primary:
11
      light: '#51a9cf'
12
      dark: '#126d95'
13
    secondary:
14
      light: '#ec706a'
15
      dark: '#7e252f'
16
    accent:
17
      light: '#76A786'
18
      dark: '#385742'
19
    grayscale:
20
      light: '#bac2c5'
21
      dark: '#394343'
22
  graph:
23
    label:
24
      chain:
25
        next: successor
261
D docs/div.md
1
# Fenced divs
2
3
This section describes the syntax to generate HTML `div` elements. The
4
syntax is known as a _fenced div_.
5
6
# Basic syntax
7
8
A fenced div has the following basic syntax:
9
10
``` markdown
11
::: name
12
Content
13
:::
14
```
15
16
To start a fenced div, begin a line with at least three colons (`:::`),
17
followed by at least one space, followed by any word. Content may follow
18
immediately on the next line. Terminate the fenced div with at least
19
three colons. The terminating colons needn't match in number to the starting
20
colons, but it's a good idea to maintain symmetry.
21
22
The HTML that is generated from the above fenced div will resemble:
23
24
``` html
25
<div class="name">
26
<p>Content</p>
27
</div>
28
```
29
30
# Extended syntax
31
32
A fenced div may use an extended syntax. The extended syntax can provide
33
a unique identifier, multiple class names, and key/value data pairs. For
34
example:
35
36
``` markdown
37
::: {#poem-01 .stanza author="Emily Dickinson" year=1890}
38
Because I could not stop for Death —
39
He kindly stopped for me —
40
The Carriage held but just Ourselves —
41
And Immortality.
42
:::
43
```
44
45
The above snippet produces:
46
47
``` html
48
<div id="poem-01" class="stanza" data-author="Emily Dickinson" data-year="1890">
49
<p>Because I could not stop for Death —
50
He kindly stopped for me —
51
The Carriage held but just Ourselves —
52
And Immortality.</p>
53
</div>
54
```
55
56
Note that when using the extended syntax, class styles must be prefixed with
57
a period (e.g., `.stanza` in the example).
58
59
# Nested syntax
60
61
Fenced divs may be nested, such as in the following example:
62
63
``` markdown
64
::: poem
65
:::::: stanza
66
Because I could not stop for Death —
67
He kindly stopped for me —
68
The Carriage held but just Ourselves —
69
And Immortality.
70
::::::
71
:::
72
```
73
74
The above example produces:
75
76
``` html
77
<div class="poem"><div class="stanza">
78
<p>Because I could not stop for Death —
79
He kindly stopped for me —
80
The Carriage held but just Ourselves —
81
And Immortality.</p>
82
</div></div>
83
```
84
851
D docs/i18n.md
1
# Internationalization
2
3
The application supports internationalization (I18N). There are multiple
4
components to editing and previewing internationalized text documents.
5
These include:
6
7
* Fonts
8
* Language
9
10
Both fonts and language must be set for non-Latin-based text.
11
12
# Fonts
13
14
The text editors and preview panel have independent font settings. For
15
all Chinese, Japanese, and Korean (CJK) fonts, you may have to type in
16
the font family name directly.
17
18
For example, CJK font families for the editor have the following names:
19
20
* **Noto Sans CJK KR** --- Korean font
21
* **Noto Sans CJK JP** --- Japanese font
22
* **Noto Sans CJK HN** --- Chinese font
23
* **Noto Sans CJK SC** --- Simplified Chinese font
24
25
While CJK font families for the preview have the following names:
26
27
* **Noto Serif CJK KR** --- Korean font
28
* **Noto Serif CJK JP** --- Japanese font
29
* **Noto Serif CJK HN** --- Chinese font
30
* **Noto Serif CJK SC** --- Simplified Chinese font
31
32
## Editor
33
34
Complete the following steps to change the editor font:
35
36
1. Click **Edit → Preferences**.
37
1. Click **Fonts**.
38
1. Click **Change** under **Editor Font**.
39
1. Find the font name by typing or scrolling.
40
1. Click the desired font family.
41
1. Click **OK**.
42
1. Click **Apply**.
43
44
The text editor font is changed.
45
46
Note the following:
47
48
* The font must be installed in the system for this to work.
49
* You may have to edit the font name if it cannot be selected from the list.
50
* Setting the editor font also sets the statistics panel font.
51
52
## Preview
53
54
The preview panel uses regular and monospace fonts.
55
56
### Regular
57
58
Complete the following steps to change the regular preview font:
59
60
1. Click **Edit → Preferences**.
61
1. Click **Fonts**.
62
1. Click **Change** under **Preview Font** for the **Preview pane font name**.
63
1. Find the font name by typing or scrolling.
64
1. Click the desired font family.
65
1. Click **OK**.
66
1. Click **Apply**.
67
68
The regular preview font is changed.
69
70
### Monospace
71
72
Complete the following steps to change the monospace preview font:
73
74
1. Click **Edit → Preferences**.
75
1. Click **Fonts**.
76
1. Click **Change** under **Preview Font** for the **Monospace font name**.
77
1. Find the font name by typing or scrolling.
78
1. Click the desired font family.
79
1. Click **OK**.
80
1. Click **Apply**.
81
82
The monospace font is changed.
83
84
# Language
85
86
Language settings control the locale that the application uses. When using
87
a CJK font, for example, the application must also be instructed to use
88
a particular locale. Change the locale as follows:
89
90
1. Click **Edit → Preferences**.
91
1. Click **Language**.
92
1. Select a value for **Locale**.
93
1. Click **Apply**.
94
95
The language is set.
96
971
M docs/images/architecture/architecture.png
Binary file
M docs/images/architecture/architecture.svg
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
22
<svg
3
   xmlns:dc="http://purl.org/dc/elements/1.1/"
4
   xmlns:cc="http://creativecommons.org/ns#"
5
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
6
   xmlns:svg="http://www.w3.org/2000/svg"
7
   xmlns="http://www.w3.org/2000/svg"
8
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
9
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10
   inkscape:export-ydpi="150.0097"
11
   inkscape:export-xdpi="150.0097"
12
   sodipodi:docname="architecture.svg"
13
   viewBox="0 0 764.4414 811.46748"
14
   height="811.46747"
15
   width="764.44141"
16
   id="svg4610"
17
   version="1.2"
18
   inkscape:version="1.0 (4035a4fb49, 2020-05-01)">
19
  <metadata
20
     id="metadata4616">
21
    <rdf:RDF>
22
      <cc:Work
23
         rdf:about="">
24
        <dc:format>image/svg+xml</dc:format>
25
        <dc:type
26
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
27
        <dc:title />
28
      </cc:Work>
29
    </rdf:RDF>
30
  </metadata>
31
  <defs
32
     id="defs4614">
33
    <marker
34
       inkscape:stockid="Arrow1Mend"
35
       orient="auto"
36
       refY="0"
37
       refX="0"
38
       id="marker10933"
39
       style="overflow:visible"
40
       inkscape:isstock="true">
41
      <path
42
         id="path10931"
43
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
44
         style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1"
45
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
46
         inkscape:connector-curvature="0" />
47
    </marker>
48
    <marker
49
       inkscape:stockid="Arrow1Mend"
50
       orient="auto"
51
       refY="0"
52
       refX="0"
53
       id="marker9893"
54
       style="overflow:visible"
55
       inkscape:isstock="true">
56
      <path
57
         id="path9891"
58
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
59
         style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1"
60
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
61
         inkscape:connector-curvature="0" />
62
    </marker>
63
    <marker
64
       inkscape:collect="always"
65
       inkscape:isstock="true"
66
       style="overflow:visible"
67
       id="marker9767"
68
       refX="0"
69
       refY="0"
70
       orient="auto"
71
       inkscape:stockid="Arrow1Mend">
72
      <path
73
         inkscape:connector-curvature="0"
74
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
75
         style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1"
76
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
77
         id="path9765" />
78
    </marker>
79
    <marker
80
       inkscape:collect="always"
81
       inkscape:stockid="Arrow1Mend"
82
       orient="auto"
83
       refY="0"
84
       refX="0"
85
       id="marker9761"
86
       style="overflow:visible"
87
       inkscape:isstock="true">
88
      <path
89
         id="path9759"
90
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
91
         style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1"
92
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
93
         inkscape:connector-curvature="0" />
94
    </marker>
95
    <marker
96
       inkscape:isstock="true"
97
       style="overflow:visible"
98
       id="marker9750"
99
       refX="0"
100
       refY="0"
101
       orient="auto"
102
       inkscape:stockid="Arrow1Mend">
103
      <path
104
         inkscape:connector-curvature="0"
105
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
106
         style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1"
107
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
108
         id="path9748" />
109
    </marker>
110
    <marker
111
       inkscape:isstock="true"
112
       style="overflow:visible"
113
       id="marker9715"
114
       refX="0"
115
       refY="0"
116
       orient="auto"
117
       inkscape:stockid="Arrow1Mend">
118
      <path
119
         inkscape:connector-curvature="0"
120
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
121
         style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1"
122
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
123
         id="path9713" />
124
    </marker>
125
    <marker
126
       inkscape:collect="always"
127
       inkscape:stockid="Arrow1Mend"
128
       orient="auto"
129
       refY="0"
130
       refX="0"
131
       id="marker9685"
132
       style="overflow:visible"
133
       inkscape:isstock="true">
134
      <path
135
         id="path9683"
136
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
137
         style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1"
138
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
139
         inkscape:connector-curvature="0" />
140
    </marker>
141
    <marker
142
       inkscape:collect="always"
143
       inkscape:stockid="Arrow1Mend"
144
       orient="auto"
145
       refY="0"
146
       refX="0"
147
       id="marker9679"
148
       style="overflow:visible"
149
       inkscape:isstock="true">
150
      <path
151
         id="path9677"
152
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
153
         style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1"
154
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
155
         inkscape:connector-curvature="0" />
156
    </marker>
157
    <marker
158
       inkscape:collect="always"
159
       inkscape:isstock="true"
160
       style="overflow:visible"
161
       id="marker9640"
162
       refX="0"
163
       refY="0"
164
       orient="auto"
165
       inkscape:stockid="Arrow1Mend">
166
      <path
167
         inkscape:connector-curvature="0"
168
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
169
         style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1"
170
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
171
         id="path9638" />
172
    </marker>
173
    <marker
174
       inkscape:collect="always"
175
       inkscape:isstock="true"
176
       style="overflow:visible"
177
       id="marker9513"
178
       refX="0"
179
       refY="0"
180
       orient="auto"
181
       inkscape:stockid="Arrow1Mend">
182
      <path
183
         inkscape:connector-curvature="0"
184
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
185
         style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1"
186
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
187
         id="path9511" />
188
    </marker>
189
    <marker
190
       inkscape:stockid="Arrow1Mend"
191
       orient="auto"
192
       refY="0"
193
       refX="0"
194
       id="marker9509"
195
       style="overflow:visible"
196
       inkscape:isstock="true">
197
      <path
198
         id="path9507"
199
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
200
         style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1"
201
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
202
         inkscape:connector-curvature="0" />
203
    </marker>
204
    <marker
205
       inkscape:isstock="true"
206
       style="overflow:visible"
207
       id="marker9505"
208
       refX="0"
209
       refY="0"
210
       orient="auto"
211
       inkscape:stockid="Arrow1Mend">
212
      <path
213
         inkscape:connector-curvature="0"
214
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
215
         style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1"
216
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
217
         id="path9503" />
218
    </marker>
219
    <marker
220
       inkscape:collect="always"
221
       inkscape:stockid="Arrow1Mend"
222
       orient="auto"
223
       refY="0"
224
       refX="0"
225
       id="marker9479"
226
       style="overflow:visible"
227
       inkscape:isstock="true">
228
      <path
229
         id="path9477"
230
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
231
         style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1"
232
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
233
         inkscape:connector-curvature="0" />
234
    </marker>
235
    <clipPath
236
       id="ID000001">
237
      <rect
238
         id="rect6"
239
         height="961.125"
240
         width="1381.6169"
241
         y="-43.688"
242
         x="-62.683998" />
243
    </clipPath>
244
    <filter
245
       id="filter2842"
246
       inkscape:label="Drop Shadow"
247
       style="color-interpolation-filters:sRGB;">
248
      <feFlood
249
         id="feFlood2832"
250
         result="flood"
251
         flood-color="rgb(0,0,0)"
252
         flood-opacity="0.498039" />
253
      <feComposite
254
         id="feComposite2834"
255
         result="composite1"
256
         operator="in"
257
         in2="SourceGraphic"
258
         in="flood" />
259
      <feGaussianBlur
260
         id="feGaussianBlur2836"
261
         result="blur"
262
         stdDeviation="2"
263
         in="composite1" />
264
      <feOffset
265
         id="feOffset2838"
266
         result="offset"
267
         dy="3"
268
         dx="3" />
269
      <feComposite
270
         id="feComposite2840"
271
         result="composite2"
272
         operator="over"
273
         in2="offset"
274
         in="SourceGraphic" />
275
    </filter>
276
    <filter
277
       id="filter2854"
278
       inkscape:label="Drop Shadow"
279
       style="color-interpolation-filters:sRGB;">
280
      <feFlood
281
         id="feFlood2844"
282
         result="flood"
283
         flood-color="rgb(0,0,0)"
284
         flood-opacity="0.498039" />
285
      <feComposite
286
         id="feComposite2846"
287
         result="composite1"
288
         operator="in"
289
         in2="SourceGraphic"
290
         in="flood" />
291
      <feGaussianBlur
292
         id="feGaussianBlur2848"
293
         result="blur"
294
         stdDeviation="2"
295
         in="composite1" />
296
      <feOffset
297
         id="feOffset2850"
298
         result="offset"
299
         dy="3"
300
         dx="3" />
301
      <feComposite
302
         id="feComposite2852"
303
         result="composite2"
304
         operator="over"
305
         in2="offset"
306
         in="SourceGraphic" />
307
    </filter>
308
    <filter
309
       id="filter2866"
310
       inkscape:label="Drop Shadow"
311
       style="color-interpolation-filters:sRGB;">
312
      <feFlood
313
         id="feFlood2856"
314
         result="flood"
315
         flood-color="rgb(0,0,0)"
316
         flood-opacity="0.498039" />
317
      <feComposite
318
         id="feComposite2858"
319
         result="composite1"
320
         operator="in"
321
         in2="SourceGraphic"
322
         in="flood" />
323
      <feGaussianBlur
324
         id="feGaussianBlur2860"
325
         result="blur"
326
         stdDeviation="2"
327
         in="composite1" />
328
      <feOffset
329
         id="feOffset2862"
330
         result="offset"
331
         dy="3"
332
         dx="3" />
333
      <feComposite
334
         id="feComposite2864"
335
         result="composite2"
336
         operator="over"
337
         in2="offset"
338
         in="SourceGraphic" />
339
    </filter>
340
    <filter
341
       id="filter2878"
342
       inkscape:label="Drop Shadow"
343
       style="color-interpolation-filters:sRGB;">
344
      <feFlood
345
         id="feFlood2868"
346
         result="flood"
347
         flood-color="rgb(0,0,0)"
348
         flood-opacity="0.498039" />
349
      <feComposite
350
         id="feComposite2870"
351
         result="composite1"
352
         operator="in"
353
         in2="SourceGraphic"
354
         in="flood" />
355
      <feGaussianBlur
356
         id="feGaussianBlur2872"
357
         result="blur"
358
         stdDeviation="2"
359
         in="composite1" />
360
      <feOffset
361
         id="feOffset2874"
362
         result="offset"
363
         dy="3"
364
         dx="3" />
365
      <feComposite
366
         id="feComposite2876"
367
         result="composite2"
368
         operator="over"
369
         in2="offset"
370
         in="SourceGraphic" />
371
    </filter>
372
    <filter
373
       id="filter2890"
374
       inkscape:label="Drop Shadow"
375
       style="color-interpolation-filters:sRGB;">
376
      <feFlood
377
         id="feFlood2880"
378
         result="flood"
379
         flood-color="rgb(0,0,0)"
380
         flood-opacity="0.498039" />
381
      <feComposite
382
         id="feComposite2882"
383
         result="composite1"
384
         operator="in"
385
         in2="SourceGraphic"
386
         in="flood" />
387
      <feGaussianBlur
388
         id="feGaussianBlur2884"
389
         result="blur"
390
         stdDeviation="2"
391
         in="composite1" />
392
      <feOffset
393
         id="feOffset2886"
394
         result="offset"
395
         dy="3"
396
         dx="3" />
397
      <feComposite
398
         id="feComposite2888"
399
         result="composite2"
400
         operator="over"
401
         in2="offset"
402
         in="SourceGraphic" />
403
    </filter>
404
    <filter
405
       id="filter2902"
406
       inkscape:label="Drop Shadow"
407
       style="color-interpolation-filters:sRGB;">
408
      <feFlood
409
         id="feFlood2892"
410
         result="flood"
411
         flood-color="rgb(0,0,0)"
412
         flood-opacity="0.498039" />
413
      <feComposite
414
         id="feComposite2894"
415
         result="composite1"
416
         operator="in"
417
         in2="SourceGraphic"
418
         in="flood" />
419
      <feGaussianBlur
420
         id="feGaussianBlur2896"
421
         result="blur"
422
         stdDeviation="2"
423
         in="composite1" />
424
      <feOffset
425
         id="feOffset2898"
426
         result="offset"
427
         dy="3"
428
         dx="3" />
429
      <feComposite
430
         id="feComposite2900"
431
         result="composite2"
432
         operator="over"
433
         in2="offset"
434
         in="SourceGraphic" />
435
    </filter>
436
    <filter
437
       id="filter2914"
438
       inkscape:label="Drop Shadow"
439
       style="color-interpolation-filters:sRGB;">
440
      <feFlood
441
         id="feFlood2904"
442
         result="flood"
443
         flood-color="rgb(0,0,0)"
444
         flood-opacity="0.498039" />
445
      <feComposite
446
         id="feComposite2906"
447
         result="composite1"
448
         operator="in"
449
         in2="SourceGraphic"
450
         in="flood" />
451
      <feGaussianBlur
452
         id="feGaussianBlur2908"
453
         result="blur"
454
         stdDeviation="2"
455
         in="composite1" />
456
      <feOffset
457
         id="feOffset2910"
458
         result="offset"
459
         dy="3"
460
         dx="3" />
461
      <feComposite
462
         id="feComposite2912"
463
         result="composite2"
464
         operator="over"
465
         in2="offset"
466
         in="SourceGraphic" />
467
    </filter>
468
    <filter
469
       id="filter2926"
470
       inkscape:label="Drop Shadow"
471
       style="color-interpolation-filters:sRGB;">
472
      <feFlood
473
         id="feFlood2916"
474
         result="flood"
475
         flood-color="rgb(0,0,0)"
476
         flood-opacity="0.498039" />
477
      <feComposite
478
         id="feComposite2918"
479
         result="composite1"
480
         operator="in"
481
         in2="SourceGraphic"
482
         in="flood" />
483
      <feGaussianBlur
484
         id="feGaussianBlur2920"
485
         result="blur"
486
         stdDeviation="2"
487
         in="composite1" />
488
      <feOffset
489
         id="feOffset2922"
490
         result="offset"
491
         dy="3"
492
         dx="3" />
493
      <feComposite
494
         id="feComposite2924"
495
         result="composite2"
496
         operator="over"
497
         in2="offset"
498
         in="SourceGraphic" />
499
    </filter>
500
    <filter
501
       id="filter2938"
502
       inkscape:label="Drop Shadow"
503
       style="color-interpolation-filters:sRGB;">
504
      <feFlood
505
         id="feFlood2928"
506
         result="flood"
507
         flood-color="rgb(0,0,0)"
508
         flood-opacity="0.498039" />
509
      <feComposite
510
         id="feComposite2930"
511
         result="composite1"
512
         operator="in"
513
         in2="SourceGraphic"
514
         in="flood" />
515
      <feGaussianBlur
516
         id="feGaussianBlur2932"
517
         result="blur"
518
         stdDeviation="2"
519
         in="composite1" />
520
      <feOffset
521
         id="feOffset2934"
522
         result="offset"
523
         dy="3"
524
         dx="3" />
525
      <feComposite
526
         id="feComposite2936"
527
         result="composite2"
528
         operator="over"
529
         in2="offset"
530
         in="SourceGraphic" />
531
    </filter>
532
    <filter
533
       id="filter2950"
534
       inkscape:label="Drop Shadow"
535
       style="color-interpolation-filters:sRGB;">
536
      <feFlood
537
         id="feFlood2940"
538
         result="flood"
539
         flood-color="rgb(0,0,0)"
540
         flood-opacity="0.498039" />
541
      <feComposite
542
         id="feComposite2942"
543
         result="composite1"
544
         operator="in"
545
         in2="SourceGraphic"
546
         in="flood" />
547
      <feGaussianBlur
548
         id="feGaussianBlur2944"
549
         result="blur"
550
         stdDeviation="2"
551
         in="composite1" />
552
      <feOffset
553
         id="feOffset2946"
554
         result="offset"
555
         dy="3"
556
         dx="3" />
557
      <feComposite
558
         id="feComposite2948"
559
         result="composite2"
560
         operator="over"
561
         in2="offset"
562
         in="SourceGraphic" />
563
    </filter>
564
    <filter
565
       id="filter2962"
566
       inkscape:label="Drop Shadow"
567
       style="color-interpolation-filters:sRGB;">
568
      <feFlood
569
         id="feFlood2952"
570
         result="flood"
571
         flood-color="rgb(0,0,0)"
572
         flood-opacity="0.498039" />
573
      <feComposite
574
         id="feComposite2954"
575
         result="composite1"
576
         operator="in"
577
         in2="SourceGraphic"
578
         in="flood" />
579
      <feGaussianBlur
580
         id="feGaussianBlur2956"
581
         result="blur"
582
         stdDeviation="2"
583
         in="composite1" />
584
      <feOffset
585
         id="feOffset2958"
586
         result="offset"
587
         dy="3"
588
         dx="3" />
589
      <feComposite
590
         id="feComposite2960"
591
         result="composite2"
592
         operator="over"
593
         in2="offset"
594
         in="SourceGraphic" />
595
    </filter>
596
    <filter
597
       id="filter2974"
598
       inkscape:label="Drop Shadow"
599
       style="color-interpolation-filters:sRGB;">
600
      <feFlood
601
         id="feFlood2964"
602
         result="flood"
603
         flood-color="rgb(0,0,0)"
604
         flood-opacity="0.498039" />
605
      <feComposite
606
         id="feComposite2966"
607
         result="composite1"
608
         operator="in"
609
         in2="SourceGraphic"
610
         in="flood" />
611
      <feGaussianBlur
612
         id="feGaussianBlur2968"
613
         result="blur"
614
         stdDeviation="2"
615
         in="composite1" />
616
      <feOffset
617
         id="feOffset2970"
618
         result="offset"
619
         dy="3"
620
         dx="3" />
621
      <feComposite
622
         id="feComposite2972"
623
         result="composite2"
624
         operator="over"
625
         in2="offset"
626
         in="SourceGraphic" />
627
    </filter>
628
    <filter
629
       id="filter2986"
630
       inkscape:label="Drop Shadow"
631
       style="color-interpolation-filters:sRGB;">
632
      <feFlood
633
         id="feFlood2976"
634
         result="flood"
635
         flood-color="rgb(0,0,0)"
636
         flood-opacity="0.498039" />
637
      <feComposite
638
         id="feComposite2978"
639
         result="composite1"
640
         operator="in"
641
         in2="SourceGraphic"
642
         in="flood" />
643
      <feGaussianBlur
644
         id="feGaussianBlur2980"
645
         result="blur"
646
         stdDeviation="2"
647
         in="composite1" />
648
      <feOffset
649
         id="feOffset2982"
650
         result="offset"
651
         dy="3"
652
         dx="3" />
653
      <feComposite
654
         id="feComposite2984"
655
         result="composite2"
656
         operator="over"
657
         in2="offset"
658
         in="SourceGraphic" />
659
    </filter>
660
  </defs>
661
  <sodipodi:namedview
662
     inkscape:snap-text-baseline="false"
663
     inkscape:document-rotation="0"
664
     fit-margin-bottom="20"
665
     fit-margin-right="20"
666
     fit-margin-left="20"
667
     fit-margin-top="20"
668
     inkscape:current-layer="svg4610"
669
     inkscape:cy="370.55742"
670
     inkscape:cx="398.61418"
671
     inkscape:zoom="1.3753763"
672
     showgrid="false"
673
     id="namedview4612"
674
     inkscape:window-height="1280"
675
     inkscape:window-width="2055"
676
     inkscape:pageshadow="2"
677
     inkscape:pageopacity="1"
678
     guidetolerance="10"
679
     gridtolerance="10"
680
     objecttolerance="10"
681
     borderopacity="1"
682
     bordercolor="#666666"
683
     pagecolor="#ffffff"
684
     inkscape:window-x="215"
685
     inkscape:window-y="26"
686
     inkscape:window-maximized="0" />
687
  <path
688
     sodipodi:nodetypes="ccssssc"
689
     inkscape:connector-curvature="0"
690
     style="fill:#333333;fill-opacity:0.0666667;fill-rule:nonzero;stroke:#df4d65;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
691
     d="M 53.35547,445.11522 V 790.96744 H 741.0332 c 1.6112,0 2.90821,-1.29701 2.90821,-2.9082 V 448.02342 c 0,-1.6112 -1.297,-2.9082 -2.90821,-2.9082 z"
692
     id="path9961" />
693
  <path
694
     sodipodi:nodetypes="sssccssss"
695
     id="path9940"
696
     d="m 20.5,787.82486 c 0,0.87013 0.35019,1.65683 0.91797,2.22461 0.56778,0.56778 1.35253,0.91797 2.22265,0.91797 H 53.35547 V 445.11522 H 23.64062 c -0.87012,0 -1.65487,0.35019 -2.22265,0.91797 -0.56778,0.56778 -0.91797,1.35254 -0.91797,2.22266 z"
697
     style="fill:#df4d65;fill-opacity:1;fill-rule:nonzero;stroke:#df4d65;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
698
     inkscape:connector-curvature="0" />
699
  <path
700
     sodipodi:nodetypes="sssccssss"
701
     id="path11125"
702
     d="m 20.5,423.31014 c 0,0.87013 0.35019,1.65683 0.91797,2.22461 0.56778,0.56778 1.354494,0.9764 2.22265,0.91797 H 53.35547 V 210.6005 H 23.64062 c -0.87012,0 -1.65487,0.3502 -2.22265,0.918 C 20.85019,212.08629 20.5,212.871 20.5,213.74109 Z"
703
     style="fill:#3e3e3e;fill-opacity:1;fill-rule:nonzero;stroke:#3e3e3e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
704
     inkscape:connector-curvature="0" />
705
  <path
706
     sodipodi:nodetypes="ccssssc"
707
     inkscape:connector-curvature="0"
708
     style="fill:#333333;fill-opacity:0.0666667;fill-rule:nonzero;stroke:#3e3e3e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
709
     d="m 53.35547,210.6005 v 215.85222 h 687.67774 c 1.6112,0 2.9082,-1.29701 2.9082,-2.9082 V 213.5087 c 0,-1.6112 -1.29701,-2.90352 -2.9082,-2.9082 z"
710
     id="path11123" />
711
  <path
712
     id="path6150"
713
     d="m 557.756,222.53493 c -0.87012,0 -1.65683,0.35019 -2.22461,0.91797 -0.56778,0.56778 -0.91797,1.35253 -0.91797,2.22265 v 29.71485 h 165.6211 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91797,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z"
714
     style="fill:#c53bd7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2926)"
715
     inkscape:connector-curvature="0"
716
     sodipodi:nodetypes="sssccssss" />
717
  <path
718
     sodipodi:nodetypes="ccssssc"
719
     id="path6134"
720
     d="m 720.75716,255.39041 h -165.6211 v 152.63392 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 h 159.80469 c 1.6112,0 2.9082,-1.29701 2.9082,-2.90821 z"
721
     style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2926)"
722
     inkscape:connector-curvature="0" />
723
  <path
724
     id="path6082"
725
     d="m 317.13559,222.53494 c -0.87011,0 -1.65683,0.35019 -2.2246,0.91797 -0.56779,0.56778 -0.91798,1.35253 -0.91798,2.22265 v 29.71485 h 165.62111 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91798,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z"
726
     style="fill:#3dd092;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2938)"
727
     inkscape:connector-curvature="0"
728
     sodipodi:nodetypes="sssccssss" />
729
  <path
730
     sodipodi:nodetypes="ccssssc"
731
     id="path6080"
732
     d="M 479.61412,255.39041 H 313.99301 v 152.63392 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 h 159.80469 c 1.6112,0 2.90821,-1.29701 2.90821,-2.90821 z"
733
     style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2938)"
734
     inkscape:connector-curvature="0" />
735
  <path
736
     id="path10980"
737
     d="M 53.35547,20.500012 V 188.35224 h 687.67774 c 1.6112,0 2.9082,-1.29701 2.9082,-2.9082 V 23.408212 c 0,-1.6112 -1.29701,-2.912886 -2.9082,-2.9082 z"
738
     style="fill:#333333;fill-opacity:0.0666667;fill-rule:nonzero;stroke:#3e3e3e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
739
     inkscape:connector-curvature="0"
740
     sodipodi:nodetypes="ccssssc" />
741
  <path
742
     inkscape:connector-curvature="0"
743
     style="fill:#3e3e3e;fill-opacity:1;fill-rule:nonzero;stroke:#3e3e3e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
744
     d="m 20.5,185.20966 c 0,0.87013 0.35019,1.65683 0.91797,2.22461 0.56778,0.56778 1.35253,0.91797 2.22265,0.91797 H 53.35547 V 20.500012 H 23.64062 c -0.87012,0 -1.65487,0.350201 -2.22265,0.918 -0.56778,0.5678 -0.91797,1.3525 -0.91797,2.2226 z"
745
     id="path10982"
746
     sodipodi:nodetypes="sssccssss" />
747
  <path
748
     sodipodi:nodetypes="sssccssss"
749
     inkscape:connector-curvature="0"
750
     style="fill:#c53bd7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2962)"
751
     d="m 557.75599,36.704447 c -0.87012,0 -1.65683,0.35019 -2.22461,0.91797 -0.56778,0.56778 -0.91797,1.35253 -0.91797,2.22265 v 29.71485 h 165.6211 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91797,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z"
752
     id="path4857" />
753
  <path
754
     inkscape:connector-curvature="0"
755
     style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2962)"
756
     d="M 720.23451,69.559917 H 554.61341 V 169.2396 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 h 159.80469 c 1.6112,0 2.9082,-1.29701 2.9082,-2.90821 z"
757
     id="path4853" />
758
  <path
759
     sodipodi:nodetypes="sssccssss"
760
     inkscape:connector-curvature="0"
761
     style="fill:#3dd092;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2974)"
762
     d="m 317.13558,36.704447 c -0.87011,0 -1.65683,0.35019 -2.2246,0.91797 -0.56779,0.56778 -0.91798,1.35253 -0.91798,2.22265 v 29.71485 h 165.62111 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91798,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z"
763
     id="path5726" />
764
  <path
765
     inkscape:connector-curvature="0"
766
     style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2974)"
767
     d="M 479.61411,69.559917 H 313.993 V 169.2396 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 H 476.7059 c 1.6112,0 2.90821,-1.29701 2.90821,-2.90821 z"
768
     id="path5724" />
769
  <path
770
     id="path4721"
771
     d="m 235.85308,44.704447 c 0.87012,0 1.65488,0.35019 2.22266,0.91797 0.56778,0.56778 0.91797,1.35253 0.91797,2.22265 v -0.23242 c 0,-1.6112 -1.297,-2.9082 -2.9082,-2.9082 z"
772
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
773
     inkscape:connector-curvature="0" />
774
  <path
775
     sodipodi:nodetypes="sssccssss"
776
     id="path4719"
777
     d="m 76.515197,36.704447 c -0.870125,0 -1.656831,0.35019 -2.22461,0.91797 -0.567778,0.56778 -0.917968,1.35253 -0.917968,2.22265 v 29.71485 H 238.99371 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91797,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z"
778
     style="fill:#46c7f0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2986)"
779
     inkscape:connector-curvature="0" />
780
  <path
781
     id="path4723"
782
     d="M 238.99372,69.559917 H 73.372613 V 169.2396 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 H 236.08552 c 1.6112,0 2.9082,-1.29701 2.9082,-2.90821 z"
783
     style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2986)"
784
     inkscape:connector-curvature="0" />
785
  <path
786
     id="rect4622"
787
     d="m 76.280822,44.704447 c -1.611195,0 -2.908203,1.297 -2.908203,2.9082 v 0.23242 c 0,-0.87012 0.35019,-1.65487 0.917968,-2.22265 0.567779,-0.56778 1.354485,-0.91797 2.22461,-0.91797 z"
788
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
789
     inkscape:connector-curvature="0" />
790
  <path
791
     sodipodi:nodetypes="cc"
792
     inkscape:connector-curvature="0"
793
     id="path9889"
794
     d="m 397.61301,500.62068 -0.50618,32.59418"
795
     style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:1.9694221;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9893)" />
796
  <path
797
     style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9715)"
798
     d="m 554.61351,648.83688 -69.6817,47.69253"
799
     id="path9711"
800
     inkscape:connector-curvature="0"
801
     sodipodi:nodetypes="cc" />
802
  <path
803
     sodipodi:nodetypes="cc"
804
     inkscape:connector-curvature="0"
805
     id="path9675"
806
     d="M 554.61351,567.95047 484.93181,615.643"
807
     style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9679)" />
808
  <rect
809
     ry="3.9839513"
810
     rx="3.9205718"
811
     y="537.09552"
812
     x="554.61353"
813
     height="32.855"
814
     width="165.621"
815
     id="rect9618"
816
     style="opacity:1;fill:#c53bd7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2842)" />
817
  <rect
818
     ry="3.9839513"
819
     rx="3.9205718"
820
     y="537.09552"
821
     x="73.372665"
822
     height="32.855"
823
     width="165.621"
824
     id="rect9614"
825
     style="opacity:1;fill:#46c7f0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2914)" />
826
  <path
827
     inkscape:connector-curvature="0"
828
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
829
     d="m 235.85308,545.09525 c 0.87012,0 1.65488,0.35019 2.22266,0.91797 0.56778,0.56778 0.91797,1.35253 0.91797,2.22265 v -0.23242 c 0,-1.6112 -1.297,-2.9082 -2.9082,-2.9082 z"
830
     id="path9323" />
831
  <path
832
     inkscape:connector-curvature="0"
833
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
834
     d="m 76.280823,545.09525 c -1.611195,0 -2.908203,1.297 -2.908203,2.9082 v 0.23242 c 0,-0.87012 0.35019,-1.65487 0.917968,-2.22265 0.567779,-0.56778 1.354485,-0.91797 2.22461,-0.91797 z"
835
     id="path9327" />
836
  <rect
837
     style="opacity:1;fill:#3dd092;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2902)"
838
     id="rect9616"
839
     width="165.621"
840
     height="32.855"
841
     x="313.99307"
842
     y="537.09552"
843
     rx="3.9205718"
844
     ry="3.9839513" />
845
  <path
846
     sodipodi:nodetypes="cc"
847
     inkscape:connector-curvature="0"
848
     id="path9491"
849
     d="m 240.99257,554.11276 65.23376,-1.01307"
850
     style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9513)" />
851
  <path
852
     style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9640)"
853
     d="m 481.61298,554.11276 65.23376,-1.01307"
854
     id="path9501"
855
     inkscape:connector-curvature="0"
856
     sodipodi:nodetypes="cc" />
857
  <rect
858
     ry="3.9839513"
859
     rx="3.9205718"
860
     y="617.79578"
861
     x="313.99307"
862
     height="32.855"
863
     width="165.621"
864
     id="rect9620"
865
     style="opacity:1;fill:#3dd092;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2890)" />
866
  <path
867
     sodipodi:nodetypes="cc"
868
     inkscape:connector-curvature="0"
869
     id="path9681"
870
     d="m 481.61298,634.81299 65.23376,-1.01307"
871
     style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9685)" />
872
  <rect
873
     style="opacity:1;fill:#c53bd7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2854)"
874
     id="rect9687"
875
     width="165.621"
876
     height="32.855"
877
     x="554.61353"
878
     y="617.79578"
879
     rx="3.9205718"
880
     ry="3.9839513" />
881
  <path
882
     style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9750)"
883
     d="m 481.61298,715.51321 65.23376,-1.01307"
884
     id="path9734"
885
     inkscape:connector-curvature="0"
886
     sodipodi:nodetypes="cc" />
887
  <rect
888
     ry="3.9839513"
889
     rx="3.9205718"
890
     y="698.49591"
891
     x="554.61353"
892
     height="32.855"
893
     width="165.621"
894
     id="rect9736"
895
     style="opacity:1;fill:#c53bd7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2866)" />
896
  <path
897
     id="path9830"
898
     d="m 356.40451,489.45323 c -0.80426,0 -1.45167,0.64741 -1.45167,1.45166 v 0.11602 c 0,-0.43433 0.1748,-0.82605 0.45822,-1.10946 0.28341,-0.28342 0.6761,-0.45822 1.11043,-0.45822 z"
899
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.10902636;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
900
     inkscape:connector-curvature="0" />
901
  <rect
902
     style="opacity:1;fill:#ffb73a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9391377;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
903
     id="rect9826"
904
     width="120.98324"
905
     height="24"
906
     x="336.82672"
907
     y="477.86002"
908
     rx="2.8639088"
909
     ry="2.9102066" />
910
  <path
911
     id="path10514"
912
     d="m 235.85301,637.23875 c 0.87012,0 1.65488,0.35019 2.22266,0.91797 0.56778,0.56778 0.91797,1.35253 0.91797,2.22265 v -0.23242 c 0,-1.6112 -1.297,-2.9082 -2.9082,-2.9082 z"
913
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
914
     inkscape:connector-curvature="0" />
915
  <rect
916
     style="opacity:1;fill:#3dd092;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2878)"
917
     id="rect9717"
918
     width="165.621"
919
     height="32.855"
920
     x="313.99307"
921
     y="698.49591"
922
     rx="3.9205718"
923
     ry="3.9839513" />
924
  <path
925
     id="path10537"
926
     d="M 238.99366,636.97465 H 73.372671 V 729.175 c 0,1.2055 0.970418,2.17592 2.175911,2.17592 H 236.81776 c 1.20549,0 2.1759,-0.97042 2.1759,-2.17592 z"
927
     style="opacity:1;fill:#333333;fill-opacity:0.93333333;fill-rule:nonzero;stroke:none;stroke-width:0.16342013;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
928
     inkscape:connector-curvature="0"
929
     sodipodi:nodetypes="ccssssc" />
930
  <path
931
     sodipodi:nodetypes="sssccssss"
932
     id="path10516"
933
     d="m 75.723937,612.39226 c -0.651025,0 -1.239637,0.26201 -1.664447,0.68682 -0.424811,0.42482 -0.686822,1.01196 -0.686822,1.66299 v 22.23258 H 238.99366 v -22.23258 c 0,-0.65103 -0.26201,-1.23817 -0.68682,-1.66299 -0.42481,-0.42481 -1.01197,-0.68682 -1.66299,-0.68682 z"
934
     style="opacity:1;fill:#ffb73a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.16342013;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
935
     inkscape:connector-curvature="0" />
936
  <path
937
     style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker10933)"
938
     d="m 240.99257,715.51318 65.23376,-1.01307"
939
     id="path10929"
940
     inkscape:connector-curvature="0"
941
     sodipodi:nodetypes="cc" />
942
  <path
943
     style="fill:#df4d65;fill-opacity:1;fill-rule:evenodd;stroke-width:0.05250736"
944
     d="m 399.47357,99.155037 -0.12716,0.0127 -0.12716,0.0141 -0.12574,0.0141 -0.12716,0.0155 -0.61883,0.967813 -0.29106,0.9325 -0.17943,0.91977 -0.1215,1.09073 -0.30943,0.0636 -0.308,0.0678 -0.308,0.0735 -0.30801,0.0763 -0.58069,-0.93108 -0.5609,-0.75023 -0.66687,-0.71349 -0.97912,-0.6033 -0.12009,0.0409 -0.1201,0.0424 -0.12009,0.0424 -0.12009,0.0424 -0.38854,1.08085 -0.0763,0.97487 0.0297,0.93673 0.12575,1.08932 -0.28823,0.1314 -0.28681,0.13563 -0.28398,0.13987 -0.28117,0.14271 -0.77425,-0.77849 -0.7149,-0.60612 -0.80816,-0.54819 -1.0879,-0.37017 -0.10879,0.0678 -0.10738,0.0679 -0.10738,0.0678 -0.10738,0.0678 -0.13846,1.14018 0.14129,0.9664 0.23735,0.90706 0.36594,1.03563 -0.25149,0.19215 -0.24865,0.19497 -0.24585,0.19922 -0.24442,0.20204 -0.92825,-0.58634 -0.83077,-0.43234 -0.90988,-0.35463 -1.14301,-0.11868 -0.0904,0.0904 -0.0904,0.089 -0.089,0.0904 -0.0904,0.0904 0.11868,1.14301 0.35462,0.90988 0.43234,0.83218 0.58634,0.92684 -0.20204,0.24442 -0.19921,0.24584 -0.19498,0.24867 -0.19215,0.25148 -1.03563,-0.36593 -0.90705,-0.23736 -0.96641,-0.14128 -1.14018,0.13845 -0.0678,0.10738 -0.0678,0.10738 -0.0678,0.10738 -0.0678,0.10879 0.37016,1.0879 0.5482,0.80816 0.60612,0.71491 0.77848,0.77425 -0.1427,0.28117 -0.13987,0.28398 -0.13564,0.28681 -0.13139,0.28823 -1.09073,-0.12575 -0.93532,-0.0297 -0.97487,0.0763 -1.08084,0.38854 -0.0424,0.12009 -0.0424,0.12009 -0.0424,0.1201 -0.0409,0.12009 0.6033,0.97912 0.7135,0.66686 0.75023,0.56091 0.93107,0.58069 -0.0763,0.30801 -0.0735,0.308 -0.0678,0.308 -0.0636,0.30942 -1.09073,0.1215 -0.91977,0.17944 -0.9325,0.29105 -0.96781,0.61883 -0.0156,0.12717 -0.0141,0.12574 -0.0141,0.12716 -0.0127,0.12716 0.80533,0.81804 0.84348,0.49168 0.85619,0.38006 1.03704,0.36028 -0.006,0.31648 -0.003,0.31648 0.003,0.31648 0.006,0.31648 -1.03704,0.35887 -0.85619,0.38006 -0.84348,0.49168 -0.80533,0.81946 0.0127,0.12716 0.0141,0.12574 0.0141,0.12716 0.0156,0.12574 0.96781,0.62026 0.9325,0.29104 0.91977,0.17944 1.09073,0.12009 0.0636,0.30942 0.0678,0.30941 0.0735,0.30801 0.0763,0.30659 -0.93107,0.5821 -0.75023,0.56091 -0.7135,0.66687 -0.6033,0.97771 0.0409,0.12008 0.0424,0.12151 0.0424,0.1201 0.0424,0.11868 1.08084,0.38995 0.97487,0.0763 0.93532,-0.0297 1.09073,-0.12574 0.13139,0.28822 0.13564,0.2854 0.13987,0.28399 0.1427,0.28257 -0.77848,0.77425 -0.60612,0.7135 -0.5482,0.80957 -0.37016,1.08791 0.0678,0.10737 0.0678,0.10879 0.0678,0.10738 0.0678,0.10738 1.14018,0.13846 0.96641,-0.1427 0.90705,-0.23736 1.03563,-0.36452 0.19215,0.25149 0.19498,0.24866 0.19921,0.24584 0.20204,0.24302 -0.58634,0.92825 -0.43234,0.83076 -0.35462,0.9113 -0.11868,1.14159 0.0904,0.0918 0.089,0.089 0.0904,0.0904 0.0904,0.089 1.14301,-0.11868 0.90988,-0.35321 0.83077,-0.43375 0.92825,-0.58493 0.24442,0.20204 0.24585,0.19921 0.24865,0.19497 0.25149,0.19216 -0.36594,1.03563 -0.23735,0.90564 -0.14129,0.9664 0.13846,1.14018 0.10738,0.0692 0.10738,0.0678 0.10738,0.0678 0.10879,0.0664 1.0879,-0.37017 0.80816,-0.54677 0.7149,-0.60754 0.77425,-0.77708 0.28117,0.14271 0.28398,0.13987 0.28681,0.13422 0.28823,0.13139 -0.12575,1.09074 -0.0297,0.93673 0.0763,0.97346 0.38854,1.08084 0.12009,0.0438 0.12009,0.0424 0.1201,0.041 0.12009,0.0409 0.97912,-0.60188 0.66687,-0.71349 0.5609,-0.75165 0.58069,-0.93108 0.30801,0.0777 0.308,0.072 0.308,0.0692 0.30943,0.0636 0.1215,1.09073 0.17943,0.91978 0.29106,0.93249 0.61883,0.9664 0.12716,0.0156 0.12574,0.0141 0.12716,0.0141 0.12716,0.0141 0.81806,-0.80533 0.49167,-0.8449 0.38006,-0.85619 0.36028,-1.03704 0.31648,0.007 0.31648,0.003 0.31649,-0.003 0.31648,-0.007 0.36028,1.03704 0.37865,0.85619 0.49167,0.8449 0.81947,0.80533 0.12715,-0.0141 0.12574,-0.0141 0.12717,-0.0141 0.12574,-0.0156 0.62025,-0.9664 0.29104,-0.93249 0.17944,-0.91978 0.12009,-1.09073 0.30942,-0.0636 0.30942,-0.0692 0.30799,-0.072 0.3066,-0.0777 0.58211,0.93108 0.5609,0.75165 0.66687,0.71349 0.97771,0.60188 0.12009,-0.0409 0.1215,-0.041 0.1201,-0.0424 0.11868,-0.0438 0.38995,-1.08084 0.0763,-0.97346 -0.0297,-0.93673 -0.12574,-1.09074 0.28822,-0.13139 0.2854,-0.13422 0.28398,-0.13987 0.28258,-0.14271 0.77424,0.77708 0.7135,0.60754 0.80957,0.54677 1.08791,0.37017 0.10737,-0.0664 0.10879,-0.0678 0.10738,-0.0678 0.10738,-0.0692 0.13847,-1.14018 -0.14271,-0.9664 -0.23737,-0.90564 -0.36452,-1.03563 0.25149,-0.19216 0.24866,-0.19497 0.24585,-0.19921 0.24301,-0.20204 0.92825,0.58493 0.83077,0.43375 0.91129,0.35321 1.1416,0.11868 0.0904,-0.089 0.0904,-0.0904 0.0904,-0.089 0.089,-0.0918 -0.11868,-1.14159 -0.35321,-0.9113 -0.43375,-0.83076 -0.58492,-0.92825 0.20203,-0.24302 0.19921,-0.24584 0.19498,-0.24866 0.19215,-0.25149 1.03563,0.36452 0.90564,0.23736 0.9664,0.1427 1.14018,-0.13846 0.0692,-0.10738 0.0678,-0.10738 0.0678,-0.10879 0.0664,-0.10737 -0.37017,-1.08791 -0.54677,-0.80957 -0.60754,-0.7135 -0.77706,-0.77425 0.1427,-0.28257 0.13986,-0.28399 0.13423,-0.2854 0.13139,-0.28822 1.09073,0.12574 0.93674,0.0297 0.97345,-0.0763 1.08085,-0.38995 0.0438,-0.11868 0.0424,-0.1201 0.0409,-0.12151 0.041,-0.12008 -0.6019,-0.97771 -0.71349,-0.66687 -0.75164,-0.56091 -0.93108,-0.5821 0.0777,-0.30659 0.072,-0.30801 0.0692,-0.30941 0.0636,-0.30942 1.09073,-0.12009 0.91978,-0.17944 0.93249,-0.29104 0.9664,-0.62026 0.0155,-0.12574 0.0141,-0.12716 0.0141,-0.12574 0.0141,-0.12716 -0.80533,-0.81946 -0.8449,-0.49168 -0.85619,-0.38006 -1.03704,-0.35887 0.007,-0.31648 0.003,-0.31648 -0.003,-0.31648 -0.007,-0.31648 1.03704,-0.36028 0.85619,-0.38006 0.8449,-0.49168 0.80533,-0.81804 -0.0141,-0.12716 -0.0141,-0.12716 -0.0141,-0.12574 -0.0155,-0.12717 -0.9664,-0.61883 -0.93249,-0.29105 -0.91978,-0.17944 -1.09073,-0.1215 -0.0636,-0.30942 -0.0692,-0.308 -0.072,-0.308 -0.0777,-0.30801 0.93108,-0.58069 0.75164,-0.56091 0.71349,-0.66686 0.6019,-0.97912 -0.041,-0.12009 -0.0409,-0.1201 -0.0424,-0.12009 -0.0438,-0.12009 -1.08085,-0.38854 -0.97345,-0.0763 -0.93674,0.0297 -1.09073,0.12575 -0.13139,-0.28823 -0.13423,-0.28681 -0.13986,-0.28398 -0.1427,-0.28117 0.77706,-0.77425 0.60754,-0.71491 0.54677,-0.80816 0.37017,-1.0879 -0.0664,-0.10879 -0.0678,-0.10738 -0.0678,-0.10738 -0.0692,-0.10738 -1.14018,-0.13845 -0.9664,0.14128 -0.90564,0.23736 -1.03563,0.36593 -0.19215,-0.25148 -0.19498,-0.24867 -0.19921,-0.24584 -0.20203,-0.24442 0.58492,-0.92684 0.43375,-0.83218 0.35321,-0.90988 0.11868,-1.14301 -0.089,-0.0904 -0.0904,-0.0904 -0.0904,-0.089 -0.0904,-0.0904 -1.1416,0.11868 -0.91129,0.35463 -0.83077,0.43234 -0.92825,0.58634 -0.24301,-0.20204 -0.24585,-0.19922 -0.24866,-0.19497 -0.25149,-0.19215 0.36452,-1.03563 0.23737,-0.90706 0.14271,-0.9664 -0.13847,-1.14018 -0.10738,-0.0678 -0.10738,-0.0678 -0.10879,-0.0679 -0.10737,-0.0678 -1.08791,0.37017 -0.80957,0.54819 -0.7135,0.60612 -0.77424,0.77849 -0.28258,-0.14271 -0.28398,-0.13987 -0.2854,-0.13563 -0.28822,-0.1314 0.12574,-1.08932 0.0297,-0.93673 -0.0763,-0.97487 -0.38995,-1.08085 -0.11868,-0.0424 -0.1201,-0.0424 -0.1215,-0.0424 -0.12009,-0.0409 -0.97771,0.6033 -0.66687,0.71349 -0.5609,0.75023 -0.58211,0.93108 -0.3066,-0.0763 -0.30799,-0.0735 -0.30942,-0.0678 -0.30942,-0.0636 -0.12009,-1.09073 -0.17944,-0.91977 -0.29104,-0.9325 -0.62025,-0.967813 -0.12574,-0.0155 -0.12717,-0.0141 -0.12574,-0.0141 -0.12715,-0.0127 -0.81947,0.80533 -0.49167,0.843483 -0.37865,0.8562 -0.36028,1.03704 -0.31648,-0.006 -0.31649,-0.003 -0.31648,0.003 -0.31648,0.006 -0.36028,-1.03704 -0.38006,-0.8562 -0.49167,-0.843483 z m 2.68302,20.688573 a 5.3990039,5.3990039 0 0 1 5.39856,5.39997 5.3990039,5.3990039 0 0 1 -5.39856,5.39855 5.3990039,5.3990039 0 0 1 -5.39996,-5.39855 5.3990039,5.3990039 0 0 1 5.39996,-5.39997 z"
945
     id="path5693"
946
     inkscape:connector-curvature="0" />
947
  <path
948
     inkscape:connector-curvature="0"
949
     d="m 380.9529,101.31918 a 4.37599,4.37599 0 0 1 -4.37599,4.37599 4.37599,4.37599 0 0 1 -4.37599,-4.37599 4.37599,4.37599 0 0 1 4.37599,-4.375983 4.37599,4.37599 0 0 1 4.37599,4.375983 z m 4.63493,-1.27213 c -0.32212,-0.118873 -0.95326,0.0926 -0.92258,-0.401293 -0.13877,-0.39635 -0.21401,-0.74537 0.27363,-0.88946 0.78055,-0.47633 1.45123,-1.16128 1.74461,-2.04171 0.15411,-0.39145 -0.3432,-0.48754 -0.63657,-0.53536 -0.91614,-0.25589 -1.86519,0.0578 -2.73328,0.35995 -0.11023,-0.31345 -0.69059,-0.56868 -0.47901,-0.88657 0.56405,-0.84324 0.99162,-1.8335 0.85012,-2.86709 -0.031,-0.41955 -0.52073,-0.29038 -0.8058,-0.20618 -0.93646,0.16692 -1.65537,0.86143 -2.30642,1.51029 -0.23528,-0.23464 -0.86896,-0.21274 -0.81624,-0.59097 0.14241,-1.00446 0.0978,-2.08217 -0.47806,-2.95201 -0.20995,-0.36459 -0.59514,-0.0357 -0.81544,0.16385 -0.7713,0.55671 -1.11768,1.49434 -1.42274,2.36143 -0.3138,-0.10927 -0.87519,0.18536 -0.99181,-0.17826 -0.30757,-0.96675 -0.81528,-1.91841 -1.71153,-2.45229 -0.34734,-0.23737 -0.55176,0.22606 -0.66364,0.50149 -0.45331,0.83622 -0.35865,1.83127 -0.25723,2.74482 -0.33012,0.0378 -0.70817,0.54672 -0.97098,0.26977 -0.69651,-0.73763 -1.56687,-1.37476 -2.60601,-1.46682 -0.41593,-0.0631 -0.39904,0.443 -0.38034,0.73971 -0.0456,0.95009 0.47143,1.80554 0.95918,2.58463 -0.28104,0.17725 -0.40076,0.79984 -0.75777,0.6643 -0.94759,-0.36236 -2.00818,-0.55864 -2.98437,-0.1908 -0.40215,0.12357 -0.16723,0.57227 -0.0217,0.83147 0.37114,0.8758 1.2081,1.42221 1.98561,1.91248 -0.17632,0.28163 -0.0141,0.89453 -0.39449,0.92732 -1.01097,0.0847 -2.05173,0.367983 -2.77166,1.122963 -0.3087,0.2858 0.0976,0.58816 0.34122,0.75853 0.71439,0.62804 1.70558,0.75716 2.6188,0.8616 -0.0367,0.33025 0.37548,0.81204 0.0469,1.00665 -0.87415,0.51488 -1.68886,1.22174 -2.00994,2.2143 -0.15411,0.39144 0.3432,0.48753 0.63657,0.53535 0.91612,0.25589 1.86516,-0.0578 2.73323,-0.35995 0.11029,0.31341 0.69063,0.56869 0.47905,0.88657 -0.56412,0.8432 -0.99155,1.83352 -0.85015,2.86709 0.031,0.41952 0.52075,0.2904 0.80584,0.20618 0.93644,-0.16692 1.65537,-0.86139 2.30637,-1.51029 0.2353,0.23464 0.86901,0.21272 0.81629,0.59098 -0.14241,1.00446 -0.0978,2.08215 0.47802,2.95202 0.20997,0.36455 0.59517,0.0357 0.81548,-0.16387 0.77125,-0.55674 1.11768,-1.49435 1.42274,-2.36142 0.31379,0.10926 0.8752,-0.18537 0.99181,0.17824 0.30754,0.96678 0.81527,1.91842 1.71153,2.45229 0.34733,0.23738 0.55172,-0.22608 0.66362,-0.50146 0.45335,-0.83621 0.35866,-1.83128 0.25725,-2.74484 0.33011,-0.0378 0.70812,-0.54672 0.97093,-0.26977 0.69656,0.7376 1.5669,1.37477 2.60606,1.46683 0.41593,0.0632 0.39897,-0.44304 0.38032,-0.73972 0.0457,-0.95011 -0.4715,-1.8055 -0.95916,-2.58463 0.28105,-0.17722 0.40074,-0.79983 0.75772,-0.6643 0.94761,0.36234 2.00821,0.55865 2.98442,0.1908 0.40215,-0.12357 0.16723,-0.57228 0.0217,-0.83146 -0.37116,-0.87579 -1.20814,-1.42218 -1.98561,-1.91249 0.17632,-0.28163 0.0141,-0.89453 0.39449,-0.92732 1.01097,-0.0847 2.05173,-0.36799 2.77166,-1.12295 0.3087,-0.28581 -0.0976,-0.58817 -0.34122,-0.75854 -0.47483,-0.43652 -1.13407,-0.61787 -1.75144,-0.75008 z"
950
     style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke-width:0.04014921"
951
     id="path5687" />
952
  <path
953
     style="fill:#05556e;fill-opacity:1;stroke-width:0.11881336"
954
     id="path4816"
955
     d="m 619.92265,90.37586 h 2.72717 v 2.71445 h 2.51374 v -2.71445 h 2.72716 v 8.21477 h -2.72716 v -2.73825 h -2.49003 v 2.73825 h -2.75088 m 11.57268,-5.47651 h -2.40702 v -2.73826 h 7.55307 v 2.73826 h -2.41888 v 5.47651 h -2.72717 m 6.34363,-8.21477 h 2.8576 l 1.75487,2.89303 1.75487,-2.89303 h 2.8576 v 8.21477 h -2.72717 v -4.07167 l -1.90901,2.95256 -1.90902,-2.95256 v 4.07167 h -2.67974 m 10.57667,-8.21477 h 2.72717 v 5.50033 h 3.86546 v 2.71444 h -6.59263"
956
     inkscape:connector-curvature="0" />
957
  <path
958
     id="path4818"
959
     d="m 619.82779,146.45062 -3.91289,-44.09786 h 43.01811 l -3.91289,44.07405 -17.63174,4.90505"
960
     inkscape:connector-curvature="0"
961
     style="fill:#e44d26;stroke-width:0.11881336" />
962
  <path
963
     id="path4820"
964
     d="m 637.42396,147.58164 v -41.60962 h 17.5843 l -3.3556,37.62129"
965
     inkscape:connector-curvature="0"
966
     style="fill:#f16529;stroke-width:0.11881336" />
967
  <path
968
     id="path4822"
969
     d="m 623.90669,111.3652 h 13.51727 v 5.40508 h -7.61236 l 0.498,5.53605 h 7.11436 v 5.39318 h -12.04697 m 0.23714,2.71444 h 5.40691 l 0.37943,4.32169 6.02349,1.61914 v 5.64319 L 626.373,138.90255"
970
     inkscape:connector-curvature="0"
971
     style="fill:#ebebeb;stroke-width:0.11881336" />
972
  <path
973
     id="path4824"
974
     d="m 650.89379,111.3652 h -13.49355 v 5.40508 h 12.99555 m -0.48615,5.53605 h -12.5094 v 5.40508 h 6.64006 l -0.62843,7.02423 -6.01163,1.61914 v 5.61938 l 11.02724,-3.07161"
975
     inkscape:connector-curvature="0"
976
     style="fill:#ffffff;stroke-width:0.11881336" />
977
  <path
978
     sodipodi:nodetypes="cc"
979
     inkscape:connector-curvature="0"
980
     id="path5804"
981
     d="m 240.99252,105.07517 65.2338,-1.01308"
982
     style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9479)" />
983
  <path
984
     style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9505)"
985
     d="m 481.61302,105.07517 65.2337,-1.01308"
986
     id="path9497"
987
     inkscape:connector-curvature="0"
988
     sodipodi:nodetypes="cc" />
989
  <path
990
     inkscape:connector-curvature="0"
991
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
992
     d="m 235.85308,230.53494 c 0.87012,0 1.65488,0.35019 2.22266,0.91797 0.56778,0.56778 0.91797,1.35253 0.91797,2.22265 v -0.23242 c 0,-1.6112 -1.297,-2.9082 -2.9082,-2.9082 z"
993
     id="path6102" />
994
  <path
995
     inkscape:connector-curvature="0"
996
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
997
     d="m 76.280823,230.53494 c -1.611195,0 -2.908203,1.297 -2.908203,2.9082 v 0.23242 c 0,-0.87012 0.35019,-1.65487 0.917968,-2.22265 0.567779,-0.56778 1.354485,-0.91797 2.22461,-0.91797 z"
998
     id="path6106" />
999
  <path
1000
     inkscape:connector-curvature="0"
1001
     style="fill:#46c7f0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2950)"
1002
     d="m 76.515198,222.53494 c -0.870125,0 -1.656831,0.35019 -2.22461,0.91797 -0.567778,0.56778 -0.917968,1.35253 -0.917968,2.22265 v 29.71485 h 165.62109 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91797,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z"
1003
     id="path6104"
1004
     sodipodi:nodetypes="sssccssss" />
1005
  <path
1006
     sodipodi:nodetypes="ccssssc"
1007
     inkscape:connector-curvature="0"
1008
     style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2950)"
1009
     d="M 238.99371,255.39041 H 73.37262 v 152.63392 c 0,1.6112 1.297008,2.90821 2.908203,2.90821 H 236.08551 c 1.6112,0 2.9082,-1.29701 2.9082,-2.90821 z"
1010
     id="path6100" />
1011
  <path
1012
     style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9509)"
1013
     d="m 240.99257,328.95043 65.23376,-1.01307"
1014
     id="path9485"
1015
     inkscape:connector-curvature="0"
1016
     sodipodi:nodetypes="cc" />
1017
  <path
1018
     sodipodi:nodetypes="cc"
1019
     inkscape:connector-curvature="0"
1020
     id="path9757"
1021
     d="m 481.61298,300.08996 65.23376,-1.01307"
1022
     style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9761)" />
1023
  <path
1024
     style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9767)"
1025
     d="M 552.61456,372.04139 487.3808,371.02832"
1026
     id="path9763"
1027
     inkscape:connector-curvature="0"
1028
     sodipodi:nodetypes="cc" />
1029
  <text
1030
     id="text2269"
1031
     y="62.149761"
1032
     x="115.43707"
1033
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1034
     xml:space="preserve"><tspan
1035
       y="62.149761"
1036
       x="115.43707"
1037
       id="tspan2267"
1038
       sodipodi:role="line">Text Edit</tspan></text>
1039
  <text
1040
     transform="rotate(-90)"
1041
     id="text2273"
1042
     y="43.507812"
1043
     x="-132.24059"
1044
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1045
     xml:space="preserve"><tspan
1046
       y="43.507812"
1047
       x="-132.24059"
1048
       id="tspan2271"
1049
       sodipodi:role="line">Today</tspan></text>
1050
  <text
1051
     id="text2277"
1052
     y="61.540386"
1053
     x="358.88168"
1054
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1055
     xml:space="preserve"><tspan
1056
       y="61.540386"
1057
       x="358.88168"
1058
       id="tspan2275"
1059
       sodipodi:role="line">Process</tspan></text>
1060
  <text
1061
     id="text2281"
1062
     y="59.34898"
1063
     x="605.30872"
1064
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1065
     xml:space="preserve"><tspan
1066
       y="59.34898"
1067
       x="605.30872"
1068
       id="tspan2279"
1069
       sodipodi:role="line">Output</tspan></text>
1070
  <text
1071
     id="text2285"
1072
     y="245.17946"
1073
     x="605.30872"
1074
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1075
     xml:space="preserve"><tspan
1076
       y="245.17946"
1077
       x="605.30872"
1078
       id="tspan2283"
1079
       sodipodi:role="line">Output</tspan></text>
1080
  <text
1081
     id="text2289"
1082
     y="247.37088"
1083
     x="358.88168"
1084
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1085
     xml:space="preserve"><tspan
1086
       y="247.37088"
1087
       x="358.88168"
1088
       id="tspan2287"
1089
       sodipodi:role="line">Process</tspan></text>
1090
  <text
1091
     id="text2293"
1092
     y="247.98026"
1093
     x="115.43707"
1094
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1095
     xml:space="preserve"><tspan
1096
       y="247.98026"
1097
       x="115.43707"
1098
       id="tspan2291"
1099
       sodipodi:role="line">Text Edit</tspan></text>
1100
  <text
1101
     transform="rotate(-90)"
1102
     id="text2297"
1103
     y="43.630859"
1104
     x="-363.15442"
1105
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1106
     xml:space="preserve"><tspan
1107
       y="43.630859"
1108
       x="-363.15442"
1109
       id="tspan2295"
1110
       sodipodi:role="line">Proposed</tspan></text>
1111
  <text
1112
     id="text2301"
1113
     y="314.01108"
1114
     x="98.034729"
1115
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none"
1116
     xml:space="preserve"><tspan
1117
       id="tspan2299"
1118
       sodipodi:role="line"
1119
       x="98.034729"
1120
       y="314.01108">R Markdown</tspan></text>
1121
  <text
1122
     id="text2305"
1123
     y="285.84311"
1124
     x="107.43903"
1125
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none"
1126
     xml:space="preserve"><tspan
1127
       id="tspan2303"
1128
       sodipodi:role="line"
1129
       x="107.43903"
1130
       y="285.84311">Markdown</tspan></text>
1131
  <text
1132
     id="text2309"
1133
     y="342.91147"
1134
     x="134.3277"
1135
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none"
1136
     xml:space="preserve"><tspan
1137
       id="tspan2307"
1138
       sodipodi:role="line"
1139
       x="134.3277"
1140
       y="342.91147">XML</tspan></text>
1141
  <text
1142
     id="text2313"
1143
     y="370.34702"
1144
     x="113.56207"
1145
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none"
1146
     xml:space="preserve"><tspan
1147
       id="tspan2311"
1148
       sodipodi:role="line"
1149
       x="113.56207"
1150
       y="370.34702">DocBook</tspan></text>
1151
  <text
1152
     id="text2317"
1153
     y="398.51498"
1154
     x="114.3526"
1155
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none"
1156
     xml:space="preserve"><tspan
1157
       id="tspan2315"
1158
       sodipodi:role="line"
1159
       x="114.3526"
1160
       y="398.51498">AsciiDoc</tspan></text>
1161
  <text
1162
     transform="rotate(-90)"
1163
     id="text2329"
1164
     y="43.507812"
1165
     x="-774.87335"
1166
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1167
     xml:space="preserve"><tspan
1168
       y="43.507812"
1169
       x="-774.87335"
1170
       id="tspan2327"
1171
       sodipodi:role="line">Example Processing Combination</tspan></text>
1172
  <text
1173
     id="text2333"
1174
     y="562.05426"
1175
     x="135.31207"
1176
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#f3fbfe;fill-opacity:1;stroke:none"
1177
     xml:space="preserve"><tspan
1178
       y="562.05426"
1179
       x="135.31207"
1180
       id="tspan2331"
1181
       sodipodi:role="line">XML</tspan></text>
1182
  <text
1183
     id="text2337"
1184
     y="495.6918"
1185
     x="381.64142"
1186
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#333333;fill-opacity:0.866667;stroke:none"
1187
     xml:space="preserve"><tspan
1188
       y="495.6918"
1189
       x="381.64142"
1190
       id="tspan2335"
1191
       sodipodi:role="line">XSLT</tspan></text>
1192
  <text
1193
     id="text2341"
1194
     y="562.05426"
1195
     x="323.97742"
1196
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1197
     xml:space="preserve"><tspan
1198
       y="562.05426"
1199
       x="323.97742"
1200
       id="tspan2339"
1201
       sodipodi:role="line">XSLT Processor</tspan></text>
1202
  <text
1203
     id="text2345"
1204
     y="562.54059"
1205
     x="579.27557"
1206
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1207
     xml:space="preserve"><tspan
1208
       y="562.54059"
1209
       x="579.27557"
1210
       id="tspan2343"
1211
       sodipodi:role="line">R Markdown</tspan></text>
1212
  <text
1213
     id="text2349"
1214
     y="643.24084"
1215
     x="588.75018"
1216
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1217
     xml:space="preserve"><tspan
1218
       y="643.24084"
1219
       x="588.75018"
1220
       id="tspan2347"
1221
       sodipodi:role="line">Markdown</tspan></text>
1222
  <text
1223
     id="text2353"
1224
     y="642.63147"
1225
     x="339.61023"
1226
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1227
     xml:space="preserve"><tspan
1228
       y="642.63147"
1229
       x="339.61023"
1230
       id="tspan2351"
1231
       sodipodi:role="line">R Processor</tspan></text>
1232
  <text
1233
     id="text2357"
1234
     y="722.93903"
1235
     x="318.43912"
1236
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:21.3333px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1237
     xml:space="preserve"><tspan
1238
       y="722.93903"
1239
       x="318.43912"
1240
       id="tspan2355"
1241
       sodipodi:role="line">Variable Processor</tspan></text>
1242
  <text
1243
     id="text2361"
1244
     y="723.3316"
1245
     x="604.07831"
1246
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1247
     xml:space="preserve"><tspan
1248
       y="723.3316"
1249
       x="604.07831"
1250
       id="tspan2359"
1251
       sodipodi:role="line">HTML5</tspan></text>
1252
  <text
1253
     id="text2365"
1254
     y="630.84766"
1255
     x="81.211723"
1256
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#333333;fill-opacity:0.866667;stroke:none"
1257
     xml:space="preserve"><tspan
1258
       y="630.84766"
1259
       x="81.211723"
1260
       id="tspan2363"
1261
       sodipodi:role="line">Structured Data Source</tspan></text>
1262
  <text
1263
     id="text2369"
1264
     y="756.39404"
1265
     x="215.65826"
1266
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none"
1267
     xml:space="preserve"><tspan
1268
       y="756.39404"
1269
       x="215.65826"
1270
       id="tspan2367"
1271
       sodipodi:role="line">interpolated values</tspan></text>
1272
  <g
1273
     transform="translate(-0.25585322,11.831789)"
1274
     id="g2523">
1275
    <text
1276
       xml:space="preserve"
1277
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1278
       x="156.49219"
1279
       y="708.2467"
1280
       id="text2373"><tspan
1281
         sodipodi:role="line"
1282
         id="tspan2371"
1283
         x="156.49219"
1284
         y="708.2467">CSON</tspan></text>
1285
    <text
1286
       xml:space="preserve"
1287
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1288
       x="156.49219"
1289
       y="688.41504"
1290
       id="text2377"><tspan
1291
         sodipodi:role="line"
1292
         id="tspan2375"
1293
         x="156.49219"
1294
         y="688.41504">JSONNET</tspan></text>
1295
    <text
1296
       xml:space="preserve"
1297
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1298
       x="156.49219"
1299
       y="668.24695"
1300
       id="text2381"><tspan
1301
         sodipodi:role="line"
1302
         id="tspan2379"
1303
         x="156.49219"
1304
         y="668.24695">JSON5</tspan></text>
1305
    <text
1306
       xml:space="preserve"
1307
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1308
       x="156.49219"
1309
       y="648.07886"
1310
       id="text2385"><tspan
1311
         sodipodi:role="line"
1312
         id="tspan2383"
1313
         x="156.49219"
1314
         y="648.07886">JSON</tspan></text>
1315
    <text
1316
       xml:space="preserve"
1317
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1318
       x="94.110725"
1319
       y="648.41534"
1320
       id="text2389"><tspan
1321
         sodipodi:role="line"
1322
         id="tspan2387"
1323
         x="94.110725"
1324
         y="648.41534">YAML</tspan></text>
1325
    <text
1326
       xml:space="preserve"
1327
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1328
       x="94.110725"
1329
       y="668.24695"
1330
       id="text2393"><tspan
1331
         sodipodi:role="line"
1332
         id="tspan2391"
1333
         x="94.110725"
1334
         y="668.24695">TOML</tspan></text>
1335
    <text
1336
       xml:space="preserve"
1337
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1338
       x="94.110725"
1339
       y="688.41504"
1340
       id="text2397"><tspan
1341
         sodipodi:role="line"
1342
         id="tspan2395"
1343
         x="94.110725"
1344
         y="688.41504">XML</tspan></text>
1345
  </g>
1346
  <g
1347
     transform="translate(-1.2304677,-0.85937628)"
1348
     id="g2593">
1349
    <g
1350
       id="g2532">
1351
      <rect
1352
         id="rect4698"
1353
         ry="2.7292624"
1354
         y="91.740654"
1355
         x="129.16347"
1356
         height="32.205296"
1357
         width="54.039394"
1358
         style="fill:none;stroke:#05556e;stroke-width:2.72926;stroke-opacity:1" />
1359
      <path
1360
         style="fill:#05556e;fill-opacity:1;stroke-width:0.272926"
1361
         id="path4700"
1362
         d="M 135.98663,117.12279 V 98.56381 h 5.45852 l 5.45853,6.82315 5.45852,-6.82315 h 5.45853 v 18.55898 h -5.45853 v -10.64412 l -5.45852,6.82315 -5.45853,-6.82315 v 10.64412 z m 34.11578,0 -8.18779,-9.00657 h 5.45852 v -9.55241 h 5.45853 v 9.55241 h 5.45852 z"
1363
         inkscape:connector-curvature="0" />
1364
    </g>
1365
    <text
1366
       xml:space="preserve"
1367
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none"
1368
       x="108.73981"
1369
       y="152.80437"
1370
       id="text2407"><tspan
1371
         sodipodi:role="line"
1372
         id="tspan2405"
1373
         x="108.73981"
1374
         y="152.80437">Markdown</tspan></text>
1375
  </g>
1376
  <path
1377
     inkscape:connector-curvature="0"
1378
     d="m 417.86562,272.90923 c -2.81873,0.35302 -5.58858,1.78683 -7.90222,4.10047 -1.79226,1.78682 -3.43787,4.20365 -5.01832,7.35911 -1.28173,2.56347 -2.29191,5.21927 -2.90019,7.59265 l -0.1738,0.68975 -0.68975,0.35302 c -0.96673,0.49423 -1.81398,1.01561 -2.77528,1.69993 -3.29666,2.35709 -6.15341,5.19211 -8.53222,8.46705 -0.23354,0.32586 -0.45621,0.58656 -0.49966,0.58656 -0.038,0 -0.33673,-0.0435 -0.65716,-0.0923 -0.73863,-0.11949 -3.19891,-0.13578 -4.11676,-0.0272 -3.79633,0.46164 -7.25593,1.57502 -11.41613,3.68228 -3.00339,1.5207 -4.93685,2.87304 -6.8323,4.77391 -2.37881,2.37882 -3.80176,5.01832 -4.21452,7.82076 -0.0978,0.62457 -0.0978,2.39511 0,3.0414 0.51052,3.55193 2.55804,6.94636 5.27358,8.74404 3.15003,2.08554 7.40256,2.6558 12.27424,1.65105 3.62253,-0.75492 7.20161,-2.14527 10.77526,-4.19822 3.47046,-1.99321 5.87643,-4.18193 7.57093,-6.87575 0.27155,-0.43449 0.35845,-0.52682 0.53224,-0.59199 2.79701,-1.01018 4.74677,-2.05295 6.96265,-3.72572 2.02036,-1.5207 3.43244,-2.85675 6.0991,-5.77324 0.68432,-0.74949 0.8038,-0.91785 0.84182,-1.16225 0.0326,-0.17379 0.0543,-0.20095 0.15207,-0.17922 0.51595,0.10319 2.20502,0.11948 2.94908,0.0272 2.08553,-0.25526 4.05701,-1.10251 6.01763,-2.57976 2.61778,-1.97691 5.06177,-5.27901 6.78885,-9.17853 2.59606,-5.86556 3.57908,-10.80785 3.01425,-15.19073 -0.14121,-1.12423 -0.28241,-1.74881 -0.59742,-2.71554 -0.42905,-1.29803 -1.08621,-2.55804 -1.89001,-3.62796 -0.43449,-0.57026 -1.57502,-1.70536 -2.14528,-2.12898 -1.59131,-1.17855 -3.93753,-2.13442 -6.03936,-2.46028 -0.66259,-0.10319 -2.29735,-0.14664 -2.85132,-0.0815 z m 2.44399,7.82076 c 1.94433,0.46707 3.2152,2.04751 3.5302,4.39917 0.0815,0.58656 0.0815,2.10183 0,2.7427 -0.32043,2.62864 -1.26544,5.70263 -2.61235,8.48878 -1.01561,2.10725 -1.79226,3.34011 -2.88933,4.58383 -0.32587,0.36931 -1.38493,1.31975 -1.42838,1.2763 -0.005,-0.005 0.0706,-0.34216 0.1738,-0.74406 0.24983,-0.97759 0.34215,-1.56958 0.3856,-2.41683 0.0706,-1.58044 -0.27155,-3.09571 -0.98302,-4.30684 -1.20027,-2.05295 -3.17175,-3.41072 -5.47453,-3.78547 -0.11405,-0.0163 -0.20638,-0.0489 -0.20638,-0.076 0,-0.0217 0.19552,-0.53768 0.42905,-1.15139 1.41752,-3.67684 2.66666,-5.83298 4.30142,-7.40799 1.0482,-1.01562 1.70536,-1.40665 2.73726,-1.62933 0.51596,-0.11405 1.49355,-0.0978 2.03666,0.0272 z m -10.34078,17.93885 c 0.52139,0.54311 0.56483,0.76579 0.46164,2.25933 l -0.0326,0.51596 -0.14121,-0.21725 c -0.22811,-0.34215 -0.40733,-0.72233 -0.52682,-1.1188 -0.0652,-0.20095 -0.15207,-0.43992 -0.20095,-0.53224 -0.0706,-0.13035 -0.17922,-0.91243 -0.19008,-1.34691 0,-0.11949 0.29871,0.0923 0.63,0.43991 z m -7.36997,3.01425 c 0.3856,2.28649 1.18397,4.05159 2.44941,5.40393 l 0.45078,0.47793 -0.13577,0.14664 c -0.0706,0.0815 -0.46165,0.51052 -0.86355,0.9613 -1.55328,1.73795 -2.81873,2.98167 -4.05158,3.97012 -0.41819,0.34216 -0.78208,0.61915 -0.79837,0.61915 -0.0163,0 -0.0435,-0.0923 -0.0652,-0.20638 -0.076,-0.4019 -0.46708,-1.4664 -0.8038,-2.15614 -0.54311,-1.12424 -1.14596,-2.0095 -2.08554,-3.0577 l -0.45621,-0.50509 0.41276,-0.50509 c 1.19484,-1.47182 2.92192,-3.26951 4.43177,-4.62728 0.85811,-0.76578 1.37949,-1.21656 1.39578,-1.20027 0.005,0.005 0.0597,0.315 0.11949,0.67888 z m -16.52135,9.77052 c -0.0163,0.11405 -0.0815,0.54311 -0.14664,0.9613 -0.22267,1.47182 -0.23353,3.57365 -0.0272,4.78478 0.19008,1.10251 0.57569,2.11812 1.08078,2.81873 0.27699,0.38018 0.87441,0.97759 1.22199,1.20027 l 0.23354,0.1575 -0.15207,0.12492 c -0.60285,0.48879 -2.54174,1.58044 -4.18193,2.34622 -2.4114,1.12967 -4.36659,1.7651 -6.62049,2.16157 -0.77664,0.13578 -0.99932,0.15207 -2.09096,0.15207 -0.98846,0 -1.30889,-0.0217 -1.67278,-0.0978 -1.5207,-0.33672 -2.53088,-0.97216 -3.1989,-2.0095 -0.53225,-0.82552 -0.72234,-1.48268 -0.72777,-2.43855 0,-1.56415 0.57027,-2.68296 2.17244,-4.27969 1.78682,-1.77597 3.93753,-3.05227 7.72299,-4.5784 2.01493,-0.81467 4.20366,-1.37407 5.75151,-1.4664 0.74406,-0.0434 0.66803,-0.0652 0.63544,0.16294 z m 6.13712,3.5302 c -0.0163,0.0543 -0.0272,0.0109 -0.0272,-0.0923 0,-0.10319 0.0109,-0.14664 0.0272,-0.0978 0.0109,0.0543 0.0109,0.14121 0,0.19009 z"
1379
     id="path8164"
1380
     style="fill:#df4d65;fill-opacity:1;stroke:none;stroke-width:0.00543108" />
1381
  <g
1382
     transform="translate(1.378418e-5,1.0193503)"
1383
     id="g1168">
1384
    <text
1385
       id="text1158"
1386
       y="364.17905"
1387
       x="349.05551"
1388
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none"
1389
       xml:space="preserve"><tspan
1390
         id="tspan1156"
1391
         sodipodi:role="line"
1392
         x="349.05551"
1393
         y="364.17905">Processor</tspan></text>
1394
    <text
1395
       xml:space="preserve"
1396
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none"
1397
       x="370.40707"
1398
       y="392.17905"
1399
       id="text1162"><tspan
1400
         y="392.17905"
1401
         x="370.40707"
1402
         sodipodi:role="line"
1403
         id="tspan1160">Chain</tspan></text>
1404
  </g>
1405
  <g
1406
     transform="translate(0,-2.3144459)"
1407
     id="g1206">
1408
    <text
1409
       xml:space="preserve"
1410
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none"
1411
       x="586.44855"
1412
       y="327.56967"
1413
       id="text1190"><tspan
1414
         y="327.56967"
1415
         x="586.44855"
1416
         sodipodi:role="line"
1417
         id="tspan1188">Processor-</tspan></text>
1418
    <text
1419
       id="text1194"
1420
       y="355.56967"
1421
       x="588.43488"
1422
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none"
3
   inkscape:export-ydpi="150.0097"
4
   inkscape:export-xdpi="150.0097"
5
   sodipodi:docname="architecture.svg"
6
   viewBox="0 0 764.4414 811.46748"
7
   height="811.46747"
8
   width="764.44141"
9
   id="svg4610"
10
   version="1.2"
11
   inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
12
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
13
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
14
   xmlns="http://www.w3.org/2000/svg"
15
   xmlns:svg="http://www.w3.org/2000/svg"
16
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
17
   xmlns:cc="http://creativecommons.org/ns#"
18
   xmlns:dc="http://purl.org/dc/elements/1.1/">
19
  <metadata
20
     id="metadata4616">
21
    <rdf:RDF>
22
      <cc:Work
23
         rdf:about="">
24
        <dc:format>image/svg+xml</dc:format>
25
        <dc:type
26
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
27
        <dc:title />
28
      </cc:Work>
29
    </rdf:RDF>
30
  </metadata>
31
  <defs
32
     id="defs4614">
33
    <marker
34
       inkscape:stockid="Arrow1Mend"
35
       orient="auto"
36
       refY="0"
37
       refX="0"
38
       id="marker10933"
39
       style="overflow:visible"
40
       inkscape:isstock="true">
41
      <path
42
         id="path10931"
43
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
44
         style="fill:#126d95;fill-opacity:1;fill-rule:evenodd;stroke:#126d95;stroke-width:1.00000003pt;stroke-opacity:1"
45
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
46
         inkscape:connector-curvature="0" />
47
    </marker>
48
    <marker
49
       inkscape:stockid="Arrow1Mend"
50
       orient="auto"
51
       refY="0"
52
       refX="0"
53
       id="marker9893"
54
       style="overflow:visible"
55
       inkscape:isstock="true">
56
      <path
57
         id="path9891"
58
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
59
         style="fill:#126d95;fill-opacity:1;fill-rule:evenodd;stroke:#126d95;stroke-width:1.00000003pt;stroke-opacity:1"
60
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
61
         inkscape:connector-curvature="0" />
62
    </marker>
63
    <marker
64
       inkscape:collect="always"
65
       inkscape:isstock="true"
66
       style="overflow:visible"
67
       id="marker9767"
68
       refX="0"
69
       refY="0"
70
       orient="auto"
71
       inkscape:stockid="Arrow1Mend">
72
      <path
73
         inkscape:connector-curvature="0"
74
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
75
         style="fill:#126d95;fill-opacity:1;fill-rule:evenodd;stroke:#126d95;stroke-width:1.00000003pt;stroke-opacity:1"
76
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
77
         id="path9765" />
78
    </marker>
79
    <marker
80
       inkscape:collect="always"
81
       inkscape:stockid="Arrow1Mend"
82
       orient="auto"
83
       refY="0"
84
       refX="0"
85
       id="marker9761"
86
       style="overflow:visible"
87
       inkscape:isstock="true">
88
      <path
89
         id="path9759"
90
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
91
         style="fill:#126d95;fill-opacity:1;fill-rule:evenodd;stroke:#126d95;stroke-width:1.00000003pt;stroke-opacity:1"
92
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
93
         inkscape:connector-curvature="0" />
94
    </marker>
95
    <marker
96
       inkscape:isstock="true"
97
       style="overflow:visible"
98
       id="marker9750"
99
       refX="0"
100
       refY="0"
101
       orient="auto"
102
       inkscape:stockid="Arrow1Mend">
103
      <path
104
         inkscape:connector-curvature="0"
105
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
106
         style="fill:#126d95;fill-opacity:1;fill-rule:evenodd;stroke:#126d95;stroke-width:1.00000003pt;stroke-opacity:1"
107
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
108
         id="path9748" />
109
    </marker>
110
    <marker
111
       inkscape:isstock="true"
112
       style="overflow:visible"
113
       id="marker9715"
114
       refX="0"
115
       refY="0"
116
       orient="auto"
117
       inkscape:stockid="Arrow1Mend">
118
      <path
119
         inkscape:connector-curvature="0"
120
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
121
         style="fill:#126d95;fill-opacity:1;fill-rule:evenodd;stroke:#126d95;stroke-width:1.00000003pt;stroke-opacity:1"
122
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
123
         id="path9713" />
124
    </marker>
125
    <marker
126
       inkscape:collect="always"
127
       inkscape:stockid="Arrow1Mend"
128
       orient="auto"
129
       refY="0"
130
       refX="0"
131
       id="marker9685"
132
       style="overflow:visible"
133
       inkscape:isstock="true">
134
      <path
135
         id="path9683"
136
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
137
         style="fill:#126d95;fill-opacity:1;fill-rule:evenodd;stroke:#126d95;stroke-width:1.00000003pt;stroke-opacity:1"
138
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
139
         inkscape:connector-curvature="0" />
140
    </marker>
141
    <marker
142
       inkscape:collect="always"
143
       inkscape:stockid="Arrow1Mend"
144
       orient="auto"
145
       refY="0"
146
       refX="0"
147
       id="marker9679"
148
       style="overflow:visible"
149
       inkscape:isstock="true">
150
      <path
151
         id="path9677"
152
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
153
         style="fill:#126d95;fill-opacity:1;fill-rule:evenodd;stroke:#126d95;stroke-width:1.00000003pt;stroke-opacity:1"
154
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
155
         inkscape:connector-curvature="0" />
156
    </marker>
157
    <marker
158
       inkscape:collect="always"
159
       inkscape:isstock="true"
160
       style="overflow:visible"
161
       id="marker9640"
162
       refX="0"
163
       refY="0"
164
       orient="auto"
165
       inkscape:stockid="Arrow1Mend">
166
      <path
167
         inkscape:connector-curvature="0"
168
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
169
         style="fill:#126d95;fill-opacity:1;fill-rule:evenodd;stroke:#126d95;stroke-width:1.00000003pt;stroke-opacity:1"
170
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
171
         id="path9638" />
172
    </marker>
173
    <marker
174
       inkscape:collect="always"
175
       inkscape:isstock="true"
176
       style="overflow:visible"
177
       id="marker9513"
178
       refX="0"
179
       refY="0"
180
       orient="auto"
181
       inkscape:stockid="Arrow1Mend">
182
      <path
183
         inkscape:connector-curvature="0"
184
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
185
         style="fill:#126d95;fill-opacity:1;fill-rule:evenodd;stroke:#126d95;stroke-width:1.00000003pt;stroke-opacity:1"
186
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
187
         id="path9511" />
188
    </marker>
189
    <marker
190
       inkscape:stockid="Arrow1Mend"
191
       orient="auto"
192
       refY="0"
193
       refX="0"
194
       id="marker9509"
195
       style="overflow:visible"
196
       inkscape:isstock="true">
197
      <path
198
         id="path9507"
199
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
200
         style="fill:#126d95;fill-opacity:1;fill-rule:evenodd;stroke:#126d95;stroke-width:1.00000003pt;stroke-opacity:1"
201
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
202
         inkscape:connector-curvature="0" />
203
    </marker>
204
    <marker
205
       inkscape:isstock="true"
206
       style="overflow:visible"
207
       id="marker9505"
208
       refX="0"
209
       refY="0"
210
       orient="auto"
211
       inkscape:stockid="Arrow1Mend">
212
      <path
213
         inkscape:connector-curvature="0"
214
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
215
         style="fill:#126d95;fill-opacity:1;fill-rule:evenodd;stroke:#126d95;stroke-width:1.00000003pt;stroke-opacity:1"
216
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
217
         id="path9503" />
218
    </marker>
219
    <marker
220
       inkscape:collect="always"
221
       inkscape:stockid="Arrow1Mend"
222
       orient="auto"
223
       refY="0"
224
       refX="0"
225
       id="marker9479"
226
       style="overflow:visible"
227
       inkscape:isstock="true">
228
      <path
229
         id="path9477"
230
         d="M 0,0 5,-5 -12.5,0 5,5 Z"
231
         style="fill:#126d95;fill-opacity:1;fill-rule:evenodd;stroke:#126d95;stroke-width:1.00000003pt;stroke-opacity:1"
232
         transform="matrix(-0.4,0,0,-0.4,-4,0)"
233
         inkscape:connector-curvature="0" />
234
    </marker>
235
    <clipPath
236
       id="ID000001">
237
      <rect
238
         id="rect6"
239
         height="961.125"
240
         width="1381.6169"
241
         y="-43.688"
242
         x="-62.683998" />
243
    </clipPath>
244
    <filter
245
       id="filter2842"
246
       inkscape:label="Drop Shadow"
247
       style="color-interpolation-filters:sRGB;"
248
       x="-0.028981832"
249
       y="-0.14609649"
250
       width="1.0760773"
251
       height="1.3835033">
252
      <feFlood
253
         id="feFlood2832"
254
         result="flood"
255
         flood-color="rgb(0,0,0)"
256
         flood-opacity="0.498039" />
257
      <feComposite
258
         id="feComposite2834"
259
         result="composite1"
260
         operator="in"
261
         in2="SourceGraphic"
262
         in="flood" />
263
      <feGaussianBlur
264
         id="feGaussianBlur2836"
265
         result="blur"
266
         stdDeviation="2"
267
         in="composite1" />
268
      <feOffset
269
         id="feOffset2838"
270
         result="offset"
271
         dy="3"
272
         dx="3" />
273
      <feComposite
274
         id="feComposite2840"
275
         result="composite2"
276
         operator="over"
277
         in2="offset"
278
         in="SourceGraphic" />
279
    </filter>
280
    <filter
281
       id="filter2854"
282
       inkscape:label="Drop Shadow"
283
       style="color-interpolation-filters:sRGB;"
284
       x="-0.028981832"
285
       y="-0.14609649"
286
       width="1.0760773"
287
       height="1.3835033">
288
      <feFlood
289
         id="feFlood2844"
290
         result="flood"
291
         flood-color="rgb(0,0,0)"
292
         flood-opacity="0.498039" />
293
      <feComposite
294
         id="feComposite2846"
295
         result="composite1"
296
         operator="in"
297
         in2="SourceGraphic"
298
         in="flood" />
299
      <feGaussianBlur
300
         id="feGaussianBlur2848"
301
         result="blur"
302
         stdDeviation="2"
303
         in="composite1" />
304
      <feOffset
305
         id="feOffset2850"
306
         result="offset"
307
         dy="3"
308
         dx="3" />
309
      <feComposite
310
         id="feComposite2852"
311
         result="composite2"
312
         operator="over"
313
         in2="offset"
314
         in="SourceGraphic" />
315
    </filter>
316
    <filter
317
       id="filter2866"
318
       inkscape:label="Drop Shadow"
319
       style="color-interpolation-filters:sRGB;"
320
       x="-0.028981832"
321
       y="-0.14609649"
322
       width="1.0760773"
323
       height="1.3835033">
324
      <feFlood
325
         id="feFlood2856"
326
         result="flood"
327
         flood-color="rgb(0,0,0)"
328
         flood-opacity="0.498039" />
329
      <feComposite
330
         id="feComposite2858"
331
         result="composite1"
332
         operator="in"
333
         in2="SourceGraphic"
334
         in="flood" />
335
      <feGaussianBlur
336
         id="feGaussianBlur2860"
337
         result="blur"
338
         stdDeviation="2"
339
         in="composite1" />
340
      <feOffset
341
         id="feOffset2862"
342
         result="offset"
343
         dy="3"
344
         dx="3" />
345
      <feComposite
346
         id="feComposite2864"
347
         result="composite2"
348
         operator="over"
349
         in2="offset"
350
         in="SourceGraphic" />
351
    </filter>
352
    <filter
353
       id="filter2878"
354
       inkscape:label="Drop Shadow"
355
       style="color-interpolation-filters:sRGB;"
356
       x="-0.028981832"
357
       y="-0.14609649"
358
       width="1.0760773"
359
       height="1.3835033">
360
      <feFlood
361
         id="feFlood2868"
362
         result="flood"
363
         flood-color="rgb(0,0,0)"
364
         flood-opacity="0.498039" />
365
      <feComposite
366
         id="feComposite2870"
367
         result="composite1"
368
         operator="in"
369
         in2="SourceGraphic"
370
         in="flood" />
371
      <feGaussianBlur
372
         id="feGaussianBlur2872"
373
         result="blur"
374
         stdDeviation="2"
375
         in="composite1" />
376
      <feOffset
377
         id="feOffset2874"
378
         result="offset"
379
         dy="3"
380
         dx="3" />
381
      <feComposite
382
         id="feComposite2876"
383
         result="composite2"
384
         operator="over"
385
         in2="offset"
386
         in="SourceGraphic" />
387
    </filter>
388
    <filter
389
       id="filter2890"
390
       inkscape:label="Drop Shadow"
391
       style="color-interpolation-filters:sRGB;"
392
       x="-0.028981832"
393
       y="-0.14609649"
394
       width="1.0760773"
395
       height="1.3835033">
396
      <feFlood
397
         id="feFlood2880"
398
         result="flood"
399
         flood-color="rgb(0,0,0)"
400
         flood-opacity="0.498039" />
401
      <feComposite
402
         id="feComposite2882"
403
         result="composite1"
404
         operator="in"
405
         in2="SourceGraphic"
406
         in="flood" />
407
      <feGaussianBlur
408
         id="feGaussianBlur2884"
409
         result="blur"
410
         stdDeviation="2"
411
         in="composite1" />
412
      <feOffset
413
         id="feOffset2886"
414
         result="offset"
415
         dy="3"
416
         dx="3" />
417
      <feComposite
418
         id="feComposite2888"
419
         result="composite2"
420
         operator="over"
421
         in2="offset"
422
         in="SourceGraphic" />
423
    </filter>
424
    <filter
425
       id="filter2902"
426
       inkscape:label="Drop Shadow"
427
       style="color-interpolation-filters:sRGB;"
428
       x="-0.028981832"
429
       y="-0.14609649"
430
       width="1.0760773"
431
       height="1.3835033">
432
      <feFlood
433
         id="feFlood2892"
434
         result="flood"
435
         flood-color="rgb(0,0,0)"
436
         flood-opacity="0.498039" />
437
      <feComposite
438
         id="feComposite2894"
439
         result="composite1"
440
         operator="in"
441
         in2="SourceGraphic"
442
         in="flood" />
443
      <feGaussianBlur
444
         id="feGaussianBlur2896"
445
         result="blur"
446
         stdDeviation="2"
447
         in="composite1" />
448
      <feOffset
449
         id="feOffset2898"
450
         result="offset"
451
         dy="3"
452
         dx="3" />
453
      <feComposite
454
         id="feComposite2900"
455
         result="composite2"
456
         operator="over"
457
         in2="offset"
458
         in="SourceGraphic" />
459
    </filter>
460
    <filter
461
       id="filter2914"
462
       inkscape:label="Drop Shadow"
463
       style="color-interpolation-filters:sRGB;"
464
       x="-0.028981832"
465
       y="-0.14609649"
466
       width="1.0760773"
467
       height="1.3835033">
468
      <feFlood
469
         id="feFlood2904"
470
         result="flood"
471
         flood-color="rgb(0,0,0)"
472
         flood-opacity="0.498039" />
473
      <feComposite
474
         id="feComposite2906"
475
         result="composite1"
476
         operator="in"
477
         in2="SourceGraphic"
478
         in="flood" />
479
      <feGaussianBlur
480
         id="feGaussianBlur2908"
481
         result="blur"
482
         stdDeviation="2"
483
         in="composite1" />
484
      <feOffset
485
         id="feOffset2910"
486
         result="offset"
487
         dy="3"
488
         dx="3" />
489
      <feComposite
490
         id="feComposite2912"
491
         result="composite2"
492
         operator="over"
493
         in2="offset"
494
         in="SourceGraphic" />
495
    </filter>
496
    <filter
497
       id="filter2926"
498
       inkscape:label="Drop Shadow"
499
       style="color-interpolation-filters:sRGB;"
500
       x="-0.028981815"
501
       y="-0.14609439"
502
       width="1.0760773"
503
       height="1.3834978">
504
      <feFlood
505
         id="feFlood2916"
506
         result="flood"
507
         flood-color="rgb(0,0,0)"
508
         flood-opacity="0.498039" />
509
      <feComposite
510
         id="feComposite2918"
511
         result="composite1"
512
         operator="in"
513
         in2="SourceGraphic"
514
         in="flood" />
515
      <feGaussianBlur
516
         id="feGaussianBlur2920"
517
         result="blur"
518
         stdDeviation="2"
519
         in="composite1" />
520
      <feOffset
521
         id="feOffset2922"
522
         result="offset"
523
         dy="3"
524
         dx="3" />
525
      <feComposite
526
         id="feComposite2924"
527
         result="composite2"
528
         operator="over"
529
         in2="offset"
530
         in="SourceGraphic" />
531
    </filter>
532
    <filter
533
       id="filter2938"
534
       inkscape:label="Drop Shadow"
535
       style="color-interpolation-filters:sRGB;"
536
       x="-0.028981813"
537
       y="-0.14609439"
538
       width="1.0760773"
539
       height="1.3834978">
540
      <feFlood
541
         id="feFlood2928"
542
         result="flood"
543
         flood-color="rgb(0,0,0)"
544
         flood-opacity="0.498039" />
545
      <feComposite
546
         id="feComposite2930"
547
         result="composite1"
548
         operator="in"
549
         in2="SourceGraphic"
550
         in="flood" />
551
      <feGaussianBlur
552
         id="feGaussianBlur2932"
553
         result="blur"
554
         stdDeviation="2"
555
         in="composite1" />
556
      <feOffset
557
         id="feOffset2934"
558
         result="offset"
559
         dy="3"
560
         dx="3" />
561
      <feComposite
562
         id="feComposite2936"
563
         result="composite2"
564
         operator="over"
565
         in2="offset"
566
         in="SourceGraphic" />
567
    </filter>
568
    <filter
569
       id="filter2950"
570
       inkscape:label="Drop Shadow"
571
       style="color-interpolation-filters:sRGB;"
572
       x="-0.029641207"
573
       y="-0.14941832"
574
       width="1.077396"
575
       height="1.3901456">
576
      <feFlood
577
         id="feFlood2940"
578
         result="flood"
579
         flood-color="rgb(0,0,0)"
580
         flood-opacity="0.498039" />
581
      <feComposite
582
         id="feComposite2942"
583
         result="composite1"
584
         operator="in"
585
         in2="SourceGraphic"
586
         in="flood" />
587
      <feGaussianBlur
588
         id="feGaussianBlur2944"
589
         result="blur"
590
         stdDeviation="2"
591
         in="composite1" />
592
      <feOffset
593
         id="feOffset2946"
594
         result="offset"
595
         dy="3"
596
         dx="3" />
597
      <feComposite
598
         id="feComposite2948"
599
         result="composite2"
600
         operator="over"
601
         in2="offset"
602
         in="SourceGraphic" />
603
    </filter>
604
    <filter
605
       id="filter2962"
606
       inkscape:label="Drop Shadow"
607
       style="color-interpolation-filters:sRGB;"
608
       x="-0.028981815"
609
       y="-0.14609439"
610
       width="1.0760773"
611
       height="1.3834978">
612
      <feFlood
613
         id="feFlood2952"
614
         result="flood"
615
         flood-color="rgb(0,0,0)"
616
         flood-opacity="0.498039" />
617
      <feComposite
618
         id="feComposite2954"
619
         result="composite1"
620
         operator="in"
621
         in2="SourceGraphic"
622
         in="flood" />
623
      <feGaussianBlur
624
         id="feGaussianBlur2956"
625
         result="blur"
626
         stdDeviation="2"
627
         in="composite1" />
628
      <feOffset
629
         id="feOffset2958"
630
         result="offset"
631
         dy="3"
632
         dx="3" />
633
      <feComposite
634
         id="feComposite2960"
635
         result="composite2"
636
         operator="over"
637
         in2="offset"
638
         in="SourceGraphic" />
639
    </filter>
640
    <filter
641
       id="filter2974"
642
       inkscape:label="Drop Shadow"
643
       style="color-interpolation-filters:sRGB;"
644
       x="-0.028981813"
645
       y="-0.14609439"
646
       width="1.0760773"
647
       height="1.3834978">
648
      <feFlood
649
         id="feFlood2964"
650
         result="flood"
651
         flood-color="rgb(0,0,0)"
652
         flood-opacity="0.498039" />
653
      <feComposite
654
         id="feComposite2966"
655
         result="composite1"
656
         operator="in"
657
         in2="SourceGraphic"
658
         in="flood" />
659
      <feGaussianBlur
660
         id="feGaussianBlur2968"
661
         result="blur"
662
         stdDeviation="2"
663
         in="composite1" />
664
      <feOffset
665
         id="feOffset2970"
666
         result="offset"
667
         dy="3"
668
         dx="3" />
669
      <feComposite
670
         id="feComposite2972"
671
         result="composite2"
672
         operator="over"
673
         in2="offset"
674
         in="SourceGraphic" />
675
    </filter>
676
    <filter
677
       id="filter2986"
678
       inkscape:label="Drop Shadow"
679
       style="color-interpolation-filters:sRGB;"
680
       x="-0.028981816"
681
       y="-0.14609439"
682
       width="1.0760773"
683
       height="1.3834978">
684
      <feFlood
685
         id="feFlood2976"
686
         result="flood"
687
         flood-color="rgb(0,0,0)"
688
         flood-opacity="0.498039" />
689
      <feComposite
690
         id="feComposite2978"
691
         result="composite1"
692
         operator="in"
693
         in2="SourceGraphic"
694
         in="flood" />
695
      <feGaussianBlur
696
         id="feGaussianBlur2980"
697
         result="blur"
698
         stdDeviation="2"
699
         in="composite1" />
700
      <feOffset
701
         id="feOffset2982"
702
         result="offset"
703
         dy="3"
704
         dx="3" />
705
      <feComposite
706
         id="feComposite2984"
707
         result="composite2"
708
         operator="over"
709
         in2="offset"
710
         in="SourceGraphic" />
711
    </filter>
712
  </defs>
713
  <sodipodi:namedview
714
     inkscape:snap-text-baseline="false"
715
     inkscape:document-rotation="0"
716
     fit-margin-bottom="20"
717
     fit-margin-right="20"
718
     fit-margin-left="20"
719
     fit-margin-top="20"
720
     inkscape:current-layer="svg4610"
721
     inkscape:cy="219.59625"
722
     inkscape:cx="397.67357"
723
     inkscape:zoom="1.5414653"
724
     showgrid="false"
725
     id="namedview4612"
726
     inkscape:window-height="1280"
727
     inkscape:window-width="2055"
728
     inkscape:pageshadow="2"
729
     inkscape:pageopacity="1"
730
     guidetolerance="10"
731
     gridtolerance="10"
732
     objecttolerance="10"
733
     borderopacity="1"
734
     bordercolor="#666666"
735
     pagecolor="#ffffff"
736
     inkscape:window-x="849"
737
     inkscape:window-y="620"
738
     inkscape:window-maximized="0"
739
     inkscape:showpageshadow="2"
740
     inkscape:pagecheckerboard="0"
741
     inkscape:deskcolor="#d1d1d1" />
742
  <path
743
     sodipodi:nodetypes="ccssssc"
744
     inkscape:connector-curvature="0"
745
     style="fill:#333333;fill-opacity:0.0666667;fill-rule:nonzero;stroke:#df4d65;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
746
     d="M 53.35547,445.11522 V 790.96744 H 741.0332 c 1.6112,0 2.90821,-1.29701 2.90821,-2.9082 V 448.02342 c 0,-1.6112 -1.297,-2.9082 -2.90821,-2.9082 z"
747
     id="path9961" />
748
  <path
749
     sodipodi:nodetypes="sssccssss"
750
     id="path9940"
751
     d="m 20.5,787.82486 c 0,0.87013 0.35019,1.65683 0.91797,2.22461 0.56778,0.56778 1.35253,0.91797 2.22265,0.91797 H 53.35547 V 445.11522 H 23.64062 c -0.87012,0 -1.65487,0.35019 -2.22265,0.91797 -0.56778,0.56778 -0.91797,1.35254 -0.91797,2.22266 z"
752
     style="fill:#ec706a;fill-opacity:1;fill-rule:nonzero;stroke:#ec706a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
753
     inkscape:connector-curvature="0" />
754
  <path
755
     sodipodi:nodetypes="sssccssss"
756
     id="path11125"
757
     d="m 20.5,423.31014 c 0,0.87013 0.35019,1.65683 0.91797,2.22461 0.56778,0.56778 1.354494,0.9764 2.22265,0.91797 H 53.35547 V 210.6005 H 23.64062 c -0.87012,0 -1.65487,0.3502 -2.22265,0.918 C 20.85019,212.08629 20.5,212.871 20.5,213.74109 Z"
758
     style="fill:#3e3e3e;fill-opacity:1;fill-rule:nonzero;stroke:#3e3e3e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
759
     inkscape:connector-curvature="0" />
760
  <path
761
     sodipodi:nodetypes="ccssssc"
762
     inkscape:connector-curvature="0"
763
     style="fill:#333333;fill-opacity:0.0666667;fill-rule:nonzero;stroke:#3e3e3e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
764
     d="m 53.35547,210.6005 v 215.85222 h 687.67774 c 1.6112,0 2.9082,-1.29701 2.9082,-2.9082 V 213.5087 c 0,-1.6112 -1.29701,-2.90352 -2.9082,-2.9082 z"
765
     id="path11123" />
766
  <path
767
     id="path6150"
768
     d="m 557.756,222.53493 c -0.87012,0 -1.65683,0.35019 -2.22461,0.91797 -0.56778,0.56778 -0.91797,1.35253 -0.91797,2.22265 v 29.71485 h 165.6211 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91797,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z"
769
     style="fill:#ad51cf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2926)"
770
     inkscape:connector-curvature="0"
771
     sodipodi:nodetypes="sssccssss" />
772
  <path
773
     sodipodi:nodetypes="ccssssc"
774
     id="path6134"
775
     d="m 720.75716,255.39041 h -165.6211 v 152.63392 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 h 159.80469 c 1.6112,0 2.9082,-1.29701 2.9082,-2.90821 z"
776
     style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2926)"
777
     inkscape:connector-curvature="0" />
778
  <path
779
     id="path6082"
780
     d="m 317.13559,222.53494 c -0.87011,0 -1.65683,0.35019 -2.2246,0.91797 -0.56779,0.56778 -0.91798,1.35253 -0.91798,2.22265 v 29.71485 h 165.62111 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91798,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z"
781
     style="fill:#1bd46f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2938)"
782
     inkscape:connector-curvature="0"
783
     sodipodi:nodetypes="sssccssss" />
784
  <path
785
     sodipodi:nodetypes="ccssssc"
786
     id="path6080"
787
     d="M 479.61412,255.39041 H 313.99301 v 152.63392 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 h 159.80469 c 1.6112,0 2.90821,-1.29701 2.90821,-2.90821 z"
788
     style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2938)"
789
     inkscape:connector-curvature="0" />
790
  <path
791
     id="path10980"
792
     d="M 53.35547,20.500012 V 188.35224 h 687.67774 c 1.6112,0 2.9082,-1.29701 2.9082,-2.9082 V 23.408212 c 0,-1.6112 -1.29701,-2.912886 -2.9082,-2.9082 z"
793
     style="fill:#333333;fill-opacity:0.0666667;fill-rule:nonzero;stroke:#3e3e3e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
794
     inkscape:connector-curvature="0"
795
     sodipodi:nodetypes="ccssssc" />
796
  <path
797
     inkscape:connector-curvature="0"
798
     style="fill:#3e3e3e;fill-opacity:1;fill-rule:nonzero;stroke:#3e3e3e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
799
     d="m 20.5,185.20966 c 0,0.87013 0.35019,1.65683 0.91797,2.22461 0.56778,0.56778 1.35253,0.91797 2.22265,0.91797 H 53.35547 V 20.500012 H 23.64062 c -0.87012,0 -1.65487,0.350201 -2.22265,0.918 -0.56778,0.5678 -0.91797,1.3525 -0.91797,2.2226 z"
800
     id="path10982"
801
     sodipodi:nodetypes="sssccssss" />
802
  <path
803
     sodipodi:nodetypes="sssccssss"
804
     inkscape:connector-curvature="0"
805
     style="fill:#ad51cf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2962)"
806
     d="m 557.75599,36.704447 c -0.87012,0 -1.65683,0.35019 -2.22461,0.91797 -0.56778,0.56778 -0.91797,1.35253 -0.91797,2.22265 v 29.71485 h 165.6211 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91797,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z"
807
     id="path4857" />
808
  <path
809
     inkscape:connector-curvature="0"
810
     style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2962)"
811
     d="M 720.23451,69.559917 H 554.61341 V 169.2396 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 h 159.80469 c 1.6112,0 2.9082,-1.29701 2.9082,-2.90821 z"
812
     id="path4853" />
813
  <path
814
     sodipodi:nodetypes="sssccssss"
815
     inkscape:connector-curvature="0"
816
     style="fill:#1bd46f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2974)"
817
     d="m 317.13558,36.704447 c -0.87011,0 -1.65683,0.35019 -2.2246,0.91797 -0.56779,0.56778 -0.91798,1.35253 -0.91798,2.22265 v 29.71485 h 165.62111 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91798,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z"
818
     id="path5726" />
819
  <path
820
     inkscape:connector-curvature="0"
821
     style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2974)"
822
     d="M 479.61411,69.559917 H 313.993 V 169.2396 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 H 476.7059 c 1.6112,0 2.90821,-1.29701 2.90821,-2.90821 z"
823
     id="path5724" />
824
  <path
825
     id="path4721"
826
     d="m 235.85308,44.704447 c 0.87012,0 1.65488,0.35019 2.22266,0.91797 0.56778,0.56778 0.91797,1.35253 0.91797,2.22265 v -0.23242 c 0,-1.6112 -1.297,-2.9082 -2.9082,-2.9082 z"
827
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
828
     inkscape:connector-curvature="0" />
829
  <path
830
     sodipodi:nodetypes="sssccssss"
831
     id="path4719"
832
     d="m 76.515197,36.704447 c -0.870125,0 -1.656831,0.35019 -2.22461,0.91797 -0.567778,0.56778 -0.917968,1.35253 -0.917968,2.22265 v 29.71485 H 238.99371 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91797,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z"
833
     style="fill:#51a9cf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2986)"
834
     inkscape:connector-curvature="0" />
835
  <path
836
     id="path4723"
837
     d="M 238.99372,69.559917 H 73.372613 V 169.2396 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 H 236.08552 c 1.6112,0 2.9082,-1.29701 2.9082,-2.90821 z"
838
     style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2986)"
839
     inkscape:connector-curvature="0" />
840
  <path
841
     id="rect4622"
842
     d="m 76.280822,44.704447 c -1.611195,0 -2.908203,1.297 -2.908203,2.9082 v 0.23242 c 0,-0.87012 0.35019,-1.65487 0.917968,-2.22265 0.567779,-0.56778 1.354485,-0.91797 2.22461,-0.91797 z"
843
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
844
     inkscape:connector-curvature="0" />
845
  <path
846
     sodipodi:nodetypes="cc"
847
     inkscape:connector-curvature="0"
848
     id="path9889"
849
     d="m 397.61301,500.62068 -0.50618,32.59418"
850
     style="opacity:1;vector-effect:none;fill:#126d95;fill-opacity:1;stroke:#126d95;stroke-width:1.9694221;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9893)" />
851
  <path
852
     style="opacity:1;vector-effect:none;fill:#126d95;fill-opacity:1;stroke:#126d95;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9715)"
853
     d="m 554.61351,648.83688 -69.6817,47.69253"
854
     id="path9711"
855
     inkscape:connector-curvature="0"
856
     sodipodi:nodetypes="cc" />
857
  <path
858
     sodipodi:nodetypes="cc"
859
     inkscape:connector-curvature="0"
860
     id="path9675"
861
     d="M 554.61351,567.95047 484.93181,615.643"
862
     style="opacity:1;vector-effect:none;fill:#126d95;fill-opacity:1;stroke:#126d95;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9679)" />
863
  <rect
864
     ry="3.9839513"
865
     rx="3.9205718"
866
     y="537.09552"
867
     x="554.61353"
868
     height="32.855"
869
     width="165.621"
870
     id="rect9618"
871
     style="opacity:1;fill:#ad51cf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2842)" />
872
  <rect
873
     ry="3.9839513"
874
     rx="3.9205718"
875
     y="537.09552"
876
     x="73.372665"
877
     height="32.855"
878
     width="165.621"
879
     id="rect9614"
880
     style="opacity:1;fill:#51a9cf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2914)" />
881
  <path
882
     inkscape:connector-curvature="0"
883
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
884
     d="m 235.85308,545.09525 c 0.87012,0 1.65488,0.35019 2.22266,0.91797 0.56778,0.56778 0.91797,1.35253 0.91797,2.22265 v -0.23242 c 0,-1.6112 -1.297,-2.9082 -2.9082,-2.9082 z"
885
     id="path9323" />
886
  <path
887
     inkscape:connector-curvature="0"
888
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
889
     d="m 76.280823,545.09525 c -1.611195,0 -2.908203,1.297 -2.908203,2.9082 v 0.23242 c 0,-0.87012 0.35019,-1.65487 0.917968,-2.22265 0.567779,-0.56778 1.354485,-0.91797 2.22461,-0.91797 z"
890
     id="path9327" />
891
  <rect
892
     style="opacity:1;fill:#1bd46f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2902)"
893
     id="rect9616"
894
     width="165.621"
895
     height="32.855"
896
     x="313.99307"
897
     y="537.09552"
898
     rx="3.9205718"
899
     ry="3.9839513" />
900
  <path
901
     sodipodi:nodetypes="cc"
902
     inkscape:connector-curvature="0"
903
     id="path9491"
904
     d="m 240.99257,554.11276 65.23376,-1.01307"
905
     style="opacity:1;vector-effect:none;fill:#126d95;fill-opacity:1;stroke:#126d95;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9513)" />
906
  <path
907
     style="opacity:1;vector-effect:none;fill:#126d95;fill-opacity:1;stroke:#126d95;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9640)"
908
     d="m 481.61298,554.11276 65.23376,-1.01307"
909
     id="path9501"
910
     inkscape:connector-curvature="0"
911
     sodipodi:nodetypes="cc" />
912
  <rect
913
     ry="3.9839513"
914
     rx="3.9205718"
915
     y="617.79578"
916
     x="313.99307"
917
     height="32.855"
918
     width="165.621"
919
     id="rect9620"
920
     style="opacity:1;fill:#1bd46f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2890)" />
921
  <path
922
     sodipodi:nodetypes="cc"
923
     inkscape:connector-curvature="0"
924
     id="path9681"
925
     d="m 481.61298,634.81299 65.23376,-1.01307"
926
     style="opacity:1;vector-effect:none;fill:#126d95;fill-opacity:1;stroke:#126d95;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9685)" />
927
  <rect
928
     style="opacity:1;fill:#ad51cf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2854)"
929
     id="rect9687"
930
     width="165.621"
931
     height="32.855"
932
     x="554.61353"
933
     y="617.79578"
934
     rx="3.9205718"
935
     ry="3.9839513" />
936
  <path
937
     style="opacity:1;vector-effect:none;fill:#126d95;fill-opacity:1;stroke:#126d95;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9750)"
938
     d="m 481.61298,715.51321 65.23376,-1.01307"
939
     id="path9734"
940
     inkscape:connector-curvature="0"
941
     sodipodi:nodetypes="cc" />
942
  <rect
943
     ry="3.9839513"
944
     rx="3.9205718"
945
     y="698.49591"
946
     x="554.61353"
947
     height="32.855"
948
     width="165.621"
949
     id="rect9736"
950
     style="opacity:1;fill:#ad51cf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2866)" />
951
  <path
952
     id="path9830"
953
     d="m 356.40451,489.45323 c -0.80426,0 -1.45167,0.64741 -1.45167,1.45166 v 0.11602 c 0,-0.43433 0.1748,-0.82605 0.45822,-1.10946 0.28341,-0.28342 0.6761,-0.45822 1.11043,-0.45822 z"
954
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.10902636;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
955
     inkscape:connector-curvature="0" />
956
  <rect
957
     style="opacity:1;fill:#ecd980;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9391377;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
958
     id="rect9826"
959
     width="120.98324"
960
     height="24"
961
     x="336.82672"
962
     y="477.86002"
963
     rx="2.8639088"
964
     ry="2.9102066" />
965
  <path
966
     id="path10514"
967
     d="m 235.85301,637.23875 c 0.87012,0 1.65488,0.35019 2.22266,0.91797 0.56778,0.56778 0.91797,1.35253 0.91797,2.22265 v -0.23242 c 0,-1.6112 -1.297,-2.9082 -2.9082,-2.9082 z"
968
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
969
     inkscape:connector-curvature="0" />
970
  <rect
971
     style="opacity:1;fill:#1bd46f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2878)"
972
     id="rect9717"
973
     width="165.621"
974
     height="32.855"
975
     x="313.99307"
976
     y="698.49591"
977
     rx="3.9205718"
978
     ry="3.9839513" />
979
  <path
980
     id="path10537"
981
     d="M 238.99366,636.97465 H 73.372671 V 729.175 c 0,1.2055 0.970418,2.17592 2.175911,2.17592 H 236.81776 c 1.20549,0 2.1759,-0.97042 2.1759,-2.17592 z"
982
     style="opacity:1;fill:#333333;fill-opacity:0.93333333;fill-rule:nonzero;stroke:none;stroke-width:0.16342013;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
983
     inkscape:connector-curvature="0"
984
     sodipodi:nodetypes="ccssssc" />
985
  <path
986
     sodipodi:nodetypes="sssccssss"
987
     id="path10516"
988
     d="m 75.723937,612.39226 c -0.651025,0 -1.239637,0.26201 -1.664447,0.68682 -0.424811,0.42482 -0.686822,1.01196 -0.686822,1.66299 v 22.23258 H 238.99366 v -22.23258 c 0,-0.65103 -0.26201,-1.23817 -0.68682,-1.66299 -0.42481,-0.42481 -1.01197,-0.68682 -1.66299,-0.68682 z"
989
     style="opacity:1;fill:#ecd980;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.16342013;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
990
     inkscape:connector-curvature="0" />
991
  <path
992
     style="opacity:1;vector-effect:none;fill:#126d95;fill-opacity:1;stroke:#126d95;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker10933)"
993
     d="m 240.99257,715.51318 65.23376,-1.01307"
994
     id="path10929"
995
     inkscape:connector-curvature="0"
996
     sodipodi:nodetypes="cc" />
997
  <path
998
     style="fill:#ec706a;fill-opacity:1;fill-rule:evenodd;stroke-width:0.05250736"
999
     d="m 399.47357,99.155037 -0.12716,0.0127 -0.12716,0.0141 -0.12574,0.0141 -0.12716,0.0155 -0.61883,0.967813 -0.29106,0.9325 -0.17943,0.91977 -0.1215,1.09073 -0.30943,0.0636 -0.308,0.0678 -0.308,0.0735 -0.30801,0.0763 -0.58069,-0.93108 -0.5609,-0.75023 -0.66687,-0.71349 -0.97912,-0.6033 -0.12009,0.0409 -0.1201,0.0424 -0.12009,0.0424 -0.12009,0.0424 -0.38854,1.08085 -0.0763,0.97487 0.0297,0.93673 0.12575,1.08932 -0.28823,0.1314 -0.28681,0.13563 -0.28398,0.13987 -0.28117,0.14271 -0.77425,-0.77849 -0.7149,-0.60612 -0.80816,-0.54819 -1.0879,-0.37017 -0.10879,0.0678 -0.10738,0.0679 -0.10738,0.0678 -0.10738,0.0678 -0.13846,1.14018 0.14129,0.9664 0.23735,0.90706 0.36594,1.03563 -0.25149,0.19215 -0.24865,0.19497 -0.24585,0.19922 -0.24442,0.20204 -0.92825,-0.58634 -0.83077,-0.43234 -0.90988,-0.35463 -1.14301,-0.11868 -0.0904,0.0904 -0.0904,0.089 -0.089,0.0904 -0.0904,0.0904 0.11868,1.14301 0.35462,0.90988 0.43234,0.83218 0.58634,0.92684 -0.20204,0.24442 -0.19921,0.24584 -0.19498,0.24867 -0.19215,0.25148 -1.03563,-0.36593 -0.90705,-0.23736 -0.96641,-0.14128 -1.14018,0.13845 -0.0678,0.10738 -0.0678,0.10738 -0.0678,0.10738 -0.0678,0.10879 0.37016,1.0879 0.5482,0.80816 0.60612,0.71491 0.77848,0.77425 -0.1427,0.28117 -0.13987,0.28398 -0.13564,0.28681 -0.13139,0.28823 -1.09073,-0.12575 -0.93532,-0.0297 -0.97487,0.0763 -1.08084,0.38854 -0.0424,0.12009 -0.0424,0.12009 -0.0424,0.1201 -0.0409,0.12009 0.6033,0.97912 0.7135,0.66686 0.75023,0.56091 0.93107,0.58069 -0.0763,0.30801 -0.0735,0.308 -0.0678,0.308 -0.0636,0.30942 -1.09073,0.1215 -0.91977,0.17944 -0.9325,0.29105 -0.96781,0.61883 -0.0156,0.12717 -0.0141,0.12574 -0.0141,0.12716 -0.0127,0.12716 0.80533,0.81804 0.84348,0.49168 0.85619,0.38006 1.03704,0.36028 -0.006,0.31648 -0.003,0.31648 0.003,0.31648 0.006,0.31648 -1.03704,0.35887 -0.85619,0.38006 -0.84348,0.49168 -0.80533,0.81946 0.0127,0.12716 0.0141,0.12574 0.0141,0.12716 0.0156,0.12574 0.96781,0.62026 0.9325,0.29104 0.91977,0.17944 1.09073,0.12009 0.0636,0.30942 0.0678,0.30941 0.0735,0.30801 0.0763,0.30659 -0.93107,0.5821 -0.75023,0.56091 -0.7135,0.66687 -0.6033,0.97771 0.0409,0.12008 0.0424,0.12151 0.0424,0.1201 0.0424,0.11868 1.08084,0.38995 0.97487,0.0763 0.93532,-0.0297 1.09073,-0.12574 0.13139,0.28822 0.13564,0.2854 0.13987,0.28399 0.1427,0.28257 -0.77848,0.77425 -0.60612,0.7135 -0.5482,0.80957 -0.37016,1.08791 0.0678,0.10737 0.0678,0.10879 0.0678,0.10738 0.0678,0.10738 1.14018,0.13846 0.96641,-0.1427 0.90705,-0.23736 1.03563,-0.36452 0.19215,0.25149 0.19498,0.24866 0.19921,0.24584 0.20204,0.24302 -0.58634,0.92825 -0.43234,0.83076 -0.35462,0.9113 -0.11868,1.14159 0.0904,0.0918 0.089,0.089 0.0904,0.0904 0.0904,0.089 1.14301,-0.11868 0.90988,-0.35321 0.83077,-0.43375 0.92825,-0.58493 0.24442,0.20204 0.24585,0.19921 0.24865,0.19497 0.25149,0.19216 -0.36594,1.03563 -0.23735,0.90564 -0.14129,0.9664 0.13846,1.14018 0.10738,0.0692 0.10738,0.0678 0.10738,0.0678 0.10879,0.0664 1.0879,-0.37017 0.80816,-0.54677 0.7149,-0.60754 0.77425,-0.77708 0.28117,0.14271 0.28398,0.13987 0.28681,0.13422 0.28823,0.13139 -0.12575,1.09074 -0.0297,0.93673 0.0763,0.97346 0.38854,1.08084 0.12009,0.0438 0.12009,0.0424 0.1201,0.041 0.12009,0.0409 0.97912,-0.60188 0.66687,-0.71349 0.5609,-0.75165 0.58069,-0.93108 0.30801,0.0777 0.308,0.072 0.308,0.0692 0.30943,0.0636 0.1215,1.09073 0.17943,0.91978 0.29106,0.93249 0.61883,0.9664 0.12716,0.0156 0.12574,0.0141 0.12716,0.0141 0.12716,0.0141 0.81806,-0.80533 0.49167,-0.8449 0.38006,-0.85619 0.36028,-1.03704 0.31648,0.007 0.31648,0.003 0.31649,-0.003 0.31648,-0.007 0.36028,1.03704 0.37865,0.85619 0.49167,0.8449 0.81947,0.80533 0.12715,-0.0141 0.12574,-0.0141 0.12717,-0.0141 0.12574,-0.0156 0.62025,-0.9664 0.29104,-0.93249 0.17944,-0.91978 0.12009,-1.09073 0.30942,-0.0636 0.30942,-0.0692 0.30799,-0.072 0.3066,-0.0777 0.58211,0.93108 0.5609,0.75165 0.66687,0.71349 0.97771,0.60188 0.12009,-0.0409 0.1215,-0.041 0.1201,-0.0424 0.11868,-0.0438 0.38995,-1.08084 0.0763,-0.97346 -0.0297,-0.93673 -0.12574,-1.09074 0.28822,-0.13139 0.2854,-0.13422 0.28398,-0.13987 0.28258,-0.14271 0.77424,0.77708 0.7135,0.60754 0.80957,0.54677 1.08791,0.37017 0.10737,-0.0664 0.10879,-0.0678 0.10738,-0.0678 0.10738,-0.0692 0.13847,-1.14018 -0.14271,-0.9664 -0.23737,-0.90564 -0.36452,-1.03563 0.25149,-0.19216 0.24866,-0.19497 0.24585,-0.19921 0.24301,-0.20204 0.92825,0.58493 0.83077,0.43375 0.91129,0.35321 1.1416,0.11868 0.0904,-0.089 0.0904,-0.0904 0.0904,-0.089 0.089,-0.0918 -0.11868,-1.14159 -0.35321,-0.9113 -0.43375,-0.83076 -0.58492,-0.92825 0.20203,-0.24302 0.19921,-0.24584 0.19498,-0.24866 0.19215,-0.25149 1.03563,0.36452 0.90564,0.23736 0.9664,0.1427 1.14018,-0.13846 0.0692,-0.10738 0.0678,-0.10738 0.0678,-0.10879 0.0664,-0.10737 -0.37017,-1.08791 -0.54677,-0.80957 -0.60754,-0.7135 -0.77706,-0.77425 0.1427,-0.28257 0.13986,-0.28399 0.13423,-0.2854 0.13139,-0.28822 1.09073,0.12574 0.93674,0.0297 0.97345,-0.0763 1.08085,-0.38995 0.0438,-0.11868 0.0424,-0.1201 0.0409,-0.12151 0.041,-0.12008 -0.6019,-0.97771 -0.71349,-0.66687 -0.75164,-0.56091 -0.93108,-0.5821 0.0777,-0.30659 0.072,-0.30801 0.0692,-0.30941 0.0636,-0.30942 1.09073,-0.12009 0.91978,-0.17944 0.93249,-0.29104 0.9664,-0.62026 0.0155,-0.12574 0.0141,-0.12716 0.0141,-0.12574 0.0141,-0.12716 -0.80533,-0.81946 -0.8449,-0.49168 -0.85619,-0.38006 -1.03704,-0.35887 0.007,-0.31648 0.003,-0.31648 -0.003,-0.31648 -0.007,-0.31648 1.03704,-0.36028 0.85619,-0.38006 0.8449,-0.49168 0.80533,-0.81804 -0.0141,-0.12716 -0.0141,-0.12716 -0.0141,-0.12574 -0.0155,-0.12717 -0.9664,-0.61883 -0.93249,-0.29105 -0.91978,-0.17944 -1.09073,-0.1215 -0.0636,-0.30942 -0.0692,-0.308 -0.072,-0.308 -0.0777,-0.30801 0.93108,-0.58069 0.75164,-0.56091 0.71349,-0.66686 0.6019,-0.97912 -0.041,-0.12009 -0.0409,-0.1201 -0.0424,-0.12009 -0.0438,-0.12009 -1.08085,-0.38854 -0.97345,-0.0763 -0.93674,0.0297 -1.09073,0.12575 -0.13139,-0.28823 -0.13423,-0.28681 -0.13986,-0.28398 -0.1427,-0.28117 0.77706,-0.77425 0.60754,-0.71491 0.54677,-0.80816 0.37017,-1.0879 -0.0664,-0.10879 -0.0678,-0.10738 -0.0678,-0.10738 -0.0692,-0.10738 -1.14018,-0.13845 -0.9664,0.14128 -0.90564,0.23736 -1.03563,0.36593 -0.19215,-0.25148 -0.19498,-0.24867 -0.19921,-0.24584 -0.20203,-0.24442 0.58492,-0.92684 0.43375,-0.83218 0.35321,-0.90988 0.11868,-1.14301 -0.089,-0.0904 -0.0904,-0.0904 -0.0904,-0.089 -0.0904,-0.0904 -1.1416,0.11868 -0.91129,0.35463 -0.83077,0.43234 -0.92825,0.58634 -0.24301,-0.20204 -0.24585,-0.19922 -0.24866,-0.19497 -0.25149,-0.19215 0.36452,-1.03563 0.23737,-0.90706 0.14271,-0.9664 -0.13847,-1.14018 -0.10738,-0.0678 -0.10738,-0.0678 -0.10879,-0.0679 -0.10737,-0.0678 -1.08791,0.37017 -0.80957,0.54819 -0.7135,0.60612 -0.77424,0.77849 -0.28258,-0.14271 -0.28398,-0.13987 -0.2854,-0.13563 -0.28822,-0.1314 0.12574,-1.08932 0.0297,-0.93673 -0.0763,-0.97487 -0.38995,-1.08085 -0.11868,-0.0424 -0.1201,-0.0424 -0.1215,-0.0424 -0.12009,-0.0409 -0.97771,0.6033 -0.66687,0.71349 -0.5609,0.75023 -0.58211,0.93108 -0.3066,-0.0763 -0.30799,-0.0735 -0.30942,-0.0678 -0.30942,-0.0636 -0.12009,-1.09073 -0.17944,-0.91977 -0.29104,-0.9325 -0.62025,-0.967813 -0.12574,-0.0155 -0.12717,-0.0141 -0.12574,-0.0141 -0.12715,-0.0127 -0.81947,0.80533 -0.49167,0.843483 -0.37865,0.8562 -0.36028,1.03704 -0.31648,-0.006 -0.31649,-0.003 -0.31648,0.003 -0.31648,0.006 -0.36028,-1.03704 -0.38006,-0.8562 -0.49167,-0.843483 z m 2.68302,20.688573 a 5.3990039,5.3990039 0 0 1 5.39856,5.39997 5.3990039,5.3990039 0 0 1 -5.39856,5.39855 5.3990039,5.3990039 0 0 1 -5.39996,-5.39855 5.3990039,5.3990039 0 0 1 5.39996,-5.39997 z"
1000
     id="path5693"
1001
     inkscape:connector-curvature="0" />
1002
  <path
1003
     inkscape:connector-curvature="0"
1004
     d="m 380.9529,101.31918 a 4.37599,4.37599 0 0 1 -4.37599,4.37599 4.37599,4.37599 0 0 1 -4.37599,-4.37599 4.37599,4.37599 0 0 1 4.37599,-4.375983 4.37599,4.37599 0 0 1 4.37599,4.375983 z m 4.63493,-1.27213 c -0.32212,-0.118873 -0.95326,0.0926 -0.92258,-0.401293 -0.13877,-0.39635 -0.21401,-0.74537 0.27363,-0.88946 0.78055,-0.47633 1.45123,-1.16128 1.74461,-2.04171 0.15411,-0.39145 -0.3432,-0.48754 -0.63657,-0.53536 -0.91614,-0.25589 -1.86519,0.0578 -2.73328,0.35995 -0.11023,-0.31345 -0.69059,-0.56868 -0.47901,-0.88657 0.56405,-0.84324 0.99162,-1.8335 0.85012,-2.86709 -0.031,-0.41955 -0.52073,-0.29038 -0.8058,-0.20618 -0.93646,0.16692 -1.65537,0.86143 -2.30642,1.51029 -0.23528,-0.23464 -0.86896,-0.21274 -0.81624,-0.59097 0.14241,-1.00446 0.0978,-2.08217 -0.47806,-2.95201 -0.20995,-0.36459 -0.59514,-0.0357 -0.81544,0.16385 -0.7713,0.55671 -1.11768,1.49434 -1.42274,2.36143 -0.3138,-0.10927 -0.87519,0.18536 -0.99181,-0.17826 -0.30757,-0.96675 -0.81528,-1.91841 -1.71153,-2.45229 -0.34734,-0.23737 -0.55176,0.22606 -0.66364,0.50149 -0.45331,0.83622 -0.35865,1.83127 -0.25723,2.74482 -0.33012,0.0378 -0.70817,0.54672 -0.97098,0.26977 -0.69651,-0.73763 -1.56687,-1.37476 -2.60601,-1.46682 -0.41593,-0.0631 -0.39904,0.443 -0.38034,0.73971 -0.0456,0.95009 0.47143,1.80554 0.95918,2.58463 -0.28104,0.17725 -0.40076,0.79984 -0.75777,0.6643 -0.94759,-0.36236 -2.00818,-0.55864 -2.98437,-0.1908 -0.40215,0.12357 -0.16723,0.57227 -0.0217,0.83147 0.37114,0.8758 1.2081,1.42221 1.98561,1.91248 -0.17632,0.28163 -0.0141,0.89453 -0.39449,0.92732 -1.01097,0.0847 -2.05173,0.367983 -2.77166,1.122963 -0.3087,0.2858 0.0976,0.58816 0.34122,0.75853 0.71439,0.62804 1.70558,0.75716 2.6188,0.8616 -0.0367,0.33025 0.37548,0.81204 0.0469,1.00665 -0.87415,0.51488 -1.68886,1.22174 -2.00994,2.2143 -0.15411,0.39144 0.3432,0.48753 0.63657,0.53535 0.91612,0.25589 1.86516,-0.0578 2.73323,-0.35995 0.11029,0.31341 0.69063,0.56869 0.47905,0.88657 -0.56412,0.8432 -0.99155,1.83352 -0.85015,2.86709 0.031,0.41952 0.52075,0.2904 0.80584,0.20618 0.93644,-0.16692 1.65537,-0.86139 2.30637,-1.51029 0.2353,0.23464 0.86901,0.21272 0.81629,0.59098 -0.14241,1.00446 -0.0978,2.08215 0.47802,2.95202 0.20997,0.36455 0.59517,0.0357 0.81548,-0.16387 0.77125,-0.55674 1.11768,-1.49435 1.42274,-2.36142 0.31379,0.10926 0.8752,-0.18537 0.99181,0.17824 0.30754,0.96678 0.81527,1.91842 1.71153,2.45229 0.34733,0.23738 0.55172,-0.22608 0.66362,-0.50146 0.45335,-0.83621 0.35866,-1.83128 0.25725,-2.74484 0.33011,-0.0378 0.70812,-0.54672 0.97093,-0.26977 0.69656,0.7376 1.5669,1.37477 2.60606,1.46683 0.41593,0.0632 0.39897,-0.44304 0.38032,-0.73972 0.0457,-0.95011 -0.4715,-1.8055 -0.95916,-2.58463 0.28105,-0.17722 0.40074,-0.79983 0.75772,-0.6643 0.94761,0.36234 2.00821,0.55865 2.98442,0.1908 0.40215,-0.12357 0.16723,-0.57228 0.0217,-0.83146 -0.37116,-0.87579 -1.20814,-1.42218 -1.98561,-1.91249 0.17632,-0.28163 0.0141,-0.89453 0.39449,-0.92732 1.01097,-0.0847 2.05173,-0.36799 2.77166,-1.12295 0.3087,-0.28581 -0.0976,-0.58817 -0.34122,-0.75854 -0.47483,-0.43652 -1.13407,-0.61787 -1.75144,-0.75008 z"
1005
     style="fill:#126d95;fill-opacity:1;fill-rule:evenodd;stroke-width:0.04014921"
1006
     id="path5687" />
1007
  <path
1008
     style="fill:#126d95;fill-opacity:1;stroke-width:0.11881336"
1009
     id="path4816"
1010
     d="m 619.92265,90.37586 h 2.72717 v 2.71445 h 2.51374 v -2.71445 h 2.72716 v 8.21477 h -2.72716 v -2.73825 h -2.49003 v 2.73825 h -2.75088 m 11.57268,-5.47651 h -2.40702 v -2.73826 h 7.55307 v 2.73826 h -2.41888 v 5.47651 h -2.72717 m 6.34363,-8.21477 h 2.8576 l 1.75487,2.89303 1.75487,-2.89303 h 2.8576 v 8.21477 h -2.72717 v -4.07167 l -1.90901,2.95256 -1.90902,-2.95256 v 4.07167 h -2.67974 m 10.57667,-8.21477 h 2.72717 v 5.50033 h 3.86546 v 2.71444 h -6.59263"
1011
     inkscape:connector-curvature="0" />
1012
  <path
1013
     id="path4818"
1014
     d="m 619.82779,146.45062 -3.91289,-44.09786 h 43.01811 l -3.91289,44.07405 -17.63174,4.90505"
1015
     inkscape:connector-curvature="0"
1016
     style="fill:#e44d26;stroke-width:0.11881336" />
1017
  <path
1018
     id="path4820"
1019
     d="m 637.42396,147.58164 v -41.60962 h 17.5843 l -3.3556,37.62129"
1020
     inkscape:connector-curvature="0"
1021
     style="fill:#f16529;stroke-width:0.11881336" />
1022
  <path
1023
     id="path4822"
1024
     d="m 623.90669,111.3652 h 13.51727 v 5.40508 h -7.61236 l 0.498,5.53605 h 7.11436 v 5.39318 h -12.04697 m 0.23714,2.71444 h 5.40691 l 0.37943,4.32169 6.02349,1.61914 v 5.64319 L 626.373,138.90255"
1025
     inkscape:connector-curvature="0"
1026
     style="fill:#ebebeb;stroke-width:0.11881336" />
1027
  <path
1028
     id="path4824"
1029
     d="m 650.89379,111.3652 h -13.49355 v 5.40508 h 12.99555 m -0.48615,5.53605 h -12.5094 v 5.40508 h 6.64006 l -0.62843,7.02423 -6.01163,1.61914 v 5.61938 l 11.02724,-3.07161"
1030
     inkscape:connector-curvature="0"
1031
     style="fill:#ffffff;stroke-width:0.11881336" />
1032
  <path
1033
     sodipodi:nodetypes="cc"
1034
     inkscape:connector-curvature="0"
1035
     id="path5804"
1036
     d="m 240.99252,105.07517 65.2338,-1.01308"
1037
     style="opacity:1;vector-effect:none;fill:#126d95;fill-opacity:1;stroke:#126d95;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9479)" />
1038
  <path
1039
     style="opacity:1;vector-effect:none;fill:#126d95;fill-opacity:1;stroke:#126d95;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9505)"
1040
     d="m 481.61302,105.07517 65.2337,-1.01308"
1041
     id="path9497"
1042
     inkscape:connector-curvature="0"
1043
     sodipodi:nodetypes="cc" />
1044
  <path
1045
     inkscape:connector-curvature="0"
1046
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
1047
     d="m 235.85308,230.53494 c 0.87012,0 1.65488,0.35019 2.22266,0.91797 0.56778,0.56778 0.91797,1.35253 0.91797,2.22265 v -0.23242 c 0,-1.6112 -1.297,-2.9082 -2.9082,-2.9082 z"
1048
     id="path6102" />
1049
  <path
1050
     inkscape:connector-curvature="0"
1051
     style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
1052
     d="m 76.280823,230.53494 c -1.611195,0 -2.908203,1.297 -2.908203,2.9082 v 0.23242 c 0,-0.87012 0.35019,-1.65487 0.917968,-2.22265 0.567779,-0.56778 1.354485,-0.91797 2.22461,-0.91797 z"
1053
     id="path6106" />
1054
  <path
1055
     inkscape:connector-curvature="0"
1056
     style="fill:#51a9cf;fill-opacity:1;fill-rule:nonzero;stroke:#ec706a;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2950)"
1057
     d="m 76.515198,222.53494 c -0.870125,0 -1.656831,0.35019 -2.22461,0.91797 -0.567778,0.56778 -0.917968,1.35253 -0.917968,2.22265 v 29.71485 h 165.62109 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91797,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z"
1058
     id="path6104"
1059
     sodipodi:nodetypes="sssccssss" />
1060
  <path
1061
     sodipodi:nodetypes="ccssssc"
1062
     inkscape:connector-curvature="0"
1063
     style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2950)"
1064
     d="M 238.99371,255.39041 H 73.37262 v 152.63392 c 0,1.6112 1.297008,2.90821 2.908203,2.90821 H 236.08551 c 1.6112,0 2.9082,-1.29701 2.9082,-2.90821 z"
1065
     id="path6100" />
1066
  <path
1067
     style="opacity:1;vector-effect:none;fill:#126d95;fill-opacity:1;stroke:#126d95;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9509)"
1068
     d="m 240.99257,328.95043 65.23376,-1.01307"
1069
     id="path9485"
1070
     inkscape:connector-curvature="0"
1071
     sodipodi:nodetypes="cc" />
1072
  <path
1073
     sodipodi:nodetypes="cc"
1074
     inkscape:connector-curvature="0"
1075
     id="path9757"
1076
     d="m 481.61298,300.08996 65.23376,-1.01307"
1077
     style="opacity:1;vector-effect:none;fill:#126d95;fill-opacity:1;stroke:#126d95;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9761)" />
1078
  <path
1079
     style="opacity:1;vector-effect:none;fill:#126d95;fill-opacity:1;stroke:#126d95;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9767)"
1080
     d="M 552.61456,372.04139 487.3808,371.02832"
1081
     id="path9763"
1082
     inkscape:connector-curvature="0"
1083
     sodipodi:nodetypes="cc" />
1084
  <text
1085
     id="text2269"
1086
     y="62.149761"
1087
     x="115.43707"
1088
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1089
     xml:space="preserve"><tspan
1090
       y="62.149761"
1091
       x="115.43707"
1092
       id="tspan2267"
1093
       sodipodi:role="line">Text Edit</tspan></text>
1094
  <text
1095
     transform="rotate(-90)"
1096
     id="text2273"
1097
     y="43.507812"
1098
     x="-132.24059"
1099
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1100
     xml:space="preserve"><tspan
1101
       y="43.507812"
1102
       x="-132.24059"
1103
       id="tspan2271"
1104
       sodipodi:role="line">Today</tspan></text>
1105
  <text
1106
     id="text2277"
1107
     y="61.540386"
1108
     x="358.88168"
1109
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1110
     xml:space="preserve"><tspan
1111
       y="61.540386"
1112
       x="358.88168"
1113
       id="tspan2275"
1114
       sodipodi:role="line">Process</tspan></text>
1115
  <text
1116
     id="text2281"
1117
     y="59.34898"
1118
     x="605.30872"
1119
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1120
     xml:space="preserve"><tspan
1121
       y="59.34898"
1122
       x="605.30872"
1123
       id="tspan2279"
1124
       sodipodi:role="line">Output</tspan></text>
1125
  <text
1126
     id="text2285"
1127
     y="245.17946"
1128
     x="605.30872"
1129
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1130
     xml:space="preserve"><tspan
1131
       y="245.17946"
1132
       x="605.30872"
1133
       id="tspan2283"
1134
       sodipodi:role="line">Output</tspan></text>
1135
  <text
1136
     id="text2289"
1137
     y="247.37088"
1138
     x="358.88168"
1139
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1140
     xml:space="preserve"><tspan
1141
       y="247.37088"
1142
       x="358.88168"
1143
       id="tspan2287"
1144
       sodipodi:role="line">Process</tspan></text>
1145
  <text
1146
     id="text2293"
1147
     y="247.98026"
1148
     x="115.43707"
1149
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1150
     xml:space="preserve"><tspan
1151
       y="247.98026"
1152
       x="115.43707"
1153
       id="tspan2291"
1154
       sodipodi:role="line">Text Edit</tspan></text>
1155
  <text
1156
     transform="rotate(-90)"
1157
     id="text2297"
1158
     y="43.630859"
1159
     x="-363.15442"
1160
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1161
     xml:space="preserve"><tspan
1162
       y="43.630859"
1163
       x="-363.15442"
1164
       id="tspan2295"
1165
       sodipodi:role="line">Proposed</tspan></text>
1166
  <text
1167
     id="text2301"
1168
     y="314.01108"
1169
     x="98.034729"
1170
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#126d95;fill-opacity:1;stroke:none"
1171
     xml:space="preserve"><tspan
1172
       id="tspan2299"
1173
       sodipodi:role="line"
1174
       x="98.034729"
1175
       y="314.01108">R Markdown</tspan></text>
1176
  <text
1177
     id="text2305"
1178
     y="285.84311"
1179
     x="107.43903"
1180
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#126d95;fill-opacity:1;stroke:none"
1181
     xml:space="preserve"><tspan
1182
       id="tspan2303"
1183
       sodipodi:role="line"
1184
       x="107.43903"
1185
       y="285.84311">Markdown</tspan></text>
1186
  <text
1187
     id="text2309"
1188
     y="342.91147"
1189
     x="134.3277"
1190
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#126d95;fill-opacity:1;stroke:none"
1191
     xml:space="preserve"><tspan
1192
       id="tspan2307"
1193
       sodipodi:role="line"
1194
       x="134.3277"
1195
       y="342.91147">XML</tspan></text>
1196
  <text
1197
     id="text2313"
1198
     y="370.34702"
1199
     x="113.56207"
1200
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#126d95;fill-opacity:1;stroke:none"
1201
     xml:space="preserve"><tspan
1202
       id="tspan2311"
1203
       sodipodi:role="line"
1204
       x="113.56207"
1205
       y="370.34702">DocBook</tspan></text>
1206
  <text
1207
     id="text2317"
1208
     y="398.51498"
1209
     x="114.3526"
1210
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#126d95;fill-opacity:1;stroke:none"
1211
     xml:space="preserve"><tspan
1212
       id="tspan2315"
1213
       sodipodi:role="line"
1214
       x="114.3526"
1215
       y="398.51498">AsciiDoc</tspan></text>
1216
  <text
1217
     transform="rotate(-90)"
1218
     id="text2329"
1219
     y="43.507812"
1220
     x="-774.87335"
1221
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1222
     xml:space="preserve"><tspan
1223
       y="43.507812"
1224
       x="-774.87335"
1225
       id="tspan2327"
1226
       sodipodi:role="line">Example Processing Combination</tspan></text>
1227
  <text
1228
     id="text2333"
1229
     y="562.05426"
1230
     x="135.31207"
1231
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#f3fbfe;fill-opacity:1;stroke:none"
1232
     xml:space="preserve"><tspan
1233
       y="562.05426"
1234
       x="135.31207"
1235
       id="tspan2331"
1236
       sodipodi:role="line">XML</tspan></text>
1237
  <text
1238
     id="text2337"
1239
     y="495.6918"
1240
     x="381.64142"
1241
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#333333;fill-opacity:0.866667;stroke:none"
1242
     xml:space="preserve"><tspan
1243
       y="495.6918"
1244
       x="381.64142"
1245
       id="tspan2335"
1246
       sodipodi:role="line">XSLT</tspan></text>
1247
  <text
1248
     id="text2341"
1249
     y="562.05426"
1250
     x="323.97742"
1251
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1252
     xml:space="preserve"><tspan
1253
       y="562.05426"
1254
       x="323.97742"
1255
       id="tspan2339"
1256
       sodipodi:role="line">XSLT Processor</tspan></text>
1257
  <text
1258
     id="text2345"
1259
     y="562.54059"
1260
     x="579.27557"
1261
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1262
     xml:space="preserve"><tspan
1263
       y="562.54059"
1264
       x="579.27557"
1265
       id="tspan2343"
1266
       sodipodi:role="line">R Markdown</tspan></text>
1267
  <text
1268
     id="text2349"
1269
     y="643.24084"
1270
     x="588.75018"
1271
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1272
     xml:space="preserve"><tspan
1273
       y="643.24084"
1274
       x="588.75018"
1275
       id="tspan2347"
1276
       sodipodi:role="line">Markdown</tspan></text>
1277
  <text
1278
     id="text2353"
1279
     y="642.63147"
1280
     x="339.61023"
1281
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1282
     xml:space="preserve"><tspan
1283
       y="642.63147"
1284
       x="339.61023"
1285
       id="tspan2351"
1286
       sodipodi:role="line">R Processor</tspan></text>
1287
  <text
1288
     id="text2357"
1289
     y="722.54858"
1290
     x="316.10635"
1291
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:21.3333px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1292
     xml:space="preserve"><tspan
1293
       y="722.54858"
1294
       x="316.10635"
1295
       id="tspan2355"
1296
       sodipodi:role="line">Variable Processor</tspan></text>
1297
  <text
1298
     id="text2361"
1299
     y="723.3316"
1300
     x="604.07831"
1301
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1302
     xml:space="preserve"><tspan
1303
       y="723.3316"
1304
       x="604.07831"
1305
       id="tspan2359"
1306
       sodipodi:role="line">HTML5</tspan></text>
1307
  <text
1308
     id="text2365"
1309
     y="630.84766"
1310
     x="81.211723"
1311
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#333333;fill-opacity:0.866667;stroke:none"
1312
     xml:space="preserve"><tspan
1313
       y="630.84766"
1314
       x="81.211723"
1315
       id="tspan2363"
1316
       sodipodi:role="line">Structured Data Source</tspan></text>
1317
  <text
1318
     id="text2369"
1319
     y="756.39404"
1320
     x="215.65826"
1321
     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#126d95;fill-opacity:1;stroke:none"
1322
     xml:space="preserve"><tspan
1323
       y="756.39404"
1324
       x="215.65826"
1325
       id="tspan2367"
1326
       sodipodi:role="line">interpolated values</tspan></text>
1327
  <g
1328
     transform="translate(-0.25585322,11.831789)"
1329
     id="g2523">
1330
    <text
1331
       xml:space="preserve"
1332
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1333
       x="156.49219"
1334
       y="708.2467"
1335
       id="text2373"><tspan
1336
         sodipodi:role="line"
1337
         id="tspan2371"
1338
         x="156.49219"
1339
         y="708.2467">CSON</tspan></text>
1340
    <text
1341
       xml:space="preserve"
1342
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1343
       x="156.49219"
1344
       y="688.41504"
1345
       id="text2377"><tspan
1346
         sodipodi:role="line"
1347
         id="tspan2375"
1348
         x="156.49219"
1349
         y="688.41504">JSONNET</tspan></text>
1350
    <text
1351
       xml:space="preserve"
1352
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1353
       x="156.49219"
1354
       y="668.24695"
1355
       id="text2381"><tspan
1356
         sodipodi:role="line"
1357
         id="tspan2379"
1358
         x="156.49219"
1359
         y="668.24695">JSON5</tspan></text>
1360
    <text
1361
       xml:space="preserve"
1362
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1363
       x="156.49219"
1364
       y="648.07886"
1365
       id="text2385"><tspan
1366
         sodipodi:role="line"
1367
         id="tspan2383"
1368
         x="156.49219"
1369
         y="648.07886">JSON</tspan></text>
1370
    <text
1371
       xml:space="preserve"
1372
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1373
       x="94.110725"
1374
       y="648.41534"
1375
       id="text2389"><tspan
1376
         sodipodi:role="line"
1377
         id="tspan2387"
1378
         x="94.110725"
1379
         y="648.41534">YAML</tspan></text>
1380
    <text
1381
       xml:space="preserve"
1382
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1383
       x="94.110725"
1384
       y="668.24695"
1385
       id="text2393"><tspan
1386
         sodipodi:role="line"
1387
         id="tspan2391"
1388
         x="94.110725"
1389
         y="668.24695">TOML</tspan></text>
1390
    <text
1391
       xml:space="preserve"
1392
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none"
1393
       x="94.110725"
1394
       y="688.41504"
1395
       id="text2397"><tspan
1396
         sodipodi:role="line"
1397
         id="tspan2395"
1398
         x="94.110725"
1399
         y="688.41504">XML</tspan></text>
1400
  </g>
1401
  <g
1402
     transform="translate(-1.2304677,-0.85937628)"
1403
     id="g2593">
1404
    <g
1405
       id="g2532">
1406
      <rect
1407
         id="rect4698"
1408
         ry="2.7292624"
1409
         y="91.740654"
1410
         x="129.16347"
1411
         height="32.205296"
1412
         width="54.039394"
1413
         style="fill:none;stroke:#126d95;stroke-width:2.72926;stroke-opacity:1" />
1414
      <path
1415
         style="fill:#126d95;fill-opacity:1;stroke-width:0.272926"
1416
         id="path4700"
1417
         d="M 135.98663,117.12279 V 98.56381 h 5.45852 l 5.45853,6.82315 5.45852,-6.82315 h 5.45853 v 18.55898 h -5.45853 v -10.64412 l -5.45852,6.82315 -5.45853,-6.82315 v 10.64412 z m 34.11578,0 -8.18779,-9.00657 h 5.45852 v -9.55241 h 5.45853 v 9.55241 h 5.45852 z"
1418
         inkscape:connector-curvature="0" />
1419
    </g>
1420
    <text
1421
       xml:space="preserve"
1422
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#126d95;fill-opacity:1;stroke:none"
1423
       x="108.73981"
1424
       y="152.80437"
1425
       id="text2407"><tspan
1426
         sodipodi:role="line"
1427
         id="tspan2405"
1428
         x="108.73981"
1429
         y="152.80437">Markdown</tspan></text>
1430
  </g>
1431
  <path
1432
     inkscape:connector-curvature="0"
1433
     d="m 417.86562,272.90923 c -2.81873,0.35302 -5.58858,1.78683 -7.90222,4.10047 -1.79226,1.78682 -3.43787,4.20365 -5.01832,7.35911 -1.28173,2.56347 -2.29191,5.21927 -2.90019,7.59265 l -0.1738,0.68975 -0.68975,0.35302 c -0.96673,0.49423 -1.81398,1.01561 -2.77528,1.69993 -3.29666,2.35709 -6.15341,5.19211 -8.53222,8.46705 -0.23354,0.32586 -0.45621,0.58656 -0.49966,0.58656 -0.038,0 -0.33673,-0.0435 -0.65716,-0.0923 -0.73863,-0.11949 -3.19891,-0.13578 -4.11676,-0.0272 -3.79633,0.46164 -7.25593,1.57502 -11.41613,3.68228 -3.00339,1.5207 -4.93685,2.87304 -6.8323,4.77391 -2.37881,2.37882 -3.80176,5.01832 -4.21452,7.82076 -0.0978,0.62457 -0.0978,2.39511 0,3.0414 0.51052,3.55193 2.55804,6.94636 5.27358,8.74404 3.15003,2.08554 7.40256,2.6558 12.27424,1.65105 3.62253,-0.75492 7.20161,-2.14527 10.77526,-4.19822 3.47046,-1.99321 5.87643,-4.18193 7.57093,-6.87575 0.27155,-0.43449 0.35845,-0.52682 0.53224,-0.59199 2.79701,-1.01018 4.74677,-2.05295 6.96265,-3.72572 2.02036,-1.5207 3.43244,-2.85675 6.0991,-5.77324 0.68432,-0.74949 0.8038,-0.91785 0.84182,-1.16225 0.0326,-0.17379 0.0543,-0.20095 0.15207,-0.17922 0.51595,0.10319 2.20502,0.11948 2.94908,0.0272 2.08553,-0.25526 4.05701,-1.10251 6.01763,-2.57976 2.61778,-1.97691 5.06177,-5.27901 6.78885,-9.17853 2.59606,-5.86556 3.57908,-10.80785 3.01425,-15.19073 -0.14121,-1.12423 -0.28241,-1.74881 -0.59742,-2.71554 -0.42905,-1.29803 -1.08621,-2.55804 -1.89001,-3.62796 -0.43449,-0.57026 -1.57502,-1.70536 -2.14528,-2.12898 -1.59131,-1.17855 -3.93753,-2.13442 -6.03936,-2.46028 -0.66259,-0.10319 -2.29735,-0.14664 -2.85132,-0.0815 z m 2.44399,7.82076 c 1.94433,0.46707 3.2152,2.04751 3.5302,4.39917 0.0815,0.58656 0.0815,2.10183 0,2.7427 -0.32043,2.62864 -1.26544,5.70263 -2.61235,8.48878 -1.01561,2.10725 -1.79226,3.34011 -2.88933,4.58383 -0.32587,0.36931 -1.38493,1.31975 -1.42838,1.2763 -0.005,-0.005 0.0706,-0.34216 0.1738,-0.74406 0.24983,-0.97759 0.34215,-1.56958 0.3856,-2.41683 0.0706,-1.58044 -0.27155,-3.09571 -0.98302,-4.30684 -1.20027,-2.05295 -3.17175,-3.41072 -5.47453,-3.78547 -0.11405,-0.0163 -0.20638,-0.0489 -0.20638,-0.076 0,-0.0217 0.19552,-0.53768 0.42905,-1.15139 1.41752,-3.67684 2.66666,-5.83298 4.30142,-7.40799 1.0482,-1.01562 1.70536,-1.40665 2.73726,-1.62933 0.51596,-0.11405 1.49355,-0.0978 2.03666,0.0272 z m -10.34078,17.93885 c 0.52139,0.54311 0.56483,0.76579 0.46164,2.25933 l -0.0326,0.51596 -0.14121,-0.21725 c -0.22811,-0.34215 -0.40733,-0.72233 -0.52682,-1.1188 -0.0652,-0.20095 -0.15207,-0.43992 -0.20095,-0.53224 -0.0706,-0.13035 -0.17922,-0.91243 -0.19008,-1.34691 0,-0.11949 0.29871,0.0923 0.63,0.43991 z m -7.36997,3.01425 c 0.3856,2.28649 1.18397,4.05159 2.44941,5.40393 l 0.45078,0.47793 -0.13577,0.14664 c -0.0706,0.0815 -0.46165,0.51052 -0.86355,0.9613 -1.55328,1.73795 -2.81873,2.98167 -4.05158,3.97012 -0.41819,0.34216 -0.78208,0.61915 -0.79837,0.61915 -0.0163,0 -0.0435,-0.0923 -0.0652,-0.20638 -0.076,-0.4019 -0.46708,-1.4664 -0.8038,-2.15614 -0.54311,-1.12424 -1.14596,-2.0095 -2.08554,-3.0577 l -0.45621,-0.50509 0.41276,-0.50509 c 1.19484,-1.47182 2.92192,-3.26951 4.43177,-4.62728 0.85811,-0.76578 1.37949,-1.21656 1.39578,-1.20027 0.005,0.005 0.0597,0.315 0.11949,0.67888 z m -16.52135,9.77052 c -0.0163,0.11405 -0.0815,0.54311 -0.14664,0.9613 -0.22267,1.47182 -0.23353,3.57365 -0.0272,4.78478 0.19008,1.10251 0.57569,2.11812 1.08078,2.81873 0.27699,0.38018 0.87441,0.97759 1.22199,1.20027 l 0.23354,0.1575 -0.15207,0.12492 c -0.60285,0.48879 -2.54174,1.58044 -4.18193,2.34622 -2.4114,1.12967 -4.36659,1.7651 -6.62049,2.16157 -0.77664,0.13578 -0.99932,0.15207 -2.09096,0.15207 -0.98846,0 -1.30889,-0.0217 -1.67278,-0.0978 -1.5207,-0.33672 -2.53088,-0.97216 -3.1989,-2.0095 -0.53225,-0.82552 -0.72234,-1.48268 -0.72777,-2.43855 0,-1.56415 0.57027,-2.68296 2.17244,-4.27969 1.78682,-1.77597 3.93753,-3.05227 7.72299,-4.5784 2.01493,-0.81467 4.20366,-1.37407 5.75151,-1.4664 0.74406,-0.0434 0.66803,-0.0652 0.63544,0.16294 z m 6.13712,3.5302 c -0.0163,0.0543 -0.0272,0.0109 -0.0272,-0.0923 0,-0.10319 0.0109,-0.14664 0.0272,-0.0978 0.0109,0.0543 0.0109,0.14121 0,0.19009 z"
1434
     id="path8164"
1435
     style="fill:#ec706a;fill-opacity:1;stroke:none;stroke-width:0.00543108" />
1436
  <g
1437
     transform="translate(1.378418e-5,1.0193503)"
1438
     id="g1168">
1439
    <text
1440
       id="text1158"
1441
       y="364.17905"
1442
       x="349.05551"
1443
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#126d95;fill-opacity:1;stroke:none"
1444
       xml:space="preserve"><tspan
1445
         id="tspan1156"
1446
         sodipodi:role="line"
1447
         x="349.05551"
1448
         y="364.17905">Processor</tspan></text>
1449
    <text
1450
       xml:space="preserve"
1451
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#126d95;fill-opacity:1;stroke:none"
1452
       x="370.40707"
1453
       y="392.17905"
1454
       id="text1162"><tspan
1455
         y="392.17905"
1456
         x="370.40707"
1457
         sodipodi:role="line"
1458
         id="tspan1160">Chain</tspan></text>
1459
  </g>
1460
  <g
1461
     transform="translate(0,-2.3144459)"
1462
     id="g1206">
1463
    <text
1464
       xml:space="preserve"
1465
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#126d95;fill-opacity:1;stroke:none"
1466
       x="586.44855"
1467
       y="327.56967"
1468
       id="text1190"><tspan
1469
         y="327.56967"
1470
         x="586.44855"
1471
         sodipodi:role="line"
1472
         id="tspan1188">Processor-</tspan></text>
1473
    <text
1474
       id="text1194"
1475
       y="355.56967"
1476
       x="588.43488"
1477
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#126d95;fill-opacity:1;stroke:none"
14231478
       xml:space="preserve"><tspan
14241479
         id="tspan1192"
A docs/licenses/README.md
1
# Licenses
2
3
Grabbing the licenses is *mostly* automated, however there are exceptions
4
that need to be captured. Adding a file to capture these exceptions from
5
what the automated scripts pull would be useful.
6
7
# Usage
8
9
To grab the latest dependencies:
10
11
``` bash
12
gradle dependencies --configuration runtimeClasspath | fetch.sh > license.json
13
```
14
15
To convert the licenses to Markdown:
16
17
```
18
cat licenses.json | ./js2md.sh
19
```
20
21
Take the output from that and compare it with the licenses Markdown file.
22
123
A docs/licenses/fetch.sh
1
#!/usr/bin/env bash
2
3
input_file="${1:-/dev/stdin}"
4
declare -A seen_dependencies
5
6
alphanum="[a-zA-Z0-9]"
7
name_chars="[a-zA-Z0-9._-]"
8
version_chars="[a-zA-Z0-9._+-]"
9
group_artifact="${alphanum}${name_chars}*"
10
version_pattern="${alphanum}${version_chars}*${alphanum}"
11
12
NS_LICENSE_NAME='//*[local-name()="licenses"]/*[local-name()="license"]/*[local-name()="name"]/text()'
13
NS_LICENSE_URL='//*[local-name()="licenses"]/*[local-name()="license"]/*[local-name()="url"]/text()'
14
NS_PROJECT_NAME='/*[local-name()="project"]/*[local-name()="name"]/text()'
15
NS_ORG_NAME='//*[local-name()="organization"]/*[local-name()="name"]/text()'
16
NS_SCM_URL='//*[local-name()="scm"]/*[local-name()="url"]/text()'
17
NS_DEVELOPER_NAMES='//*[local-name()="developers"]/*[local-name()="developer"]/*[local-name()="name"]/text()'
18
19
out() {
20
  echo -n "$*"
21
}
22
23
field() {
24
  local key="$1"
25
  local value="$2"
26
  local comma="$3"
27
  out "\"$key\":\"$value\""
28
  [[ "$comma" == "true" ]] && out ","
29
}
30
31
map_spdx_id() {
32
  case "$1" in
33
    *Apache*2.0*) echo "Apache-2.0" ;;
34
    *MIT*) echo "MIT" ;;
35
    *BSD*2*) echo "BSD-2-Clause" ;;
36
    *2*BSD*) echo "BSD-2-Clause" ;;
37
    *3*BSD*) echo "BSD-3-Clause" ;;
38
    *BSD*3*) echo "BSD-3-Clause" ;;
39
    *LGPL*2*later) echo "LGPL-2.1-or-later" ;;
40
    *LGPL*2*) echo "LGPL-2.1-only" ;;
41
    *LGPL*3*) echo "LGPL-3.0-only" ;;
42
    *GPL*2*CE*) echo "GPL-2.0-with-classpath-exception" ;;
43
    *GPL*2*) echo "GPL-2.0-only" ;;
44
    *GPLv2*) echo "GPL-2.0-only" ;;
45
    *GPL*3*) echo "GPL-3.0-only" ;;
46
    *EPL*1.0*) echo "EPL-1.0" ;;
47
    *EPL*2.0*) echo "EPL-2.0" ;;
48
    *MPL*1.1*) echo "MPL-1.1" ;;
49
    *Mozilla*1.1*) echo "MPL-1.1" ;;
50
    *MPL*2.0*) echo "MPL-2.0" ;;
51
    *Mozilla*2.0*) echo "MPL-2.0" ;;
52
    *) echo "UNKNOWN" ;;
53
  esac
54
}
55
56
out "["; is_first=1
57
58
while IFS= read -r line; do
59
  [[ ! "$line" =~ ^[[:space:]]*[\+\|\\].*--- ]] && continue
60
  cleaned=$(echo "$line" | awk '{sub(/^[[:space:]]*[-+|\\]+[[:space:]]*/, ""); sub(/[[:space:]]*$/, ""); print}')
61
  [[ "$cleaned" =~ \(\*\)$ ]] && continue
62
  cleaned=$(echo "$cleaned" | awk '{sub(/[[:space:]]*\([^)]*\)$/, ""); sub(/ -> .*/, ""); print}')
63
64
  if [[ "$cleaned" =~ ^(${group_artifact}):(${group_artifact}):(${version_pattern})$ ]]; then
65
    group="${BASH_REMATCH[1]}"
66
    artifact="${BASH_REMATCH[2]}"
67
    version="${BASH_REMATCH[3]}"
68
    key="$group:$artifact:$version"
69
    [[ -n "${seen_dependencies[$key]}" ]] && continue
70
    seen_dependencies[$key]=1
71
72
    group_path="${group//./\/}"
73
    pom_url="https://repo1.maven.org/maven2/$group_path/$artifact/$version/$artifact-$version.pom"
74
    page_url="https://mvnrepository.com/artifact/$group/$artifact/$version"
75
76
    license_names=()
77
    license_urls=()
78
    developer_names=()
79
    project_name="$artifact"
80
    copyright=""
81
    source_url=""
82
    homepage_url=""
83
84
    if pom=$(wget -q -O - "$pom_url"); then
85
      project_name=$(echo "$pom" | xmllint --xpath "string($NS_PROJECT_NAME)" - 2>/dev/null)
86
      [[ -z "$project_name" ]] && project_name="$artifact"
87
      copyright=$(echo "$pom" | xmllint --xpath "string($NS_ORG_NAME)" - 2>/dev/null)
88
      source_url=$(echo "$pom" | xmllint --xpath "string($NS_SCM_URL)" - 2>/dev/null)
89
      mapfile -t license_names < <(echo "$pom" | xmllint --xpath "$NS_LICENSE_NAME" - 2>/dev/null)
90
      mapfile -t license_urls < <(echo "$pom" | xmllint --xpath "$NS_LICENSE_URL" - 2>/dev/null)
91
      mapfile -t developer_names < <(echo "$pom" | xmllint --xpath "$NS_DEVELOPER_NAMES" - 2>/dev/null)
92
    fi
93
94
    html_content=$(wget -q --user-agent="KeenWrite/5.0" -O - "$page_url")
95
96
    homepage_url=$(echo "$html_content" | xmllint --html --xpath '//tr[th[text()="HomePage"]]/td/a/@href' - 2>/dev/null | sed 's/href="//;s/"$//')
97
98
    if [[ -z "$project_name" ]]; then
99
      project_name=$(echo "$html_content" | xmllint --html --xpath 'string(//h2[@class="title"])' - 2>/dev/null | sed -E 's/^[[:space:]]*//;s/[[:space:]]*$//')
100
      [[ -z "$project_name" ]] && project_name=$(echo "$html_content" | xmllint --html --xpath 'string(//title)' - 2>/dev/null | sed -E 's/ - MVNRepository$//')
101
    fi
102
103
    if [[ ${#license_names[@]} -eq 0 ]]; then
104
      mapfile -t license_names < <(echo "$html_content" | xmllint --html --xpath '//div[@class="version-section"]/h2[text()="Licenses"]/following-sibling::table//tr/td[1]/text()' - 2>/dev/null)
105
      mapfile -t license_urls < <(echo "$html_content" | xmllint --html --xpath '//div[@class="version-section"]/h2[text()="Licenses"]/following-sibling::table//tr/td[2]/a/@href' - 2>/dev/null | sed 's/href="//;s/"$//')
106
    fi
107
108
    if [[ ${#developer_names[@]} -eq 0 ]]; then
109
      mapfile -t developer_names < <(echo "$html_content" | xmllint --html --xpath '//h2[text()="Developers"]/following-sibling::div//tbody/tr/td[1]/text()' - 2>/dev/null)
110
    fi
111
112
    [[ $is_first -eq 0 ]] && out ","
113
    is_first=0
114
115
    out "{"
116
    field "group" "$group" true
117
    field "artifact" "$artifact" true
118
    field "version" "$version" true
119
    field "url" "$page_url" true
120
    field "name" "$project_name" true
121
122
    out "\"licenses\":["
123
    for i in "${!license_names[@]}"; do
124
      [[ $i -gt 0 ]] && out ","
125
      name="${license_names[$i]}"
126
      url="${license_urls[$i]}"
127
      spdx=$(map_spdx_id "$name")
128
      out "{"
129
      field "name" "$name" true
130
      field "url" "$url" true
131
      field "spdx" "$spdx" false
132
      out "}"
133
    done
134
    out "],"
135
136
    field "copyright" "$copyright" true
137
    field "source" "$source_url" true
138
    field "homepage" "$homepage_url" true
139
140
    out "\"developers\":["
141
    for i in "${!developer_names[@]}"; do
142
      [[ $i -gt 0 ]] && out ","
143
      out "\"${developer_names[$i]}\""
144
    done
145
    out "]"
146
147
    out "}"
148
  fi
149
done < "$input_file"
150
151
out "]"
152
153
1154
D docs/licenses/fonts/SOURCE-SERIF-4.md
1
Copyright 2014-2019 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries.
2
3
This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
5
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
6
7
8
-----------------------------------------------------------
9
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
-----------------------------------------------------------
11
12
PREAMBLE
13
The goals of the Open Font License (OFL) are to stimulate worldwide
14
development of collaborative font projects, to support the font creation
15
efforts of academic and linguistic communities, and to provide a free and
16
open framework in which fonts may be shared and improved in partnership
17
with others.
18
19
The OFL allows the licensed fonts to be used, studied, modified and
20
redistributed freely as long as they are not sold by themselves. The
21
fonts, including any derivative works, can be bundled, embedded,
22
redistributed and/or sold with any software provided that any reserved
23
names are not used by derivative works. The fonts and derivatives,
24
however, cannot be released under any other type of license. The
25
requirement for fonts to remain under this license does not apply
26
to any document created using the fonts or their derivatives.
27
28
DEFINITIONS
29
"Font Software" refers to the set of files released by the Copyright
30
Holder(s) under this license and clearly marked as such. This may
31
include source files, build scripts and documentation.
32
33
"Reserved Font Name" refers to any names specified as such after the
34
copyright statement(s).
35
36
"Original Version" refers to the collection of Font Software components as
37
distributed by the Copyright Holder(s).
38
39
"Modified Version" refers to any derivative made by adding to, deleting,
40
or substituting -- in part or in whole -- any of the components of the
41
Original Version, by changing formats or by porting the Font Software to a
42
new environment.
43
44
"Author" refers to any designer, engineer, programmer, technical
45
writer or other person who contributed to the Font Software.
46
47
PERMISSION & CONDITIONS
48
Permission is hereby granted, free of charge, to any person obtaining
49
a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
redistribute, and sell modified and unmodified copies of the Font
51
Software, subject to the following conditions:
52
53
1) Neither the Font Software nor any of its individual components,
54
in Original or Modified Versions, may be sold by itself.
55
56
2) Original or Modified Versions of the Font Software may be bundled,
57
redistributed and/or sold with any software, provided that each copy
58
contains the above copyright notice and this license. These can be
59
included either as stand-alone text files, human-readable headers or
60
in the appropriate machine-readable metadata fields within text or
61
binary files as long as those fields can be easily viewed by the user.
62
63
3) No Modified Version of the Font Software may use the Reserved Font
64
Name(s) unless explicit written permission is granted by the corresponding
65
Copyright Holder. This restriction only applies to the primary font name as
66
presented to the users.
67
68
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
Software shall not be used to promote, endorse or advertise any
70
Modified Version, except to acknowledge the contribution(s) of the
71
Copyright Holder(s) and the Author(s) or with their explicit written
72
permission.
73
74
5) The Font Software, modified or unmodified, in part or in whole,
75
must be distributed entirely under this license, and must not be
76
distributed under any other license. The requirement for fonts to
77
remain under this license does not apply to any document created
78
using the Font Software.
79
80
TERMINATION
81
This license becomes null and void if any of the above conditions are
82
not met.
83
84
DISCLAIMER
85
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
OTHER DEALINGS IN THE FONT SOFTWARE.
941
A docs/licenses/fonts/SOURCE-SERIF.md
1
Copyright 2014-2019 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries.
2
3
This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
5
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
6
7
8
-----------------------------------------------------------
9
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
-----------------------------------------------------------
11
12
PREAMBLE
13
The goals of the Open Font License (OFL) are to stimulate worldwide
14
development of collaborative font projects, to support the font creation
15
efforts of academic and linguistic communities, and to provide a free and
16
open framework in which fonts may be shared and improved in partnership
17
with others.
18
19
The OFL allows the licensed fonts to be used, studied, modified and
20
redistributed freely as long as they are not sold by themselves. The
21
fonts, including any derivative works, can be bundled, embedded,
22
redistributed and/or sold with any software provided that any reserved
23
names are not used by derivative works. The fonts and derivatives,
24
however, cannot be released under any other type of license. The
25
requirement for fonts to remain under this license does not apply
26
to any document created using the fonts or their derivatives.
27
28
DEFINITIONS
29
"Font Software" refers to the set of files released by the Copyright
30
Holder(s) under this license and clearly marked as such. This may
31
include source files, build scripts and documentation.
32
33
"Reserved Font Name" refers to any names specified as such after the
34
copyright statement(s).
35
36
"Original Version" refers to the collection of Font Software components as
37
distributed by the Copyright Holder(s).
38
39
"Modified Version" refers to any derivative made by adding to, deleting,
40
or substituting -- in part or in whole -- any of the components of the
41
Original Version, by changing formats or by porting the Font Software to a
42
new environment.
43
44
"Author" refers to any designer, engineer, programmer, technical
45
writer or other person who contributed to the Font Software.
46
47
PERMISSION & CONDITIONS
48
Permission is hereby granted, free of charge, to any person obtaining
49
a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
redistribute, and sell modified and unmodified copies of the Font
51
Software, subject to the following conditions:
52
53
1) Neither the Font Software nor any of its individual components,
54
in Original or Modified Versions, may be sold by itself.
55
56
2) Original or Modified Versions of the Font Software may be bundled,
57
redistributed and/or sold with any software, provided that each copy
58
contains the above copyright notice and this license. These can be
59
included either as stand-alone text files, human-readable headers or
60
in the appropriate machine-readable metadata fields within text or
61
binary files as long as those fields can be easily viewed by the user.
62
63
3) No Modified Version of the Font Software may use the Reserved Font
64
Name(s) unless explicit written permission is granted by the corresponding
65
Copyright Holder. This restriction only applies to the primary font name as
66
presented to the users.
67
68
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
Software shall not be used to promote, endorse or advertise any
70
Modified Version, except to acknowledge the contribution(s) of the
71
Copyright Holder(s) and the Author(s) or with their explicit written
72
permission.
73
74
5) The Font Software, modified or unmodified, in part or in whole,
75
must be distributed entirely under this license, and must not be
76
distributed under any other license. The requirement for fonts to
77
remain under this license does not apply to any document created
78
using the Font Software.
79
80
TERMINATION
81
This license becomes null and void if any of the above conditions are
82
not met.
83
84
DISCLAIMER
85
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
OTHER DEALINGS IN THE FONT SOFTWARE.
194
A docs/licenses/js2md.sh
1
#!/usr/bin/env bash
2
3
echo "# Third-party libraries"
4
echo ""
5
6
jq -c '.[]' | while read -r library_entry; do
7
  library_name=$(jq -r '.name' <<< "$library_entry" | xargs)
8
  library_version=$(jq -r '.version' <<< "$library_entry" | xargs)
9
  library_homepage_url=$(jq -r '.homepage' <<< "$library_entry" | xargs)
10
  library_source_url=$(jq -r '.source' <<< "$library_entry" | xargs)
11
  library_maven_url=$(jq -r '.url' <<< "$library_entry" | xargs)
12
13
  echo "## $library_name"
14
  echo "- **Version:** $library_version"
15
16
  # Build the URL line with pipes
17
  url_line=""
18
  [[ $library_homepage_url ]] && url_line+="[Homepage](${library_homepage_url//[[:space:]]/})"
19
  [[ $library_source_url ]] && url_line+="${url_line:+ | }[Source](${library_source_url//[[:space:]]/})"
20
  [[ $library_maven_url ]] && url_line+="${url_line:+ | }[Maven](${library_maven_url//[[:space:]]/})"
21
  [[ $url_line ]] && echo "- $url_line"
22
23
  license_links=$(jq -r '
24
    .licenses
25
    | map(select(.url != null and .url != "") | "[\(.spdx)](\(.url))")
26
    | join(", ")
27
  ' <<< "$library_entry")
28
  [[ $license_links ]] && [[ $license_links != "" ]] && echo "- **License(s):** $license_links"
29
30
  developer_list=$(jq -r '.developers | map(trim) | unique | select(length > 0) | join(", ")' <<< "$library_entry")
31
  [[ $developer_list ]] && echo "- **Developers:** $developer_list"
32
33
  echo ""
34
done
35
36
echo ":::"
137
A docs/licenses/licenses.json
1
[
2
  {
3
    "group": "org.controlsfx",
4
    "artifact": "controlsfx",
5
    "version": "11.2.2",
6
    "url": "https://mvnrepository.com/artifact/org.controlsfx/controlsfx/11.2.2",
7
    "name": "ControlsFX",
8
    "licenses": [
9
      {
10
        "name": "The 3-Clause BSD License",
11
        "url": "http://www.opensource.org/licenses/bsd-license.php",
12
        "spdx": "BSD-3-Clause"
13
      }
14
    ],
15
    "copyright": "",
16
    "source": "https://github.com/controlsfx/controlsfx",
17
    "homepage": " http://www.controlsfx.org/",
18
    "developers": [
19
      "Jonathan Giles"
20
    ]
21
  },
22
  {
23
    "group": "org.fxmisc.richtext",
24
    "artifact": "richtextfx",
25
    "version": "0.11.6",
26
    "url": "https://mvnrepository.com/artifact/org.fxmisc.richtext/richtextfx/0.11.6",
27
    "name": "RichTextFX",
28
    "licenses": [
29
      {
30
        "name": "The BSD 2-Clause License",
31
        "url": "http://opensource.org/licenses/BSD-2-Clause",
32
        "spdx": "BSD-2-Clause"
33
      },
34
      {
35
        "name": "GPLv2 with the Classpath Exception",
36
        "url": "http://www.gnu.org/software/classpath/license.html",
37
        "spdx": "GPL-2.0-only"
38
      }
39
    ],
40
    "copyright": "",
41
    "source": "scm:git@github.com:FXMisc/RichTextFX.git",
42
    "homepage": " https://github.com/FXMisc/RichTextFX/#richtextfx",
43
    "developers": [
44
      "Tomas Mikula",
45
      "Jordan Martinez",
46
      "Jurgen Doll"
47
    ]
48
  },
49
  {
50
    "group": "org.fxmisc.wellbehaved",
51
    "artifact": "wellbehavedfx",
52
    "version": "0.3.3",
53
    "url": "https://mvnrepository.com/artifact/org.fxmisc.wellbehaved/wellbehavedfx/0.3.3",
54
    "name": "WellBehavedFX",
55
    "licenses": [
56
      {
57
        "name": "The BSD 2-Clause License",
58
        "url": "http://opensource.org/licenses/BSD-2-Clause",
59
        "spdx": "BSD-2-Clause"
60
      }
61
    ],
62
    "copyright": "",
63
    "source": "scm:git@github.com:FXMisc/WellBehavedFX.git",
64
    "homepage": " http://www.fxmisc.org/wellbehaved/",
65
    "developers": [
66
      "Tomas Mikula"
67
    ]
68
  },
69
  {
70
    "group": "org.openjfx",
71
    "artifact": "javafx-media",
72
    "version": "26-ea+3",
73
    "url": "https://mvnrepository.com/artifact/org.openjfx/javafx-media/26-ea+3",
74
    "name": "javafx media",
75
    "licenses": [
76
      {
77
        "name": "GPLv2+CE",
78
        "url": " https://openjdk.java.net/legal/gplv2+ce.html",
79
        "spdx": "GPL-2.0-with-classpath-exception"
80
      }
81
    ],
82
    "copyright": "",
83
    "source": "",
84
    "homepage": " https://openjdk.java.net/projects/openjfx/",
85
    "developers": [
86
      "OpenJFX Mailing List"
87
    ]
88
  },
89
  {
90
    "group": "com.dlsc.preferencesfx",
91
    "artifact": "preferencesfx-core",
92
    "version": "11.17.0",
93
    "url": "https://mvnrepository.com/artifact/com.dlsc.preferencesfx/preferencesfx-core/11.17.0",
94
    "name": "PreferencesFX",
95
    "licenses": [
96
      {
97
        "name": "Apache License, Version 2.0",
98
        "url": "https://www.apache.org/licenses/LICENSE-2.0.txt",
99
        "spdx": "Apache-2.0"
100
      }
101
    ],
102
    "copyright": "",
103
    "source": "https://github.com/dlsc-software-consulting-gmbh/PreferencesFX",
104
    "homepage": " https://github.com/dlsc-software-consulting-gmbh/PreferencesFX",
105
    "developers": [
106
      "Francois Martin",
107
      "Marco Sanfratello",
108
      "Dirk Lemmermann"
109
    ]
110
  },
111
  {
112
    "group": "com.panemu",
113
    "artifact": "tiwulfx-dock",
114
    "version": "0.5",
115
    "url": "https://mvnrepository.com/artifact/com.panemu/tiwulfx-dock/0.5",
116
    "name": "tiwulfx-dock",
117
    "licenses": [
118
      {
119
        "name": "MIT",
120
        "url": "https://github.com/panemu/tiwulfx-dock/blob/main/LICENSE",
121
        "spdx": "MIT"
122
      }
123
    ],
124
    "copyright": "Panemu",
125
    "source": "https://panemu@github.com/panemu/tiwulfx-dock.git",
126
    "homepage": " https://github.com/panemu/tiwulfx-dock",
127
    "developers": [
128
      "Amrullah"
129
    ]
130
  },
131
  {
132
    "group": "com.vladsch.flexmark",
133
    "artifact": "flexmark",
134
    "version": "0.64.8",
135
    "url": "https://mvnrepository.com/artifact/com.vladsch.flexmark/flexmark/0.64.8",
136
    "name": "flexmark-java core",
137
    "licenses": [
138
      {
139
        "name": "BSD 2-Clause License",
140
        "url": " http://opensource.org/licenses/BSD-2-Clause",
141
        "spdx": "BSD-2-Clause"
142
      }
143
    ],
144
    "copyright": "",
145
    "source": "",
146
    "homepage": "",
147
    "developers": [
148
      "Vladimir Schneider"
149
    ]
150
  },
151
  {
152
    "group": "com.vladsch.flexmark",
153
    "artifact": "flexmark-ext-definition",
154
    "version": "0.64.8",
155
    "url": "https://mvnrepository.com/artifact/com.vladsch.flexmark/flexmark-ext-definition/0.64.8",
156
    "name": "flexmark-java extension for definition",
157
    "licenses": [
158
      {
159
        "name": "BSD 2-Clause License",
160
        "url": " http://opensource.org/licenses/BSD-2-Clause",
161
        "spdx": "BSD-2-Clause"
162
      }
163
    ],
164
    "copyright": "",
165
    "source": "",
166
    "homepage": "",
167
    "developers": [
168
      "Vladimir Schneider"
169
    ]
170
  },
171
  {
172
    "group": "com.vladsch.flexmark",
173
    "artifact": "flexmark-ext-gfm-strikethrough",
174
    "version": "0.64.8",
175
    "url": "https://mvnrepository.com/artifact/com.vladsch.flexmark/flexmark-ext-gfm-strikethrough/0.64.8",
176
    "name": "flexmark-java extension for strikethrough",
177
    "licenses": [
178
      {
179
        "name": "BSD 2-Clause License",
180
        "url": " http://opensource.org/licenses/BSD-2-Clause",
181
        "spdx": "BSD-2-Clause"
182
      }
183
    ],
184
    "copyright": "",
185
    "source": "",
186
    "homepage": "",
187
    "developers": [
188
      "Vladimir Schneider"
189
    ]
190
  },
191
  {
192
    "group": "com.vladsch.flexmark",
193
    "artifact": "flexmark-ext-superscript",
194
    "version": "0.64.8",
195
    "url": "https://mvnrepository.com/artifact/com.vladsch.flexmark/flexmark-ext-superscript/0.64.8",
196
    "name": "flexmark-java extension for superscript",
197
    "licenses": [
198
      {
199
        "name": "BSD 2-Clause License",
200
        "url": " http://opensource.org/licenses/BSD-2-Clause",
201
        "spdx": "BSD-2-Clause"
202
      }
203
    ],
204
    "copyright": "",
205
    "source": "",
206
    "homepage": "",
207
    "developers": [
208
      "Vladimir Schneider"
209
    ]
210
  },
211
  {
212
    "group": "com.vladsch.flexmark",
213
    "artifact": "flexmark-ext-tables",
214
    "version": "0.64.8",
215
    "url": "https://mvnrepository.com/artifact/com.vladsch.flexmark/flexmark-ext-tables/0.64.8",
216
    "name": "flexmark-java extension for tables",
217
    "licenses": [
218
      {
219
        "name": "BSD 2-Clause License",
220
        "url": " http://opensource.org/licenses/BSD-2-Clause",
221
        "spdx": "BSD-2-Clause"
222
      }
223
    ],
224
    "copyright": "",
225
    "source": "",
226
    "homepage": "",
227
    "developers": [
228
      "Vladimir Schneider"
229
    ]
230
  },
231
  {
232
    "group": "com.vladsch.flexmark",
233
    "artifact": "flexmark-ext-typographic",
234
    "version": "0.64.8",
235
    "url": "https://mvnrepository.com/artifact/com.vladsch.flexmark/flexmark-ext-typographic/0.64.8",
236
    "name": "flexmark-java extension for typographic",
237
    "licenses": [
238
      {
239
        "name": "BSD 2-Clause License",
240
        "url": " http://opensource.org/licenses/BSD-2-Clause",
241
        "spdx": "BSD-2-Clause"
242
      }
243
    ],
244
    "copyright": "",
245
    "source": "",
246
    "homepage": "",
247
    "developers": [
248
      "Vladimir Schneider"
249
    ]
250
  },
251
  {
252
    "group": "com.vladsch.flexmark",
253
    "artifact": "flexmark-ext-footnotes",
254
    "version": "0.64.8",
255
    "url": "https://mvnrepository.com/artifact/com.vladsch.flexmark/flexmark-ext-footnotes/0.64.8",
256
    "name": "flexmark-java extension for footnotes",
257
    "licenses": [
258
      {
259
        "name": "BSD 2-Clause License",
260
        "url": " http://opensource.org/licenses/BSD-2-Clause",
261
        "spdx": "BSD-2-Clause"
262
      }
263
    ],
264
    "copyright": "",
265
    "source": "",
266
    "homepage": "",
267
    "developers": [
268
      "Vladimir Schneider"
269
    ]
270
  },
271
  {
272
    "group": "org.yaml",
273
    "artifact": "snakeyaml",
274
    "version": "2.5",
275
    "url": "https://mvnrepository.com/artifact/org.yaml/snakeyaml/2.5",
276
    "name": "SnakeYAML",
277
    "licenses": [
278
      {
279
        "name": "Apache License, Version 2.0",
280
        "url": "http://www.apache.org/licenses/LICENSE-2.0.txt",
281
        "spdx": "Apache-2.0"
282
      }
283
    ],
284
    "copyright": "",
285
    "source": "https://bitbucket.org/snakeyaml/snakeyaml/src",
286
    "homepage": " https://bitbucket.org/snakeyaml/snakeyaml",
287
    "developers": [
288
      "Andrey Somov",
289
      "Alexander Maslov"
290
    ]
291
  },
292
  {
293
    "group": "com.fasterxml.jackson.core",
294
    "artifact": "jackson-core",
295
    "version": "2.19.2",
296
    "url": "https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core/2.19.2",
297
    "name": "Jackson-core",
298
    "licenses": [
299
      {
300
        "name": "The Apache Software License, Version 2.0",
301
        "url": "https://www.apache.org/licenses/LICENSE-2.0.txt",
302
        "spdx": "Apache-2.0"
303
      }
304
    ],
305
    "copyright": "",
306
    "source": "https://github.com/FasterXML/jackson-core",
307
    "homepage": " https://github.com/FasterXML/jackson-core",
308
    "developers": [
309
      "Tatu Saloranta"
310
    ]
311
  },
312
  {
313
    "group": "com.fasterxml.jackson.core",
314
    "artifact": "jackson-databind",
315
    "version": "2.19.2",
316
    "url": "https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind/2.19.2",
317
    "name": "jackson-databind",
318
    "licenses": [
319
      {
320
        "name": "The Apache Software License, Version 2.0",
321
        "url": "https://www.apache.org/licenses/LICENSE-2.0.txt",
322
        "spdx": "Apache-2.0"
323
      }
324
    ],
325
    "copyright": "",
326
    "source": "https://github.com/FasterXML/jackson-databind",
327
    "homepage": " https://github.com/FasterXML/jackson",
328
    "developers": [
329
      "Tatu Saloranta"
330
    ]
331
  },
332
  {
333
    "group": "com.fasterxml.jackson.dataformat",
334
    "artifact": "jackson-dataformat-yaml",
335
    "version": "2.19.2",
336
    "url": "https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.19.2",
337
    "name": "Jackson-dataformat-YAML",
338
    "licenses": [
339
      {
340
        "name": "The Apache Software License, Version 2.0",
341
        "url": " https://www.apache.org/licenses/LICENSE-2.0.txt",
342
        "spdx": "Apache-2.0"
343
      }
344
    ],
345
    "copyright": "",
346
    "source": "",
347
    "homepage": " https://github.com/FasterXML/jackson-dataformats-text",
348
    "developers": [
349
      "Tatu Saloranta"
350
    ]
351
  },
352
  {
353
    "group": "org.jsoup",
354
    "artifact": "jsoup",
355
    "version": "1.21.2",
356
    "url": "https://mvnrepository.com/artifact/org.jsoup/jsoup/1.21.2",
357
    "name": "jsoup Java HTML Parser",
358
    "licenses": [
359
      {
360
        "name": "The MIT License",
361
        "url": "https://jsoup.org/license",
362
        "spdx": "MIT"
363
      }
364
    ],
365
    "copyright": "Jonathan Hedley",
366
    "source": "https://github.com/jhy/jsoup",
367
    "homepage": " https://jsoup.org/",
368
    "developers": [
369
      "Jonathan Hedley"
370
    ]
371
  },
372
  {
373
    "group": "org.xhtmlrenderer",
374
    "artifact": "flying-saucer-core",
375
    "version": "10.0.0",
376
    "url": "https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-core/10.0.0",
377
    "name": "Flying Saucer Core Renderer",
378
    "licenses": [
379
      {
380
        "name": "GNU Lesser General Public License (LGPL), version 2.1 or later",
381
        "url": "https://www.gnu.org/licenses/lgpl-3.0.html",
382
        "spdx": "LGPL-2.1-or-later"
383
      }
384
    ],
385
    "copyright": "",
386
    "source": "",
387
    "homepage": "",
388
    "developers": [
389
      "Patrick Wright",
390
      "Peter Brant"
391
    ]
392
  },
393
  {
394
    "group": "org.apache.commons",
395
    "artifact": "commons-compress",
396
    "version": "1.28.0",
397
    "url": "https://mvnrepository.com/artifact/org.apache.commons/commons-compress/1.28.0",
398
    "name": "Apache Commons Compress",
399
    "licenses": [
400
      {
401
        "name": "Apache-2.0",
402
        "url": " https://www.apache.org/licenses/LICENSE-2.0.txt",
403
        "spdx": "Apache-2.0"
404
      }
405
    ],
406
    "copyright": "",
407
    "source": "https://gitbox.apache.org/repos/asf?p=commons-compress.git",
408
    "homepage": " https://commons.apache.org/proper/commons-compress/",
409
    "developers": [
410
      "Torsten Curdt",
411
      "Stefan Bodewig",
412
      "Sebastian Bazley",
413
      "Christian Grobmeier",
414
      "Julius Davies",
415
      "Damjan Jovanovic",
416
      "Emmanuel Bourg",
417
      "Gary Gregory",
418
      "Rob Tompkins",
419
      "Peter Alfred Lee"
420
    ]
421
  },
422
  {
423
    "group": "org.apache.commons",
424
    "artifact": "commons-vfs2",
425
    "version": "2.10.0",
426
    "url": "https://mvnrepository.com/artifact/org.apache.commons/commons-vfs2/2.10.0",
427
    "name": "Apache Commons VFS",
428
    "licenses": [
429
      {
430
        "name": "Apache-2.0",
431
        "url": " https://www.apache.org/licenses/LICENSE-2.0.txt",
432
        "spdx": "Apache-2.0"
433
      }
434
    ],
435
    "copyright": "",
436
    "source": "",
437
    "homepage": " https://commons.apache.org/proper/commons-vfs/",
438
    "developers": [
439
      "Adam Murdoch",
440
      "James Strachan",
441
      "Mario Ivankovits",
442
      "Rahul Akolkar",
443
      "James Carman",
444
      "Ralph Goers",
445
      "Joerg Schaible",
446
      "Gary Gregory",
447
      "Bernd Eckenfels"
448
    ]
449
  },
450
  {
451
    "group": "org.codehaus.plexus",
452
    "artifact": "plexus-utils",
453
    "version": "4.0.2",
454
    "url": "https://mvnrepository.com/artifact/org.codehaus.plexus/plexus-utils/4.0.2",
455
    "name": "Plexus Common Utilities",
456
    "licenses": [
457
      {
458
        "name": "Apache License, Version 2.0",
459
        "url": "https://www.apache.org/licenses/LICENSE-2.0.txt",
460
        "spdx": "Apache-2.0"
461
      }
462
    ],
463
    "copyright": "Codehaus Plexus",
464
    "source": "https://github.com/codehaus-plexus/plexus-utils/tree/plexus-utils-4.0.2/",
465
    "homepage": " https://codehaus-plexus.github.io/plexus-utils/",
466
    "developers": [
467
      "Jason van Zyl",
468
      "Pete Kazmier",
469
      "James Taylor",
470
      "Dan Diephouse",
471
      "Kasper Nielsen",
472
      "Ben Walding",
473
      "Mark Wilkinson",
474
      "Michal Maczka",
475
      "Emmanuel Venisse",
476
      "Trygve Laugstøl",
477
      "Kenney Westerhof",
478
      "Carlos Sanchez",
479
      "Brett Porter",
480
      "John Casey",
481
      "Andrew Williams",
482
      "Rahul Thakur",
483
      "Joakim Erdfelt",
484
      "Olivier Lamy",
485
      "Hervé Boutemy",
486
      "Oleg Gusakov",
487
      "Vincent Siveton",
488
      "Kristian Rosenvold",
489
      "Andreas Gudian",
490
      "Karl Heinz Marbaise",
491
      "Michael Osipov",
492
      "Gabriel Belingueres",
493
      "Konrad Windszus",
494
      "Slawomir Jaranowski",
495
      "Sylwester Lachiewicz",
496
      "Guillaume Nodet"
497
    ]
498
  },
499
  {
500
    "group": "org.renjin",
501
    "artifact": "renjin-script-engine",
502
    "version": "3.5-beta76",
503
    "url": "https://mvnrepository.com/artifact/org.renjin/renjin-script-engine/3.5-beta76",
504
    "name": "renjin-script-engine",
505
    "licenses": [],
506
    "copyright": "",
507
    "source": "",
508
    "homepage": "",
509
    "developers": []
510
  },
511
  {
512
    "group": "org.renjin.cran",
513
    "artifact": "rjson",
514
    "version": "0.2.15-renjin-21",
515
    "url": "https://mvnrepository.com/artifact/org.renjin.cran/rjson/0.2.15-renjin-21",
516
    "name": "rjson",
517
    "licenses": [
518
      {
519
        "name": "Apache License, Version 2.0",
520
        "url": " http://www.apache.org/licenses/LICENSE-2.0.txt",
521
        "spdx": "Apache-2.0"
522
      }
523
    ],
524
    "copyright": "",
525
    "source": "",
526
    "homepage": "",
527
    "developers": []
528
  },
529
  {
530
    "group": "io.sf.carte",
531
    "artifact": "echosvg-awt-util",
532
    "version": "2.2",
533
    "url": "https://mvnrepository.com/artifact/io.sf.carte/echosvg-awt-util/2.2",
534
    "name": "echosvg-awt-util",
535
    "licenses": [
536
      {
537
        "name": "The Apache License, Version 2.0",
538
        "url": " http://www.apache.org/licenses/LICENSE-2.0.txt",
539
        "spdx": "Apache-2.0"
540
      }
541
    ],
542
    "copyright": "",
543
    "source": "",
544
    "homepage": " https://github.com/css4j/echosvg/wiki",
545
    "developers": []
546
  },
547
  {
548
    "group": "io.sf.carte",
549
    "artifact": "echosvg-bridge",
550
    "version": "2.2",
551
    "url": "https://mvnrepository.com/artifact/io.sf.carte/echosvg-bridge/2.2",
552
    "name": "echosvg-bridge",
553
    "licenses": [
554
      {
555
        "name": "The Apache License, Version 2.0",
556
        "url": " http://www.apache.org/licenses/LICENSE-2.0.txt",
557
        "spdx": "Apache-2.0"
558
      }
559
    ],
560
    "copyright": "",
561
    "source": "",
562
    "homepage": " https://github.com/css4j/echosvg/wiki",
563
    "developers": []
564
  },
565
  {
566
    "group": "io.sf.carte",
567
    "artifact": "echosvg-ext",
568
    "version": "2.2",
569
    "url": "https://mvnrepository.com/artifact/io.sf.carte/echosvg-ext/2.2",
570
    "name": "echosvg-ext",
571
    "licenses": [
572
      {
573
        "name": "The Apache License, Version 2.0",
574
        "url": " http://www.apache.org/licenses/LICENSE-2.0.txt",
575
        "spdx": "Apache-2.0"
576
      }
577
    ],
578
    "copyright": "",
579
    "source": "",
580
    "homepage": " https://github.com/css4j/echosvg/wiki",
581
    "developers": []
582
  },
583
  {
584
    "group": "io.sf.carte",
585
    "artifact": "echosvg-svggen",
586
    "version": "2.2",
587
    "url": "https://mvnrepository.com/artifact/io.sf.carte/echosvg-svggen/2.2",
588
    "name": "echosvg-svggen",
589
    "licenses": [
590
      {
591
        "name": "The Apache License, Version 2.0",
592
        "url": " http://www.apache.org/licenses/LICENSE-2.0.txt",
593
        "spdx": "Apache-2.0"
594
      }
595
    ],
596
    "copyright": "",
597
    "source": "",
598
    "homepage": " https://github.com/css4j/echosvg/wiki",
599
    "developers": []
600
  },
601
  {
602
    "group": "io.sf.carte",
603
    "artifact": "echosvg-transcoder",
604
    "version": "2.2",
605
    "url": "https://mvnrepository.com/artifact/io.sf.carte/echosvg-transcoder/2.2",
606
    "name": "echosvg-transcoder",
607
    "licenses": [
608
      {
609
        "name": "The Apache License, Version 2.0",
610
        "url": " http://www.apache.org/licenses/LICENSE-2.0.txt",
611
        "spdx": "Apache-2.0"
612
      }
613
    ],
614
    "copyright": "",
615
    "source": "",
616
    "homepage": " https://github.com/css4j/echosvg/wiki",
617
    "developers": []
618
  },
619
  {
620
    "group": "org.ahocorasick",
621
    "artifact": "ahocorasick",
622
    "version": "0.6.3",
623
    "url": "https://mvnrepository.com/artifact/org.ahocorasick/ahocorasick/0.6.3",
624
    "name": "Aho-CoraSick algorithm for efficient string matching",
625
    "licenses": [
626
      {
627
        "name": "The Apache Software License, Version 2.0",
628
        "url": "http://www.apache.org/licenses/LICENSE-2.0.txt",
629
        "spdx": "Apache-2.0"
630
      }
631
    ],
632
    "copyright": "42 BV",
633
    "source": "scm:git://github.com/robert-bor/aho-corasick",
634
    "homepage": " https://github.com/robert-bor/aho-corasick",
635
    "developers": [
636
      "Robert Bor",
637
      "Daniel Beck",
638
      "Dave Jarvis"
639
    ]
640
  },
641
  {
642
    "group": "com.github.albfernandez",
643
    "artifact": "juniversalchardet",
644
    "version": "2.5.0",
645
    "url": "https://mvnrepository.com/artifact/com.github.albfernandez/juniversalchardet/2.5.0",
646
    "name": "juniversalchardet",
647
    "licenses": [
648
      {
649
        "name": "Mozilla Public License Version 1.1",
650
        "url": "https://www.mozilla.org/en-US/MPL/1.1/",
651
        "spdx": "MPL-1.1"
652
      },
653
      {
654
        "name": "GENERAL PUBLIC LICENSE, version 3 (GPL-3.0)",
655
        "url": "http://www.gnu.org/licenses/gpl.txt",
656
        "spdx": "GPL-3.0-only"
657
      },
658
      {
659
        "name": "GNU LESSER GENERAL PUBLIC LICENSE, version 3 (LGPL-3.0)",
660
        "url": "http://www.gnu.org/licenses/lgpl.txt",
661
        "spdx": "LGPL-3.0-only"
662
      }
663
    ],
664
    "copyright": "",
665
    "source": "git@github.com:albfernandez/juniversalchardet.git",
666
    "homepage": " https://github.com/albfernandez/juniversalchardet",
667
    "developers": [
668
      "Alberto Fernández"
669
    ]
670
  },
671
  {
672
    "group": "jakarta.validation",
673
    "artifact": "jakarta.validation-api",
674
    "version": "3.1.1",
675
    "url": "https://mvnrepository.com/artifact/jakarta.validation/jakarta.validation-api/3.1.1",
676
    "name": "Jakarta Validation API",
677
    "licenses": [
678
      {
679
        "name": "Apache License 2.0",
680
        "url": "http://www.apache.org/licenses/LICENSE-2.0.txt",
681
        "spdx": "Apache-2.0"
682
      }
683
    ],
684
    "copyright": "",
685
    "source": "https://github.com/jakartaee/validation",
686
    "homepage": " https://beanvalidation.org",
687
    "developers": [
688
      "Emmanuel Bernard",
689
      "Emmanuel Bernard",
690
      "Hardy Ferentschik",
691
      "Gunnar Morling",
692
      "Guillaume Smet"
693
    ]
694
  },
695
  {
696
    "group": "org.greenrobot",
697
    "artifact": "eventbus-java",
698
    "version": "3.3.1",
699
    "url": "https://mvnrepository.com/artifact/org.greenrobot/eventbus-java/3.3.1",
700
    "name": "EventBus",
701
    "licenses": [
702
      {
703
        "name": "The Apache Software License, Version 2.0",
704
        "url": "https://www.apache.org/licenses/LICENSE-2.0.txt",
705
        "spdx": "Apache-2.0"
706
      }
707
    ],
708
    "copyright": "greenrobot",
709
    "source": "https://github.com/greenrobot/EventBus",
710
    "homepage": " https://greenrobot.org/eventbus/",
711
    "developers": [
712
      "greenrobot"
713
    ]
714
  },
715
  {
716
    "group": "org.slf4j",
717
    "artifact": "slf4j-api",
718
    "version": "2.1.0-alpha1",
719
    "url": "https://mvnrepository.com/artifact/org.slf4j/slf4j-api/2.1.0-alpha1",
720
    "name": "SLF4J API Module",
721
    "licenses": [
722
      {
723
        "name": "MIT License",
724
        "url": " http://www.opensource.org/licenses/mit-license.php",
725
        "spdx": "MIT"
726
      }
727
    ],
728
    "copyright": "",
729
    "source": "",
730
    "homepage": " http://www.slf4j.org",
731
    "developers": [
732
      "Ceki Gulcu"
733
    ]
734
  },
735
  {
736
    "group": "org.slf4j",
737
    "artifact": "slf4j-nop",
738
    "version": "2.0.17",
739
    "url": "https://mvnrepository.com/artifact/org.slf4j/slf4j-nop/2.0.17",
740
    "name": "SLF4J NOP Provider",
741
    "licenses": [
742
      {
743
        "name": "MIT",
744
        "url": " https://opensource.org/license/mit",
745
        "spdx": "MIT"
746
      }
747
    ],
748
    "copyright": "",
749
    "source": "",
750
    "homepage": " http://www.slf4j.org",
751
    "developers": [
752
      "Ceki Gulcu"
753
    ]
754
  },
755
  {
756
    "group": "info.picocli",
757
    "artifact": "picocli",
758
    "version": "4.7.7",
759
    "url": "https://mvnrepository.com/artifact/info.picocli/picocli/4.7.7",
760
    "name": "picocli",
761
    "licenses": [
762
      {
763
        "name": "The Apache Software License, version 2.0",
764
        "url": "http://www.apache.org/licenses/LICENSE-2.0.txt",
765
        "spdx": "Apache-2.0"
766
      }
767
    ],
768
    "copyright": "",
769
    "source": "https://github.com/remkop/picocli/tree/master",
770
    "homepage": " https://picocli.info",
771
    "developers": [
772
      "Remko Popma"
773
    ]
774
  },
775
  {
776
    "group": "org.jspecify",
777
    "artifact": "jspecify",
778
    "version": "1.0.0",
779
    "url": "https://mvnrepository.com/artifact/org.jspecify/jspecify/1.0.0",
780
    "name": "JSpecify annotations",
781
    "licenses": [
782
      {
783
        "name": "The Apache License, Version 2.0",
784
        "url": "http://www.apache.org/licenses/LICENSE-2.0.txt",
785
        "spdx": "Apache-2.0"
786
      }
787
    ],
788
    "copyright": "",
789
    "source": "https://github.com/jspecify/jspecify/",
790
    "homepage": " http://jspecify.org/",
791
    "developers": [
792
      "Kevin Bourrillion"
793
    ]
794
  },
795
  {
796
    "group": "com.google.errorprone",
797
    "artifact": "error_prone_annotations",
798
    "version": "2.41.0",
799
    "url": "https://mvnrepository.com/artifact/com.google.errorprone/error_prone_annotations/2.41.0",
800
    "name": "error-prone annotations",
801
    "licenses": [
802
      {
803
        "name": "Apache 2.0",
804
        "url": "http://www.apache.org/licenses/LICENSE-2.0.txt",
805
        "spdx": "Apache-2.0"
806
      }
807
    ],
808
    "copyright": "",
809
    "source": "",
810
    "homepage": "",
811
    "developers": [
812
      "Eddie Aftandilian"
813
    ]
814
  },
815
  {
816
    "group": "org.openjfx",
817
    "artifact": "javafx-swing",
818
    "version": "24.0.2",
819
    "url": "https://mvnrepository.com/artifact/org.openjfx/javafx-swing/24.0.2",
820
    "name": "javafx swing",
821
    "licenses": [
822
      {
823
        "name": "GPLv2+CE",
824
        "url": " https://openjdk.java.net/legal/gplv2+ce.html",
825
        "spdx": "GPL-2.0-with-classpath-exception"
826
      }
827
    ],
828
    "copyright": "",
829
    "source": "",
830
    "homepage": " https://openjdk.java.net/projects/openjfx/",
831
    "developers": [
832
      "OpenJFX Mailing List"
833
    ]
834
  }
835
]
1836
D docs/metadata.md
1
# Document metadata
2
3
Document metadata is information about a document. Metadata often includes
4
a title, author name, copyright date, and keywords.
5
6
# Custom metadata
7
8
The following screenshot shows example metadata preferences:
9
10
![Metadata screenshot](images/screenshots/09.png)
11
12
The **Key** column lists metadata names and the **Value** column lists
13
the metadata content for each corresponding **Key**. The content may
14
include references to variable definitions. When the document is typeset,
15
the values for the variables will be substituted upon export.
16
17
When the document is exported as XHTML, the header will include the
18
keys and values conforming to the XHTML specification. For example:
19
20
``` html
21
<head>
22
  <title>Document Title</title>
23
  <meta content="science, nature" name="keywords"/>
24
  <meta content="Penn Surnom" name="author"/>
25
  <meta content="4311" name="count"/>
26
</head>
27
```
28
29
# Special metadata
30
31
When exporting the document, note the following special metadata:
32
33
* **author** -- Included as PDF metadata
34
* **byline** -- Replaces author in PDF metadata (e.g., for pen names)
35
* **count** -- Total word count in document, automatically included
36
* **keywords** -- Included as PDF metadata
37
* **title** -- Included as a `<title>` tag, rather than a `<meta>` tag
38
391
A docs/metadata.yaml
1
document:
2
  title: "{{app.title}}"
3
  subtitle: User Manual
4
  copyright: White Magic Software, Ltd.
5
app:
6
  title: KeenWrite
7
  classes:
8
    processors:
9
      markdown: MarkdownProcessor
10
      variable:
11
        definition: DefinitionProcessor
12
      preview: PreviewProcessor
13
  palette:
14
    primary:
15
      light: '#51a9cf'
16
      dark: '#126d95'
17
    secondary:
18
      light: '#ec706a'
19
      dark: '#7e252f'
20
    accent:
21
      light: '#76A786'
22
      dark: '#385742'
23
    grayscale:
24
      light: '#bac2c5'
25
      dark: '#394343'
26
  graph:
27
    label:
28
      chain:
29
        next: successor
30
fonts:
31
  protocol: 'https'
32
  server: 'fonts.keenwrite.com'
33
  path: '/download'
34
  url: "{{fonts.protocol}}://{{fonts.server}}/{{fonts.path}}"
35
36
repository:
37
  protocol: 'https'
38
  server: 'repo.autonoma.ca'
39
  url: "{{repository.protocol}}://{{repository.server}}"
40
41
install:
42
  java: "keenwrite.jar"
43
  config:
44
    unix: "${HOME}/.local/share/keenwrite"
45
    win: "C:\\Users\\%USERNAME%\\AppData\\Roaming\\keenwrite"
46
  mac:
47
    native: "keenwrite.app"
48
    java: "{{install.unix.java}}"
49
  unix:
50
    native: "keenwrite.bin"
51
    java: "keenwrite.sh"
52
  win:
53
    native: "keenwrite.exe"
54
    java: "keenwrite.bat"
55
  path:
56
    unix:
57
      bin: "${HOME}/.local/bin"
58
  url:
59
    unix:
60
      launcher: "{{repository.url}}/keenwrite.git/raw/HEAD/scripts/{{install.unix.java}}"
61
    windows:
62
      script: "{{repository.url}}/keenwrite.git/raw/HEAD/{{install.win.java}}"
63
      path: "{{repository.url}}/keenwrite.git/raw/HEAD/scripts/localpath.bat"
64
65
skins:
66
  url:
67
    main: "{{repository.url}}/keenwrite.git/tree/main/src/main/resources/com/keenwrite/skins"
68
    markdown: "{{repository.url}}/keenwrite.git/blob/main/src/main/resources/com/keenwrite/editor/markdown.css"
69
170
D docs/quotes.md
1
# Quotation marks
2
3
When converting straight single quotes into curled single quotes, the
4
application offers a variety of entities to use for encoding:
5
6
* **regular** -- Do not encode.
7
* **modifier** -- Encode as \&#x2bc;, the modifier letter apostrophe.
8
* **apos** -- Encode as \&apos;, curled when typeset to PDF.
9
* **aposhex** -- Encode as \&#x27;, the apostrophe's numeric value.
10
* **quote** -- Encode as \&rsquo;, the right single quotation mark, which
11
is typically curled in HTML and XHTML documents by default.
12
* **quotehex** -- Encode \&#8217;, the right single quotation mark's numeric
13
value.
14
15
When typsetting into a PDF document, only the semantically correct value
16
of \&apos; will be curled automatically.
17
18
# History
19
20
Quotation marks trace back to Ancient Greek, later adopted to the diplé (⸖)
21
circa 625 BCE, foreshadowing its later curve. By the seventeenth century,
22
quotation marks grew common. During the nineteenth century, Western Europe
23
turned the convexity of quotation mark pairs outward.
24
25
Early mechanical typewriters, circa 1825, lacked many punctuation marks. As
26
technology improved, additional keys were added while some keys played dual
27
roles (such as I for 1). Straight single and double quotes could be co-opted
28
for quotation marks and apostrophes, feet and inches marks, and primes and
29
double-primes. There wasn't a pressing need to type curled versions because
30
humans excel at understanding from context.
31
32
Eventually straight quotes were codified for computers. Unfortunately, the
33
apostrophe carried with it the baggage from typewriters. That is, burgeoning
34
encoding standards failed to let users capture the nuances of the English
35
language; computers forced users to treat the apostrophe as a straight quote.
36
Standards bodies suggested using the right single quotation mark for an
37
apostrophe instead, shirking off its semantic meaning. Consequently,
38
text containing English quotations, especially British English, is now
39
riddled with ambiguity.
40
41
Consider the sentence:
42
43
> Ambiguity lurks in "'cause the horses'".
44
45
Does `'cause` mean _because_ or _induce_? The answer determines whether
46
an open left single quote is used or an apostrophe, semantically speaking.
47
It's amazing how ancient decisions still affect modern systems.
48
491
D docs/r.md
1
# Introduction
2
3
This document describes how to use the [R](https://www.r-project.org/)
4
programming language from within the application. The application uses an
5
interpreter known as [Renjin](https://www.renjin.org/) to integrate with R.
6
7
# Hello world
8
9
Complete the following steps to see R in action:
10
11
1. Start the application.
12
1. Click **File → New** to create a new file.
13
1. Click **File → Save As**.
14
1. Set **Name** to: `addition.Rmd`
15
1. Click **Save**.
16
17
Setting the file name extension tells the application what processor to
18
use when transforming the contents for display in the preview pane. Continue
19
by typing in the following text, including the backticks:
20
21
```r
22
`r#1 + 1`
23
```
24
25
The preview pane shows the result of `1` plus `1`:
26
27
```
28
2.0
29
```
30
31
# Bootstrap script
32
33
Being able to run R code while editing an R Markdown document is convenient.
34
Having the ability to call functions is where the power of R can be
35
leveraged.
36
37
Complete the following steps to call an R function from your own library:
38
39
1. Click **File → New** to create a new file.
40
1. Click **File → Save As**.
41
1. Browse to your home directory.
42
1. Set **Name** to: `library.R`.
43
1. Click **Save**.
44
1. Set the contents to:
45
    ``` r
46
    sum <- function( a, b ) {
47
      a + b
48
    }
49
    ```
50
1. Click the **Save** icon.
51
1. Click **R → Script**.
52
1. Set the **R Startup Script** contents to:
53
    ``` r
54
    source( 'library.R' );
55
    ```
56
1. Click **OK**.
57
1. Create a new file.
58
1. Set the contents to:
59
    ``` r
60
    `r#sum( 5, 5 )`
61
    ```
62
1. Save the file as `sum.R`.
63
64
The preview panel shows the result of calling the `sum` function:
65
66
```
67
10.0
68
```
69
70
This shows how the bootstrap script can load `library.R`, which defines
71
a `sum` function that is called by name in the Markdown document.
72
73
# Working directory
74
75
R files may be sourced from any directory, not just the user's home
76
directory. Accomplish this as follows:
77
78
1. Click **R → Directory**.
79
1. Set **Directory** to a different directory.
80
1. Click **OK**.
81
1. Create the directory if it does not exist.
82
1. Move `library.R` into the directory.
83
1. Append a new function to `library.R` as follows:
84
    ``` r
85
    mul <- function( a, b ) {
86
      a * b
87
    }
88
    ```
89
1. Click **R → Script**.
90
1. Set the **R Startup Script** contents to:
91
    ``` r
92
    setwd( v$application$r$working$directory );
93
    source( "library.R" );
94
    ```
95
1. Change `sum.Rmd` to:
96
    ``` r
97
    `r#mul( 5, 5 )`
98
    ```
99
1. Close the file `sum.Rmd`.
100
1. Confirm saving the file when prompted.
101
1. Re-open `sum.Rmd`.
102
103
The preview panel shows:
104
105
```
106
25.0
107
```
108
109
Calling `setwd` using `v$application$r$working$directory` changes the
110
working directory where the R engine searches for source files.
111
112
# YAML variable definitions
113
114
To see how variable definitions work in R, try the following:
115
116
1. Create a new file.
117
1. Change the contents to (use spaces not tabs):
118
    ``` yaml
119
    project:
120
      title: Project Title
121
      author: Author Name
122
    ```
123
1. Save the file as `definitions.yaml`.
124
1. Click **File → Open**.
125
1. Set **Source Files** to **Variable Files**.
126
1. Select `definitions.yaml`.
127
1. Click **Open**.
128
1. Open `sum.Rmd` if it is not already open.
129
1. Type: `je`
130
1. Press `Ctrl+Space`
131
132
The editor inserts the following text (matches `je` against Pro**je**ct):
133
134
``` r
135
`r#x( v$project$title )`
136
```
137
138
The preview panel shows:
139
140
```
141
r#x( 'Project Title' )
142
```
143
144
This is because the application inserts variable reference names based
145
on the type of file being edited. By default, the R engine does not have
146
a function named `x` defined.
147
148
Continue as follows:
149
150
1. Click **R → Script**.
151
1. Append the following:
152
    ``` r
153
    x <- function( s ) {
154
      tryCatch( {
155
        r = eval( parse( text = s ) )
156
157
        ifelse( is.atomic( r ), r, s );
158
      },
159
      warning = function( w ) { s },
160
      error = function( e ) { s } )
161
    }
162
    ```
163
1. Click **OK**.
164
1. Close and re-open `sum.Rmd`.
165
166
The preview panel shows:
167
168
```
169
25.0
170
171
Project Title
172
```
173
174
The `x` function attempts to evaluate the expression defined by the YAML
175
variable. This means that the YAML variables can also include expressions
176
that R is capable of evaluating.
177
178
While the `x` function can be defined within the R Startup Script, it is
179
better practice to put it into its own library so that it can be reused
180
outside of the application.
181
1821
D docs/references.md
1
# Captions and cross-references
2
3
Users may define captions and cross-references to tables, figures,
4
and equations. Unfortunately, at time of writing, the CommonMark
5
specification is frozen. This means cross-references must be implemented
6
as an extension to the Markdown specification, leaving the door open for
7
differing Markdown rendering libraries and applications to diverge with
8
respect to syntax.
9
10
# Syntax
11
12
This section describes how to use captions and cross-references within
13
Markdown documents. The CommonMark standard details different ways to
14
add captions to tables and figures. While those are supported, a more
15
consistent syntax has been implemented.
16
17
## Captions
18
19
Tables, figures, and equations are captioned using the same syntax. In
20
general, a line that starts with a double colon after a blank line will
21
result in a caption added to the item immediately preceding it. The
22
remainder of this section provides examples.
23
24
### Images
25
26
An image caption:
27
28
```
29
![image title](https://loremflickr.com/600/350)
30
31
:: Figure caption text
32
```
33
34
### Table
35
36
A table caption:
37
38
```
39
| a | b | c |
40
|---|---|---|
41
| 1 | 2 | 3 |
42
| 4 | 5 | 6 |
43
| 7 | 8 | 9 |
44
45
:: Table caption text
46
```
47
48
### Equation
49
50
An equation caption:
51
52
```
53
$$E = mc^2$$
54
55
:: Equation caption
56
```
57
58
# Cross-references
59
60
There are two parts to a cross-reference: the anchor name and its references.
61
An anchor name must be uniquely defined. Any number of references may refer
62
to an anchor name. Anchor names can be associated with any item in the
63
document, and are primarily added to captions.
64
65
The general syntax for anchor names and references is:
66
67
* `{#type-name:label}` (anchor name)
68
* `[@type-name:label]` (reference)
69
70
The `type-name` can be any alphanumeric value, starting with a letter or
71
ideogram. Type names are user-defined categories for the item type. Labels
72
are user-defined identifiers that must be unique per item.
73
74
Consider the following example:
75
76
```
77
In [@fig:animal], a cute animal is shown.
78
79
![image title](https://loremflickr.com/600/350)
80
81
:: World's cutest animal {#fig:animal}
82
83
There is no cuter animal than the one in [@fig:animal].
84
```
85
86
The anchor name uniquely defines where an item in a document is located. Any
87
number of references, anywhere in the document, may reference an anchor name.
88
There are few restrictions placed on the possible type names and labels. Here
89
are a few more anchor name examples:
90
91
```
92
{#fig:cats}
93
{#図版:猫}
94
{#eq:mass-energy}
95
{#eqn:laplace}
96
```
97
98
## Type names
99
100
To avoid duplicating writing the label each time (e.g., Figure, Table,
101
Equation), there are a number of predefined labels associated with
102
type names. The following table lists the type names and the label
103
generated by the typesetting system:
104
105
| Type name | English name |
106
|-----------|--------------|
107
| algorithm | Algorithm    |
108
| alg       | Algorithm    |
109
| equation  | Equation     |
110
| eqn       | Equation     |
111
| eq        | Equation     |
112
| figure    | Figure       |
113
| fig       | Figure       |
114
| formula   | Formula      |
115
| listing   | Listing      |
116
| list      | Listing      |
117
| lst       | Listing      |
118
| lyric     | Lyrics       |
119
| music     | Score        |
120
| score     | Score        |
121
| source    | Listing      |
122
| src       | Listing      |
123
| tab       | Table        |
124
| table     | Table        |
125
| tbl       | Table        |
126
127
These values are defined in the theme's `xhtml/xml-references.tex` file.
1281
D docs/screenshots.md
1
# Variables
2
3
Diagrams that include variables:
4
5
![GraphViz diagram screenshot](images/screenshots/01.png)
6
7
![Family tree diagram screenshot](images/screenshots/05.png)
8
9
# PDF themes
10
11
In the background of the following screenshot, the editor shows a novel
12
being edited:
13
14
![PDF themes](images/screenshots/08.png)
15
16
Highlighted items of note:
17
18
* PDF icon in the upper-left
19
* Novel metadata as integrated variables towards the top-left
20
* Theme selection dialog in the upper-middle
21
* Three different styles, including:
22
    * Boschet, based on Baskerville font, nicely styled
23
    * Handrit, based on Courier font, double-spaced, manuscript format
24
    * Tarmes, based on Times Roman font, minimal styling
25
* Variations in page numbers
26
* Manuscript includes word count, automatically
27
* Preferences dialog in the middle
28
29
# Internationalization
30
31
Poem with locale settings:
32
33
![Korean poem screenshot](images/screenshots/02.png)
34
35
# Equations
36
37
TeX equations with detached preview:
38
39
![TeX equations screenshot](images/screenshots/03.png)
40
41
# Dockable tabs
42
43
Document outline opened and docked in bottom-left corner:
44
45
![Document outline](images/screenshots/04.png)
46
471
D docs/skins.md
1
# Skins
2
3
The application provides bundled skins and the ability to add custom
4
skins. This document describes the interplay between bundled skins
5
and building your own look and feel.
6
7
A skin is a set of styles, similar to cascading style sheet classes,
8
that configures the user interface colours, fonts, spacing, highlights,
9
drop-shadows, gradients, and more.
10
11
For more information on CSS, see the [W3C CSS tutorial](https://www.w3.org/Style/Examples/011/firstcss).
12
13
# Order
14
15
The order that stylesheets are applied matters so that stylesheets can
16
override styles defined previously. The application's user interface
17
is made up of the following stylesheets, applied in the order listed:
18
19
* **scene.css** --- Defines toolbar styling.
20
* **markdown.css** --- Defines text editor styling.
21
* **skins/skin_name.css** --- Bundled skin selected in preferences.
22
* **custom.css** --- User-defined file set in preferences.
23
24
# Customization
25
26
Create a custom skin as follows:
27
28
1. Start the application.
29
1. Click **File → New** to create a new file.
30
1. Click **File → Save As** to rename the file.
31
1. Save the file as `custom.css`.
32
1. Change the content to the following:
33
``` css
34
.root {
35
  -fx-base: rgb( 30, 30, 30 );
36
  -fx-background: -fx-base;
37
}
38
```
39
40
Next, apply the skin as follows:
41
42
1. Click **Edit → Preferences** to open the preferences dialog.
43
1. Click **Skins** to view the available options.
44
1. Click **Browse** to select a custom file.
45
1. Browse to and select `custom.css`, created previously.
46
1. Click **Open**.
47
1. Click **Apply**.
48
49
The user interface immediately changes to a dark mode. Continue:
50
51
1. Click **OK** to close the dialog.
52
1. Change the **rgb** numbers in **custom.css** from `30` to `60`.
53
1. Click **File → Save** to save the CSS file.
54
55
The user interface immediately changes colour.
56
57
# Classes
58
59
When creating your own skin, there many classes that can be styled. The
60
previous section showed how to set up a rudimentary skin. Instead, start
61
with a template that already has a number of classes defined so that you
62
can tweak them to your taste. Accomplish this as follows:
63
64
1. Visit the [skin](https://gitlab.com/DaveJarvis/KeenWrite/-/tree/main/src/main/resources/com/keenwrite/skins) repository directory
65
1. Click one of the files (e.g., `haunted_grey.css`).
66
1. Click **Raw**.
67
1. Copy the entire text.
68
1. Return to `custom.css`.
69
1. Delete the contents.
70
1. Paste the copied text.
71
1. Save the file.
72
73
To see how the CSS styles are applied to the text editor, open
74
[markdown.css](https://gitlab.com/DaveJarvis/KeenWrite/-/blob/main/src/main/resources/com/keenwrite/editor/markdown.css), which is also in the repository.
75
76
# Modena
77
78
The basic look used by the application is _Modena Light_. Typically we
79
only need to override a few classes to completely change the application's
80
look and feel. For a full listing of available styles see the OpenJDK's
81
[Modena CSS file](https://github.com/openjdk/jfx/blob/master/modules/javafx.controls/src/main/resources/com/sun/javafx/scene/control/skin/modena/modena.css).
82
83
# JavaFX CSS
84
85
The [Java CSS Reference Guide](https://openjfx.io/javadoc/21/javafx.graphics/javafx/scene/doc-files/cssref.html) is exhaustive. In addition to showing many
86
differences between JavaFX CSS and W3C CSS, the guide introduces numerous
87
helpful functions for manipulating colours and gradients using existing
88
colour definitions.
89
90
# RichTextFX
91
92
The application uses RichTextFX to render the text editor. Styling various
93
text editor classes can require using the prefix `-rtfx` instead of the
94
regular JavaFX `-fx`.
95
96
# Submit
97
98
If you have a look that you'd like to contribute to the project, do pass
99
it along. Either open a new issue in the [issue tracker](https://gitlab.com/DaveJarvis/KeenWrite/-/issues) that contains the CSS file or submit a pull request.
100
1011
D docs/svg.md
1
# Introduction
2
3
The Scalable Vector Graphics (SVG) drawing software---[Batik](https://xmlgraphics.apache.org/batik/)---that's used by the application may be unable to read certain SVG files produced by [Inkscape](https://inkscape.org/). The result is that embedding the vector graphics files may trigger the following issues:
4
5
* Unable to create nested element
6
* Black blocks, no text displayed
7
* Black text instead of coloured
8
9
The remainder of this document explains these problems and how to fix them.
10
11
# Nested element
12
13
When referencing a vector graphic using Markdown, the status bar may show the following error:
14
15
> The current document is unable to create an element of the requested type (namespace: http://www.w3.org/2000/svg, name: flowRoot).
16
17
This error is due to a version mismatch of the `flowRoot` element that Inkscape creates.
18
19
## Fix
20
21
Resolve the issue by changing the SVG version number as follows:
22
23
1. Edit the vector graphics file using any text editor.
24
1. Find `version="1.1"` and change it to `version="1.2"`.
25
1. Save the file.
26
27
The SVG will now appear inside the application; however, the text may appear as black blocks.
28
29
# Black blocks
30
31
Depending on how text is added to a vector graphic in Inkscape, the text may be inserted within an element called a `flowRoot`. Although Batik recognizes `flowRoot` for SVG version 1.2, it cannot fully interpret the contents. Black blocks are drawn instead of the text, such as those depicted in the following figure:
32
33
![Missing text](images/blocked-text.png)
34
35
## Fix
36
37
Resolve the issue by "unflowing" all text elements as follows:
38
39
1. Start Inkscape.
40
1. Load the SVG file.
41
1. Select all the text elements.
42
1. Click **Text → Unflow**.
43
44
The text may change size and position; recreate the text without dragging using the text tool. After all the text areas have been recreated, continue as follows:
45
46
1. Click **Edit → XML Editor**.
47
1. Expand the **XML Editor** to see more elements.
48
1. Delete all elements named `svg:flowRoot`.
49
1. Save the file.
50
51
When the illustration is reloaded, the black blocks will have disappeared, but the text elements ignore any assigned colour.
52
53
# Black text
54
55
When an SVG `style` attribute contains a reference to `-inkscape-font-specification`, Batik ignores all values that follow said reference. This results in black text, such as:
56
57
![Black text](images/black-text.png)
58
59
## Fix
60
61
Resolve the issue of colourless text as follows:
62
63
1. Open the SVG file in a plain text editor.
64
1. Remove all references `-inkscape-font-specification:'<FONT>';`, including the trailing (or leading) semicolon.
65
1. Save the file.
66
67
When the illustration is reloaded, the colours will have reappeared, such as:
68
69
![Resolved text](images/resolved-text.png)
70
711
D docs/typesetting-custom.md
1
# Overview
2
3
Typesetting PDF files entails the following:
4
5
* Download and install typesetting software
6
* Download a theme pack
7
8
These are described in the subsequent sections. Once the requirements have been met, continue reading to learn how to typeset a document.
9
10
# Download typesetter
11
12
Download the typesetting software as follows:
13
14
1. Start the text editor.
15
1. Click **File → Export As → PDF**.
16
    * Note the following details (e.g., Windows X86 64-bit):
17
        * operating system name;
18
        * instruction set; and
19
        * architecture.
20
1. Click the [link](https://wiki.contextgarden.net/Installation) in the dialog.
21
1. Download the appropriate archive file.
22
23
# Install typesetter
24
25
This section describes the installation steps for various platforms. Follow the steps that apply to the computer's operating system:
26
27
* [Windows](#windows) (includes Windows 7, Windows 10, and similar)
28
* [Unix](#unix) (includes MacOS, FreeBSD, Linux, and similar)
29
30
## Windows
31
32
Proceed with a Windows installation of the typesetting software as follows:
33
34
1. Extract the `.zip` file into `C:\Users\%USERNAME%\AppData\Local\context` (the "root" directory)
35
1. Run **install.bat** to download and install the software.
36
    * If prompted, click **Run anyway** (or click **More info** first).
37
1. Right-click [localpath.bat](https://gitlab.com/DaveJarvis/KeenWrite/-/raw/main/scripts/localpath.bat).
38
1. Select **Save Link As** (or similar).
39
1. Save the file to the typesetting software's "root" directory.
40
1. Rename `localpath.bat.txt` to `localpath.bat`, if necessary.
41
1. Run `localpath.bat` (to set and save the `PATH` environment variable).
42
43
Installation is complete. Verify the installation as follows:
44
45
1. Type: `context --version`
46
1. Press `Enter`.
47
48
If version information is displayed then the software is installed correctly.
49
50
Continue by installing a [theme pack](#theme-pack).
51
52
## Unix
53
54
For Linux, MacOS, FreeBSD, and similar operating systems, proceed as follows:
55
56
1. Create `$HOME/.local/bin/context`
57
1. Extract the `.zip` file within `$HOME/.local/bin/context`
58
1. Run `sh install.sh`
59
1. Add `export PATH=$PATH:$HOME/.local/bin/context/tex/texmf-linux-64/bin` to the login script.
60
61
Installation is complete. Verify the installation as follows:
62
63
1. Open a new terminal (to export the new PATH setting).
64
1. Type: `context --version`
65
1. Press `Enter`.
66
67
If version information is displayed then the software is installed correctly.
68
69
Continue by installing a [theme pack](#theme-pack).
70
71
# Theme pack
72
73
A theme pack is a set of themes that define how documents appear when typeset. Broadly, themes are applied as follows:
74
75
* Install a theme pack
76
* Configure individual themes
77
78
## Install theme pack
79
80
Install and configure the default theme pack as follows:
81
82
1. Download the <a href="https://gitlab.com/DaveJarvis/keenwrite-themes/-/releases/permalink/latest/downloads/theme-pack.zip">theme-pack.zip</a> archive.
83
1. Extract archive into a known location.
84
1. Start the text editor, if not already running.
85
1. Click **Edit → Preferences**.
86
1. Click **Typesetting**.
87
1. Click **Browse** beside **Themes**.
88
1. Navigate to the `themes` directory.
89
1. Click **Open**.
90
1. Click **OK**.
91
92
The theme pack is installed.
93
94
Each theme has its own requirements, described below. 
95
96
## Configure Boschet theme
97
98
Download and install the following font families:
99
100
* [Libre Baskerville](https://fonts.google.com/specimen/Libre+Baskerville)
101
* [Archivo Narrow](https://fonts.google.com/specimen/Archivo+Narrow)
102
* [Inconsolata](https://fonts.google.com/specimen/Inconsolata)
103
104
The theme is configured.
105
106
# Typeset single document
107
108
Typeset a document as follows:
109
110
1. Start the text editor, if not already running.
111
1. Click **File → New** (or type `Ctrl+n`).
112
1. Type in some text.
113
1. Click **File → Export As → PDF** (or type `Ctrl+p`).
114
1. Select a theme from the drop-down list.
115
1. Click **OK** (or press `Enter`).
116
1. Set the **File name** to the PDF file name.
117
1. Click **Save**.
118
119
The document is typeset; open the PDF file in a PDF reader to view the result.
120
121
# Typeset multiple documents
122
123
Typeset multiple documents similar to single documents, with one difference:
124
125
* Click **File → Export As → Joined PDF** (or type `Ctrl+Shift+p`).
126
127
All documents having the same file name extension in the same directory
128
(or sub-directories) as the actively edited file are first concatenated then
129
typeset into a single PDF document. The order that files are concatenated
130
is numeric and alphabetic.
131
132
For example, if `1.Rmd` is a sibling of the following files in the same
133
directory, then all the files will be included in the PDF, as expected:
134
135
    chapter_1.Rmd
136
    chapter_2.Rmd
137
    chapter_2a.Rmd
138
    chapter_2b.Rmd
139
    chapter_3.Rmd
140
    chapter_10.Rmd
141
142
Basically, sorting honours numbers and letters in file names.
143
144
# Background 
145
146
This text editor helps keep content separated from presentation. Plain text documents will remain readable long after proprietary formats have become obsolete. However, we've come to expect much more in what we read than mere text: from hyperlinked tables of contents to indexes, from footers to footnotes, from mathematical expressions to complex graphics, modern documents are nuanced and multifaceted.
147
148
## History
149
150
Before computer-based typesetting, much of mathematics was put to page by hand. Professional typesetters, who were often expensive and usually not mathematicians, would inadvertently introduce typographic errors into equations. Phototypesetting technology improved upon hand-typesetting, but well-known computer scientist Donald Knuth---whose third volume of *The Art of Computer Programming* was phototypeset in 1976---expressed dissatisfaction with its typographic quality. He set himself two goals: let anyone create high-quality books without much effort and provide software that typesets consistently on all capable computers. Two years later, he released a typesetting system and a font description language: TeX and METAFONT, respectively.
151
152
In short, TeX is software that helps typeset plain text documents.
153
154
## ConTeXt
155
156
Programming computers to typeset internationalized text automatically at the level we've become accustomed takes decades of development effort. Many free and open source software solutions can typeset text, including: ConTeXt, LaTeX, Sile, and others. ConTeXt, which builds upon TeX, is ideal for typesetting plain text into beautiful documents because it is developed with a notion of *setups*. These setups can wholly describe how text is to be typeset and---by being external to the text itself---configuring setups provides ample control over the document's final appearance without changing the prose.
157
158
# Further reading
159
160
Here are a few documents that introduce the typesetting system:
161
162
* [What is ConTeXt?](https://www.pragma-ade.com/general/manuals/what-is-context.pdf)
163
* [A not so short introduction to ConTeXt](https://github.com/contextgarden/not-so-short-introduction-to-context)
164
* [Dealing with XML in ConTeXt MKIV](https://pragma-ade.com/general/manuals/xml-mkiv.pdf)
165
* [Typographic Programming](https://www.pragma-ade.com/general/manuals/style.pdf)
166
167
The [documentation library](https://wiki.contextgarden.net/Documentation) includes the following gems:
168
169
* [ConTeXt Manual](https://www.pragma-ade.nl/general/manuals/ma-cb-en.pdf)
170
* [ConTeXt command reference](https://www.pragma-ade.nl/general/qrcs/setup-en.pdf)
171
* [METAFUN Manual](https://www.pragma-ade.nl/general/manuals/metafun-p.pdf)
172
* [It's in the Details](https://www.pragma-ade.nl/general/manuals/details.pdf)
173
* [Fonts out of ConTeXt](https://www.pragma-ade.com/general/manuals/fonts-mkiv.pdf)
174
175
Expert-level documentation includes the [LuaTeX Reference Manual](https://www.pragma-ade.nl/general/manuals/luatex.pdf).
176
1771
D docs/typesetting.md
1
# Typesetting
2
3
The application uses the [ConTeXt](https://contextgarden.net) typesetting
4
system, the [podman](https://podman.io/) container manager, various
5
[themes](https://gitlab.com/DaveJarvis/keenwrite-themes), and numerous
6
fonts to produce high-quality PDF files. The container manager significantly
7
reduces the number of manual steps in the installation process.
8
9
When exporting a document to a PDF file for the first time, a series of
10
semi-automated steps guides users through the installation process. These
11
steps differ depending on the operating system.
12
13
Run the installation wizard as follows:
14
15
1. Start the application.
16
1. Click **File → Export As → PDF**.
17
18
Follow the steps in the wizard to install the requisite software and
19
typesetting themes.
20
211
A docs/user-manual.pdf
Binary file
D docs/variables.md
1
# Introduction
2
3
This document describes how to use the application.
4
5
# Variable definitions
6
7
Variable definitions provide a way to insert key names having associated values into a document. The variable names and values are declared inside an external file using the [YAML](http://www.yaml.org/) file format. Simply put, variables are written in the file as follows:
8
9
```
10
key: value
11
```
12
13
Any number of variables can be defined, in any order:
14
15
```
16
key_1: Value 1
17
key_2: Value 2
18
```
19
20
Variables can reference other variables by bookending the key name within symbols:
21
22
```
23
key: Value
24
key_1: {{key}} 1
25
key_2: {{key}} 2
26
```
27
28
Variables can use a nested structure to help group related information:
29
30
```
31
novel:
32
  title: Book Title
33
  author: Author Name
34
  isbn: 978-3-16-148410-0
35
```
36
37
Use a period to reference nested keys, such as:
38
39
```
40
novel:
41
  author: Author Name
42
copyright:
43
  owner: {{novel.author}}
44
```
45
46
Save the variable definitions in a file having an extension of `.yaml` or `.yml`.
47
48
# Document editing
49
50
The application's purpose is to completely separate the document's content from its presentation. To achieve this, documents are composed using a [plain text](http://spec.commonmark.org/0.28/) format.
51
52
## Create document
53
54
Start a new document as follows:
55
56
1. Start the application.
57
1. Click **File → New** to create an empty document to edit.
58
1. Click **File → Open** to open a variable definition file.
59
1. Change **Source Files** to **Variable Files** to list variable definition files.
60
1. Browse to and select a file saved with a `.yaml` or `.yml` extension.
61
1. Click **Open**.
62
63
The variable definitions appear in the variable definition pane under the heading of **Variables**.
64
65
## Edit document
66
67
Edit the document as normal. Notice how the preview pane updates as new content is added. The toolbar shows various icons that perform different formatting operations. Try them to see how they appear in the preview pane. Other operations not shown on the toolbar include:
68
69
* Struck text (enclose the words within `~~` and `~~`)
70
* Horizontal rule (use `---` on an otherwise empty line).
71
72
The preview pane shows one way to interpret and format the document, but many other presentations are possible.
73
74
## Insert variable
75
76
Let's assume that the variable definitions loaded into the application include:
77
78
```
79
novel:
80
  title: Diary of {{novel.author}}
81
  author: Anne Frank
82
```
83
84
To reference a variable, type in the key name enclosed within double braces, such as:
85
86
```
87
The novel "{{novel.title}}" is one of the most widely read books in the world.
88
```
89
90
The preview pane shows:
91
92
> The novel "Diary of Anne Frank" is one of the most widely read books in the world.
93
94
As it is laborious to type in variable names, it is possible to inject the variable name using autocomplete. Accomplish this as follows:
95
96
1. Create a new file.
97
1. Type in a partial variable value, such as **Dia**.
98
1. Press `Ctrl+Space` (hold down the `Control` key and tap the spacebar).
99
100
The editor shows:
101
102
```
103
{{novel.title}}
104
```
105
106
The preview pane shows:
107
108
```
109
Diary of Anne Frank
110
```
111
112
The variable name is inserted into the document and the preview pane shows the variable's value.
113
1141
M installer.sh
2121
readonly OPT_JAVA=$(cat << END_OF_ARGS
2222
-Dprism.order=sw \
23
--enable-native-access=javafx.graphics \
24
--sun-misc-unsafe-memory-access=allow \
2325
--add-opens=javafx.controls/javafx.scene.control=ALL-UNNAMED \
2426
--add-opens=javafx.controls/javafx.scene.control.skin=ALL-UNNAMED \
2527
--add-opens=javafx.graphics/javafx.scene.text=ALL-UNNAMED \
2628
--add-opens=javafx.graphics/com.sun.javafx.css=ALL-UNNAMED \
29
--add-opens=javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED \
2730
--add-opens=javafx.graphics/com.sun.javafx.text=ALL-UNNAMED \
2831
--add-exports=javafx.base/com.sun.javafx.event=ALL-UNNAMED \
...
6063
ARGUMENTS+=(
6164
  "a,arch,Target operating system architecture (amd64)"
62
  "o,os,Target operating system (linux, windows, macos)"
65
  "o,os,Target operating system (linux; windows; macos)"
6366
  "u,update,Java update version number (${ARG_JAVA_UPDATE})"
6467
  "v,version,Full Java version (${ARG_JAVA_VERSION})"
...
175178
utile_create_launch_script_linux() {
176179
  $log "Create Linux launch script"
180
181
  [[ -x $(command -v "grep") ]] && \
182
    local -r REDIRECT="2> >(grep -v -E \"^WARNING|Gdk-WARNING\" >&2)" || \
183
    local -r REDIRECT=""
177184
178185
  cat > "${FILE_LAUNCHER_SCRIPT}" << __EOT
179186
#!/usr/bin/env bash
180187
181188
readonly SCRIPT_SRC="\$(dirname "\${BASH_SOURCE[\${#BASH_SOURCE[@]} - 1]}")"
182
183
"\${SCRIPT_SRC}/${ARG_JAVA_DIR}/bin/java" ${OPT_JAVA} -jar "\${SCRIPT_SRC}/${FILE_APP_JAR}" "\$@"
189
"\${SCRIPT_SRC}/${ARG_JAVA_DIR}/bin/java" ${OPT_JAVA} -jar "\${SCRIPT_SRC}/${FILE_APP_JAR}" "\$@" ${REDIRECT}
184190
__EOT
185191
...
235241
# ---------------------------------------------------------------------------
236242
# Modify the Windows binary to include signed certificate information.
243
#
244
# Removed until funding for signing is secured.
237245
# ---------------------------------------------------------------------------
238246
utile_sign_windows() {
239
  local -r FILE_CERTIFICATE="${SCRIPT_DIR}/tokens/code-sign-cert.pfx"
240
  local -r FILE_BINARY="${APP_NAME}.exe"
241
  local -r FILE_SIGNED_BINARY="signed-${FILE_BINARY}"
242
243
  rm -f "${FILE_SIGNED_BINARY}"
244
245
  $log "Sign ${FILE_BINARY}"
246
  ${SCRIPT_DIR}/bin/osslsigncode sign \
247
    -pkcs12 "${FILE_CERTIFICATE}" \
248
    -askpass \
249
    -n "${APP_NAME}" \
250
    -i "https://www.${APP_NAME_LC}.com" \
251
    -in "${FILE_BINARY}" \
252
    -out "${FILE_SIGNED_BINARY}"
253
254
  $log "Rename ${FILE_SIGNED_BINARY} to ${FILE_BINARY}"
255
  mv -f "${FILE_SIGNED_BINARY}" "${FILE_BINARY}"
247
  1
256248
}
257249
M java.version
1
23.0.1+13
1
24.0.2+12
22
A keenwrite.bat
1
@echo off
2
3
set SCRIPT_DIR=%~dp0
4
5
java ^
6
  -Dprism.order=sw ^
7
  --enable-native-access=javafx.graphics ^
8
  --sun-misc-unsafe-memory-access=allow ^
9
  --add-opens=javafx.controls/javafx.scene.control=ALL-UNNAMED ^
10
  --add-opens=javafx.controls/javafx.scene.control.skin=ALL-UNNAMED ^
11
  --add-opens=javafx.graphics/javafx.scene.text=ALL-UNNAMED ^
12
  --add-opens=javafx.graphics/com.sun.javafx.css=ALL-UNNAMED ^
13
  --add-opens=javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED ^
14
  --add-opens=javafx.graphics/com.sun.javafx.text=ALL-UNNAMED ^
15
  --add-exports=javafx.base/com.sun.javafx.event=ALL-UNNAMED ^
16
  --add-exports=javafx.graphics/com.sun.javafx.application=ALL-UNNAMED ^
17
  --add-exports=javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED ^
18
  --add-exports=javafx.graphics/com.sun.javafx.text=ALL-UNNAMED ^
19
  --add-exports=javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED ^
20
  --add-exports=javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED ^
21
  --add-exports=javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED ^
22
  -jar "%SCRIPT_DIR%\keenwrite.jar" %* 2>&1
23
124
M keenwrite.sh
11
#!/usr/bin/env bash
22
3
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
3
readonly SCRIPT_SRC="$(dirname "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}")"
4
readonly SCRIPT_DIR="$(cd "${SCRIPT_SRC}" >/dev/null 2>&1 && pwd)"
45
56
java \
67
  -Dprism.order=sw \
8
  --enable-native-access=javafx.graphics \
9
  --sun-misc-unsafe-memory-access=allow \
710
  --add-opens=javafx.controls/javafx.scene.control=ALL-UNNAMED \
811
  --add-opens=javafx.controls/javafx.scene.control.skin=ALL-UNNAMED \
...
1821
  --add-exports=javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED \
1922
  --add-exports=javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED \
20
  -jar ${SCRIPT_DIR}/keenwrite.jar $@
23
  -jar "${SCRIPT_DIR}/keenwrite.jar" $@ 2> >(grep -v -E "Gdk-WARNING" >&2)
2124
2225
M libs/keenquotes.jar
Binary file
M libs/keenspell.jar
Binary file
A notes.sh
1
#!/usr/bin/env bash
2
3
release_notes() {
4
  if [ -z "$1" ]; then
5
    echo "Error: Provide a starting tag." >&2
6
    return 1
7
  fi
8
  readonly TAG_BEGAN=$1
9
  readonly TAG_ENDED=${2:-$(git describe --abbrev=0 --tags)}
10
  readonly REPO_URL="https://repo.autonoma.ca/keenwrite.git"
11
  readonly CURRENT_DATE=$(date +"%B %d, %Y")
12
13
  if [ -z "$TAG_ENDED" ]; then
14
    echo "Error: Could not determine end tag." >&2
15
    return 1
16
  fi
17
18
  # Get all tags between the two specified tags (inclusive of end, exclusive of start)
19
  local tags_between
20
  tags_between=$(git tag --sort=-version:refname --merged="$TAG_ENDED" | \
21
    awk "/$TAG_ENDED/{found=1; print} found && /$TAG_BEGAN/{exit} found")
22
23
  cat << EOF
24
# Release Notes
25
26
$CURRENT_DATE
27
28
Changes between $TAG_BEGAN and $TAG_ENDED.
29
30
EOF
31
32
  # If no intermediate tags, show all changes as one section
33
  if [ -z "$tags_between" ]; then
34
    local commits
35
    commits=$(git log --pretty=format:'* [%h]('$REPO_URL'/commit/%H) -- %s' --reverse "$TAG_BEGAN".."$TAG_ENDED")
36
    if [ -n "$commits" ]; then
37
      echo "## $TAG_ENDED"
38
      echo
39
      echo "$commits"
40
      echo
41
    fi
42
    return 0
43
  fi
44
45
  # Process each version section (newest first)
46
  local next_tag="$TAG_ENDED"
47
48
  # Add the starting tag to the list to ensure we capture everything
49
  tags_between=$(echo -e "$tags_between\n$TAG_BEGAN")
50
51
  while IFS= read -r current_tag; do
52
    [ -z "$current_tag" ] && continue
53
54
    # Get commits between current_tag and next_tag
55
    local commits
56
    commits=$(git log --pretty=format:'* [%h]('$REPO_URL'/commit/%H) -- %s' --reverse "$current_tag".."$next_tag")
57
58
    if [ -n "$commits" ]; then
59
      echo "## $next_tag"
60
      echo
61
      echo "$commits"
62
      echo
63
    fi
64
    next_tag="$current_tag"
65
  done <<< "$tags_between"
66
}
67
68
release_notes "$@"
69
170
M publish.sh
99
readonly APP_NAME=$(cut -d= -f2 ./src/main/resources/bootstrap.properties)
1010
readonly APP_NAME_LC=${APP_NAME,,}
11
readonly PATH_TOKEN="tokens/${APP_NAME_LC}.pat"
1211
readonly URL=$(cat "tokens/publish.url")
1312
readonly FILE_VERSION="version.txt"
1413
1514
# ---------------------------------------------------------------------------
1615
# Adds download URLs to a release.
1716
#
18
# $1 - The system (Linux, WIndows, MacOS, Java)
17
# $1 - The system (Linux, Windows, MacOS, Java)
1918
# ---------------------------------------------------------------------------
2019
release() {
2120
  local -r OS="${1}"
22
  local ARCH=" (64-bit, x86)"
2321
  local FILE_PREFIX="${APP_NAME_LC}"
2422
  local FILE_SUFFIX="bin"
...
3331
    ;;
3432
    Java)
35
      ARCH=""
3633
      FILE_SUFFIX="jar"
3734
    ;;
...
4441
4542
  upload "${BINARY}"
46
47
  glab release upload ${RELEASE} \
48
    --assets-links="[{
49
      \"name\":\"${APP_NAME} for ${OS}${ARCH}\",
50
      \"url\":\"https://${APP_NAME_LC}.com/downloads/${BINARY}\",
51
      \"link_type\":\"other\"
52
    }]"
5343
}
5444
...
6454
    scp "${FILENAME}" "${URL}"
6555
  else
66
    echo "Missing ${FILE_BINARY}, continuing."
56
    $log "Skipping ${FILE_BINARY} ..."
6757
  fi
6858
}
69
70
if [ -f "${PATH_TOKEN}" ]; then
71
  cat "${PATH_TOKEN}" | glab auth login --hostname gitlab.com --stdin
72
73
  glab release create ${RELEASE}
7459
75
  release "Windows"
76
  release "MacOS"
77
  release "Linux"
78
  release "Java"
60
release "Windows"
61
release "MacOS"
62
release "Linux"
63
release "Java"
7964
80
  echo "${RELEASE}" > "${FILE_VERSION}"
81
  upload "${FILE_VERSION}"
82
  mv "${FILE_VERSION}" "www/downloads"
83
else
84
  echo "Create ${PATH_TOKEN} before publishing the release."
85
fi
65
echo "${RELEASE}" > "${FILE_VERSION}"
66
upload "${FILE_VERSION}"
67
mv "${FILE_VERSION}" "www/downloads"
8668
8769
M release.sh
3636
  ${BIN_INSTALLER} -o macos
3737
38
  $log "Build Windows installer binary"
39
  ${BIN_INSTALLER} -o windows
38
  #$log "Build Windows installer binary"
39
  #${BIN_INSTALLER} -o windows
4040
}
4141
M src/main/java/com/keenwrite/AppCommands.java
2020
2121
import static com.keenwrite.events.StatusEvent.clue;
22
import static com.keenwrite.events.StatusEvent.fire;
2223
import static com.keenwrite.io.MediaType.TEXT_R_MARKDOWN;
2324
import static com.keenwrite.processors.ProcessorFactory.createProcessors;
...
130131
    final var concat = context.getConcatenate();
131132
    final var inputPath = context.getSourcePath();
132
    final var parent = inputPath.getParent();
133
    final var parent = inputPath.toAbsolutePath().getParent();
133134
    final var filename = SysFile.getFileName( inputPath );
134135
    final var extension = getExtension( filename );
...
141142
142143
    final var command = new ConcatenateCommand(
143
      parent, extension, context.getChapters() );
144
      filename, parent, extension, context.getChapters()
145
    );
144146
    return command.call();
145147
  }
M src/main/java/com/keenwrite/ExportFormat.java
55
package com.keenwrite;
66
7
import com.keenwrite.events.StatusEvent;
87
import com.keenwrite.io.MediaType;
98
import com.keenwrite.io.MediaTypeExtension;
...
4746
   */
4847
  TEXT_TEX( ".txt" ),
48
49
  /**
50
   * For Markdown exports, encode TeX using {@code $} delimiters.
51
   */
52
  TEXT_MARKDOWN( ".md" ),
4953
5054
  /**
...
115119
        ? XHTML_TEX_SVG
116120
        : XHTML_TEX;
121
      case TEXT_PLAIN, TEXT_MARKDOWN -> TEXT_TEX;
117122
      case APP_PDF -> APPLICATION_PDF;
118123
      default -> throw new IllegalArgumentException( format(
M src/main/java/com/keenwrite/MainPane.java
886886
   * When binning the files, this makes sure that at least one file exists
887887
   * for every type. If the user has opted to close a particular type (such
888
   * as the definition pane), the view will suppressed elsewhere.
888
   * as the definition pane), the view will suppress elsewhere.
889889
   * </p>
890890
   * <p>
M src/main/java/com/keenwrite/cmdline/Arguments.java
1616
import java.io.File;
1717
import java.io.IOException;
18
import java.nio.file.Files;
19
import java.nio.file.Path;
20
import java.util.HashMap;
21
import java.util.Locale;
22
import java.util.Map;
23
import java.util.Map.Entry;
24
import java.util.concurrent.Callable;
25
import java.util.function.Consumer;
26
27
import static com.keenwrite.constants.Constants.DIAGRAM_SERVER_NAME;
28
import static java.lang.String.format;
29
import static java.nio.charset.StandardCharsets.UTF_8;
30
import static java.nio.file.Files.*;
31
32
/**
33
 * Responsible for mapping command-line arguments to keys that are used by
34
 * the application.
35
 */
36
@CommandLine.Command(
37
  name = "KeenWrite",
38
  mixinStandardHelpOptions = true,
39
  description = "Plain text editor for editing with variables"
40
)
41
@SuppressWarnings( "unused" )
42
public final class Arguments implements Callable<Integer> {
43
  @CommandLine.Spec
44
  CommandLine.Model.CommandSpec mSpecifications;
45
46
  @CommandLine.Option(
47
    names = { "--all" },
48
    description =
49
      "Concatenate files before processing (${DEFAULT-VALUE})",
50
    defaultValue = "false"
51
  )
52
  private boolean mConcatenate;
53
54
  @CommandLine.Option(
55
    names = { "--keep-files" },
56
    description =
57
      "Retain temporary build files (${DEFAULT-VALUE})",
58
    defaultValue = "false"
59
  )
60
  private boolean mKeepFiles;
61
62
  @CommandLine.Option(
63
    names = { "-c", "--chapters" },
64
    description =
65
      "Export chapter ranges, no spaces (e.g., -3,5-9,15-)",
66
    paramLabel = "String"
67
  )
68
  private String mChapters;
69
70
  @CommandLine.Option(
71
    names = { "--curl-quotes" },
72
    description =
73
      "Encode quotation marks (see docs)",
74
    paramLabel = "String",
75
    defaultValue = "regular"
76
  )
77
  private String mCurlQuotes;
78
79
  @CommandLine.Option(
80
    names = { "-d", "--debug" },
81
    description =
82
      "Enable logging to the console (${DEFAULT-VALUE})",
83
    paramLabel = "Boolean",
84
    defaultValue = "false"
85
  )
86
  private boolean mDebug;
87
88
  @CommandLine.Option(
89
    names = { "-i", "--input" },
90
    description =
91
      "Source document path",
92
    paramLabel = "PATH",
93
    defaultValue = "stdin",
94
    required = true
95
  )
96
  private Path mSourcePath;
97
98
  @CommandLine.Option(
99
    names = { "--html-head" },
100
    description =
101
      "Document fragment to append to HTML head element",
102
    paramLabel = "PATH",
103
    defaultValue = "",
104
    required = true
105
  )
106
  private Path mHtmlHeadPath;
107
108
  @CommandLine.Option(
109
    names = { "--html-foot" },
110
    description =
111
      "Document fragment to append to HTML body element",
112
    paramLabel = "PATH",
113
    defaultValue = "",
114
    required = true
115
  )
116
  private Path mHtmlFootPath;
117
118
  @CommandLine.Option(
119
    names = { "--font-dir" },
120
    description =
121
      "Directory to specify additional fonts",
122
    paramLabel = "String"
123
  )
124
  private File mFontDir;
125
126
  @CommandLine.Option(
127
    names = { "--mode" },
128
    description =
129
      "Enable one or more modes when typesetting",
130
    paramLabel = "String"
131
  )
132
  private String mTypesetMode;
133
134
  @CommandLine.Option(
135
    names = { "--format-subtype" },
136
    description =
137
      "Export TeX subtype for HTML formats: svg, delimited",
138
    paramLabel = "String",
139
    defaultValue = "svg"
140
  )
141
  private String mFormatSubtype;
142
143
  @CommandLine.Option(
144
    names = { "--cache-dir" },
145
    description =
146
      "Directory to store remote resources",
147
    paramLabel = "DIR"
148
  )
149
  private File mCachesDir;
150
151
  @CommandLine.Option(
152
    names = { "--image-dir" },
153
    description =
154
      "Directory containing images",
155
    paramLabel = "DIR"
156
  )
157
  private File mImagesDir;
158
159
  @CommandLine.Option(
160
    names = { "--image-order" },
161
    description =
162
      "Comma-separated image order (${DEFAULT-VALUE})",
163
    paramLabel = "String",
164
    defaultValue = "svg,pdf,png,jpg,tiff"
165
  )
166
  private String mImageOrder;
167
168
  @CommandLine.Option(
169
    names = { "--image-server" },
170
    description =
171
      "SVG diagram rendering service (${DEFAULT-VALUE})",
172
    paramLabel = "String",
173
    defaultValue = DIAGRAM_SERVER_NAME
174
  )
175
  private String mImageServer;
176
177
  @CommandLine.Option(
178
    names = { "--locale" },
179
    description =
180
      "Set localization (${DEFAULT-VALUE})",
181
    paramLabel = "String",
182
    defaultValue = "en"
183
  )
184
  private String mLocale;
185
186
  @CommandLine.Option(
187
    names = { "-m", "--metadata" },
188
    description =
189
      "Map metadata keys to values, variable names allowed",
190
    paramLabel = "key=value"
191
  )
192
  private Map<String, String> mMetadata;
193
194
  @CommandLine.Option(
195
    names = { "-o", "--output" },
196
    description =
197
      "Destination document path",
198
    paramLabel = "PATH",
199
    defaultValue = "stdout",
200
    required = true
201
  )
202
  private Path mTargetPath;
203
204
  @CommandLine.Option(
205
    names = { "-q", "--quiet" },
206
    description =
207
      "Suppress all status messages (${DEFAULT-VALUE})",
208
    defaultValue = "false"
209
  )
210
  private boolean mQuiet;
211
212
  @CommandLine.Option(
213
    names = { "--r-dir" },
214
    description =
215
      "R working directory",
216
    paramLabel = "DIR"
217
  )
218
  private Path mRWorkingDir;
219
220
  @CommandLine.Option(
221
    names = { "--r-script" },
222
    description =
223
      "R bootstrap script path",
224
    paramLabel = "PATH"
225
  )
226
  private Path mRScriptPath;
227
228
  @CommandLine.Option(
229
    names = { "-s", "--set" },
230
    description =
231
      "Set (or override) a document variable value",
232
    paramLabel = "key=value"
233
  )
234
  private Map<String, String> mOverrides;
235
236
  @CommandLine.Option(
237
    names = { "--sigil-opening" },
238
    description =
239
      "Starting sigil for variable names (${DEFAULT-VALUE})",
240
    paramLabel = "String",
241
    defaultValue = "{{"
242
  )
243
  private String mSigilBegan;
244
245
  @CommandLine.Option(
246
    names = { "--sigil-closing" },
247
    description =
248
      "Ending sigil for variable names (${DEFAULT-VALUE})",
249
    paramLabel = "String",
250
    defaultValue = "}}"
251
  )
252
  private String mSigilEnded;
253
254
  @CommandLine.Option(
255
    names = { "--theme-dir" },
256
    description =
257
      "Theme directory",
258
    paramLabel = "DIR"
259
  )
260
  private Path mThemesDir;
261
262
  @CommandLine.Option(
263
    names = { "-v", "--variables" },
264
    description =
265
      "Variables path",
266
    paramLabel = "PATH"
267
  )
268
  private Path mPathVariables;
269
270
  private final Consumer<Arguments> mLauncher;
271
272
  public Arguments( final Consumer<Arguments> launcher ) {
273
    mLauncher = launcher;
274
  }
275
276
  public ProcessorContext createProcessorContext()
277
    throws IOException {
278
    final var definitions = parse( mPathVariables );
279
    final var format = ExportFormat.valueFrom( mTargetPath, mFormatSubtype );
280
    final var locale = lookupLocale( mLocale );
281
    final var rScript = read( mRScriptPath );
282
    final var htmlHead = read( mHtmlHeadPath );
283
    final var htmlFoot = read( mHtmlFootPath );
284
285
    return ProcessorContext
286
      .builder()
287
      .with( Mutator::setSourcePath, mSourcePath )
288
      .with( Mutator::setTargetPath, mTargetPath )
289
      .with( Mutator::setHtmlHead, htmlHead )
290
      .with( Mutator::setHtmlFoot, htmlFoot )
291
      .with( Mutator::setThemeDir, () -> mThemesDir )
292
      .with( Mutator::setCacheDir, () -> mCachesDir )
293
      .with( Mutator::setImageDir, () -> mImagesDir )
294
      .with( Mutator::setImageServer, () -> mImageServer )
295
      .with( Mutator::setImageOrder, () -> mImageOrder )
296
      .with( Mutator::setFontDir, () -> mFontDir )
297
      .with( Mutator::setModesEnabled, () -> mTypesetMode )
298
      .with( Mutator::setExportFormat, format )
299
      .with( Mutator::setDefinitions, () -> definitions )
300
      .with( Mutator::setMetadata, () -> mMetadata )
301
      .with( Mutator::setOverrides, () -> mOverrides )
302
      .with( Mutator::setLocale, () -> locale )
303
      .with( Mutator::setConcatenate, () -> mConcatenate )
304
      .with( Mutator::setChapters, () -> mChapters )
305
      .with( Mutator::setSigilBegan, () -> mSigilBegan )
306
      .with( Mutator::setSigilEnded, () -> mSigilEnded )
307
      .with( Mutator::setRScript, () -> rScript )
308
      .with( Mutator::setRWorkingDir, () -> mRWorkingDir )
309
      .with( Mutator::setCurlQuotes, () -> mCurlQuotes )
310
      .with( Mutator::setAutoRemove, () -> !mKeepFiles )
311
      .build();
312
  }
313
314
  public boolean quiet() {
315
    return mQuiet;
316
  }
317
318
  public boolean debug() {
319
    return mDebug;
320
  }
321
322
  /**
323
   * Launches the main application window. This is called when not running
324
   * in headless mode.
325
   *
326
   * @return {@code 0}
327
   * @throws Exception The application encountered an unrecoverable error.
328
   */
329
  @Override
330
  public Integer call() throws Exception {
331
    mLauncher.accept( this );
332
    return 0;
333
  }
334
335
  public void iterate(
336
    final ParseResult parseResult,
337
    final Consumer<String> consumer
338
  ) {
339
    final var options = mSpecifications.options();
340
341
    for( final var opt : options ) {
342
      consumer.accept( format( "%s=%s", opt.longestName(), opt.getValue() ) );
343
    }
344
  }
345
346
  private static String read( final Path path ) throws IOException {
347
    return path == null
348
      ? ""
349
      : canRead( path )
350
      ? readString( path, UTF_8 )
351
      : "";
352
  }
353
354
  private static boolean canRead( final Path path ) {
355
    return exists( path ) && isRegularFile( path ) && isReadable( path );
356
  }
357
358
  /**
359
   * Parses the given YAML document into a map of key-value pairs.
360
   *
361
   * @param vars Variable definition file to read, may be {@code null} if no
362
   *             variables are specified.
363
   * @return A non-interpolated variable map, or an empty map.
364
   * @throws IOException Could not read the variable definition file
365
   */
366
  private static Map<String, String> parse( final Path vars )
367
    throws IOException {
368
    final var map = new HashMap<String, String>();
369
370
    if( vars != null ) {
371
      final var yaml = read( vars );
372
      final var factory = new YAMLFactory();
373
      final var json = new ObjectMapper( factory ).readTree( yaml );
374
375
      parse( json, "", map );
376
    }
377
378
    return map;
379
  }
380
381
  private static void parse(
382
    final JsonNode json, final String parent, final Map<String, String> map ) {
383
    assert json != null;
384
    assert parent != null;
385
    assert map != null;
386
387
    final var fields = json.properties().iterator();
388
389
    fields.forEachRemaining( node -> parse( node, parent, map ) );
390
  }
391
392
  private static void parse(
393
    final Entry<String, JsonNode> node,
394
    final String parent,
395
    final Map<String, String> map ) {
396
    assert node != null;
397
    assert parent != null;
398
    assert map != null;
399
400
    final var jsonNode = node.getValue();
401
    final var keyName = format( "%s.%s", parent, node.getKey() );
402
403
    if( jsonNode.isNull() ) {
404
      map.put( keyName.substring( 1 ), "" );
405
    }
406
    else if( jsonNode.isValueNode() ) {
407
      // Trim the leading period, which is always present.
408
      map.put( keyName.substring( 1 ), node.getValue().asText() );
409
    }
410
    else if( jsonNode.isObject() ) {
411
      parse( jsonNode, keyName, map );
412
    }
413
  }
414
415
  private static Locale lookupLocale( final String locale ) {
416
    try {
417
      return Locale.forLanguageTag( locale );
418
    } catch( final Exception ex ) {
18
import java.nio.file.Path;
19
import java.util.HashMap;
20
import java.util.Locale;
21
import java.util.Map;
22
import java.util.Map.Entry;
23
import java.util.concurrent.Callable;
24
import java.util.function.Consumer;
25
26
import static com.keenwrite.constants.Constants.DIAGRAM_SERVER_NAME;
27
import static java.lang.String.format;
28
import static java.nio.charset.StandardCharsets.UTF_8;
29
import static java.nio.file.Files.*;
30
31
/**
32
 * Responsible for mapping command-line arguments to keys that are used by
33
 * the application.
34
 */
35
@CommandLine.Command(
36
  name = "KeenWrite",
37
  mixinStandardHelpOptions = true,
38
  description = "Plain text editor for editing with variables"
39
)
40
@SuppressWarnings( "unused" )
41
public final class Arguments implements Callable<Integer> {
42
  @CommandLine.Spec
43
  CommandLine.Model.CommandSpec mSpecifications;
44
45
  @CommandLine.Option(
46
    names = { "--all" },
47
    description =
48
      "Concatenate files before processing (${DEFAULT-VALUE})",
49
    defaultValue = "false"
50
  )
51
  private boolean mConcatenate;
52
53
  @CommandLine.Option(
54
    names = { "--keep-files" },
55
    description =
56
      "Retain temporary build files (${DEFAULT-VALUE})",
57
    defaultValue = "false"
58
  )
59
  private boolean mKeepFiles;
60
61
  @CommandLine.Option(
62
    names = { "-c", "--chapters" },
63
    description =
64
      "Export chapter ranges, no spaces (e.g., -3,5-9,15-)",
65
    paramLabel = "String"
66
  )
67
  private String mChapters;
68
69
  @CommandLine.Option(
70
    names = { "--curl-quotes" },
71
    description =
72
      "Encode quotation marks (see docs)",
73
    paramLabel = "String",
74
    defaultValue = "apos"
75
  )
76
  private String mCurlQuotes;
77
78
  @CommandLine.Option(
79
    names = { "-d", "--debug" },
80
    description =
81
      "Enable logging to the console (${DEFAULT-VALUE})",
82
    paramLabel = "Boolean",
83
    defaultValue = "false"
84
  )
85
  private boolean mDebug;
86
87
  @CommandLine.Option(
88
    names = { "-i", "--input" },
89
    description =
90
      "Source document path",
91
    paramLabel = "PATH",
92
    defaultValue = "stdin",
93
    required = true
94
  )
95
  private Path mSourcePath;
96
97
  @CommandLine.Option(
98
    names = { "--html-head" },
99
    description =
100
      "Document fragment to append to HTML head element",
101
    paramLabel = "PATH",
102
    defaultValue = "",
103
    required = true
104
  )
105
  private Path mHtmlHeadPath;
106
107
  @CommandLine.Option(
108
    names = { "--html-foot" },
109
    description =
110
      "Document fragment to append to HTML body element",
111
    paramLabel = "PATH",
112
    defaultValue = "",
113
    required = true
114
  )
115
  private Path mHtmlFootPath;
116
117
  @CommandLine.Option(
118
    names = { "--font-dir" },
119
    description =
120
      "Directory to specify additional fonts",
121
    paramLabel = "String"
122
  )
123
  private File mFontDir;
124
125
  @CommandLine.Option(
126
    names = { "--mode" },
127
    description =
128
      "Enable one or more modes when typesetting",
129
    paramLabel = "String"
130
  )
131
  private String mTypesetMode;
132
133
  @CommandLine.Option(
134
    names = { "--format-subtype" },
135
    description =
136
      "Export TeX subtype for HTML formats: svg, delimited",
137
    paramLabel = "String",
138
    defaultValue = "svg"
139
  )
140
  private String mFormatSubtype;
141
142
  @CommandLine.Option(
143
    names = { "--cache-dir" },
144
    description =
145
      "Directory to store remote resources",
146
    paramLabel = "DIR"
147
  )
148
  private File mCachesDir;
149
150
  @CommandLine.Option(
151
    names = { "--image-dir" },
152
    description =
153
      "Directory containing images",
154
    paramLabel = "DIR"
155
  )
156
  private File mImagesDir;
157
158
  @CommandLine.Option(
159
    names = { "--image-order" },
160
    description =
161
      "Comma-separated image order (${DEFAULT-VALUE})",
162
    paramLabel = "String",
163
    defaultValue = "svg,pdf,png,jpg,tiff"
164
  )
165
  private String mImageOrder;
166
167
  @CommandLine.Option(
168
    names = { "--image-server" },
169
    description =
170
      "SVG diagram rendering service (${DEFAULT-VALUE})",
171
    paramLabel = "String",
172
    defaultValue = DIAGRAM_SERVER_NAME
173
  )
174
  private String mImageServer;
175
176
  @CommandLine.Option(
177
    names = { "--locale" },
178
    description =
179
      "Set localization (${DEFAULT-VALUE})",
180
    paramLabel = "String",
181
    defaultValue = "en"
182
  )
183
  private String mLocale;
184
185
  @CommandLine.Option(
186
    names = { "-m", "--metadata" },
187
    description =
188
      "Map metadata keys to values, variable names allowed",
189
    paramLabel = "key=value"
190
  )
191
  private Map<String, String> mMetadata;
192
193
  @CommandLine.Option(
194
    names = { "-o", "--output" },
195
    description =
196
      "Destination document path",
197
    paramLabel = "PATH",
198
    defaultValue = "stdout",
199
    required = true
200
  )
201
  private Path mTargetPath;
202
203
  @CommandLine.Option(
204
    names = { "-q", "--quiet" },
205
    description =
206
      "Suppress all status messages (${DEFAULT-VALUE})",
207
    defaultValue = "false"
208
  )
209
  private boolean mQuiet;
210
211
  @CommandLine.Option(
212
    names = { "--r-dir" },
213
    description =
214
      "R working directory",
215
    paramLabel = "DIR"
216
  )
217
  private Path mRWorkingDir;
218
219
  @CommandLine.Option(
220
    names = { "--r-script" },
221
    description =
222
      "R bootstrap script path",
223
    paramLabel = "PATH"
224
  )
225
  private Path mRScriptPath;
226
227
  @CommandLine.Option(
228
    names = { "-s", "--set" },
229
    description =
230
      "Set (or override) a document variable value",
231
    paramLabel = "key=value"
232
  )
233
  private Map<String, String> mOverrides;
234
235
  @CommandLine.Option(
236
    names = { "--sigil-opening" },
237
    description =
238
      "Starting sigil for variable names (${DEFAULT-VALUE})",
239
    paramLabel = "String",
240
    defaultValue = "{{"
241
  )
242
  private String mSigilBegan;
243
244
  @CommandLine.Option(
245
    names = { "--sigil-closing" },
246
    description =
247
      "Ending sigil for variable names (${DEFAULT-VALUE})",
248
    paramLabel = "String",
249
    defaultValue = "}}"
250
  )
251
  private String mSigilEnded;
252
253
  @CommandLine.Option(
254
    names = { "--theme-dir" },
255
    description =
256
      "Theme directory",
257
    paramLabel = "DIR"
258
  )
259
  private Path mThemesDir;
260
261
  @CommandLine.Option(
262
    names = { "-v", "--variables" },
263
    description =
264
      "Variables path",
265
    paramLabel = "PATH"
266
  )
267
  private Path mPathVariables;
268
269
  private final Consumer<Arguments> mLauncher;
270
271
  public Arguments( final Consumer<Arguments> launcher ) {
272
    mLauncher = launcher;
273
  }
274
275
  public ProcessorContext createProcessorContext()
276
    throws IOException {
277
    final var definitions = parse( mPathVariables );
278
    final var format = ExportFormat.valueFrom( mTargetPath, mFormatSubtype );
279
    final var locale = lookupLocale( mLocale );
280
    final var rScript = read( mRScriptPath );
281
    final var htmlHead = read( mHtmlHeadPath );
282
    final var htmlFoot = read( mHtmlFootPath );
283
284
    return ProcessorContext
285
      .builder()
286
      .with( Mutator::setSourcePath, mSourcePath )
287
      .with( Mutator::setTargetPath, mTargetPath )
288
      .with( Mutator::setHtmlHead, htmlHead )
289
      .with( Mutator::setHtmlFoot, htmlFoot )
290
      .with( Mutator::setThemeDir, () -> mThemesDir )
291
      .with( Mutator::setCacheDir, () -> mCachesDir )
292
      .with( Mutator::setImageDir, () -> mImagesDir )
293
      .with( Mutator::setImageServer, () -> mImageServer )
294
      .with( Mutator::setImageOrder, () -> mImageOrder )
295
      .with( Mutator::setFontDir, () -> mFontDir )
296
      .with( Mutator::setModesEnabled, () -> mTypesetMode )
297
      .with( Mutator::setExportFormat, format )
298
      .with( Mutator::setDefinitions, () -> definitions )
299
      .with( Mutator::setMetadata, () -> mMetadata )
300
      .with( Mutator::setOverrides, () -> mOverrides )
301
      .with( Mutator::setLocale, () -> locale )
302
      .with( Mutator::setConcatenate, () -> mConcatenate )
303
      .with( Mutator::setChapters, () -> mChapters )
304
      .with( Mutator::setSigilBegan, () -> mSigilBegan )
305
      .with( Mutator::setSigilEnded, () -> mSigilEnded )
306
      .with( Mutator::setRScript, () -> rScript )
307
      .with( Mutator::setRWorkingDir, () -> mRWorkingDir )
308
      .with( Mutator::setCurlQuotes, () -> mCurlQuotes )
309
      .with( Mutator::setAutoRemove, () -> !mKeepFiles )
310
      .build();
311
  }
312
313
  public boolean quiet() {
314
    return mQuiet;
315
  }
316
317
  public boolean debug() {
318
    return mDebug;
319
  }
320
321
  /**
322
   * Launches the main application window. This is called when not running
323
   * in headless mode.
324
   *
325
   * @return {@code 0}
326
   * @throws Exception The application encountered an unrecoverable error.
327
   */
328
  @Override
329
  public Integer call() throws Exception {
330
    mLauncher.accept( this );
331
    return 0;
332
  }
333
334
  public void iterate(
335
    final ParseResult parseResult,
336
    final Consumer<String> consumer
337
  ) {
338
    final var options = mSpecifications.options();
339
340
    for( final var opt : options ) {
341
      consumer.accept( format( "%s=%s", opt.longestName(), opt.getValue() ) );
342
    }
343
  }
344
345
  private static String read( final Path path ) throws IOException {
346
    return path == null
347
      ? ""
348
      : canRead( path )
349
      ? readString( path, UTF_8 )
350
      : "";
351
  }
352
353
  private static boolean canRead( final Path path ) {
354
    return exists( path ) && isRegularFile( path ) && isReadable( path );
355
  }
356
357
  /**
358
   * Parses the given YAML document into a map of key-value pairs.
359
   *
360
   * @param vars Variable definition file to read, may be {@code null} if no
361
   *             variables are specified.
362
   * @return A non-interpolated variable map, or an empty map.
363
   * @throws IOException Could not read the variable definition file
364
   */
365
  private static Map<String, String> parse( final Path vars )
366
    throws IOException {
367
    final var map = new HashMap<String, String>();
368
369
    if( vars != null ) {
370
      final var yaml = read( vars );
371
      final var factory = new YAMLFactory();
372
      final var json = new ObjectMapper( factory ).readTree( yaml );
373
374
      parse( json, "", map );
375
    }
376
377
    return map;
378
  }
379
380
  private static void parse(
381
    final JsonNode json, final String parent, final Map<String, String> map ) {
382
    assert json != null;
383
    assert parent != null;
384
    assert map != null;
385
386
    final var fields = json.properties().iterator();
387
388
    fields.forEachRemaining( node -> parse( node, parent, map ) );
389
  }
390
391
  private static void parse(
392
    final Entry<String, JsonNode> node,
393
    final String parent,
394
    final Map<String, String> map ) {
395
    assert node != null;
396
    assert parent != null;
397
    assert map != null;
398
399
    final var jsonNode = node.getValue();
400
    final var keyName = format( "%s.%s", parent, node.getKey() );
401
402
    if( jsonNode.isNull() ) {
403
      map.put( keyName.substring( 1 ), "" );
404
    }
405
    else if( jsonNode.isValueNode() ) {
406
      // Trim the leading period, which is always present.
407
      map.put( keyName.substring( 1 ), node.getValue().asText() );
408
    }
409
    else if( jsonNode.isObject() ) {
410
      parse( jsonNode, keyName, map );
411
    }
412
  }
413
414
  private static Locale lookupLocale( final String locale ) {
415
    try {
416
      return Locale.forLanguageTag( locale );
417
    }
418
    catch( final Exception ex ) {
419419
      return Locale.ENGLISH;
420420
    }
M src/main/java/com/keenwrite/cmdline/HeadlessApp.java
5454
5555
    if( !mArgs.quiet() ) {
56
      final var stacktrace = event.getProblem();
57
      final var problem = stacktrace.isBlank()
58
        ? ""
59
        : format( "%n%s", stacktrace );
60
      final var msg = format( "%s%s", event, problem );
61
62
      mErrStream.println( msg );
56
      event.print( mErrStream );
6357
    }
6458
  }
M src/main/java/com/keenwrite/commands/ConcatenateCommand.java
1616
1717
import static com.keenwrite.events.StatusEvent.clue;
18
import static com.keenwrite.events.StatusEvent.fire;
1819
import static com.keenwrite.util.FileWalker.walk;
1920
import static java.lang.String.format;
...
3334
  private static final int DOCUMENT_LENGTH = 150_000 * 6;
3435
36
  private final String mFilename;
3537
  private final Path mParent;
3638
  private final String mExtension;
3739
  private final String mRange;
3840
3941
  public ConcatenateCommand(
42
    final String filename,
4043
    final Path parent,
4144
    final String extension,
4245
    final String range ) {
46
    assert filename != null;
4347
    assert parent != null;
4448
    assert extension != null;
4549
    assert range != null;
4650
51
    mFilename = filename;
4752
    mParent = parent;
4853
    mExtension = extension;
4954
    mRange = range;
5055
  }
5156
52
  public static int toDigits( final String filename, final int fallback ) {
57
  public static int toDigits( final String filename ) {
5358
    final var stripped = filename.replaceAll( "\\D", "" );
54
55
    return stripped.isEmpty() ? fallback : Integer.parseInt( stripped );
59
    return stripped.isBlank() ? -1 : Integer.parseInt( stripped );
5660
  }
5761
...
6670
    walk( mParent, glob, files::add );
6771
    files.sort( new AlphanumComparator<>() );
72
73
    final var useDigits = toDigits( mFilename ) != -1;
74
6875
    files.forEach( file -> {
6976
      try {
7077
        final var filename = SysFile.getFileName( file );
71
        final var digits = toDigits( filename, chapter.incrementAndGet() );
78
        final var digits = toDigits( filename );
7279
73
        if( validator.test( digits ) ) {
74
          clue( "Main.status.export.concat", file );
80
        // If first file has digits, only process files with digits
81
        // If first file has no digits, process all files
82
        final var process = !useDigits || digits != -1;
7583
76
          text.append( readString( file, UTF_8 ) )
84
        if( process ) {
85
          final var chapterNum = chapter.incrementAndGet();
86
87
          if( validator.test( chapterNum ) ) {
88
            clue( "Main.status.export.concat", file );
89
90
            text.append( readString( file, UTF_8 ) )
7791
              .append( eol );
92
          }
7893
        }
79
      } catch( final IOException ex ) {
94
        else {
95
          clue( "Main.status.export.concat.skip", file );
96
        }
97
      }
98
      catch( final IOException ex ) {
8099
        clue( "Main.status.export.concat.io", file );
81100
      }
M src/main/java/com/keenwrite/editors/markdown/LinkVisitor.java
5757
  }
5858
59
  protected NodeVisitor createVisitor() {
59
  private NodeVisitor createVisitor() {
6060
    return new NodeVisitor(
6161
      new VisitHandler<>( Link.class, LinkVisitor.this::visit ) );
A src/main/java/com/keenwrite/events/PagingEvent.java
1
/* Copyright 2025 White Magic Software, Ltd. -- All rights reserved.
2
 *
3
 * SPDX-License-Identifier: MIT
4
 */
5
package com.keenwrite.events;
6
7
import java.io.PrintStream;
8
9
import static com.keenwrite.Messages.get;
10
11
/**
12
 * Represents pagination progress during document typesetting operations.
13
 */
14
public final class PagingEvent extends StatusEvent {
15
  /**
16
   * Constructs a new paging event with pagination details.
17
   *
18
   * @param pageCount The current page number being processed (1-based).
19
   * @param pageTotal The total number of pages, or -1 if unknown.
20
   * @param passCount The current pass number for multi-pass operations.
21
   */
22
  private PagingEvent(
23
    final int pageCount, final int pageTotal, final int passCount
24
  ) {
25
    super(
26
      get(
27
        "Main.status.typeset.page",
28
        pageCount,
29
        pageTotal < 1 ? "?" : pageTotal,
30
        passCount
31
      )
32
    );
33
  }
34
35
  /**
36
   * Uses carriage return to overwrite the same line for typesetting progress.
37
   *
38
   * @param stream The output stream to write to.
39
   * @param msg    The message to print.
40
   */
41
  @Override
42
  protected void print( final PrintStream stream, final String msg ) {
43
    stream.print( msg + "\r" );
44
    stream.flush();
45
  }
46
47
  /**
48
   * Convenience method to create and fire a paging event in one call.
49
   *
50
   * @param pageCount The current page number being processed.
51
   * @param pageTotal The total number of pages, or -1 if unknown.
52
   * @param passCount The current pass number.
53
   */
54
  public static void fire(
55
    final int pageCount,
56
    final int pageTotal,
57
    final int passCount
58
  ) {
59
    new PagingEvent( pageCount, pageTotal, passCount ).publish();
60
  }
61
}
162
M src/main/java/com/keenwrite/events/StatusEvent.java
55
package com.keenwrite.events;
66
7
import java.io.PrintStream;
78
import java.util.List;
89
...
1920
 * exceptions, state problems, parsing errors, and so forth.
2021
 */
21
public final class StatusEvent implements AppEvent {
22
public class StatusEvent implements AppEvent {
2223
  private static final String ENGLISHIFY =
2324
    "(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])";
...
8081
8182
    return sb.toString();
83
  }
84
85
  public void print( final PrintStream stream ) {
86
    final var stacktrace = getProblem();
87
    final var problem = stacktrace.isBlank()
88
      ? ""
89
      : format( "%n%s", stacktrace );
90
    final var msg = format( "%s%s", this, problem );
91
92
    print( stream, msg );
93
  }
94
95
  protected void print( final PrintStream stream, final String msg ) {
96
    stream.println( msg );
8297
  }
8398
M src/main/java/com/keenwrite/preview/images/ResampleOp.java
2929
  private static final int MAX_CHANNEL_VALUE = 255;
3030
31
  private int nrChannels;
32
  private int srcWidth;
33
  private int srcHeight;
34
  private int dstWidth;
35
  private int dstHeight;
31
  private volatile int nrChannels;
32
  private volatile int srcWidth;
33
  private volatile int srcHeight;
34
  private volatile int dstWidth;
35
  private volatile int dstHeight;
3636
3737
  static class SubSamplingData {
M src/main/java/com/keenwrite/processors/ProcessorContext.java
475475
  /**
476476
   * Answers whether to process a single text file or all text files in
477
   * the same directory as a single text file. See {@link #getSourcePath()}
478
   * for the file to process (or all files in its directory).
477
   * the directory hierarchy as a single text file. See {@link #getSourcePath()}
478
   * for the file to process (or all files in all subdirectories).
479479
   *
480480
   * @return {@code true} means to process all text files, {@code false}
M src/main/java/com/keenwrite/processors/ProcessorFactory.java
6969
      case HTML_TEX_DELIMITED, HTML_TEX_SVG -> createHtmlProcessor( context );
7070
      case XHTML_TEX, XHTML_TEX_SVG -> createXhtmlProcessor( context );
71
      case TEXT_TEX -> createTextProcessor( context );
71
      case TEXT_TEX, TEXT_MARKDOWN -> createTextProcessor( context );
7272
      case APPLICATION_PDF -> createPdfProcessor( context );
73
      default -> createIdentityProcessor( context );
7473
    };
7574
    final var inputType = context.getSourceFileType();
M src/main/java/com/keenwrite/processors/markdown/BaseMarkdownProcessor.java
1414
import com.keenwrite.processors.markdown.extensions.r.RInlineExtension;
1515
import com.keenwrite.processors.markdown.extensions.references.CrossReferenceExtension;
16
import com.keenwrite.processors.markdown.extensions.spans.BracketedSpanExtension;
1617
import com.vladsch.flexmark.ext.definition.DefinitionExtension;
18
import com.vladsch.flexmark.ext.footnotes.FootnoteExtension;
1719
import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughSubscriptExtension;
1820
import com.vladsch.flexmark.ext.superscript.SuperscriptExtension;
...
7476
    extensions.add( CrossReferenceExtension.create() );
7577
    extensions.add( CaptionExtension.create() );
78
    extensions.add( FootnoteExtension.create() );
7679
    extensions.add( EscapedQuotesExtension.create() );
80
    extensions.add( BracketedSpanExtension.create() );
7781
7882
    return extensions;
A src/main/java/com/keenwrite/processors/markdown/extensions/spans/BracketedSpanExtension.java
1
/* Copyright 2025 White Magic Software, Ltd. -- All rights reserved.
2
 *
3
 * SPDX-License-Identifier: MIT
4
 */
5
package com.keenwrite.processors.markdown.extensions.spans;
6
7
import com.keenwrite.processors.markdown.extensions.common.MarkdownRendererExtension;
8
import com.vladsch.flexmark.html.renderer.NodeRendererFactory;
9
import com.vladsch.flexmark.parser.Parser.Builder;
10
11
/**
12
 * Extension for parsing and rendering bracketed span syntax:
13
 * [text]{.class key="val" #id}
14
 */
15
public final class BracketedSpanExtension extends MarkdownRendererExtension {
16
  private BracketedSpanExtension() {
17
  }
18
19
  public static BracketedSpanExtension create() {
20
    return new BracketedSpanExtension();
21
  }
22
23
  @Override
24
  public void extend( final Builder builder ) {
25
    builder.customInlineParserExtensionFactory(
26
      new BracketedSpanParserFactory()
27
    );
28
  }
29
30
  @Override
31
  protected NodeRendererFactory createNodeRendererFactory() {
32
    return BracketedSpanRenderer.factory();
33
  }
34
}
135
A src/main/java/com/keenwrite/processors/markdown/extensions/spans/BracketedSpanNode.java
1
/* Copyright 2025 White Magic Software, Ltd. -- All rights reserved.
2
 *
3
 * SPDX-License-Identifier: MIT
4
 */
5
package com.keenwrite.processors.markdown.extensions.spans;
6
7
import com.vladsch.flexmark.html.HtmlWriter;
8
import com.vladsch.flexmark.html.renderer.NodeRendererContext;
9
import com.vladsch.flexmark.util.ast.Node;
10
import com.vladsch.flexmark.util.sequence.BasedSequence;
11
import org.jetbrains.annotations.NotNull;
12
13
import java.util.List;
14
import java.util.Map;
15
16
public class BracketedSpanNode extends Node {
17
  private final List<String> mClasses;
18
  private final String mId;
19
  private final Map<String, String> mAttributes;
20
  private final BasedSequence mText;
21
22
  public BracketedSpanNode(
23
    final @NotNull List<String> classes,
24
    final @NotNull String id,
25
    final Map<String, String> attributes,
26
    final BasedSequence text
27
  ) {
28
    this.mClasses = classes;
29
    this.mId = id;
30
    this.mAttributes = attributes;
31
    this.mText = text;
32
  }
33
34
  public void render(
35
    final NodeRendererContext context,
36
    final HtmlWriter html
37
  ) {
38
    html.raw( "<span" );
39
40
    if( !mClasses.isEmpty() ) {
41
      html
42
        .raw( " class=\"" )
43
        .raw( String.join( " ", mClasses ) )
44
        .raw( "\"" );
45
    }
46
47
    if( !mId.isBlank() ) {
48
      html.raw( " id=\"" ).raw( mId ).raw( "\"" );
49
    }
50
51
    for( var entry : mAttributes.entrySet() ) {
52
      html
53
        .raw( " " ).raw( entry.getKey() )
54
        .raw( "=\"" ).raw( entry.getValue() )
55
        .raw( "\"" );
56
    }
57
58
    html.raw( ">" );
59
60
    if( hasChildren() ) {
61
      for( var child : getChildren() ) {
62
        context.render( child );
63
      }
64
    }
65
    else {
66
      html.raw( mText.toString() );
67
    }
68
69
    html.raw( "</span>" );
70
  }
71
72
  @Override
73
  public @NotNull BasedSequence[] getSegments() {
74
    return new BasedSequence[ 0 ];
75
  }
76
}
177
A src/main/java/com/keenwrite/processors/markdown/extensions/spans/BracketedSpanParser.java
1
/* Copyright 2025 White Magic Software, Ltd. -- All rights reserved.
2
 *
3
 * SPDX-License-Identifier: MIT
4
 */
5
/* Copyright 2025 White Magic Software, Ltd. -- All rights reserved.
6
 *
7
 * SPDX-License-Identifier: MIT
8
 */
9
/* Copyright 2025 White Magic Software, Ltd. -- All rights reserved.
10
 *
11
 * SPDX-License-Identifier: MIT
12
 */
13
package com.keenwrite.processors.markdown.extensions.spans;
14
15
import com.vladsch.flexmark.parser.InlineParser;
16
import com.vladsch.flexmark.parser.InlineParserExtension;
17
import com.vladsch.flexmark.parser.LightInlineParser;
18
import com.vladsch.flexmark.util.sequence.BasedSequence;
19
import org.jetbrains.annotations.NotNull;
20
21
import java.util.ArrayList;
22
import java.util.HashMap;
23
import java.util.regex.Pattern;
24
25
public class BracketedSpanParser implements InlineParserExtension {
26
  private static final Pattern ATTR_PATTERN = Pattern.compile(
27
    "\\.([\\w-]+)|" +
28
      "#([\\w-]+)|" +
29
      "(\\w+)=\"((?:\\\\\"|[^\"])*)\""
30
  );
31
32
  public BracketedSpanParser( @NotNull final LightInlineParser ignoredParser ) {
33
  }
34
35
  @Override
36
  public boolean parse( @NotNull final LightInlineParser parser ) {
37
    var result = false;
38
    final var input = parser.getInput();
39
    final var index = parser.getIndex();
40
    final var ch = input.charAt( index );
41
42
    if( ch == '[' ) {
43
      final var iCloseBracket = input.indexOf( ']', index + 1 );
44
      final var iOpenBrace = input.indexOf( '{', iCloseBracket + 1 );
45
46
      if(
47
        iCloseBracket != -1 &&
48
          iOpenBrace != -1 &&
49
          iOpenBrace == iCloseBracket + 1
50
      ) {
51
        final var braceEnd = input.indexOf( '}', iOpenBrace + 1 );
52
53
        if( braceEnd != -1 ) {
54
          final var content = input.subSequence( index + 1, iCloseBracket );
55
          final var span = getBracketedSpan(
56
            input, iOpenBrace, braceEnd, content );
57
58
          span.setChars( input.subSequence( index, braceEnd + 1 ) );
59
          parser.flushTextNode();
60
          parser.getBlock().appendChild( span );
61
          parser.setIndex( braceEnd + 1 );
62
          result = true;
63
        }
64
      }
65
    }
66
67
    return result;
68
  }
69
70
  @NotNull
71
  private static BracketedSpanNode getBracketedSpan(
72
    final BasedSequence input,
73
    final int braceStart,
74
    final int braceEnd,
75
    final BasedSequence content
76
  ) {
77
    final var attrSeq = input.subSequence( braceStart + 1, braceEnd );
78
    final var attrs = new HashMap<String, String>();
79
    final var classes = new ArrayList<String>();
80
    String id = "";
81
82
    final var matcher = ATTR_PATTERN.matcher( attrSeq.toString() );
83
84
    while( matcher.find() ) {
85
      if( matcher.group( 1 ) != null ) {
86
        classes.add( matcher.group( 1 ) );
87
      }
88
      else if( matcher.group( 2 ) != null ) {
89
        id = matcher.group( 2 );
90
      }
91
      else if( matcher.group( 3 ) != null && matcher.group( 4 ) != null ) {
92
        final var key = matcher.group( 3 );
93
        final var value = matcher.group( 4 ).replace( "\\\"", "\"" );
94
95
        attrs.put( key, value );
96
      }
97
    }
98
99
    return new BracketedSpanNode( classes, id, attrs, content );
100
  }
101
102
  @Override
103
  public void finalizeDocument( @NotNull final InlineParser parser ) {
104
  }
1105
106
  @Override
107
  public void finalizeBlock( @NotNull final InlineParser parser ) {
108
  }
109
}
A src/main/java/com/keenwrite/processors/markdown/extensions/spans/BracketedSpanParserFactory.java
1
/* Copyright 2025 White Magic Software, Ltd. -- All rights reserved.
2
 *
3
 * SPDX-License-Identifier: MIT
4
 */
5
package com.keenwrite.processors.markdown.extensions.spans;
6
7
import com.vladsch.flexmark.parser.InlineParserExtension;
8
import com.vladsch.flexmark.parser.InlineParserExtensionFactory;
9
import com.vladsch.flexmark.parser.LightInlineParser;
10
import org.jetbrains.annotations.NotNull;
11
12
import java.util.Set;
13
14
/**
15
 * Factory for creating the bracketed span inline parser.
16
 */
17
public final class BracketedSpanParserFactory implements InlineParserExtensionFactory {
18
  public BracketedSpanParserFactory() {
19
  }
20
21
  /**
22
   * Characters that trigger this parser. In this case, '[' starts a
23
   * bracketed span.
24
   */
25
  @Override
26
  public @NotNull CharSequence getCharacters() {
27
    return "[";
28
  }
29
30
  /**
31
   * Creates a new instance of the parser.
32
   */
33
  @Override
34
  public @NotNull InlineParserExtension apply( @NotNull LightInlineParser parser ) {
35
    return new BracketedSpanParser( parser );
36
  }
37
38
  @Override
39
  public @NotNull Set<Class<?>> getAfterDependents() {
40
    return Set.of();
41
  }
42
43
  @Override
44
  public @NotNull Set<Class<?>> getBeforeDependents() {
45
    return Set.of();
46
  }
47
48
  @Override
49
  public boolean affectsGlobalScope() {
50
    return false;
51
  }
52
}
153
A src/main/java/com/keenwrite/processors/markdown/extensions/spans/BracketedSpanRenderer.java
1
/* Copyright 2025 White Magic Software, Ltd. -- All rights reserved.
2
 *
3
 * SPDX-License-Identifier: MIT
4
 */
5
package com.keenwrite.processors.markdown.extensions.spans;
6
7
import com.vladsch.flexmark.html.renderer.NodeRenderer;
8
import com.vladsch.flexmark.html.renderer.NodeRendererFactory;
9
import com.vladsch.flexmark.html.renderer.NodeRenderingHandler;
10
11
import java.util.Collections;
12
import java.util.Set;
13
14
public class BracketedSpanRenderer implements NodeRenderer {
15
  @Override
16
  public Set<NodeRenderingHandler<?>> getNodeRenderingHandlers() {
17
    return Collections.singleton(
18
      new NodeRenderingHandler<>(
19
        BracketedSpanNode.class,
20
        BracketedSpanNode::render
21
      )
22
    );
23
  }
24
25
  public static NodeRendererFactory factory() {
26
    return _ -> new BracketedSpanRenderer();
27
  }
28
}
129
M src/main/java/com/keenwrite/processors/markdown/extensions/tex/TexInlineDelimiterProcessor.java
1414
    final Delimiter opener,
1515
    final Delimiter closer,
16
    final int delimitersUsed ) {
16
    final int delimitersUsed
17
  ) {
1718
    final var node = new TexNode( opener, closer );
1819
    opener.moveNodesBetweenDelimitersTo( node, closer );
M src/main/java/com/keenwrite/processors/markdown/extensions/tex/TexNodeRenderer.java
117117
   */
118118
  private static class TexSvgNodeRenderer extends RendererFacade {
119
    void render( final TexNode node,
120
                 final NodeRendererContext context,
121
                 final HtmlWriter html ) {
119
    void render(
120
      final TexNode node,
121
      final NodeRendererContext context,
122
      final HtmlWriter html
123
    ) {
122124
      final var tex = node.getText().toStringOrNull();
123125
      final var doc = MathRenderer.toDocument(
...
133135
   */
134136
  private static class TexDelimitedNodeRenderer extends RendererFacade {
135
    void render( final TexNode node,
136
                 final NodeRendererContext context,
137
                 final HtmlWriter html ) {
137
    void render(
138
      final TexNode node,
139
      final NodeRendererContext context,
140
      final HtmlWriter html
141
    ) {
138142
      html.raw( TOKEN_OPEN );
139143
      html.raw( getEvaluator().apply( node.getText().toString() ) );
M src/main/java/com/keenwrite/spelling/impl/SymSpellSpeller.java
1515
import java.util.Map;
1616
17
import static com.keenwrite.events.StatusEvent.clue;
1718
import static io.gitlab.rxp90.jsymspell.Verbosity.ALL;
1819
import static io.gitlab.rxp90.jsymspell.Verbosity.CLOSEST;
...
7172
7273
    final var words = lookup( lexeme, CLOSEST );
73
    return !words.isEmpty() && lexeme.equals( words.get( 0 ).getSuggestion() );
74
    return !words.isEmpty() && lexeme.equals( words.getFirst().getSuggestion() );
7475
  }
7576
...
147148
    assert v != null;
148149
149
    return mSymSpell.lookup( lexeme, v );
150
    try {
151
      return mSymSpell.lookup( lexeme, v );
152
    }
153
    catch( final NotInitializedException ex ) {
154
       clue( ex );
155
    }
156
157
    return new ArrayList<>();
150158
  }
151159
}
M src/main/java/com/keenwrite/typesetting/PaginationListener.java
22
package com.keenwrite.typesetting;
33
4
import com.keenwrite.events.PagingEvent;
5
46
import java.util.Scanner;
57
import java.util.function.Consumer;
...
5355
5456
      // Inform the user of pages being typeset.
55
      clue( "Main.status.typeset.page",
56
            mPageCount, mPageTotal < 1 ? "?" : mPageTotal, mPassCount
57
      );
57
      PagingEvent.fire( mPageCount, mPageTotal, mPassCount );
5858
    }
5959
  }
M src/main/java/com/keenwrite/ui/actions/GuiCommands.java
661661
    try {
662662
      final var command = new ConcatenateCommand(
663
        parent, extension, getString( KEY_TYPESET_CONTEXT_CHAPTERS ) );
663
        filename, parent, extension, getString( KEY_TYPESET_CONTEXT_CHAPTERS )
664
      );
665
664666
      return command.call();
665667
    } catch( final Throwable t ) {
M src/main/resources/com/keenwrite/messages.properties
6464
workspace.images.order.title=Extensions
6565
workspace.images.resize=Resize
66
workspace.images.resize.desc=Scale images to fit the preview panel when resizing, automatically.
66
workspace.images.resize.desc=Scale images to fit the preview tab when resizing, automatically.
6767
workspace.images.resize.title=Resize
6868
workspace.images.server=Diagram Server
...
104104
workspace.ui.font.preview=Preview Font
105105
workspace.ui.font.preview.name=Name
106
workspace.ui.font.preview.name.desc=Preview pane font name (must support ligatures, serif font recommended).
106
workspace.ui.font.preview.name.desc=Preview tab font name (must support ligatures, serif font recommended).
107107
workspace.ui.font.preview.name.title=Family
108108
workspace.ui.font.preview.size=Size
...
209209
Main.status.export.concat.parent=No parent directory found for ''{0}''
210210
Main.status.export.concat.extension=File name must have an extension ''{0}''
211
Main.status.export.concat.skip=File name has no digits, skipping ''{0}''
211212
Main.status.export.concat.io=Could not read from ''{0}''
212213
...
239240
240241
# ########################################################################
241
# Definition Pane and its Tree View
242
# Definition Tab and its Tree View
242243
# ########################################################################
243244
244245
Definition.menu.add.default=Undefined
245246
246247
# ########################################################################
247
# Variable Definitions Pane
248
# Variable Definitions Tab
248249
# ########################################################################
249250
250251
Pane.definition.node.root.title=Variables
251252
252253
# ########################################################################
253
# HTML Preview Pane
254
# HTML Preview Tab
254255
# ########################################################################
255256
256257
Pane.preview.title=Preview
257258
258259
# ########################################################################
259
# Document Outline Pane
260
# Document Outline Tab
260261
# ########################################################################
261262
262263
Pane.outline.title=Outline
263264
264265
# ########################################################################
265
# File Manager Pane
266
# File Manager Tab
266267
# ########################################################################
267268
268269
Pane.files.title=Files
269270
270271
# ########################################################################
271
# Document Outline Pane
272
# Document Outline Tab
272273
# ########################################################################
273274
...
327328
Wizard.typesetter.name=ConTeXt
328329
Wizard.typesetter.container.name=Podman
329
Wizard.typesetter.container.version=5.6.0
330
Wizard.typesetter.container.checksum=fc8960481e6165b5d1ef05970a11b691b13d434d1f97ceb29b8be6f3902ba86c
330
Wizard.typesetter.container.version=5.6.1
331
Wizard.typesetter.container.checksum=602b21a68d077ed5589f8c3acc78764d64b9e5e6f6e151d356db2e6582309142
331332
Wizard.typesetter.container.image.name=typesetter
332333
Wizard.typesetter.container.image.version=3.3.0
333334
Wizard.typesetter.container.image.tag=${Wizard.typesetter.container.image.name}:${Wizard.typesetter.container.image.version}
334335
Wizard.typesetter.container.image.url=https://repository.keenwrite.com/containers/${Wizard.typesetter.container.image.tag}
335
Wizard.typesetter.themes.version=1.11.0
336
Wizard.typesetter.themes.checksum=87e258329d2a4c2802135c4828c2b095a92d62adf7e02925dba24ec4cc1fee6e
336
Wizard.typesetter.themes.version=1.12.0
337
Wizard.typesetter.themes.checksum=5d3a1073071bcb57005a1907d8a01fdd95f1e75e990ff40b2594e31679ff2e94
337338
338339
Wizard.container.install.command=Installing container using: ''{0}''
A src/test/java/com/keenwrite/processors/markdown/extensions/links/HyperlinkVariablesTest.java
1
/* Copyright 2025 White Magic Software, Ltd. -- All rights reserved.
2
 *
3
 * SPDX-License-Identifier: MIT
4
 */
5
package com.keenwrite.processors.markdown.extensions.links;
6
7
import com.keenwrite.processors.ProcessorContext;
8
import com.keenwrite.processors.ProcessorFactory;
9
import org.junit.jupiter.api.Test;
10
11
import java.nio.file.Paths;
12
import java.util.Map;
13
import java.util.function.Supplier;
14
15
import static com.keenwrite.ExportFormat.TEXT_MARKDOWN;
16
import static org.junit.jupiter.api.Assertions.assertEquals;
17
18
public class HyperlinkVariablesTest {
19
  private final static String TEXT = "Text";
20
  private final static String URL = "https://localhost";
21
  private final static String KEY = "F12";
22
  private final static String EXPECTED = "<html><head></head><body><p>" +
23
    "<a href=\"" + URL + "\">" + TEXT + "</a> " +
24
    "<span class=\"kbd\">" + KEY + "</span>" +
25
    "</p>\n</body></html>";
26
27
  @Test
28
  void test_MarkdownProcessing_VariablesInLink_RendersHtmlAnchor() {
29
    final Supplier<Map<String, String>> DEFINITIONS = () -> Map.of(
30
      "text", TEXT,
31
      "url", URL,
32
      "key", KEY
33
    );
34
35
    final var context = ProcessorContext.builder()
36
      .with( ProcessorContext.Mutator::setSourcePath, Paths.get( "test.md" ) )
37
      .with( ProcessorContext.Mutator::setDefinitions, DEFINITIONS )
38
      .with( ProcessorContext.Mutator::setExportFormat, TEXT_MARKDOWN )
39
      .build();
40
41
    final var mp = ProcessorFactory.createProcessors( context );
42
    final var actual = mp.apply( "[{{text}}]({{url}}) [{{key}}]{.kbd}" );
43
44
    assertEquals( EXPECTED, actual );
45
  }
46
}
147
M src/test/java/com/keenwrite/util/AlphanumComparatorTest.java
1111
1212
/**
13
 * Responsible for testing the http://www.davekoelle.com/alphanum.html
13
 * Tests <a href="http://www.davekoelle.com/alphanum.html">alphanum</a>
1414
 * implementation.
1515
 */
...
2424
  public void test_Sort_UnsortedList_SortedAlphanumerically() {
2525
    final var expected = Arrays.asList(
26
      "01-introduction.md",
27
      "02-variables.md",
2628
      "10X Radonius",
2729
      "20X Radonius",
M src/test/java/com/keenwrite/util/RangeValidatorTest.java
1717
    final var validator = new RangeValidator( lo + "-" + hi );
1818
19
    for( int i = lo; i < hi; i++ ) {
19
    for( var i = lo; i < hi; i++ ) {
2020
      assertTrue( validator.test( i ) );
2121
    }
...
4444
4545
    // Arbitrary end value.
46
    for( int i = lo; i < lo + 101; i++ ) {
46
    for( var i = lo; i < lo + 101; i++ ) {
4747
      assertTrue( validator.test( i ) );
4848
    }
...
5757
    final var validator = new RangeValidator( "-" + hi );
5858
59
    for( int i = 1; i < hi; i++ ) {
59
    for( var i = 1; i < hi; i++ ) {
6060
      assertTrue( validator.test( i ) );
6161
    }
A tokens/.gitignore
1
publish.url
12
A tokens/.placeholder
11