Skip to content

Instantly share code, notes, and snippets.

@spacegangster
Created January 28, 2021 10:32
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spacegangster/10b5b0a9bba9e028d713c2d0748c8abd to your computer and use it in GitHub Desktop.
Save spacegangster/10b5b0a9bba9e028d713c2d0748c8abd to your computer and use it in GitHub Desktop.
Simple Clojure typography transformations for English, French, and Russian typography styles.
(ns common.typography
"Improve quotes and make whitespace non-breaking after 1-2 letter words"
(:require [clojure.string :as str]))
(def typo-replace-starting-nbsp
[#"(^[a-zA-Z\u0400-\u0500]{1,2})\ ", "$1 "])
(assert (= "A&nbsp;being in Australia <a class='yoy'>"
(apply str/replace "A being in Australia <a class='yoy'>" typo-replace-starting-nbsp)))
(def typo-replace-nbsp-ru-i-a
[#"(\bи|а|я\b)\ ", "$1&nbsp;"])
(assert (= "Ему я&nbsp;и&nbsp;а&nbsp;также"
(apply str/replace "Ему я и а также" typo-replace-nbsp-ru-i-a)))
(def typo-replace-nbsp-a
[#"([^<]\ba\b)\ ", "$1&nbsp;"])
(assert (= "A being in a&nbsp;grave <a class='yoy'>"
(apply str/replace "A being in a grave <a class='yoy'>" typo-replace-nbsp-a)))
(def typo-replace-nbsp
[#"([^<]\b[;a-zA-Z\u0400-\u0500]{1,2})\ ", "$1&nbsp;"])
(assert (= "A being in&nbsp;Australia <a class='yoy'>"
(apply str/replace "A being in Australia <a class='yoy'>" typo-replace-nbsp)))
(def typo-replace-whitespace
[#"(\s{2,})", " "])
(assert (= "A being in Australia"
(apply str/replace "A being in Australia" typo-replace-whitespace)))
(def typo-tiret
[#"--" "—"])
(def typo-russian-quotes
[#"\"([0-9\u0400-\u0500a-zA-Z -:~]+?)\"" #(str "«" (second %) "»")])
(def typo-french-quotes
[#"\"([0-9\u0400-\u0500a-zA-Z -:~]+?)\"" #(str "« " (second %) " »")])
(def typo-english-quotes
[#"\"([0-9a-zA-Z -]+)\"" #(str "“" (second %) "”")])
(def replacements-ru
[typo-tiret
typo-replace-whitespace
typo-russian-quotes
typo-replace-starting-nbsp
typo-replace-nbsp-ru-i-a
typo-replace-nbsp])
(def replacements-fr
[typo-tiret
typo-replace-whitespace
typo-french-quotes
typo-replace-starting-nbsp
typo-replace-nbsp-a
typo-replace-nbsp])
(def replacements-en
[typo-tiret
typo-replace-whitespace
typo-english-quotes
typo-replace-starting-nbsp
typo-replace-nbsp-a
typo-replace-nbsp])
(def typography
{:ru replacements-ru
:fr replacements-fr
:en replacements-en})
(defn typogrify [lang string]
(let [replaces (typography lang)
replacer (fn [string [replace-regexp replacement]]
(str/replace string replace-regexp replacement))]
(reduce replacer string replaces)))
(def typogrify-ru
"Apply a set of Russian typography transformations"
(partial typogrify :ru))
(assert (= "Тире — вместо двойных дефисов, и&nbsp;«лапки» вместо программистских кавычек, также всё норм с&nbsp;тегами «~ : Хохохо», «~ : Hey man»"
(typogrify-ru (str "Тире -- вместо двойных дефисов, и \"лапки\" вместо программистских кавычек,"
" также всё норм с тегами \"~ : Хохохо\", \"~ : Hey man\""))))
(def typogrify-en
"Apply a set of English typography transformations"
(partial typogrify :en))
(assert (= "A&nbsp;tiret — instead of&nbsp;double dash, curly “quotes” instead of&nbsp;straight ones"
(typogrify-en "A tiret -- instead of double dash, curly \"quotes\" instead of straight ones")))
(def typogrify-fr
"Apply a set of French typography transformations"
(partial typogrify :fr))
(assert (= "Un&nbsp;long tiret au&nbsp;lieu d'un&nbsp;double signe « - » et&nbsp;des bonnes « guillemets »"
(typogrify-fr "Un long tiret au lieu d'un double signe \"-\" et des bonnes \"guillemets\"")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment