| 17 | 17 | keenwrite.build_artifacts.txt |
| 18 | 18 | todo |
| 19 | tokens | |
| 19 | 20 |
| 5 | 5 | ## Download |
| 6 | 6 | |
| 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. | |
| 12 | 8 | |
| 13 | 9 | ## Run |
| ... | ||
| 28 | 24 | ``` |
| 29 | 25 | |
| 30 | ### Other | |
| 26 | ### MacOS | |
| 31 | 27 | |
| 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: | |
| 33 | 38 | |
| 34 | 39 | 1. Download the *Full version* of the Java Runtime Environment, [JRE 21](https://bell-sw.com/pages/downloads). |
| 35 | 40 | * JavaFX, which is bundled with BellSoft's *Full version*, is required. |
| 36 | 41 | 1. Install the JRE (include JRE's `bin` directory in the `PATH` environment variable). |
| 37 | 42 | 1. Open a new terminal. |
| 38 | 43 | 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). | |
| 41 | 46 | 1. Place the `.jar` and `.sh` in the same directory. |
| 42 | 47 | 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. | |
| 43 | 53 | 1. Run: `./keenwrite.sh` |
| 44 | 54 | |
| ... | ||
| 59 | 69 | * Integrated file manager |
| 60 | 70 | * Interactive document outline |
| 61 | * Internationalized font support (e.g., Chinese, Japanese, Korean, etc.) | |
| 71 | * Internationalized font support (e.g., Chinese, Japanese, Korean) | |
| 62 | 72 | * Support for Pandoc's fenced div extended attribute syntax |
| 63 | 73 | * R integration |
| 5 | 5 | ## 下载 |
| 6 | 6 | |
| 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/) | |
| 12 | 8 | |
| 13 | 9 | ## 跑 |
| ... | ||
| 32 | 28 | ``` |
| 33 | 29 | |
| 34 | ### Other | |
| 30 | ### MacOS | |
| 35 | 31 | |
| 36 | Download and install a full version of [OpenJDK 20](https://bell-sw.com/pages/downloads) that includes JavaFX module support, then run: | |
| 32 | 执行以下命令: | |
| 37 | 33 | |
| 38 | 34 | ``` bash |
| 39 | java -jar keenwrite.jar | |
| 35 | chmod +x keenwrite.app | |
| 36 | ./keenwrite.app | |
| 40 | 37 | ``` |
| 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 | 应用程序已启动。 | |
| 41 | 60 | |
| 42 | 61 | ## 特征 |
| 9 | 9 | } |
| 10 | 10 | 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" | |
| 13 | 13 | } |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | 16 | plugins { |
| 17 | 17 | id 'application' |
| 18 | 18 | id 'org.openjfx.javafxplugin' version '0.1.0' |
| 19 | 19 | 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" | |
| 21 | 21 | } |
| 22 | 22 | |
| ... | ||
| 89 | 89 | |
| 90 | 90 | dependencies { |
| 91 | def v_junit = '5.9.3' | |
| 91 | def v_junit = '5.10.0' | |
| 92 | 92 | def v_flexmark = '0.64.8' |
| 93 | def v_jackson = '2.15.2' | |
| 93 | def v_jackson = '2.15.3' | |
| 94 | 94 | def v_echosvg = '1.0' |
| 95 | 95 | def v_picocli = '4.7.5' |
| 96 | 96 | |
| 97 | 97 | // JavaFX |
| 98 | 98 | 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' | |
| 101 | 101 | implementation 'org.fxmisc.wellbehaved:wellbehavedfx:0.3.3' |
| 102 | implementation 'com.miglayout:miglayout-javafx:11.1' | |
| 102 | implementation 'com.miglayout:miglayout-javafx:11.2' | |
| 103 | 103 | implementation 'com.dlsc.preferencesfx:preferencesfx-core:11.16.0' |
| 104 | 104 | implementation 'com.panemu:tiwulfx-dock:0.2' |
| ... | ||
| 148 | 148 | implementation 'org.apache.commons:commons-configuration2:2.9.0' |
| 149 | 149 | 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' | |
| 151 | 151 | implementation 'org.greenrobot:eventbus-java:3.3.1' |
| 152 | 152 | |
| ... | ||
| 169 | 169 | testImplementation "org.junit.jupiter:junit-jupiter-api:${v_junit}" |
| 170 | 170 | testImplementation "org.junit.jupiter:junit-jupiter-params:${v_junit}" |
| 171 | testImplementation 'org.assertj:assertj-core:3.24.2' | |
| 171 | 172 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' |
| 172 | 173 | } |
| 10 | 10 | source $HOME/bin/build-template |
| 11 | 11 | |
| 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" | |
| 14 | 20 | |
| 15 | 21 | readonly OPT_JAVA=$(cat << END_OF_ARGS |
| ... | ||
| 31 | 37 | ARG_JAVA_OS="linux" |
| 32 | 38 | 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" | |
| 35 | 41 | ARG_JAVA_DIR="java" |
| 36 | 42 | |
| 37 | 43 | ARG_DIR_DIST="dist" |
| 38 | 44 | |
| 39 | FILE_DIST_EXEC="run.sh" | |
| 45 | FILE_LAUNCHER_SCRIPT="run.sh" | |
| 40 | 46 | |
| 41 | 47 | ARG_PATH_DIST_JAR="${SCRIPT_DIR}/build/libs/${FILE_APP_JAR}" |
| 42 | 48 | |
| 43 | 49 | DEPENDENCIES=( |
| 44 | 50 | "gradle,https://gradle.org" |
| 45 | 51 | "warp-packer,https://github.com/Reisz/warp/releases" |
| 46 | 52 | "linux-x64.warp-packer,https://github.com/dgiagio/warp/releases" |
| 53 | "osslsigncode,https://www.winehq.org" | |
| 47 | 54 | "tar,https://www.gnu.org/software/tar" |
| 48 | 55 | "wine,https://www.winehq.org" |
| ... | ||
| 62 | 69 | |
| 63 | 70 | # --------------------------------------------------------------------------- |
| 64 | # Generates | |
| 71 | # Generates an application binary as a self-extracting installer. | |
| 65 | 72 | # --------------------------------------------------------------------------- |
| 66 | 73 | execute() { |
| ... | ||
| 80 | 87 | |
| 81 | 88 | $do_brand_windows |
| 89 | $do_sign_windows | |
| 82 | 90 | |
| 83 | 91 | return 1 |
| ... | ||
| 91 | 99 | ARCHIVE_EXT="zip" |
| 92 | 100 | ARCHIVE_APP="unzip -qq" |
| 93 | FILE_DIST_EXEC="run.bat" | |
| 101 | FILE_LAUNCHER_SCRIPT="run.bat" | |
| 94 | 102 | APP_EXTENSION="exe" |
| 95 | 103 | do_create_launch_script=utile_create_launch_script_windows |
| 96 | 104 | do_brand_windows=utile_brand_windows |
| 105 | do_sign_windows=utile_sign_windows | |
| 97 | 106 | elif [ "${ARG_JAVA_OS}" = "macos" ]; then |
| 98 | 107 | APP_EXTENSION="app" |
| ... | ||
| 166 | 175 | $log "Create Linux launch script" |
| 167 | 176 | |
| 168 | cat > "${FILE_DIST_EXEC}" << __EOT | |
| 177 | cat > "${FILE_LAUNCHER_SCRIPT}" << __EOT | |
| 169 | 178 | #!/usr/bin/env bash |
| 170 | 179 | |
| 171 | 180 | readonly SCRIPT_SRC="\$(dirname "\${BASH_SOURCE[\${#BASH_SOURCE[@]} - 1]}")" |
| 172 | 181 | |
| 173 | 182 | "\${SCRIPT_SRC}/${ARG_JAVA_DIR}/bin/java" ${OPT_JAVA} -jar "\${SCRIPT_SRC}/${FILE_APP_JAR}" "\$@" 2>/dev/null |
| 174 | 183 | __EOT |
| 175 | 184 | |
| 176 | chmod +x "${FILE_DIST_EXEC}" | |
| 185 | chmod +x "${FILE_LAUNCHER_SCRIPT}" | |
| 177 | 186 | } |
| 178 | 187 | |
| 179 | 188 | # --------------------------------------------------------------------------- |
| 180 | 189 | # Create Windows-specific launch script. |
| 181 | 190 | # --------------------------------------------------------------------------- |
| 182 | 191 | utile_create_launch_script_windows() { |
| 183 | 192 | $log "Create Windows launch script" |
| 184 | 193 | |
| 185 | cat > "${FILE_DIST_EXEC}" << __EOT | |
| 194 | cat > "${FILE_LAUNCHER_SCRIPT}" << __EOT | |
| 186 | 195 | @echo off |
| 187 | 196 | |
| 188 | 197 | 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 | |
| 190 | 199 | __EOT |
| 191 | 200 | |
| 192 | 201 | # Convert Unix end of line characters (\n) to Windows format (\r\n). |
| 193 | 202 | # 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}" | |
| 195 | 204 | } |
| 196 | 205 | |
| 197 | 206 | # --------------------------------------------------------------------------- |
| 198 | # Modify the binary to include icon and identifying information. | |
| 207 | # Modify the Windows binary to include icon and identifying information. | |
| 199 | 208 | # --------------------------------------------------------------------------- |
| 200 | 209 | 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}) | |
| 214 | 217 | |
| 215 | wine ${SCRIPT_DIR}/scripts/rcedit-x64.exe "${BINARY}" \ | |
| 218 | $log "Brand ${BINARY_LC}" | |
| 219 | wine "${SCRIPT_DIR}/scripts/rcedit-x64.exe" "${BINARY_LC}" \ | |
| 216 | 220 | --set-icon "scripts/logo.ico" \ |
| 217 | --set-version-string "OriginalFilename" "${application_title}.exe" \ | |
| 221 | --set-version-string "OriginalFilename" "${BINARY}" \ | |
| 218 | 222 | --set-version-string "CompanyName" "${COMPANY}" \ |
| 219 | --set-version-string "ProductName" "${application_title}" \ | |
| 223 | --set-version-string "ProductName" "${APP_NAME}" \ | |
| 220 | 224 | --set-version-string "LegalCopyright" "Copyright ${YEAR} ${COMPANY}" \ |
| 221 | 225 | --set-version-string "FileDescription" "${DESCRIPTION}" \ |
| 222 | 226 | --set-version-string "Size" "${DESCRIPTION}" \ |
| 223 | 227 | --set-product-version "${VERSION}" \ |
| 224 | 228 | --set-file-version "${VERSION}" |
| 225 | 229 | |
| 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}" | |
| 227 | 255 | } |
| 228 | 256 | |
| ... | ||
| 243 | 271 | packer_opt_input="input-dir" |
| 244 | 272 | |
| 245 | local -r FILE_APP_NAME="${APP_NAME}.${APP_EXTENSION}" | |
| 273 | local -r FILE_APP_NAME="${APP_NAME_LC}.${APP_EXTENSION}" | |
| 246 | 274 | $log "Create ${FILE_APP_NAME}" |
| 247 | 275 | |
| ... | ||
| 265 | 293 | --arch "${ARG_JAVA_OS}-${ARG_JAVA_ARCH}" \ |
| 266 | 294 | --${packer_opt_input} "${ARG_DIR_DIST}" \ |
| 267 | --exec "${FILE_DIST_EXEC}" \ | |
| 295 | --exec "${FILE_LAUNCHER_SCRIPT}" \ | |
| 268 | 296 | --output "${FILE_APP_NAME}" > /dev/null |
| 269 | 297 | |
| ... | ||
| 300 | 328 | do_create_launcher=utile_create_launcher |
| 301 | 329 | do_brand_windows=: |
| 330 | do_sign_windows=: | |
| 302 | 331 | |
| 303 | 332 | main "$@" |
| 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 | ||
| 1 | 19 |
| 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 | ||
| 1 | 39 |
| 1 | sign.sh | |
| 1 | code-sign-cert.pfx | |
| 2 | 2 |
| 272 | 272 | } |
| 273 | 273 | |
| 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 | ||
| 274 | 282 | /* SPEECH BUBBLE ***/ |
| 275 | 283 | div.bubblerx, div.bubbletx { |
| 27 | 27 | } |
| 28 | 28 | |
| 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"; | |
| 32 | 31 | |
| 33 | 32 | @Test |
| ... | ||
| 43 | 42 | }; |
| 44 | 43 | |
| 45 | final var file = File.createTempFile("kw-", "test"); | |
| 44 | final var file = File.createTempFile( "kw-", "test" ); | |
| 46 | 45 | file.deleteOnExit(); |
| 47 | 46 | |
| 1 | 1 |
| 1 | 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> |
| 2 | <!-- Created with Inkscape (http://www.inkscape.org/) --> | |
| 3 | ||
| 4 | 2 | <svg |
| 5 | 3 | 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" | |
| 8 | 6 | version="1.1" |
| 9 | id="svg1" | |
| 7 | id="svg7" | |
| 10 | 8 | xmlns:xlink="http://www.w3.org/1999/xlink" |
| 11 | 9 | xmlns="http://www.w3.org/2000/svg" |
| 12 | 10 | xmlns:svg="http://www.w3.org/2000/svg"> |
| 13 | 11 | <defs |
| 14 | id="defs1"> | |
| 12 | id="defs2"> | |
| 15 | 13 | <linearGradient |
| 16 | 14 | 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" /> | |
| 24 | 22 | <linearGradient |
| 25 | 23 | 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"> | |
| 32 | 30 | <stop |
| 33 | 31 | offset="0" |
| 34 | 32 | stop-color="#ec706a" |
| 35 | id="stop2" /> | |
| 33 | id="stop1" /> | |
| 36 | 34 | <stop |
| 37 | 35 | offset="1" |
| 38 | 36 | stop-color="#ecd980" |
| 39 | id="stop4" /> | |
| 37 | id="stop2" /> | |
| 40 | 38 | </linearGradient> |
| 41 | 39 | </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" /> | |
| 42 | 64 | <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" /> | |
| 103 | 70 | </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" /> | |
| 104 | 97 | </svg> |
| 105 | 98 |
| 4 | 4 | <title>KeenWrite</title> |
| 5 | 5 | <meta charset="UTF-8"> |
| 6 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| 6 | 7 | <meta name="description" content="cross-platform, open-source desktop editor"> |
| 7 | 8 | <meta name="keywords" content="markdown, text, editor, software"> |
| 8 | 9 | <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'"> | |
| 138 | 12 | </head> |
| 139 | 13 | <body> |
| 140 | 14 | <header> |
| 141 | 15 | <img src="images/logo/title.svg" alt="KeenWrite" class="title"> |
| 142 | 16 | <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. | |
| 144 | 19 | </p> |
| 145 | 20 | </header> |
| 146 | 21 | <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> | |
| 175 | 52 | </main> |
| 176 | 53 | <nav> |
| 177 | 54 | <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> | |
| 182 | 60 | </ul> |
| 183 | 61 | </nav> |
| 1 | user-agent: * | |
| 2 | disallow: | |
| 3 | crawl-delay: 60 | |
| 1 | 4 |
| 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 | © 2023, White Magic Software, Ltd. | |
| 64 | </footer> | |
| 65 | </body> | |
| 66 | </html> | |
| 67 | ||
| 1 | 68 |
| 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 | ||
| 1 | 150 |