Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/keenwrite.git
M .gitignore
1717
keenwrite.build_artifacts.txt
1818
todo
19
tokens
1920
M README.md
55
## Download
66
7
Download one of the following editions:
8
9
* [Windows](https://github.com/DaveJarvis/keenwrite/releases/latest/download/keenwrite.exe)
10
* [Linux](https://github.com/DaveJarvis/keenwrite/releases/latest/download/keenwrite.bin)
11
* [Java Archive](https://github.com/DaveJarvis/keenwrite/releases/latest/download/keenwrite.jar)
7
Visit [KeenWrite.com](https://keenwrite.com/) for downloads.
128
139
## Run
...
2824
```
2925
30
### Other
26
### MacOS
3127
32
On other platforms, such as MacOS, start the application as follows:
28
Execute the following commands in a terminal:
29
30
``` bash
31
chmod +x keenwrite.app
32
./keenwrite.app
33
```
34
35
### Java
36
37
Using Java, first follow these one-time setup steps:
3338
3439
1. Download the *Full version* of the Java Runtime Environment, [JRE 21](https://bell-sw.com/pages/downloads).
3540
   * JavaFX, which is bundled with BellSoft's *Full version*, is required.
3641
1. Install the JRE (include JRE's `bin` directory in the `PATH` environment variable).
3742
1. Open a new terminal.
3843
1. Verify the installation: `java -version`
39
1. Download [keenwrite.jar](https://github.com/DaveJarvis/keenwrite/releases/latest/download/keenwrite.jar).
40
1. Download [keenwrite.sh](https://raw.githubusercontent.com/DaveJarvis/keenwrite/master/keenwrite.sh).
44
1. Download [keenwrite.jar](https://keenwrite.com/downloads/keenwrite.jar).
45
1. Download [keenwrite.sh](https://gitlab.com/DaveJarvis/KeenWrite/-/raw/main/keenwrite.sh?inline=false).
4146
1. Place the `.jar` and `.sh` in the same directory.
4247
1. Make `keenwrite.sh` executable: `chmod +x keenwrite.sh`
48
49
Start the application as follows:
50
51
1. Open a new terminal.
52
1. Change to the `.jar` and `.sh` directory.
4353
1. Run: `./keenwrite.sh`
4454
...
5969
* Integrated file manager
6070
* Interactive document outline
61
* Internationalized font support (e.g., Chinese, Japanese, Korean, etc.)
71
* Internationalized font support (e.g., Chinese, Japanese, Korean)
6272
* Support for Pandoc's fenced div extended attribute syntax
6373
* R integration
M README.zh-CN.md
55
## 下载
66
7
下载以下版本之一:
8
9
* [Windows](https://github.com/DaveJarvis/keenwrite/releases/latest/download/keenwrite.exe)
10
* [Linux](https://github.com/DaveJarvis/keenwrite/releases/latest/download/keenwrite.bin)
11
* [Java Archive](https://github.com/DaveJarvis/keenwrite/releases/latest/download/keenwrite.jar)
7
[KeenWrite.com](https://keenwrite.com/)
128
139
## 跑
...
3228
```
3329
34
### Other
30
### MacOS
3531
36
Download and install a full version of [OpenJDK 20](https://bell-sw.com/pages/downloads) that includes JavaFX module support, then run:
32
执行以下命令:
3733
3834
``` bash
39
java -jar keenwrite.jar
35
chmod +x keenwrite.app
36
./keenwrite.app
4037
```
38
39
### Java
40
41
使用Java,首先按照以下一次性设置步骤进行操作:
42
43
1. 下载Java Runtime Environment(JRE)的*完整版本*,[JRE 21](https://bell-sw.com/pages/downloads)。
44
   * 需要BellSoft的*完整版本*中捆绑的JavaFX。
45
1. 安装JRE(将JRE的`bin`目录包含在`PATH`环境变量中)。
46
1. 打开一个新的终端。
47
1. 验证安装:`java -version`
48
1. 下载[keenwrite.jar](https://keenwrite.com/downloads/keenwrite.jar)。
49
1. 下载[keenwrite.sh](https://gitlab.com/DaveJarvis/KeenWrite/-/raw/main/keenwrite.sh?inline=false)。
50
1. 将`.jar`和`.sh`文件放置在同一个目录中。
51
1. 使`keenwrite.sh`可执行:`chmod +x keenwrite.sh`
52
53
按以下方式启动应用程序:
54
55
1. 打开一个新的终端。
56
1. 切换到`.jar`和`.sh`目录。
57
1. 运行:`./keenwrite.sh`
58
59
应用程序已启动。
4160
4261
## 特征
M build.gradle
99
  }
1010
  dependencies {
11
    classpath 'org.owasp:dependency-check-gradle:8.2.1'
12
    classpath "com.github.spotbugs.snom:spotbugs-gradle-plugin:5.0.14"
11
    classpath 'org.owasp:dependency-check-gradle:8.4.2'
12
    classpath "com.github.spotbugs.snom:spotbugs-gradle-plugin:5.2.1"
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.0.0'
20
  id "com.github.spotbugs" version "5.1.3"
20
  id "com.github.spotbugs" version "5.2.1"
2121
}
2222
...
8989
9090
dependencies {
91
  def v_junit = '5.9.3'
91
  def v_junit = '5.10.0'
9292
  def v_flexmark = '0.64.8'
93
  def v_jackson = '2.15.2'
93
  def v_jackson = '2.15.3'
9494
  def v_echosvg = '1.0'
9595
  def v_picocli = '4.7.5'
9696
9797
  // JavaFX
9898
  implementation 'org.controlsfx:controlsfx:11.1.2'
99
  implementation 'org.fxmisc.richtext:richtextfx:0.11.1'
100
  implementation 'org.fxmisc.flowless:flowless:0.7.1'
99
  implementation 'org.fxmisc.richtext:richtextfx:0.11.2'
100
  implementation 'org.fxmisc.flowless:flowless:0.7.2'
101101
  implementation 'org.fxmisc.wellbehaved:wellbehavedfx:0.3.3'
102
  implementation 'com.miglayout:miglayout-javafx:11.1'
102
  implementation 'com.miglayout:miglayout-javafx:11.2'
103103
  implementation 'com.dlsc.preferencesfx:preferencesfx-core:11.16.0'
104104
  implementation 'com.panemu:tiwulfx-dock:0.2'
...
148148
  implementation 'org.apache.commons:commons-configuration2:2.9.0'
149149
  implementation 'com.github.albfernandez:juniversalchardet:2.4.0'
150
  implementation 'javax.validation:validation-api:2.0.1.Final'
150
  implementation 'jakarta.validation:jakarta.validation-api:3.0.2'
151151
  implementation 'org.greenrobot:eventbus-java:3.3.1'
152152
...
169169
  testImplementation "org.junit.jupiter:junit-jupiter-api:${v_junit}"
170170
  testImplementation "org.junit.jupiter:junit-jupiter-params:${v_junit}"
171
  testImplementation 'org.assertj:assertj-core:3.24.2'
171172
  testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
172173
}
M installer.sh
1010
source $HOME/bin/build-template
1111
12
readonly APP_NAME=$(find "${SCRIPT_DIR}/src" -type f -name "settings.properties" -exec cat {} \; | grep "application.title=" | cut -d'=' -f2)
13
readonly FILE_APP_JAR="${APP_NAME}.jar"
12
# Case sensitive application name.
13
readonly APP_NAME=$(cat \
14
  "${SCRIPT_DIR}/src/main/resources/bootstrap.properties" | \
15
  cut -d'=' -f2
16
)
17
# Lowercase application name.
18
readonly APP_NAME_LC=${APP_NAME,,}
19
readonly FILE_APP_JAR="${APP_NAME_LC}.jar"
1420
1521
readonly OPT_JAVA=$(cat << END_OF_ARGS
...
3137
ARG_JAVA_OS="linux"
3238
ARG_JAVA_ARCH="amd64"
33
ARG_JAVA_VERSION="21"
34
ARG_JAVA_UPDATE="37"
39
ARG_JAVA_VERSION="21.0.1"
40
ARG_JAVA_UPDATE="12"
3541
ARG_JAVA_DIR="java"
3642
3743
ARG_DIR_DIST="dist"
3844
39
FILE_DIST_EXEC="run.sh"
45
FILE_LAUNCHER_SCRIPT="run.sh"
4046
4147
ARG_PATH_DIST_JAR="${SCRIPT_DIR}/build/libs/${FILE_APP_JAR}"
4248
4349
DEPENDENCIES=(
4450
  "gradle,https://gradle.org"
4551
  "warp-packer,https://github.com/Reisz/warp/releases"
4652
  "linux-x64.warp-packer,https://github.com/dgiagio/warp/releases"
53
  "osslsigncode,https://www.winehq.org"
4754
  "tar,https://www.gnu.org/software/tar"
4855
  "wine,https://www.winehq.org"
...
6269
6370
# ---------------------------------------------------------------------------
64
# Generates
71
# Generates an application binary as a self-extracting installer.
6572
# ---------------------------------------------------------------------------
6673
execute() {
...
8087
8188
  $do_brand_windows
89
  $do_sign_windows
8290
8391
  return 1
...
9199
    ARCHIVE_EXT="zip"
92100
    ARCHIVE_APP="unzip -qq"
93
    FILE_DIST_EXEC="run.bat"
101
    FILE_LAUNCHER_SCRIPT="run.bat"
94102
    APP_EXTENSION="exe"
95103
    do_create_launch_script=utile_create_launch_script_windows
96104
    do_brand_windows=utile_brand_windows
105
    do_sign_windows=utile_sign_windows
97106
  elif [ "${ARG_JAVA_OS}" = "macos" ]; then
98107
    APP_EXTENSION="app"
...
166175
  $log "Create Linux launch script"
167176
168
  cat > "${FILE_DIST_EXEC}" << __EOT
177
  cat > "${FILE_LAUNCHER_SCRIPT}" << __EOT
169178
#!/usr/bin/env bash
170179
171180
readonly SCRIPT_SRC="\$(dirname "\${BASH_SOURCE[\${#BASH_SOURCE[@]} - 1]}")"
172181
173182
"\${SCRIPT_SRC}/${ARG_JAVA_DIR}/bin/java" ${OPT_JAVA} -jar "\${SCRIPT_SRC}/${FILE_APP_JAR}" "\$@" 2>/dev/null
174183
__EOT
175184
176
  chmod +x "${FILE_DIST_EXEC}"
185
  chmod +x "${FILE_LAUNCHER_SCRIPT}"
177186
}
178187
179188
# ---------------------------------------------------------------------------
180189
# Create Windows-specific launch script.
181190
# ---------------------------------------------------------------------------
182191
utile_create_launch_script_windows() {
183192
  $log "Create Windows launch script"
184193
185
  cat > "${FILE_DIST_EXEC}" << __EOT
194
  cat > "${FILE_LAUNCHER_SCRIPT}" << __EOT
186195
@echo off
187196
188197
set SCRIPT_DIR=%~dp0
189
"%SCRIPT_DIR%\\${ARG_JAVA_DIR}\\bin\\java" ${OPT_JAVA} -jar "%SCRIPT_DIR%\\${APP_NAME}.jar" %* 2>nul
198
"%SCRIPT_DIR%\\${ARG_JAVA_DIR}\\bin\\java" ${OPT_JAVA} -jar "%SCRIPT_DIR%\\${FILE_APP_JAR}" %* 2>nul
190199
__EOT
191200
192201
  # Convert Unix end of line characters (\n) to Windows format (\r\n).
193202
  # This avoids any potential line conversion issues with the repository.
194
  sed -i 's/$/\r/' "${FILE_DIST_EXEC}"
203
  sed -i 's/$/\r/' "${FILE_LAUNCHER_SCRIPT}"
195204
}
196205
197206
# ---------------------------------------------------------------------------
198
# Modify the binary to include icon and identifying information.
207
# Modify the Windows binary to include icon and identifying information.
199208
# ---------------------------------------------------------------------------
200209
utile_brand_windows() {
201
  # Read the properties file to get the application name (case sensitvely).
202
  while IFS='=' read -r key value
203
  do
204
    key=$(echo $key | tr '.' '_')
205
    eval ${key}=\${value}
206
  done < "src/main/resources/bootstrap.properties"
207
208
  readonly BINARY="${APP_NAME}.exe"
209
  readonly VERSION=$(git describe --tags)
210
  readonly COMPANY="White Magic Software, Ltd."
211
  readonly YEAR=$(date +%Y)
212
  readonly DESCRIPTION="Markdown editor with live preview, variables, and math."
213
  readonly SIZE=$(stat --format="%s" ${BINARY})
210
  local -r BINARY="${APP_NAME}.exe"
211
  local -r BINARY_LC="${APP_NAME_LC}.exe"
212
  local -r VERSION=$(git describe --tags)
213
  local -r COMPANY="White Magic Software, Ltd."
214
  local -r YEAR=$(date +%Y)
215
  local -r DESCRIPTION="Markdown editor with live preview, variables, and math."
216
  local -r SIZE=$(stat --format="%s" ${BINARY_LC})
214217
215
  wine ${SCRIPT_DIR}/scripts/rcedit-x64.exe "${BINARY}" \
218
  $log "Brand ${BINARY_LC}"
219
  wine "${SCRIPT_DIR}/scripts/rcedit-x64.exe" "${BINARY_LC}" \
216220
    --set-icon "scripts/logo.ico" \
217
    --set-version-string "OriginalFilename" "${application_title}.exe" \
221
    --set-version-string "OriginalFilename" "${BINARY}" \
218222
    --set-version-string "CompanyName" "${COMPANY}" \
219
    --set-version-string "ProductName" "${application_title}" \
223
    --set-version-string "ProductName" "${APP_NAME}" \
220224
    --set-version-string "LegalCopyright" "Copyright ${YEAR} ${COMPANY}" \
221225
    --set-version-string "FileDescription" "${DESCRIPTION}" \
222226
    --set-version-string "Size" "${DESCRIPTION}" \
223227
    --set-product-version "${VERSION}" \
224228
    --set-file-version "${VERSION}"
225229
226
  mv -f "${BINARY}" "${application_title}.exe"
230
  $log "Rename ${BINARY_LC} to ${BINARY}"
231
  mv -f "${BINARY_LC}" "${BINARY}"
232
}
233
234
# ---------------------------------------------------------------------------
235
# Modify the Windows binary to include signed certificate information.
236
# ---------------------------------------------------------------------------
237
utile_sign_windows() {
238
  local -r FILE_CERTIFICATE="${SCRIPT_DIR}/tokens/code-sign-cert.pfx"
239
  local -r FILE_BINARY="${APP_NAME}.exe"
240
  local -r FILE_SIGNED_BINARY="signed-${FILE_BINARY}"
241
242
  rm -f "${FILE_SIGNED_BINARY}"
243
244
  $log "Sign ${FILE_BINARY}"
245
  osslsigncode sign \
246
    -pkcs12 "${FILE_CERTIFICATE}" \
247
    -askpass \
248
    -n "${APP_NAME}" \
249
    -i "https://www.${APP_NAME_LC}.com" \
250
    -in "${FILE_BINARY}" \
251
    -out "${FILE_SIGNED_BINARY}"
252
253
  $log "Rename ${FILE_SIGNED_BINARY} to ${FILE_BINARY}"
254
  mv -f "${FILE_SIGNED_BINARY}" "${FILE_BINARY}"
227255
}
228256
...
243271
  packer_opt_input="input-dir"
244272
245
  local -r FILE_APP_NAME="${APP_NAME}.${APP_EXTENSION}"
273
  local -r FILE_APP_NAME="${APP_NAME_LC}.${APP_EXTENSION}"
246274
  $log "Create ${FILE_APP_NAME}"
247275
...
265293
    --arch "${ARG_JAVA_OS}-${ARG_JAVA_ARCH}" \
266294
    --${packer_opt_input} "${ARG_DIR_DIST}" \
267
    --exec "${FILE_DIST_EXEC}" \
295
    --exec "${FILE_LAUNCHER_SCRIPT}" \
268296
    --output "${FILE_APP_NAME}" > /dev/null
269297
...
300328
do_create_launcher=utile_create_launcher
301329
do_brand_windows=:
330
do_sign_windows=:
302331
303332
main "$@"
A keenwrite.sh
1
#!/usr/bin/env bash
2
3
java \
4
  --add-opens=javafx.controls/javafx.scene.control=ALL-UNNAMED \
5
  --add-opens=javafx.controls/javafx.scene.control.skin=ALL-UNNAMED \
6
  --add-opens=javafx.graphics/javafx.scene.text=ALL-UNNAMED \
7
  --add-opens=javafx.graphics/com.sun.javafx.css=ALL-UNNAMED \
8
  --add-opens=javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED \
9
  --add-opens=javafx.graphics/com.sun.javafx.text=ALL-UNNAMED \
10
  --add-exports=javafx.base/com.sun.javafx.event=ALL-UNNAMED \
11
  --add-exports=javafx.graphics/com.sun.javafx.application=ALL-UNNAMED \
12
  --add-exports=javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED \
13
  --add-exports=javafx.graphics/com.sun.javafx.text=ALL-UNNAMED \
14
  --add-exports=javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED \
15
  --add-exports=javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED \
16
  --add-exports=javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED \
17
  -jar keenwrite.jar $@
18
119
D libs/keencount-min.jar
Binary file
A libs/keencount.jar
Binary file
M libs/keenquotes.jar
Binary file
A publish.sh
1
#!/usr/bin/env bash
2
3
# ---------------------------------------------------------------------------
4
# This script uploads the latest application release for all supported
5
# platforms.
6
# ---------------------------------------------------------------------------
7
8
readonly RELEASE=$(git describe --abbrev=0 --tags)
9
readonly APP_NAME=$(cut -d= -f2 ./src/main/resources/bootstrap.properties)
10
readonly PATH_TOKEN="tokens/${APP_NAME,,}.pat"
11
readonly URL=$(cat tokens/publish.url)
12
13
# ---------------------------------------------------------------------------
14
# Publishes a self-extracting installer to the repository.
15
#
16
# $1 - The relative path to the file to upload.
17
# ---------------------------------------------------------------------------
18
publish() {
19
  local -r PATH_ARCHIVE="${1}"
20
21
  if [ -f "${PATH_ARCHIVE}" ]; then
22
    scp "${PATH_ARCHIVE}" "${URL}"
23
  else
24
    echo "Missing ${PATH_ARCHIVE}, continuing."
25
  fi
26
}
27
28
if [ -f "${PATH_TOKEN}" ]; then
29
  cat "${PATH_TOKEN}" | glab auth login --hostname gitlab.com --stdin
30
31
  publish "${APP_NAME,,}.jar"
32
  publish "${APP_NAME,,}.bin"
33
  publish "${APP_NAME,,}.app"
34
  publish "${APP_NAME}.exe"
35
else
36
  echo "Create ${PATH_TOKEN} before publishing the release."
37
fi
38
139
M scripts/.gitignore
1
sign.sh
1
code-sign-cert.pfx
22
M src/main/resources/com/keenwrite/preview/webview.css
272272
}
273273
274
/* SIMULTANEOUS ACTION ***/
275
div.concurrent {
276
  border-top: .125em solid #ccc;
277
  border-left: .125em solid #ccc;
278
  border-radius: .25em;
279
  padding-left: .5em;
280
}
281
274282
/* SPEECH BUBBLE ***/
275283
div.bubblerx, div.bubbletx {
M src/test/java/com/keenwrite/io/downloads/DownloadManagerTest.java
2727
  }
2828
29
  private static final String SITE = "https://github.com/";
30
  private static final String URL
31
    = SITE + "DaveJarvis/keenwrite/releases/latest/download/keenwrite.exe";
29
  private static final String URL =
30
    "https://keenwrite.com/downloads/KeenWrite.exe";
3231
3332
  @Test
...
4342
    };
4443
45
    final var file = File.createTempFile("kw-", "test");
44
    final var file = File.createTempFile( "kw-", "test" );
4645
    file.deleteOnExit();
4746
A www/favicon.ico
11
M www/images/logo/title.svg
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
42
<svg
53
   width="300"
6
   height="71.784302"
7
   viewBox="0 0 79.374996 18.99293"
4
   height="71.784"
5
   viewBox="0 0 79.375 18.993"
86
   version="1.1"
9
   id="svg1"
7
   id="svg7"
108
   xmlns:xlink="http://www.w3.org/1999/xlink"
119
   xmlns="http://www.w3.org/2000/svg"
1210
   xmlns:svg="http://www.w3.org/2000/svg">
1311
  <defs
14
     id="defs1">
12
     id="defs2">
1513
    <linearGradient
1614
       xlink:href="#a"
17
       id="linearGradient347"
18
       gradientUnits="userSpaceOnUse"
19
       gradientTransform="matrix(-5.2145621,25.530992,-25.530992,-5.2145621,762.29957,221.94944)"
20
       x1="0.152358"
21
       y1="-0.044911999"
22
       x2="0.96880901"
23
       y2="-0.049470998" />
15
       id="b"
16
       x1=".152"
17
       x2=".969"
18
       y1="-.045"
19
       y2="-.049"
20
       gradientTransform="matrix(-5.21456 25.531 -25.531 -5.21456 762.3 221.95)"
21
       gradientUnits="userSpaceOnUse" />
2422
    <linearGradient
2523
       id="a"
26
       gradientTransform="matrix(-5.2145621,25.530992,-25.530992,-5.2145621,762.29957,221.94944)"
27
       gradientUnits="userSpaceOnUse"
28
       x1="0.152358"
29
       x2="0.96880901"
30
       y1="-0.044911999"
31
       y2="-0.049470998">
24
       x1=".152"
25
       x2=".969"
26
       y1="-.045"
27
       y2="-.049"
28
       gradientTransform="matrix(-5.21456 25.531 -25.531 -5.21456 762.3 221.95)"
29
       gradientUnits="userSpaceOnUse">
3230
      <stop
3331
         offset="0"
3432
         stop-color="#ec706a"
35
         id="stop2" />
33
         id="stop1" />
3634
      <stop
3735
         offset="1"
3836
         stop-color="#ecd980"
39
         id="stop4" />
37
         id="stop2" />
4038
    </linearGradient>
4139
  </defs>
40
  <path
41
     id="path32"
42
     style="fill:#51a9cf;fill-opacity:1"
43
     d="M 76.696905 4.2860773 C 75.760905 4.2860773 74.906182 4.5252025 74.132183 5.0038687 C 73.363517 5.4772016 72.75569 6.1470652 72.309024 7.0130643 C 71.857024 7.8677302 71.631024 8.8301007 71.631024 9.9007663 C 71.631024 10.551432 71.749377 11.151121 71.986044 11.69912 C 72.22271 12.242453 72.599183 12.680446 73.115183 13.013779 C 73.609849 13.347112 74.249645 13.514011 75.034977 13.514011 L 75.036011 13.515045 C 75.401344 13.515045 75.774515 13.471486 76.155848 13.384819 C 76.543181 13.293486 76.914668 13.167728 77.270001 13.007061 C 77.63 12.840395 77.957928 12.643578 78.253928 12.416912 C 78.554594 12.191579 78.804426 11.944165 79.003759 11.674832 L 78.278216 10.319866 C 78.132883 10.513199 77.91502 10.709648 77.625021 10.908982 C 77.334354 11.107648 77.019551 11.274547 76.680885 11.409213 C 76.342218 11.54388 76.024997 11.610753 75.728997 11.610753 C 75.341664 11.610753 75.061765 11.52782 74.889765 11.361154 C 74.717766 11.194487 74.615472 10.938419 74.582805 10.593753 L 74.582805 10.367925 C 75.255471 10.195925 75.882142 9.9917041 76.462808 9.7550376 C 77.043475 9.5130379 77.551793 9.2307205 77.987792 8.9080542 C 78.423125 8.5860545 78.761759 8.2149346 79.003759 7.794935 C 79.251092 7.3702687 79.374799 6.8890835 79.374799 6.351084 C 79.374799 5.9477511 79.27544 5.5926906 79.076106 5.2860243 C 78.882773 4.9746912 78.586815 4.7302129 78.188815 4.5522131 C 77.796149 4.3748799 77.298904 4.2860773 76.696905 4.2860773 z M 76.066964 5.8188125 C 76.28763 5.8188125 76.440888 5.8834174 76.526888 6.0120839 C 76.618888 6.1360838 76.664865 6.3406717 76.664865 6.6260048 C 76.664865 6.9160045 76.602828 7.1983219 76.478828 7.4729882 C 76.355495 7.7416546 76.189113 7.986133 75.979113 8.2067994 C 75.774447 8.4267992 75.548446 8.6044044 75.301113 8.7390709 C 75.054447 8.8737374 74.804098 8.9485318 74.550765 8.9638652 C 74.561478 8.6893636 74.596925 8.3453745 74.656186 7.9318786 C 74.714853 7.517879 74.857404 7.1312164 75.08407 6.7712167 C 75.25607 6.5018837 75.414314 6.275883 75.55898 6.0932165 C 75.704314 5.9105501 75.873631 5.8188125 76.066964 5.8188125 z " />
44
  <path
45
     id="path25"
46
     style="fill:#51a9cf;fill-opacity:1"
47
     d="M 15.616943 4.2860773 C 14.680944 4.2860773 13.826221 4.5252025 13.052222 5.0038687 C 12.283556 5.4772016 11.675729 6.1470652 11.229063 7.0130643 C 10.777063 7.8677302 10.551062 8.8301007 10.551062 9.9007663 C 10.551062 10.551432 10.669416 11.151121 10.906082 11.69912 C 11.142749 12.24312 11.519222 12.68148 12.035221 13.014813 C 12.529888 13.348146 13.169684 13.515045 13.955016 13.515045 L 13.95605 13.515045 C 14.321383 13.515045 14.694554 13.471486 15.075887 13.384819 C 15.46322 13.293486 15.834707 13.167728 16.19004 13.007061 C 16.550039 12.840395 16.877967 12.643578 17.173967 12.416912 C 17.474633 12.191579 17.724464 11.944165 17.923798 11.674832 L 17.198255 10.319866 C 17.052922 10.513199 16.834692 10.709648 16.544026 10.908982 C 16.254026 11.107648 15.93959 11.274547 15.600924 11.409213 C 15.262257 11.54388 14.945036 11.610753 14.649036 11.610753 C 14.261703 11.610753 13.981804 11.52782 13.809804 11.361154 C 13.637804 11.194487 13.53551 10.938419 13.502844 10.593753 L 13.502844 10.367925 C 14.17551 10.195925 14.802181 9.9917041 15.382847 9.7550376 C 15.963513 9.5130379 16.471464 9.2307205 16.906797 8.9080542 C 17.342797 8.5860545 17.681798 8.2149346 17.923798 7.794935 C 18.171131 7.3702687 18.294837 6.8890835 18.294837 6.351084 C 18.294837 5.9477511 18.195478 5.5926906 17.996145 5.2860243 C 17.802812 4.9746912 17.506853 4.7302129 17.108854 4.5522131 C 16.716188 4.3748799 16.218943 4.2860773 15.616943 4.2860773 z M 14.987003 5.8188125 C 15.207669 5.8188125 15.360927 5.8834174 15.446927 6.0120839 C 15.538926 6.1360838 15.584904 6.3406717 15.584904 6.6260048 C 15.584904 6.9160045 15.522867 7.1983219 15.398867 7.4729882 C 15.275534 7.7416546 15.109152 7.986133 14.899152 8.2067994 C 14.694486 8.4267992 14.468485 8.6044044 14.221152 8.7390709 C 13.974485 8.8737374 13.724137 8.9488987 13.470804 8.9648987 C 13.481471 8.6902323 13.516892 8.3458782 13.576225 7.9318786 C 13.634891 7.517879 13.777443 7.1312164 14.004109 6.7712167 C 14.176109 6.5018837 14.334353 6.275883 14.479019 6.0932165 C 14.624352 5.9105501 14.79367 5.8188125 14.987003 5.8188125 z " />
48
  <path
49
     id="path27"
50
     style="fill:#51a9cf;fill-opacity:1"
51
     d="M 24.377202 4.2860773 C 23.441869 4.2860773 22.586629 4.5252025 21.811963 5.0038687 C 21.043297 5.4772016 20.43547 6.1470652 19.988804 7.0130643 C 19.536805 7.8677302 19.310804 8.8301007 19.310804 9.9007663 C 19.310804 10.551432 19.429158 11.151121 19.665824 11.69912 C 19.90249 12.24312 20.278964 12.68148 20.794963 13.014813 C 21.290296 13.348146 21.930092 13.515045 22.714758 13.515045 C 23.080757 13.515045 23.455179 13.471486 23.837179 13.384819 C 24.223845 13.293486 24.594448 13.167728 24.949781 13.007061 C 25.309781 12.840395 25.638225 12.643578 25.934225 12.416912 C 26.235558 12.191579 26.48539 11.944165 26.684056 11.674832 L 25.957996 10.319866 C 25.812663 10.513199 25.594801 10.709648 25.304801 10.908982 C 25.014135 11.107648 24.699848 11.274547 24.361182 11.409213 C 24.022516 11.54388 23.705144 11.610753 23.409811 11.610753 C 23.021812 11.610753 22.742062 11.52782 22.570063 11.361154 C 22.398729 11.194487 22.296435 10.938419 22.263102 10.593753 L 22.263102 10.367925 C 22.935768 10.195925 23.56244 9.9917041 24.143106 9.7550376 C 24.723772 9.5130379 25.23209 9.2307205 25.668089 8.9080542 C 26.103422 8.5860545 26.442423 8.2149346 26.68509 7.794935 C 26.931756 7.3702687 27.055096 6.8890835 27.055096 6.351084 C 27.055096 5.9477511 26.955587 5.5926906 26.75692 5.2860243 C 26.562921 4.9746912 26.267112 4.7302129 25.869112 4.5522131 C 25.477113 4.3748799 24.979868 4.2860773 24.377202 4.2860773 z M 23.747778 5.8188125 C 23.967778 5.8188125 24.121552 5.8834174 24.208218 6.0120839 C 24.299552 6.1360838 24.345162 6.3406717 24.345162 6.6260048 C 24.345162 6.9160045 24.283125 7.1983219 24.159125 7.4729882 C 24.035792 7.7416546 23.868893 7.986133 23.658894 8.2067994 C 23.454894 8.4267992 23.228893 8.6044044 22.980893 8.7390709 C 22.734227 8.8737374 22.484396 8.9488987 22.231062 8.9648987 C 22.242396 8.6902323 22.2773 8.3458782 22.335966 7.9318786 C 22.3953 7.517879 22.537851 7.1312164 22.763851 6.7712167 C 22.935851 6.5018837 23.094461 6.275883 23.239794 6.0932165 C 23.385128 5.9105501 23.554445 5.8188125 23.747778 5.8188125 z " />
52
  <path
53
     d="M751.566 230.706c-2.527 12.283 1.949 15.415 1.949 15.415s1.787-7.837 5.132-6.391c2.871 1.237.668 6.515.668 6.515s18.882-18.12 4.517-24.348c0 0-3.15-1.644-6.354-.387-2.345.92-4.718 3.391-5.912 9.196"
54
     paint-order="stroke"
55
     style="fill:url(#b);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.72817;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
56
     transform="matrix(.20372 0 0 .20372 -95.423 -31.173)"
57
     id="path2" />
58
  <path
59
     fill="#126d95"
60
     d="m771.784 223.478-6.529-10.073 1.046-3.86 5.948 1.61zM773.124 207.876l-.545 2.01-5.935-1.607.545-2.01z"
61
     style="stroke-width:.59394"
62
     transform="matrix(.20372 0 0 .20372 -95.423 -31.173)"
63
     id="path3" />
4264
  <g
43
     id="layer1"
44
     transform="matrix(0.76997495,0,0,0.76997495,-41.151955,-104.91711)">
45
    <g
46
       id="g3650"
47
       transform="matrix(0.26458333,0,0,0.26458333,-70.48435,95.775023)">
48
      <path
49
         style="fill:url(#linearGradient347);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.72817;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
50
         paint-order="stroke"
51
         d="m 751.56561,230.70578 c -2.52643,12.28316 1.94926,15.41557 1.94926,15.41557 v 0 c 0,0 1.78754,-7.83729 5.13213,-6.39182 v 0 c 2.87111,1.23717 0.66827,6.51553 0.66827,6.51553 v 0 c 0,0 18.8813,-18.11967 4.51682,-24.34816 v 0 c 0,0 -3.14959,-1.64397 -6.35422,-0.3873 v 0 c -2.34448,0.91995 -4.71811,3.39174 -5.91226,9.19618"
52
         stroke-linecap="round"
53
         id="path14" />
54
      <path
55
         d="m 771.78395,223.47824 -6.52862,-10.07293 1.0453,-3.86041 5.94821,1.61096 z"
56
         fill="#126d95"
57
         id="path9"
58
         style="stroke-width:0.59394" />
59
      <path
60
         d="m 773.12415,207.87594 -0.54488,2.01024 -5.9356,-1.60759 0.54487,-2.01024 z"
61
         fill="#126d95"
62
         id="path11"
63
         style="stroke-width:0.59394" />
64
      <g
65
         fill="#51a9cf"
66
         id="g19"
67
         transform="matrix(0.5939397,0,0,0.5939397,281.00899,-270.18322)">
68
        <path
69
           d="m 834.01973,741.0381 c -1.68105,0.0185 -3.22054,1.13771 -3.68367,2.84981 -0.56186,2.07405 0.665,4.21099 2.73743,4.77241 l -13.96475,51.52944 -9.99361,-2.70665 c 8.36013,-31.46487 4.99411,-51.98144 4.99411,-51.98144 14.99782,-11.92097 23.67,-25.56577 27.63101,-32.97331 z"
70
           id="path13" />
71
        <path
72
           d="m 818.56767,802.18881 -0.9174,3.38458 -10.03996,-2.72957 0.91314,-3.37522 z"
73
           id="path15" />
74
        <path
75
           d="m 817.07405,807.70594 -1.75995,6.49966 -18.03534,9.08805 9.78412,-18.31044 z"
76
           id="path17" />
77
      </g>
78
      <path
79
         d="m 777.66024,170.31167 4.58864,-16.94469 c -0.18977,4.99163 0.16898,14.58143 4.28633,25.18926 0,0 -7.06553,9.8014 -13.06542,28.13866 l -5.95984,-1.61407 8.29457,-30.60477 c 1.23671,0.33502 2.50072,-0.39558 2.83417,-1.62646 0.26981,-0.99336 -0.15781,-2.0094 -0.97845,-2.53792"
80
         fill="#126d95"
81
         id="path21"
82
         style="stroke-width:0.59394" />
83
    </g>
84
    <g
85
       style="font-style:italic;font-weight:800;font-size:133.333px;font-family:'Merriweather Sans';letter-spacing:0;word-spacing:0;fill:#51a9cf"
86
       id="g35"
87
       transform="matrix(0.15714654,0,0,0.15714654,50.302906,133.11748)">
88
      <text
89
         x="16.133343"
90
         y="130.6234"
91
         id="text29"><tspan
92
           x="16.133343"
93
           y="130.6234"
94
           id="tspan27">KeenWr</tspan></text>
95
      <text
96
         x="552.53137"
97
         y="130.6234"
98
         id="text33"><tspan
99
           x="552.53137"
100
           y="130.6234"
101
           id="tspan31">te</tspan></text>
102
    </g>
65
     fill="#51a9cf"
66
     id="g4">
67
    <path
68
       d="M62.74 3.45a.467.467 0 0 0-.446.344.47.47 0 0 0 .332.578l-1.69 6.235-1.21-.328c1.012-3.807.605-6.29.605-6.29A13.105 13.105 0 0 0 63.674 0zM60.87 10.849l-.11.41-1.215-.33.11-.41zM60.69 11.516l-.213.787-2.182 1.1 1.183-2.216z"
69
       id="path4" />
10370
  </g>
71
  <path
72
     fill="#126d95"
73
     d="m777.66 170.312 4.589-16.945c-.19 4.992.169 14.581 4.286 25.19 0 0-7.065 9.8-13.065 28.138l-5.96-1.614 8.295-30.605a2.308 2.308 0 0 0 1.855-4.164"
74
     style="stroke-width:.59394"
75
     transform="matrix(.20372 0 0 .20372 -95.423 -31.173)"
76
     id="path5" />
77
  <path
78
     style="fill:#51a9cf;fill-opacity:1"
79
     d="M 52.691,13.385 53.917,4.4 h 2.71 l -0.129,1.872 q 0.178,-0.525 0.516,-0.976 0.34,-0.452 0.799,-0.726 0.46,-0.283 0.992,-0.283 0.428,0 0.549,0.097 l -0.5,2.856 Q 58.797,7.143 58.555,7.086 58.313,7.03 58.079,7.03 q -0.347,0 -0.645,0.072 -0.29,0.065 -0.565,0.218 -0.266,0.154 -0.548,0.404 l -0.823,5.662 z"
80
     id="path31" />
81
  <path
82
     style="fill:#51a9cf;fill-opacity:1"
83
     d="M 40.107,13.385 38.639,1.334 h 2.823 l 0.452,7.711 0.161,1.759 0.532,-1.759 2.033,-5.05 -0.29,-2.661 h 2.726 l 0.468,7.711 0.178,1.759 0.42,-1.759 2.629,-7.711 h 2.872 l -4.68,12.051 H 45.705 L 45.253,9.078 45.108,7.755 44.624,9.078 43.059,13.385 Z"
84
     id="path30" />
85
  <path
86
     style="fill:#51a9cf;fill-opacity:1"
87
     d="M 28.088,13.385 29.314,4.4 h 2.694 l -0.113,1.63 q 0.549,-0.823 1.29,-1.283 0.75,-0.46 1.63,-0.46 1.065,0 1.622,0.549 0.556,0.548 0.556,1.823 0,0.177 -0.056,0.645 -0.049,0.46 -0.13,1.025 -0.072,0.556 -0.137,1.024 L 36.582,9.95 q -0.057,0.436 -0.137,1 -0.073,0.557 -0.154,1.097 -0.072,0.54 -0.129,0.912 l -0.056,0.427 h -2.807 q 0.12,-0.806 0.217,-1.516 0.105,-0.718 0.186,-1.34 0.08,-0.628 0.145,-1.16 Q 33.944,8.554 34,8.014 34.065,7.465 34.073,7.175 34.089,6.748 33.928,6.578 33.767,6.401 33.428,6.401 33.21,6.401 32.968,6.506 32.734,6.61 32.5,6.812 32.266,7.006 32.048,7.28 31.838,7.554 31.669,7.885 l -0.774,5.501 z"
88
     id="path29" />
89
  <path
90
     style="fill:#51a9cf;fill-opacity:1"
91
     d="M 0,13.385 1.726,1.334 h 2.71 L 3.662,6.609 7.905,1.334 H 11.1 L 6.324,6.642 q 0.113,0.21 0.274,0.532 0.17,0.315 0.404,0.79 0.242,0.468 0.572,1.138 0.34,0.67 0.8,1.59 0.209,0.427 0.41,0.814 0.202,0.379 0.388,0.718 0.185,0.33 0.355,0.62 l 0.33,0.541 H 6.582 Q 6.55,13.329 6.462,13.151 6.372,12.974 6.235,12.675 6.098,12.369 5.905,11.949 l -0.42,-0.968 -1,-2.307 -1.29,1.356 -0.485,3.355 z"
92
     id="path6" />
93
  <path
94
     style="fill:#51a9cf;fill-opacity:1"
95
     d="m 67.21,13.547 q -0.854,0 -1.355,-0.444 -0.5,-0.444 -0.5,-1.25 0,-0.073 0.024,-0.347 l 0.057,-0.613 q 0.04,-0.347 0.08,-0.638 L 66.081,6.109 H 65.42 l 0.29,-1.71 h 0.823 l 0.774,-2.162 h 2.114 L 69.114,4.4 h 1.759 l -0.178,1.71 h -1.79 l -0.307,2.227 -0.194,1.387 q -0.072,0.508 -0.104,0.774 l -0.049,0.388 q -0.008,0.12 -0.008,0.226 0,0.242 0.113,0.379 0.113,0.137 0.436,0.137 0.169,0 0.427,-0.089 0.258,-0.097 0.516,-0.242 0.259,-0.153 0.428,-0.315 l 0.436,1.34 q -0.42,0.322 -0.944,0.605 -0.517,0.274 -1.13,0.451 -0.613,0.17 -1.314,0.17 z"
96
     id="path7" />
10497
</svg>
10598
A www/images/screenshots/01.png
Binary file
A www/images/screenshots/02.png
Binary file
A www/images/screenshots/03.png
Binary file
A www/images/screenshots/04.png
Binary file
A www/images/screenshots/05.png
Binary file
A www/images/screenshots/06.png
Binary file
A www/images/screenshots/07.png
Binary file
A www/images/screenshots/08.png
Binary file
M www/index.html
44
  <title>KeenWrite</title>
55
  <meta charset="UTF-8">
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
67
  <meta name="description" content="cross-platform, open-source desktop editor">
78
  <meta name="keywords" content="markdown, text, editor, software">
89
  <meta name="robots" content="index, follow">
9
  <style>
10
/* ************************************************************************ 
11
 *
12
 * Page
13
 *
14
 * ************************************************************************ */
15
:root {
16
  --accent-colour: #ec706a;
17
  --link-colour: #8cc6de;
18
}
19
20
body {
21
  /* Ensure the page doesn't extend full screen on large monitors. */
22
	max-width: 1000px; 
23
	margin: 0 auto;
24
25
  background: #363636;
26
  color: #eaeaea;
27
}
28
29
/* Text alignment. */
30
header, nav, footer {
31
  text-align: center;
32
}
33
34
/* ************************************************************************ 
35
 * Header
36
 * ************************************************************************ */
37
38
header {
39
  /* Avoid being flush with top of page, put space between the title and
40
   * the download buttons, ensure any text won't be flush with edges.
41
   */
42
  margin: 2em;
43
}
44
45
header p {
46
  line-height: 1.5em;
47
}
48
49
/* Ensure the application title is large enough. */
50
header > img.title {
51
  width: 100%;
52
  height: 72pt;
53
}
54
55
/* ************************************************************************ 
56
 * Download buttons
57
 * ************************************************************************ */
58
59
main {
60
  /* Arrange the buttons in a responsive, 2 x 2 grid. */
61
  display: grid;
62
  grid-template-rows: 1fr 1fr;
63
  grid-template-columns: max-content max-content;
64
  justify-content: center;
65
}
66
67
/* Make hyperlinks resemble buttons. */
68
a.download {
69
  display: inline-block;
70
71
  /* Separate the buttons from one another. */
72
  margin-top: 2em;
73
  margin-left: 1em;
74
  margin-right: 1em;
75
76
  /* Fancy buttons. */
77
  border-radius: 1em;
78
  background: var( --accent-colour );
79
}
80
81
a.download:hover {
82
  background: var( --link-colour );
83
}
84
85
img.download {
86
  /* Replace icon black with another colour. */
87
  filter: invert(6%)
88
    sepia(58%) saturate(857%) hue-rotate(158deg) brightness(91%) contrast(91%);
89
}
90
91
/* ************************************************************************ 
92
 * Navigation
93
 * ************************************************************************ */
94
95
nav {
96
  /* Don't crowd navigation links against the download buttons. */
97
  margin-top: 4em;
98
}
99
100
nav ul {
101
  /* Remove the bullets */
102
  list-style: none;
103
  padding: 0;
104
  margin: 0;
105
}
106
107
nav li {
108
  /* Put navigation items along a single line. */
109
  display: inline;
110
}
111
112
nav li:not(:last-child)::after {
113
  /* Separate navigation items with a bar. */
114
  content: " | ";
115
}
116
117
nav a, nav a:visited {
118
  color: var( --link-colour );
119
}
120
121
nav a:link:hover, nav a:visited:hover {
122
  color: var( --accent-colour );
123
}
124
125
/* ************************************************************************ 
126
 * Footer
127
 * ************************************************************************ */
128
129
/* Align and center footer along bottom of page. */
130
footer {
131
  position: fixed;
132
  bottom: 1em;
133
  left: 50%;
134
  transform: translateX(-50%);
135
  width: 100%;
136
}
137
  </style>
10
  <link rel="stylesheet" href="styles/base.css"
11
    media="print" onload="this.media='all'">
13812
</head>
13913
<body>
14014
<header>
14115
  <img src="images/logo/title.svg" alt="KeenWrite" class="title">
14216
  <p>
143
  A free, cross-platform, open-source desktop text editor.
17
    A free, cross-platform desktop text editor for producing beautifully
18
    typeset PDF files.
14419
  </p>
14520
</header>
14621
<main>
147
  <a href="https://gitlab.com/DaveJarvis/KeenWrite/-/releases/permalink/latest/keenwrite.bin"
148
     class="download"
149
     title="Download for 64-bit Linux (x86)"
150
     aria-label="Download for Linux"><img
151
       src="images/icons/linux.svg"
152
       alt="Download for Linux"
153
       class="download"></a>
154
  <a href="https://gitlab.com/DaveJarvis/KeenWrite/-/releases/permalink/latest/keenwrite.jar"
155
     class="download"
156
     title="Download for Java virtual machine"
157
     aria-label="Download for Java"><img
158
       src="images/icons/java.svg"
159
       alt="Download for Java"
160
       class="download"></a>
161
  <a href="https://gitlab.com/DaveJarvis/KeenWrite/-/releases/permalink/latest/keenwrite.exe"
162
     class="download"
163
     title="Download for 64-bit Windows (x86)"
164
     aria-label="Download for Windows"><img
165
       src="images/icons/windows.svg"
166
       alt="Download for Windows"
167
       class="download"></a>
168
  <a href="https://gitlab.com/DaveJarvis/KeenWrite/-/releases/permalink/latest/keenwrite.app"
169
     class="download"
170
     title="Download for 64-bit MacOS (x86)"
171
     aria-label="Download for MacOS"><img
172
       src="images/icons/apple.svg"
173
       alt="Download for MacOS"
174
       class="download"></a>
22
  <div class="downloads">
23
    <a href="downloads/keenwrite.bin"
24
       class="download"
25
       title="Download for 64-bit Linux (x86)"
26
       aria-label="Download for Linux"><img
27
         src="images/icons/linux.svg"
28
         alt="Download for Linux"
29
         class="download"></a>
30
    <a href="downloads/keenwrite.jar"
31
       class="download"
32
       title="Download for Java virtual machine"
33
       aria-label="Download for Java"><img
34
         src="images/icons/java.svg"
35
         alt="Download for Java"
36
         class="download"></a>
37
    <a href="downloads/KeenWrite.exe"
38
       class="download"
39
       title="Download for 64-bit Windows (x86)"
40
       aria-label="Download for Windows"><img
41
         src="images/icons/windows.svg"
42
         alt="Download for Windows"
43
         class="download"></a>
44
    <a href="downloads/keenwrite.app"
45
       class="download"
46
       title="Download for 64-bit MacOS (x86)"
47
       aria-label="Download for MacOS"><img
48
         src="images/icons/apple.svg"
49
         alt="Download for MacOS"
50
         class="download"></a>
51
  </div>
17552
</main>
17653
<nav>
17754
  <ul>
178
    <li><a href="https://www.youtube.com/playlist?list=PLB-WIt1cZYLm1MMx2FBG9KWzPIoWZMKu_">Tutorials</a></li>
179
    <li><a href="https://gitlab.com/DaveJarvis/KeenWrite">Sources</a></li>
180
    <li><a href="https://gitlab.com/DaveJarvis/KeenWrite/issues">Issues</a></li>
181
    <li><a href="https://gitlab.com/DaveJarvis/KeenWrite/-/blob/main/docs/README.md">Documentation</a></li>
55
    <li><a href="screenshots.html">screenshots</a></li>
56
    <li><a href="https://www.youtube.com/playlist?list=PLB-WIt1cZYLm1MMx2FBG9KWzPIoWZMKu_">tutorials</a></li>
57
    <li><a href="https://gitlab.com/DaveJarvis/KeenWrite">sources</a></li>
58
    <li><a href="https://gitlab.com/DaveJarvis/KeenWrite/issues">issues</a></li>
59
    <li><a href="https://gitlab.com/DaveJarvis/KeenWrite/-/blob/main/docs/README.md">documentation</a></li>
18260
  </ul>
18361
</nav>
A www/robots.txt
1
user-agent: * 
2
disallow: 
3
crawl-delay: 60
14
A www/screenshots.html
1
<!DOCTYPE html>
2
<html lang="en">
3
<head>
4
  <title>KeenWrite</title>
5
  <meta charset="UTF-8">
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
  <meta name="description" content="cross-platform, open-source desktop editor">
8
  <meta name="keywords" content="markdown, text, editor, software">
9
  <meta name="robots" content="index, follow">
10
  <link rel="stylesheet" href="styles/base.css"> 
11
</head>
12
<body>
13
<header>
14
  <img src="images/logo/title.svg" alt="KeenWrite" class="title">
15
  <p>
16
  A free, cross-platform desktop text editor for producing beautifully typeset PDF files.
17
  </p>
18
</header>
19
<main class="screenshots">
20
  <p>
21
  Interpolated variable replacement
22
  </p>
23
  <img src="images/screenshots/05.png" class="screenshot" alt="variables">
24
  <p>
25
  Technical diagrams
26
  </p>
27
  <img src="images/screenshots/01.png" class="screenshot" alt="diagrams">
28
  <p>
29
  Internationalization
30
  </p>
31
  <img src="images/screenshots/02.png" class="screenshot" alt="internationalization">
32
  <p>
33
  Mathematics
34
  </p>
35
  <img src="images/screenshots/03.png" class="screenshot" alt="math">
36
  <p>
37
  Document outline
38
  </p>
39
  <img src="images/screenshots/04.png" class="screenshot" alt="outline">
40
  <p>
41
  Single sourced metadata
42
  </p>
43
  <img src="images/screenshots/06.png" class="screenshot" alt="multi-window">
44
  <p>
45
  R computations
46
  </p>
47
  <img src="images/screenshots/07.png" class="screenshot" alt="computation">
48
  <p>
49
  Theme-driven PDF output
50
  </p>
51
  <img src="images/screenshots/08.png" class="screenshot" alt="output">
52
</main>
53
<nav>
54
  <ul>
55
    <li><a href="index.html">home</a></li>
56
    <li><a href="https://www.youtube.com/playlist?list=PLB-WIt1cZYLm1MMx2FBG9KWzPIoWZMKu_">tutorials</a></li>
57
    <li><a href="https://gitlab.com/DaveJarvis/KeenWrite">sources</a></li>
58
    <li><a href="https://gitlab.com/DaveJarvis/KeenWrite/issues">issues</a></li>
59
    <li><a href="https://gitlab.com/DaveJarvis/KeenWrite/-/blob/main/docs/README.md">documentation</a></li>
60
  </ul>
61
</nav>
62
<footer>
63
  &copy; 2023, White Magic Software, Ltd.
64
</footer>
65
</body>
66
</html>
67
168
A www/styles/base.css
1
/* ************************************************************************ 
2
 * Page
3
 * ************************************************************************ */
4
:root {
5
  --accent-colour: #ec706a;
6
  --link-colour: #8cc6de;
7
}
8
9
body {
10
  /* Ensure the page doesn't extend full screen on large monitors. */
11
  max-width: 1000px; 
12
  margin: 0 auto;
13
14
  background: #363636;
15
  color: #eaeaea;
16
}
17
18
/* Text alignment. */
19
header, nav, footer {
20
  text-align: center;
21
}
22
23
/* ************************************************************************ 
24
 * Header
25
 * ************************************************************************ */
26
27
header {
28
  /* Avoid being flush with top of page, put space between the title and
29
   * the download buttons, ensure any text won't be flush with edges.
30
   */
31
  margin: 2em;
32
  margin-top: 1em;
33
}
34
35
header p {
36
  line-height: 1.5em;
37
}
38
39
/* Ensure the application title is large enough. */
40
header > img.title {
41
  width: 100%;
42
  height: 72pt;
43
}
44
45
/* ************************************************************************ 
46
 * Screenshots
47
 * ************************************************************************ */
48
49
main.screenshots {
50
  text-align: center;
51
}
52
53
main.screenshots > p {
54
  padding-top: 1em;
55
}
56
57
main > img.screenshot {
58
  width: 80%;
59
60
  display: block;
61
  margin-left: auto;
62
  margin-right: auto;
63
64
  transition: all .2s ease-in-out;
65
}
66
67
main > img.screenshot:hover {
68
  width: 100%;
69
  transform: scale(1);
70
}
71
72
/* ************************************************************************ 
73
 * Download buttons
74
 * ************************************************************************ */
75
76
main > div.downloads {
77
  /* Arrange the buttons in a responsive, 2 x 2 grid. */
78
  display: grid;
79
  grid-template-rows: 1fr 1fr;
80
  grid-template-columns: max-content max-content;
81
  justify-content: center;
82
}
83
84
/* Make hyperlinks resemble buttons. */
85
a.download {
86
  display: inline-block;
87
88
  /* Separate the buttons from one another. */
89
  margin-top: 2em;
90
  margin-left: 1em;
91
  margin-right: 1em;
92
93
  /* Fancy buttons. */
94
  border-radius: 1em;
95
  background: var( --accent-colour );
96
}
97
98
a.download:hover {
99
  background: var( --link-colour );
100
}
101
102
img.download {
103
  /* Replace icon black with another colour. */
104
  filter: invert(6%)
105
    sepia(58%) saturate(857%) hue-rotate(158deg) brightness(91%) contrast(91%);
106
}
107
108
/* ************************************************************************ 
109
 * Navigation
110
 * ************************************************************************ */
111
112
nav {
113
  /* Don't crowd navigation links against the download buttons. */
114
  margin-top: 4em;
115
}
116
117
nav ul {
118
  /* Remove the bullets */
119
  list-style: none;
120
  padding: 0;
121
  margin: 0;
122
}
123
124
nav li {
125
  /* Put navigation items along a single line. */
126
  display: inline;
127
}
128
129
nav li:not(:last-child)::after {
130
  /* Separate navigation items with a bar. */
131
  content: " | ";
132
}
133
134
nav a, nav a:visited {
135
  color: var( --link-colour );
136
}
137
138
nav a:link:hover, nav a:visited:hover {
139
  color: var( --accent-colour );
140
}
141
142
/* ************************************************************************ 
143
 * Footer
144
 * ************************************************************************ */
145
footer {
146
  margin-top: 2em;
147
  margin-bottom: 1em;
148
}
149
1150