SuperMemo editions supported by this tool come in two kind of bundles:
- Zip file
- Contains all files needed to run a specific edition of SuperMemo—all that is needed is uncompress these files to an appropriate location.
- Executable installer
- Running one triggers a guided, graphical installer (wizard) that downloads files needed by the application to the local system.
Each kind of bundle, separately, shows repeatable behavior that is amenable to automation. In this tool, commonalities are abstracted into an installer template, which specifies how to carry on the installation steps. Installers for each supported SuperMemo edition stem from adapting one of these two kinds of template. The end result is a POSIX shell script that can be used by Winetricks–in this form, according to the nomenclature used by the Winetricks project, it is a Winetricks verb.
The described operation merits the definition of the following:
- Winetricks verb
- A shell script function to be used in conjunction with the
winetricks
script. It may install a package or otherwise perform a specific action inside a Wine prefix. - Installer template
- Source for a shell script with percent-encoded text placeholders. It lives only as an intermediate file in a temporary location, and is customized by an installer definition to produce a Winetricks verb
- Installer definition
- A Lisp form that uses one of the two installer templates, and carries metadata specific to a given SuperMemo edition. Its evaluation creates the final Winetricks verb for that edition.
A top banner serves to identify the project and where to get help.
Created by supermemo-wine
URL: https://github.com/alessivs/supermemo-wine
Edit with care.
This Winetricks verb installs %t.
For the meaning of %t
, a percent-encoded placeholder, see *Template placeholders.
Templates make themselves available for further processing from the filesystem.
(defvar zip-installer-template-path (make-temp-file "smwine-zip." nil ".sh")
"The location of the tangled template that serves as basis for Zip installer support.")
(defvar wizard-installer-template-path (make-temp-file "smwine-wiz." nil ".sh")
"The location of the tangled template that serves as basis for Wizard-type installer support.")
Encoded as | Role | Commentary |
---|---|---|
%a | application name | short name; used to name a verb |
%t | application title | full name of the application |
%m | installer media type | as defined by Winetricks |
%i | installer file name | |
%u | installer URL | |
%s | installer sha256 checksum | |
%e | command that installs IE 8 | ommitted in SuperMemos that don’t require it |
%d | command that downloads the bundle |
# <<banner>>
<<verb metadata>>
load_%a()
{
w_package_unsupported_win64
%e
<<prefix tweaks>>
%d
w_try_unzip "$W_DRIVE_C/SuperMemo" "$W_CACHE/$W_PACKAGE"/%i
<<shortcut creation>>
}
# <<banner>>
<<verb metadata>>
load_%a()
{
w_package_unsupported_win64
%e
<<prefix tweaks>>
%d
w_try_cd "$W_CACHE/$W_PACKAGE"
w_ahk_do "
<<wizard automation>>
"
<<shortcut creation>>
}
Winetricks verbs need metadata in a prescribed format identifying the package name, publisher, type of install, and the name of the executable on disk.
w_metadata %a apps \
title="%t" \
publisher="SuperMemo World" \
media="%m" \
file1="%i" \
installed_exe1="c:/SuperMemo/%x"
Prior to the actual installation of SuperMemo, the following verbs and packages are added to the Wine prefix:
w_call gdiplus_winxp
w_call tahoma
w_call fontsmooth=rgb
w_call winxp
- gdiplus_winxp
- Improves performance in presence of images in MSHTML (particularly inline images, background images). (Thanks to user James at SuperMemopedia for the pointer.)
- tahoma
- Provide a consistent visual with what is expected of Windows XP. This Tahoma font is not part of
corefonts
and allows some menu items to be properly rendered in bold. - fontsmooth=rgb
- Hints the prefix to adopt RGB font smoothing, with best results on LCD screens. The user can always change it through the registry or the
winecfg
tool. - winxp
- Ensures identification as Windows XP.
Automation of the wizard installer involves going through the installation by clicking buttons. Thankfully, SuperMemo installation wizards are structured in the same fashion.
The following sequence instructs the installer not to create a desktop shortcut, for we are creating our own, which is better integrated with Wine.
run, %i
WinWait, SuperMemo Install Wizard, Welcome to the SuperMemo
Sleep 800
ControlClick, Button2
WinWait, SuperMemo Install Wizard, Choose Install Folder
Sleep 800
ControlClick, Button2
WinWait, SuperMemo Install Wizard, Choose Start Menu
Sleep 800
ControlClick, Button4
Sleep 800
ControlClick, Button2
WinWait, SuperMemo Install Wizard, Choose Additional
Sleep 800
ControlClick, Button8
Sleep 800
ControlClick, Button2
WinWait, SuperMemo Install Wizard, Completing the
ControlClick, Button4
Sleep 800
ControlClick, Button2
Sleep 800
WinWaitClose, SuperMemo Install Wizard
The installer creates a shortcut (desktop entry file) to simplify starting the program. To aid identification on desktop systems, the official SuperMemo application icon is to be referenced by the desktop entry file. To preserve the standalone property of the installation script, it is embedded as a base64 string, so copying the icon must involve decoding the application icon into place (with the base64
tool, which must be available).
base64 ./assets/smglobe-64.png
cat <<EOF | base64 --decode > "$WINEPREFIX/drive_c/SuperMemo/smicon.png"
<<smglobe base64()>>EOF
The desktop entry file specifies the command to run and ensure its entry appears in the Education category of the system’s application menu.
_W_prefix_name="${WINEPREFIX##*/}"
_W_shortcut="${W_TMP}/%a.${_W_prefix_name}.desktop"
cat > "$_W_shortcut" <<EOF
[Desktop Entry]
Name=%t ($_W_prefix_name)
Exec=env WINEPREFIX="$WINEPREFIX" $WINE "$WINEPREFIX/drive_c/SuperMemo/%x"
Type=Application
Categories=Education;
StartupNotify=true
Comment=Organize your knowledge and learn at the maximum possible speed
Path=$WINEPREFIX/drive_c/SuperMemo
Icon=$WINEPREFIX/drive_c/SuperMemo/smicon.png
StartupWMClass=%x
EOF
In determining the target directory where the desktop entry file is to be copied, the XDG user-specific data directory is tried first. If that folder cannot be found, the XDG Desktop directory is tried instead.
if test -d "$XDG_DATA_HOME" && test -d "$XDG_DATA_HOME/applications"
then
cp "$_W_shortcut" "$XDG_DATA_HOME/applications"
else
if ! test -d "$XDG_DESKTOP_DIR" && test -f "$XDG_CONFIG_HOME/user-dirs.dirs"
then
. "$XDG_CONFIG_HOME/user-dirs.dirs"
fi
if test -d "$XDG_DESKTOP_DIR"
then
cp "$_W_shortcut" "$XDG_DESKTOP_DIR"
fi
fi
unset _W_prefix_name _W_shortcut
app-name | Short name for the application (unique) |
app-title | Long name for the application |
media-type | One of: “download”, “manual_download” |
bundle-file-name | Name of the file to be downloaded |
bundle-url | URL to the application distributable, or the website to download it from |
bundle-sha256sum | SHA-256 checksum, for integrity verification |
installed-exe | Name of the local executable that starts the application |
require-ie8-p | Whether Internet Explorer 8 is required |
(defun make-installer (template-path &rest definition)
"Load a template from TEMPLATE-PATH and a DEFINITION to produce a Winetricks verb."
(let* ((app-name (plist-get definition :app-name))
(app-title (plist-get definition :app-title))
(media-type (plist-get definition :media-type))
(bundle-file-name (plist-get definition :bundle-file-name))
(bundle-url (plist-get definition :bundle-url))
(bundle-sha256sum (plist-get definition :bundle-sha256sum))
(installed-exe (plist-get definition :installed-exe))
(require-ie8-p (plist-get definition :require-ie8-p))
(ie8-cmd (if require-ie8-p "w_call ie8" ""))
(dl-cmd (if (string= media-type "manual_download")
(format "w_download_manual %s %s %s"
bundle-url bundle-file-name bundle-sha256sum)
(format "w_download %s %s"
bundle-url bundle-sha256sum)))
(fspec (format-spec-make
?a app-name
?t app-title
?m media-type
?i bundle-file-name
?u bundle-url
?s bundle-sha256sum
?x installed-exe
?e ie8-cmd
?d dl-cmd)))
(with-temp-buffer
(insert-file-contents-literally template-path)
(print (format-spec (buffer-string) fspec)))))
(defalias 'make-zip-installer
(apply-partially 'make-installer zip-installer-template-path))
(defalias 'make-wizard-installer
(apply-partially 'make-installer wizard-installer-template-path))
(make-zip-installer
:app-name "supermemo9"
:app-title "SuperMemo 98"
:media-type "download"
:bundle-file-name "sm98.zip"
:bundle-url "https://supermemo.org/ftp/sm98.zip"
:bundle-sha256sum "a8064cc9a6f076779617a3228e49a91c48691c0870aa76b91c228ad00d4f7e5d"
:installed-exe "sm98.exe"
:require-ie8-p nil)
(make-zip-installer
:app-name "supermemo12"
:app-title "SuperMemo 2004"
:media-type "download"
:bundle-file-name "sm2004.zip"
:bundle-url "https://supermemo.org/ftp/sm2004.zip"
:bundle-sha256sum "f2819822db0680b99f18cd2380bd2d14f2f62fe3281b7231be6d0a3d28a907a3"
:installed-exe "sm2004.exe"
:require-ie8-p t)
(make-zip-installer
:app-name "supermemo15_4"
:app-title "SuperMemo 15.4"
:media-type "download"
:bundle-file-name "sm15abc.zip"
:bundle-url "https://supermemo.org/install/15/sm15abc.zip"
:bundle-sha256sum "f501d7273a879cb4fd640056eb5c40ba427db765cf1d2f69bb0eb88984e511b9"
:installed-exe "sm15.exe"
:require-ie8-p t)
(make-wizard-installer
:app-name "supermemo15"
:app-title "SuperMemo 15"
:media-type "download"
:bundle-file-name "sm15inst.exe"
:bundle-url "https://supermemo.org/install/sm15inst.exe"
:bundle-sha256sum "2add9eebc8398847e9a82b711ff88cd04fcba877700dc0f086630701bd98b5c4"
:installed-exe "sm15.exe"
:require-ie8-p t)
(make-wizard-installer
:app-name "supermemo16"
:app-title "SuperMemo 16"
:media-type "download"
:bundle-file-name "sm16inst.exe"
:bundle-url "https://supermemo.org/install/sm16inst.exe"
:bundle-sha256sum "2add9eebc8398847e9a82b711ff88cd04fcba877700dc0f086630701bd98b5c4"
:installed-exe "sm16.exe"
:require-ie8-p t)
(make-wizard-installer
:app-name "supermemo17"
:app-title "SuperMemo 17"
:media-type "manual_download"
:bundle-file-name "sm17inst.exe"
:bundle-url "https://super-memo.com"
:bundle-sha256sum "09269ed14c042099e492283e3d3376931c99e31b94d9e3d8b1ce0334a0386920"
:installed-exe "sm17.exe"
:require-ie8-p t)
(make-wizard-installer
:app-name "supermemo18"
:app-title "SuperMemo 18"
:media-type "manual_download"
:bundle-file-name "sm18inst.exe"
:bundle-url "https://super-memo.com"
:bundle-sha256sum "87ebd4da706c825575655aeddc9a68291d52712880fe1c39e1e1d0a41853b35f"
:installed-exe "sm18.exe"
:require-ie8-p t)