Created
August 28, 2018 02:59
-
-
Save ENAML/f7b75bb843d74452a6e1fd7cdff95c83 to your computer and use it in GitHub Desktop.
justify-text-js
This file contains 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 { log } = console; | |
const SPACE = " "; | |
const isString = (val) => typeof val === 'string' || val instanceof String; | |
/** | |
* Justify Text | |
* ============ | |
* TODO: description | |
*/ | |
const justify = (words, lineWidth) => { | |
// make sure words is an array | |
words = (isString(words) ? words.split(' ') : words); | |
words = words | |
.map((w) => w.trim()) | |
.filter((w) => w.length > 0); | |
const res = []; | |
const n = words.length; | |
let line_st_idx = 0; | |
let cur_len = words[0].length; | |
for (let i = 1; i < n; i++) { | |
const w = words[i]; | |
const w_len = w.length; | |
const new_len = cur_len + 1 + w_len; | |
if (new_len > lineWidth) { | |
res.push(buildLine(words, line_st_idx, i-1, lineWidth)); | |
line_st_idx = i; | |
cur_len = w_len; | |
} | |
else { | |
cur_len = new_len; | |
} | |
} | |
// add last line | |
res.push(buildLastLine(words, line_st_idx, n-1, lineWidth)); | |
return res; | |
// return res.join('\n'); | |
}; | |
/** | |
* StringBuilder | |
*/ | |
class StringBuilder { | |
constructor() { | |
this._datas = []; | |
this._length = 0; | |
} | |
append(data) { | |
const dStr = data.toString(); | |
this._length += dStr.length; | |
this._datas.push(dStr); | |
} | |
push(data) { this.append(data) } | |
get length() { throw new Error("length property not valid") } | |
length() { return this._length } | |
toString() { return this._datas.join('') } | |
} | |
/** | |
* TODO - description | |
*/ | |
function buildLine(words, lo, hi, lineWidth) { | |
const w_ct = (hi - lo + 1); | |
const sp_ct = w_ct - 1; | |
let w_size = 0; | |
for (let i = lo; i <= hi; i++) w_size += words[i].length; | |
const sp_size = lineWidth - w_size; | |
let sp_extra = (sp_ct > 0 ? sp_size % sp_ct : 0); | |
const sb = new StringBuilder(); | |
sb.push(words[lo]); | |
for (let i = lo+1; i <= hi; i++) { | |
let num_spaces = parseInt(sp_size / sp_ct); | |
if (sp_extra > 0) { | |
sp_extra--; | |
num_spaces++; | |
} | |
if (sp_ct > 0 && num_spaces > 0) sb.push(SPACE.repeat(num_spaces)); | |
sb.push(words[i]); | |
} | |
while (sb.length() < lineWidth) sb.push(SPACE); | |
return sb.toString(); | |
} | |
/** | |
* TODO - description | |
*/ | |
function buildLastLine(words, lo, hi, lineWidth) { | |
const sb = new StringBuilder(); | |
sb.push(words[lo]); | |
for (let i = lo+1; i <= hi; i++) { | |
sb.push(SPACE); | |
sb.push(words[i]); | |
} | |
while (sb.length() < lineWidth) sb.push(SPACE); | |
return sb.toString(); | |
} | |
module.exports = justify; |
This file contains 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 justify = require('./justify'); | |
const test = (words, lineWidth) => { | |
console.log(`words: `, JSON.stringify(words)); | |
console.log(`lineWidth: `, lineWidth); | |
console.log(`--> res: `); | |
let res = justify(words, lineWidth); | |
// pad result like this: | |
// ┌─────────┬───┐ | |
// │ (index) │ 0 │ | |
// ├─────────┼───┤ | |
// │ 0 │ 0 │ | |
// │ 1 │ 1 │ | |
// └─────────┴───┘ | |
const spaceRow = " ".repeat(res[0].length); | |
res = [spaceRow, ...res, spaceRow]; | |
const padL = "│ "; | |
const padR = " │"; | |
res = res | |
.map((line, i) => padL + line + padR) | |
const pad = "─".repeat(res[0].length - 2); | |
const padTop = "┌" + pad + "┐"; | |
const padBtm = "└" + pad + "┘"; | |
res = [padTop, ...res, padBtm] | |
.join(`\n`); | |
console.log(res); | |
console.log(`\n`); | |
}; | |
test( | |
["Text", "justification", "is", "trickier", "than", "it", "seems!"], | |
14, | |
) | |
test( | |
["Listen", "to", "many,", "speak", "to", "a", "few."], | |
6 | |
) | |
test( | |
["The", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dogs."], | |
11 | |
) | |
test( | |
["The", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dogs."], | |
16 | |
) | |
test( | |
["stay", "c", "ova", "bouw", "q", "tinean", "long", "r", "flops", "bl", "bharti", "jack", "prau", "z", "my", "imbe", "b", "wf", "gervas", "akka", "t", "fg", "bals", "israel", "gula", "rly", "cass", "zs", "bu", "ter", "doat", "form", "indulges", "felt", "ll", "pave", "wc", "num", "coendure", "yip", "vers", "wh", "avo", "rig", "ruts", "memo", "doit", "b", "heh", "ctge", "a", "posed", "md", "tannic", "d", "adust", "hf", "rectors", "typw", "crests", "l", "zak", "butted", "o", "waget", "unbeaued", "rekeys", "l", "otus", "reast", "caup", "ggr", "geo", "ofer", "cribs", "gum", "palt", "whew", "outshown", "grig", "qm", "tall", "vo", "dew", "rebellow", "yod", "dhan", "mi", "gtd", "tnt", "buhr", "shut", "elsa", "c", "kors", "pa", "ulu", "mike", "wi", "alec", "z", "bumpy", "vl", "amygdalase", "long", "reis", "sodas", "elix", "tuner", "lo", "outpulls", "goi", "chank", "sow", "assahy", "gaen", "aa", "leukocytic", "plum", "hgt", "funs", "pain", "immeshes", "bats", "fc", "depe", "qv", "esu", "ligroine", "ama", "vaus", "mb", "vac", "pep", "swum", "dust", "bide", "dink", "deb", "arid", "on", "pfx", "waac", "piddler"], | |
60 | |
) | |
test( | |
["unlumbering", "mp", "wamp", "southeast", "bhar", "prospector"], | |
11 | |
) | |
test( | |
["eben", "nv", "aa", "nishada", "db", "hehe", "petrosilicious"], | |
16 | |
) | |
test( | |
["kapa", "marc", "qr", "rotge", "apt"], | |
5 | |
) | |
test( | |
["ki", "dug", "jar", "laps", "eir", "tinc", "op", "ash", "rwd", "fuffy", "act", "baas", "wd", "hod", "reg", "wack", "oud", "bdle", "aw", "urf", "pur", "shamim", "lbs", "waco", "md", "arf", "fwd", "ureal", "abc", "merk", "ux", "wee", "wan", "ficins", "haf", "bone", "tb", "mele", "ur", "snag", "uts", "aivr"], | |
26 | |
) | |
test( | |
["pooh", "cb", "bz", "ceride", "renn", "yese", "ug", "ality", "bono", "adad", "ctg", "goa", "tck", "afb", "fir", "ir", "schute", "jurels", "bey", "lh", "vita", "amir", "roe", "oath", "ht", "timish", "go", "sida", "josh", "dca", "ean", "scuft", "mats", "ss", "uh", "tapa", "fain", "tiens", "apa", "oto", "is", "encysts", "fw", "yow", "chewer", "girl"], | |
25 | |
) | |
test( | |
["sciaenoid", "ass", "engem", "gange", "abb", "xvi", "indwell", "alipeds", "norma", "rt", "hest", "unsainted", "s", "seg", "dovelet", "hoplology", "aq", "raptest", "jem", "inspirers", "wf", "lie", "parachutism", "jour", "shp", "nov", "oda", "dourest", "mamamu", "mlx", "ho", "gid", "blackit", "ld", "j", "trios", "mysis", "leet", "forbite", "diddled", "ordo", "pipilo", "kb", "lim", "elcaja", "fc", "confreres", "tha", "ls", "niggardly", "ctf", "lect", "gitalin", "jo", "yoi", "twi", "et", "p", "kilty", "plasmoquine", "ot", "andy", "john", "db", "ooid", "pars", "qy", "unglossy", "t", "keelfat", "rm","uvid", "realm", "up", "j", "balor", "middleweights", "sui", "rowan", "gis", "quip", "tsks", "blist", "tapen", "razz", "sqrt", "balaic", "undig", "pepsi", "sb", "et", "mavourneen", "chicles", "ife", "merism", "whit", "om", "fugles", "fc", "match", "tef", "no", "r", "stalky", "alaloi", "mb", "taupou", "isopodous", "sa", "basest", "remeasuring", "js", "wauled", "arcane", "fulk", "luncher", "rep", "donny", "ayme", "yoruba", "gau", "stag", "ohm", "ombudsman", "dept", "coed", "subserviate", "xw", "lor", "cronk", "hoe", "seax", "merry", "xu", "sea", "fs", "nucleons", "sct", "mucid", "meek", "aurify", "ecod", "eyn", "weli", "maniples", "pind", "wy", "bkt", "picot", "zip", "tk", "yaw", "humet", "shades", "toba", "nasa", "sel", "tracy", "lt", "sh", "fed", "tr", "roe", "projet", "tendre", "ol", "on", "ferrocene", "caon", "tu", "chi", "millimetre", "mils", "skair", "gree", "dol", "demies", "punk", "duos", "welk", "adj", "do", "maile", "hypnotise", "wl", "bz", "sizars", "aul", "cv", "gu", "pq", "cyul", "waferwork", "dm", "vol", "eleme", "gley", "hypapante", "storey", "thimbled", "mico", "cloky", "idiotry", "mulm", "nt", "cods", "secondary", "cherries", "pg", "luri", "andia", "fee", "lesiy", "dana","nace", "ern", "iyar", "nana", "emailed", "by", "protoamphibian", "cy", "adam", "empair", "drammed", "sapa", "monad", "hunk", "chang", "rwy", "sctd", "jami", "xd", "emend", "pari", "ceca", "putted", "prude", "lym", "lamed", "daub", "v", "rum", "ylems", "ak", "lavenite", "foh", "yird", "iliotibial", "si", "pht", "resteel", "gs", "mew", "forgift", "inn", "fee", "comoid", "scolb", "esd", "jymold", "vest", "koa", "laager"], | |
80 | |
) | |
test( | |
["mn", "chart", "untell", "musks", "ccws", "ure", "kbar", "o", "eld", "im", "aseismicity", "eye", "gibus", "geog", "bual", "crissa", "avion", "near"], | |
20 | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment