|
| 1 | +<!DOCTYPE html> |
| 2 | +<title>Universal Default Justification Experiment</title> |
| 3 | +<meta charset=utf-8> |
| 4 | +<style id="renderStyle"> |
| 5 | +.space { } |
| 6 | +.letter { } |
| 7 | +</style> |
| 8 | + |
| 9 | +<h1>Universal Default Justification Experiment</h1> |
| 10 | + |
| 11 | +<p id="render"></p> |
| 12 | + |
| 13 | +<form> |
| 14 | +<label>Text to Justify: <textarea name=text id=text>서울특별시(서울特別市)는 한반도</textarea></label> |
| 15 | +<label>Space-CJK Threshold: <input id=cjk name=cjk value=1></label> |
| 16 | +<!-- <label>Space-SEA Threshold: <input id=sea name=sea value=3></label> --> |
| 17 | +<label>Split Hangul-Han: <input type=checkbox name=splitHangul id=splitHangul></label> |
| 18 | +<p onclick="render()" style="color: green; font-weight: bold; cursor: pointer;">Render!</p> |
| 19 | +</form> |
| 20 | + |
| 21 | +<style> |
| 22 | +form { text-align: right; display: table; width: 100%; } |
| 23 | +textarea { display: table-row; margin: auto; vertical-align: top; } |
| 24 | +label { display: table-row; font-size: smaller; font-weight: bold; } |
| 25 | +input, textarea { width: calc(96vw - 15rem); box-sizing: border-box; } |
| 26 | +#render { |
| 27 | + box-shadow: 0.25em 0.25em 0.5em; |
| 28 | + border: solid 1px silver; |
| 29 | + min-height: 1em; |
| 30 | + max-width: 15em; |
| 31 | + margin: 1.5em auto 2em; |
| 32 | + white-space: nowrap; |
| 33 | + position: relative; |
| 34 | +} |
| 35 | +</style> |
| 36 | + |
| 37 | +<script> |
| 38 | +charCats = { |
| 39 | + // copied from http://fluxbb.org/forums/viewtopic.php?id=3866 |
| 40 | + 'space' : |
| 41 | + ' ' // U+0020 |
| 42 | + , |
| 43 | + 'hangul' : |
| 44 | + '[\u1100-\u11FF' + // Hangul Jamo 1100-11FF (http://www.fileformat.info/info/unicode/block/hangul_jamo/index.htm) |
| 45 | + '\u3130-\u318F' + // Hangul Compatibility Jamo 3130-318F (http://www.fileformat.info/info/unicode/block/hangul_compatibility_jamo/index.htm) |
| 46 | + '\uAC00-\uD7AF]' // Hangul Syllables AC00-D7AF (http://www.fileformat.info/info/unicode/block/hangul_syllables/index.htm) |
| 47 | + , |
| 48 | + 'han' : |
| 49 | + '[\u2E80-\u2EFF' + // CJK Radicals Supplement 2E80-2EFF (http://www.fileformat.info/info/unicode/block/cjk_radicals_supplement/index.htm) |
| 50 | + '\u2F00-\u2FDF' + // Kangxi Radicals 2F00-2FDF (http://www.fileformat.info/info/unicode/block/kangxi_radicals/index.htm) |
| 51 | + '\u2FF0-\u2FFF' + // Ideographic Description Characters 2FF0-2FFF (http://www.fileformat.info/info/unicode/block/ideographic_description_characters/index.htm) |
| 52 | + '\u3000-\u303F' + // CJK Symbols and Punctuation 3000-303F (http://www.fileformat.info/info/unicode/block/cjk_symbols_and_punctuation/index.htm) |
| 53 | + '\u31C0-\u31EF' + // CJK Strokes 31C0-31EF (http://www.fileformat.info/info/unicode/block/cjk_strokes/index.htm) |
| 54 | + '\u3200-\u32FF' + // Enclosed CJK Letters and Months 3200-32FF (http://www.fileformat.info/info/unicode/block/enclosed_cjk_letters_and_months/index.htm) |
| 55 | + '\u3400-\u4DBF' + // CJK Unified Ideographs Extension A 3400-4DBF (http://www.fileformat.info/info/unicode/block/cjk_unified_ideographs_extension_a/index.htm) |
| 56 | + '\u4E00-\u9FFF]' // CJK Unified Ideographs 4E00-9FFF (http://www.fileformat.info/info/unicode/block/cjk_unified_ideographs/index.htm) |
| 57 | + // '\u20000-\u2A6DF' // CJK Unified Ideographs Extension B 20000-2A6DF (http://www.fileformat.info/info/unicode/block/cjk_unified_ideographs_extension_b/index.htm) |
| 58 | + , |
| 59 | + 'kana' : |
| 60 | + '[\u3040-\u30FF]' // Kana |
| 61 | +}; |
| 62 | + |
| 63 | +function render() { |
| 64 | + var renderer = document.getElementById('render'); |
| 65 | + var text = document.getElementById('text').value; |
| 66 | + var charList = []; |
| 67 | + for (c in text) { |
| 68 | + charList.push('<span>' + text[c] + '</span>'); |
| 69 | + } |
| 70 | + renderer.innerHTML = charList.join(''); |
| 71 | + document.getElementById('renderStyle').textContent = ''; |
| 72 | + |
| 73 | + var splitHangul = document.getElementById('splitHangul').checked; |
| 74 | + var charList = renderer.childNodes; |
| 75 | + var numSpaces = 0; // number of spaces |
| 76 | + var numCJK = 0; // number of stretchable gaps around CJK |
| 77 | + for (var c of charList) { |
| 78 | + if (c.textContent.match(charCats['space'])) { |
| 79 | + c.setAttribute('class', 'space'); |
| 80 | + numSpaces++; |
| 81 | + } |
| 82 | + else { |
| 83 | + n = c.nextSibling; |
| 84 | + if (!n) break; // no space after last char |
| 85 | + if (c.textContent.match(charCats['han']) || |
| 86 | + (c.textContent.match(charCats['hangul']) && !splitHangul)) { |
| 87 | + c.setAttribute('class', 'cjk'); |
| 88 | + numCJK++; |
| 89 | + } |
| 90 | + else if (n && n.textContent.match(charCats['han']) || |
| 91 | + (n.textContent.match(charCats['hangul']) && !splitHangul)) { |
| 92 | + numCJK++; |
| 93 | + } |
| 94 | + } |
| 95 | + } |
| 96 | + //alert(charList.length + ',' + numSpaces + ',' + numCJK); |
| 97 | + |
| 98 | + /* Calculate Space */ |
| 99 | + renderWidth = renderer.offsetWidth; |
| 100 | + renderWidth -= getComputedStyle(renderer).borderLeftWidth.slice(0,-2); |
| 101 | + renderWidth -= getComputedStyle(renderer).borderRightWidth.slice(0,-2); |
| 102 | + renderWidth -= getComputedStyle(renderer).paddingLeft.slice(0,-2); |
| 103 | + renderWidth -= getComputedStyle(renderer).paddingRight.slice(0,-2); |
| 104 | + |
| 105 | + lastChar = charList[charList.length-1]; |
| 106 | + contentSize = lastChar.offsetLeft + lastChar.offsetWidth; |
| 107 | + |
| 108 | + spaceToFill = renderWidth - contentSize; |
| 109 | + x = spaceToFill; |
| 110 | + |
| 111 | + /* Split Space */ |
| 112 | + fontSize = getComputedStyle(renderer).fontSize.slice(0,-2); |
| 113 | + cjkSpaceLimit = document.getElementById('cjk').value * fontSize; |
| 114 | + //seaSpaceLimit = document.getElementById('sea').value * fontSize; |
| 115 | + |
| 116 | + addToSpace = spaceToFill / numSpaces; |
| 117 | + if (addToSpace > cjkSpaceLimit) |
| 118 | + addToSpace = cjkSpaceLimit; |
| 119 | + spaceToFill -= addToSpace * numSpaces; |
| 120 | + |
| 121 | + addToCJK = spaceToFill / (numCJK+numSpaces); |
| 122 | + //alert(renderWidth + ' - ' + contentSize + ' = ' + x + ' = ' + numSpaces + '*' + addToSpace + '+' + (numCJK+numSpaces) + '*' + addToCJK); |
| 123 | + |
| 124 | + document.getElementById('renderStyle').textContent = |
| 125 | + '.space { padding-right: ' + (addToSpace+addToCJK) + 'px; }\n' + |
| 126 | + '.cjk { padding: 0 ' + addToCJK + 'px; }\n' + |
| 127 | + ':first-child, .cjk + .cjk { padding-left: 0; }'; |
| 128 | +} |
| 129 | +</script> |
| 130 | + |
0 commit comments