#lang racket/base (require db racket/file racket/string "private/config.rkt" "private/database.rkt") (provide tr translations-for current-language write-language! translation-page-slug) (define english (hash 'users "Users" 'translations "Translations" 'todo "Todo" 'search-wiki "Search wiki" 'contents "Contents" 'pages "Pages" 'edit "Edit" 'history "History" 'delete "Delete" 'page-not-found "Page not found" 'cancel "Cancel" 'save "Save" 'page-title "Page title" 'tags "Tags (comma separated)" 'version-summary "Version summary (optional)" 'search "Search" 'page-history "Page history" 'back "Back" 'user-administration "User administration" 'username "Username" 'display-name "Display name" 'initial-password "Initial password" 'create-user "Create user" 'sign-in "Sign in" 'sign-out "Sign out" 'password "Password" 'upload-image "Upload image" 'upload-file "Upload file" 'saved "Saved" 'offline "Offline" 'online "Online" 'todo-items "Todo items" 'no-todos "No todo items." 'no-matching-pages "No matching pages." 'this-page-missing "This page does not exist yet." 'no-pages "No pages yet" 'view "View" 'compare-previous "Compare previous" 'new-password "New password" 'created "Created" 'modified "Modified" 'version "Version" 'tags-none "Tags: none" 'you-are-here "You are here" 'setup-title "Set up Racket Wiki" 'setup-description "Configure PostgreSQL, create the first administrator and install the browser libraries. This page does not require JavaScript." 'postgresql "PostgreSQL" 'server "Server" 'port "Port" 'database "Database" 'user "User" 'tls-ssl "TLS/SSL" 'ssl-no "No (typical localhost setup)" 'ssl-optional "Optional" 'ssl-required "Required" 'administrator "Administrator" 'administrator-username "Administrator username" 'administrator-password "Administrator password" 'repeat-password "Repeat password" 'ready "Ready" 'required "Required" 'administrator-account "Administrator account" 'frontend-libraries "Frontend libraries" 'will-download "Will be downloaded" 'complete-setup "Complete setup" 'tags-label "Tags: " 'page-address "Page address" 'page-address-generated "Page address will be generated from the title when you save." 'saving "Saving…" 'created-page "Created page" 'edited-page "Edited page" 'line "line" 'bold "Bold" 'italic "Italic" 'strikethrough "Strikethrough" 'heading "Heading" 'quote "Quote" 'bulleted-list "Bulleted list" 'numbered-list "Numbered list" 'checklist "Checklist" 'code-block "Code block" 'table "Table" 'link "Link" 'horizontal-rule "Horizontal rule" 'undo "Undo" 'redo "Redo" 'preview "Preview" 'side-by-side "Side by side" 'fullscreen "Fullscreen" 'language "Language" 'language-en "English" 'language-nl "Dutch" 'no-headings "No headings" 'uploading "Uploading" 'image-upload-complete "Image upload complete" 'upload-complete "Upload complete" 'by "by" 'result "result" 'results "results" 'for "for" 'page-does-not-exist "The page does not exist.")) (define dutch (hash 'users "Gebruikers" 'translations "Vertalingen" 'todo "Todo" 'search-wiki "Wiki doorzoeken" 'contents "Inhoud" 'pages "Pagina's" 'edit "Bewerken" 'history "Geschiedenis" 'delete "Verwijderen" 'page-not-found "Pagina niet gevonden" 'cancel "Annuleren" 'save "Opslaan" 'page-title "Paginatitel" 'tags "Tags (komma-gescheiden)" 'version-summary "Versiesamenvatting (optioneel)" 'search "Zoeken" 'page-history "Paginageschiedenis" 'back "Terug" 'user-administration "Gebruikersbeheer" 'username "Gebruikersnaam" 'display-name "Weergavenaam" 'initial-password "Initieel wachtwoord" 'create-user "Gebruiker aanmaken" 'sign-in "Inloggen" 'sign-out "Uitloggen" 'password "Wachtwoord" 'upload-image "Afbeelding uploaden" 'upload-file "Bestand uploaden" 'saved "Opgeslagen" 'offline "Offline" 'online "Online" 'todo-items "Todo-items" 'no-todos "Geen todo-items." 'no-matching-pages "Geen overeenkomende pagina's." 'this-page-missing "Deze pagina bestaat nog niet." 'no-pages "Nog geen pagina's" 'view "Bekijken" 'compare-previous "Vergelijk vorige" 'new-password "Nieuw wachtwoord" 'created "Aangemaakt" 'modified "Gewijzigd" 'version "Versie" 'tags-none "Tags: geen" 'you-are-here "U bent hier" 'setup-title "Racket Wiki instellen" 'setup-description "Configureer PostgreSQL, maak de eerste beheerder aan en installeer de browserbibliotheken. Deze pagina heeft geen JavaScript nodig." 'postgresql "PostgreSQL" 'server "Server" 'port "Poort" 'database "Database" 'user "Gebruiker" 'tls-ssl "TLS/SSL" 'ssl-no "Nee (gebruikelijk op localhost)" 'ssl-optional "Optioneel" 'ssl-required "Verplicht" 'administrator "Beheerder" 'administrator-username "Gebruikersnaam beheerder" 'administrator-password "Wachtwoord beheerder" 'repeat-password "Herhaal wachtwoord" 'ready "Gereed" 'required "Verplicht" 'administrator-account "Beheerdersaccount" 'frontend-libraries "Frontendbibliotheken" 'will-download "Worden gedownload" 'complete-setup "Setup voltooien" 'tags-label "Tags: " 'page-address "Pagina-adres" 'page-address-generated "Het pagina-adres wordt bij opslaan uit de titel afgeleid." 'saving "Opslaan…" 'created-page "Pagina aangemaakt" 'edited-page "Pagina gewijzigd" 'line "regel" 'bold "Vet" 'italic "Cursief" 'strikethrough "Doorhalen" 'heading "Kop" 'quote "Citaat" 'bulleted-list "Opsomming" 'numbered-list "Genummerde lijst" 'checklist "Checklist" 'code-block "Codeblok" 'table "Tabel" 'link "Link" 'horizontal-rule "Horizontale lijn" 'undo "Ongedaan maken" 'redo "Opnieuw" 'preview "Voorbeeld" 'side-by-side "Naast elkaar" 'fullscreen "Volledig scherm" 'language "Taal" 'language-en "Engels" 'language-nl "Nederlands" 'no-headings "Geen koppen" 'uploading "Uploaden" 'image-upload-complete "Afbeelding geüpload" 'upload-complete "Upload voltooid" 'by "door" 'result "resultaat" 'results "resultaten" 'for "voor" 'page-does-not-exist "De pagina bestaat niet.")) (define (base-translations language) (if (string-ci=? language "nl") dutch english)) (define (current-language config) (with-handlers ((exn:fail? (λ (_e) (wiki-config-language config)))) (if (file-exists? (language-config-path config)) (call-with-input-file (language-config-path config) (λ (in) (define value (read in)) (if (string? value) value (wiki-config-language config)))) (wiki-config-language config)))) (define (write-language! config language) (make-directory* (wiki-config-data-dir config)) (call-with-output-file (language-config-path config) (λ (out) (write language out) (newline out)) #:exists 'truncate/replace) (void)) (define (translation-page-slug language) (string-append "wiki-translations-" (string-downcase language))) (define (parse-overrides markdown) (for/fold ((result (hash))) ((line (in-list (string-split markdown "\n")))) (define match (regexp-match #px"^\\s*([A-Za-z0-9._-]+)\\s*=\\s*(.*?)\\s*$" line)) (if match (hash-set result (string->symbol (list-ref match 1)) (list-ref match 2)) result))) (define (database-overrides config) (with-handlers ((exn:fail? (λ (_e) (hash)))) (if (not (database-ready? config)) (hash) (call-with-wiki-database config (λ (db) (define markdown (query-maybe-value db "SELECT markdown FROM pages WHERE slug = $1 AND archived = FALSE" (translation-page-slug (current-language config)))) (if markdown (parse-overrides markdown) (hash))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; goal : Return all translations active for the configured wiki language. ; pre : config is a wiki-config value. ; post : Translation override page, when available, has only been read. ; result : A hash from translation symbols to strings. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (translations-for config) (for/fold ((result (base-translations (current-language config)))) (((key value) (in-hash (database-overrides config)))) (hash-set result key value))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; goal : Translate one UI key for the configured wiki language. ; pre : key is a symbol. ; post : Translation data has only been read. ; result : The translated string, or the symbolic key when no translation exists. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (tr config key) (hash-ref (translations-for config) key (symbol->string key)))