Created
March 16, 2020 17:05
-
-
Save pavelglac/c661f784a405374f64c6474aa1ec7f88 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const typo = { | |
| inLineElements : ["B", "BIG", "I", "SMALL", "TT", "ABBR", "ACRONYM", "CITE", "DFN", "EM", "KDB", "STRONG", "SAMP", "VAR", "A", "BDO", "MAP", "OBJECT", "Q", "SPAN", "SUB", "SUP", "BUTTON", "INPUT", "LABEL", "SELECT", "TEXTAREA"], | |
| ignoredElemenents : ["SCRIPT", "NOSCRIPT", "STYLE", "TITLE", "IFRAME", "HEAD", "META", "HTML", "BR", "IMG", ""], | |
| uselessChar : "\uE000", | |
| uselessCharsCollection : ["\u001A", "\uE001", "\uE990"], | |
| options : { | |
| quote: true, | |
| units: true, | |
| number: true, | |
| space: true, | |
| date: true, | |
| ellipsis: true, | |
| year: true | |
| }, | |
| Rules : { | |
| // rules for czech quotes | |
| quote: [ | |
| [/(“|")(\w)/g, "„$2"], | |
| [/(“|")\uE000(\w)/g, "„\uE000$2"], | |
| [/(”|")( |,|\n*|$)/g, "“$2"], | |
| [/(”|")\uE000( |,|\n*|$)/g, "“\uE000$2"], | |
| [/(!|\?|\.)(”|")/g, "$1“"], | |
| [/(!|\?|\.)\uE000(”|")/g, "$1\uE000“"], | |
| [/(\w)(')(\w)/g, "$1’$3"] | |
| ], | |
| // rules for units | |
| // there must be a space between numbers and the unit | |
| units: [ | |
| [/(\d+)(| )(|m)s/g, "$1"+"\u00a0"+"$3s"], | |
| [/(\d+)(| )\uE000(| )(|m)s/g, "$1"+"\u00a0\uE000"+"$4s"], | |
| [/(\d+)(| )(min|h|d)/g, "$1"+"\u00a0"+"$3"], | |
| [/(\d+)(| )\uE000(| )(min|h|d)/g, "$1"+"\u00a0\uE000"+"$4"], | |
| [/(\d+)(| )(|n|m|c|d|k)m/g, "$1"+"\u00a0"+"$3m"], | |
| [/(\d+)(| )\uE000(| )(|n|m|c|d|k)m/g, "$1"+"\u00a0\uE000"+"$3m"], | |
| [/(\d+)(| )(|m|h|d|c|b)l/g, "$1"+"\u00a0"+"$3l"], | |
| [/(\d+)(| )\uE000(| )(|m|h|d|c|b)l/g, "$1"+"\u00a0\uE000"+"$3l"], | |
| [/(\d+)(| )(ccm|gal)/g, "$1"+"\u00a0"+"$3"], | |
| [/(\d+)(| )\uE000(| )(ccm|gal)/g, "$1"+"\u00a0\uE000"+"$3"], | |
| [/(\d+)(| )(|m|c|d|k)m(\d)/g, "$1"+"\u00a0"+"$3m$4"], | |
| [/(\d+)(| )\uE000(| )(|m|c|d|k)m(\d)/g, "$1"+"\u00a0\uE000"+"$3m$4"], | |
| [/(\d+)(| )(ccm|gal)/g, "$1"+"\u00a0"+"$3"], | |
| [/(\d+)(| )\uE000(| )(ccm|gal)/g, "$1"+"\u00a0\uE000"+"$4"], | |
| [/(\d+)(| )(ha|a)/g, "$1"+"\u00a0"+"$3"], | |
| [/(\d+)(| )\uE000(| )(ha|a)/g, "$1"+"\u00a0\uE000"+"$4"], | |
| [/(\d+)(| )(|k|M)J/g, "$1"+"\u00a0"+"$3J"], | |
| [/(\d+)(| )\uE000(| )(|k|M)J/g, "$1"+"\u00a0\uE000"+"$4J"], | |
| [/(\d+)(| )(|k)cal/g, "$1"+"\u00a0"+"$3cal"], | |
| [/(\d+)(| )\uE000(| )(|k)cal/g, "$1"+"\u00a0"+"$4cal"], | |
| [/(\d+)(| )(|kWh|M)Wh/g, "$1"+"\u00a0"+"$3Wh"], | |
| [/(\d+)(| )\uE000(| )(|kWh|M)Wh/g, "$1"+"\u00a0\uE000"+"$4Wh"], | |
| [/(\d+)(| )(|k)m\/(s|min|h)/g, "$1"+"\u00a0"+"$3m/$4"], | |
| [/(\d+)(| )\uE000(| )(|k)m\/(s|min|h)/g, "$1"+"\u00a0\uE000"+"$4m/$5"], | |
| [/(\d+)(| )(K|°C|°F)/g, "$1"+"\u00a0"+"$3"], | |
| [/(\d+)(| )\uE000(| )(K|°C|°F)/g, "$1"+"\u00a0\uE000"+"$4"], | |
| [/(\d+)(| )(|h|k|M)Pa/g, "$1"+"\u00a0"+"$3Pa"], | |
| [/(\d+)(| )\uE000(| )(|h|k|M)Pa/g, "$1"+"\u00a0\uE000"+"$4Pa"], | |
| [/(\d+)(| )(bar|atm)/g, "$1"+"\u00a0"+"$3"], | |
| [/(\d+)(| )\uE000(| )(bar|atm)/g, "$1"+"\u00a0\uE000"+"$4"], | |
| [/(\d+)(| )(|k)W/g, "$1"+"\u00a0"+"$3"], | |
| [/(\d+)(| )\uE000(| )(|k)W/g, "$1"+"\u00a0\uE000"+"$4"], | |
| [/(\d+)(| )(%)/g, "$1"+"\u00a0"+"$3"], | |
| [/(\d+)(| )\uE000(| )(%)/g, "$1"+"\u00a0\uE000"+"$3"], | |
| ], | |
| // rule for number formatting | |
| number: [ | |
| [/(\d)( |\u00a0)(\d)/g, "$1$3"], | |
| [/(\d)\uE000( |\u00a0)(\d)/g, "$1\uE000$3"], | |
| [/(\d)( |\u00a0)\uE000(\d)/g, "$1\uE000$3"], | |
| //all position how number can be decomposed into different elements | |
| [/(\d|\uE000)(?=(\d{3}|\d{3}\uE000|\d\uE000\d{2}|\d{2}\uE000\d|\uE000\d{3}|\d\uE000\d\uE000\d|\uE000\d\uE000r\d\uE000\d|\d\uE000\d\uE000\d\uE000)+(?!(\d|\uE000\d|\d\uE000)))/g, "$1"+"\u202F"] | |
| ], | |
| // rules for hard spaces | |
| space: [ | |
| [/ /g, " "], | |
| [/ (a|i|o|u|s|z|k|v|A|I|O|U|S|Z|K|V) /g, " $1\u00a0"], | |
| [/ (a|i|o|u|s|z|k|v|A|I|O|U|S|Z|K|V)\uE000 /g, " $1\u00a0\uE000"], | |
| [/ \uE000(a|i|o|u|s|z|k|v|A|I|O|U|S|Z|K|V)\uE000 /g, " \uE000$1\u00a0\uE000"], | |
| [/ \uE000(a|i|o|u|s|z|k|v|A|I|O|U|S|Z|K|V) /g, " \uE000$1\u00a0"], | |
| [/([§|#])( )(\d)/g, "$1"+"\u00a0"+"$3"], | |
| [/([§|#])(| )\uE000(| )(\d)/g, "$1"+"\u00a0\uE000"+"$4"], | |
| [/(tj|tzv|tzn)\. /g, "$1.\u00a0"] | |
| ], | |
| // rules for dates | |
| date: [ | |
| [/(\d{1,2}\.)(| )(\d{1,2}\.)(| )(\d{4})/g, "$1"+"\u00a0"+"$3"+" "+"$5"], | |
| [/(\d{1,2}\.)(| )(\d{1,2}\.)(| )(\d)\u202F(\d{3})/g, "$1"+"\u00a0"+"$3"+" "+"$5"+"$6"], | |
| [/(\d{1,2}\.)(| )(\d{1,2}\.)(| )(\d)\u202F(\d{2}\uE000\d)/g, "$1"+"\u00a0"+"$3"+" "+"$5$6"], | |
| [/(\d{1,2}\.)(| )(\d{1,2}\.)(| )(\d)\u202F\d\uE000(\d{2})/g, "$1"+"\u00a0"+"$3"+" "+"$5$6"], | |
| [/(\d{1,2}\.)(| )(\d{1,2}\.)(| )(\d)\u202F(\uE000\d{3})/g, "$1"+"\u00a0"+"$3"+" "+"$5$6"] | |
| ], | |
| // rule for ellipsis instead of 3 dots | |
| ellipsis: [ | |
| [/\.{3}/g, "…"], | |
| [/\.{2}\uE000\./g, "…\uE000"], | |
| [/\.\uE000\.\./g, "\uE000…"], | |
| [/\.\uE000\.\uE000\./g, "\uE000…\uE000"] | |
| ], | |
| year: [ | |
| [/( | \uE000|–|–\uE000|-|-\uE000|\u002F|\u002F\uE000)(1)\u202F(\d{3})(?!\u202F)/g, "$1$2$3"], | |
| [/( | \uE000|–|–\uE000|-|-\uE000|\u002F|\u002F\uE000)(2)\u202F(100|0\d\d)(?!\u202F)/g, "$1$2$3"] | |
| ], | |
| }, | |
| /** | |
| * init function of whole script | |
| * | |
| * @param {object} settings [set parameters of the object options] | |
| * @param {HTML collection} node [collection for iteration] | |
| * @return | |
| */ | |
| runAutoCorrector : function runAutoCorrector(settings, node) | |
| { | |
| while (typo.checkUselessChar()) {typo.setUselessChar();} | |
| options = Object.assign(typo.options, settings); | |
| const elementsWithClass = document.getElementsByClassName("typography-autocorrector"); | |
| if (node !== undefined) | |
| { | |
| typo.elementsDescendants(node); | |
| return; | |
| } | |
| if (elementsWithClass.length > 0) | |
| { | |
| typo.elementsDescendants(elementsWithClass); | |
| return; | |
| } | |
| /** | |
| * If there is none node in the parameter | |
| * or | |
| * no class with the name typography-autocorrector | |
| */ | |
| const all = document.getElementsByTagName("*"); | |
| typo.elementIteration(all); | |
| }, | |
| elementsDescendants : function elementsDescendants(nodes) | |
| { | |
| /** | |
| * get all nodes of node with class typography-autocorrector | |
| * | |
| * @type {Number} max [number of elements with class] | |
| */ | |
| for (let node of nodes) | |
| { | |
| const descendants = node.getElementsByTagName("*"); | |
| typo.elementIteration(node); | |
| if (descendants > 0) {typo.elementIteration(descendants);} | |
| } | |
| }, | |
| setUselessChar : function setUselessChar() | |
| { | |
| for (let rule in typo.Rules) | |
| { | |
| rule.replace(typo.uselessChar, typo.uselessCharsCollection[0]) | |
| } | |
| typo.uselessChar = typo.uselessCharsCollection[0]; | |
| typo.uselessCharsCollection.shift(); | |
| return; | |
| }, | |
| checkUselessChar : function checkUselessChar() | |
| { | |
| if (typo.uselessCharsCollection.length === 0){console.error("Změňte proměnou uselessChar ve scriptu na znak, který se nevyskystuje na stránce.");return false;} | |
| const str = document.getElementsByTagName("BODY")[0].textContent; | |
| const patt = new RegExp(typo.uselessChar); | |
| const result = patt.test(str); | |
| return result; | |
| }, | |
| elementIteration : function elementIteration(all) | |
| { | |
| if (all.length > 0) | |
| { | |
| for (let element of all) | |
| { | |
| if (typo.shouldSkip(element)){continue;} | |
| typo.textJoining(element); | |
| } | |
| }else{ | |
| if (typo.shouldSkip(all)){return;} | |
| typo.textJoining(all); | |
| } | |
| }, | |
| shouldSkip : function shouldSkip(node) | |
| { | |
| if (typo.ignoredElemenents.includes(node.tagName) || node.textContent === "" || typo.inLineElements.includes(node.tagName)) {return true;} | |
| return false; | |
| }, | |
| getSiblings : function getSiblings(element) | |
| { | |
| let sibs = []; | |
| sibs.push(element); | |
| if (element.nextSibling === null) {return sibs;} | |
| while (element = element.nextSibling) | |
| { | |
| sibs.push(element); | |
| } | |
| return sibs; | |
| }, | |
| textJoining : function textJoining(node) | |
| { | |
| const nodes = typo.getText(node); | |
| let text = ""; | |
| for (let node of nodes) { | |
| text = text.concat(node.textContent); | |
| text = text.concat(typo.uselessChar); | |
| } | |
| text = typo.improveTypography(text); | |
| const textField = text.split(typo.uselessChar, nodes.length); | |
| for (let i = 0; i < textField.length; i++) | |
| { | |
| nodes[i].textContent = textField[i]; | |
| } | |
| return; | |
| }, | |
| getText : function getText(node) | |
| { | |
| let sibsWithText = []; | |
| if (node.textContent === "") {return sibsWithText} | |
| const sibs = typo.getSiblings(node.childNodes[0]); | |
| for (let sib of sibs) | |
| { | |
| if (sib.nodeValue !== null && sib.nodeType === 3){sibsWithText.push(sib);} | |
| if (sib.hasChildNodes && sib.textContent !== "" && typo.inLineElements.includes(sib.tagName) && sib.nodeType === 1) | |
| { | |
| /* | |
| iteration of the DOM in depth | |
| */ | |
| const sibsOfChild = typo.getText(sib); | |
| for (let sibWithText of sibsOfChild) | |
| { | |
| sibsWithText.push(sibWithText); | |
| } | |
| } | |
| } | |
| return sibsWithText; | |
| }, | |
| improveTypography : function improveTypography(string) | |
| { | |
| if (typo.options.quote) | |
| { | |
| for(let rule of typo.Rules.quote) | |
| { | |
| string = string.replace(rule[0], rule[1]); | |
| } | |
| } | |
| if (typo.options.units) | |
| { | |
| for(let rule of typo.Rules.units) | |
| { | |
| string = string.replace(rule[0], rule[1]); | |
| } | |
| } | |
| if (typo.options.number) | |
| { | |
| for(let rule of typo.Rules.number) | |
| { | |
| string = string.replace(rule[0], rule[1]); | |
| } | |
| } | |
| if (typo.options.space) | |
| { | |
| for(let rule of typo.Rules.space) | |
| { | |
| string = string.replace(rule[0], rule[1]); | |
| } | |
| } | |
| if (typo.options.date) | |
| { | |
| for(let rule of typo.Rules.date) | |
| { | |
| string = string.replace(rule[0], rule[1]); | |
| } | |
| } | |
| if (typo.options.ellipsis) | |
| { | |
| for(let rule of typo.Rules.ellipsis) | |
| { | |
| string = string.replace(rule[0], rule[1]); | |
| } | |
| } | |
| if (typo.options.year) | |
| { | |
| for(let rule of typo.Rules.year) | |
| { | |
| string = string.replace(rule[0], rule[1]); | |
| } | |
| } | |
| return string; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment