Quantcast
Channel: CSSタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8764

HTMLで和文と欧文の間にスペース(アキ)を自動で挿入する

$
0
0
和文と欧文が混じった文章において、読みやすさのため少し文字間のスペース(アキ)を入れたいときがあります。LaTeXなど組版に特化した環境ではそのような機能がサポートされていますが、HTMLでは今のところ標準ではサポートされていません。ただし、半角スペースを直接入力すると 入れるか入れないかの一貫性をとりにくい 幅の調整がしにくい といった問題があります。そこでJSとCSSで自動的に挿入されるようにします。 以下のコードは中国語向けのこちらを参考にしています。 main.ts import * as findAndReplaceDOMText from 'findandreplacedomtext'; enum Space { Quarter = 'quarter', Half = 'half' } class TextAutospace { static readonly ELEMENT_NODE = 1; quarterPatterns: Array<string>; halfPatterns: Array<string>; constructor() { const hiragana = '\u3040-\u309F~'; const katakana = '\u30A0-\u30FF'; const kanji = '\u2E80-\u2FFF\u31C0-\u31EF\u3300-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF\uFE30-\uFE4F'; const punct: string = '[—@&=_\,\.\?\!\$\%\^\*\-\+\/]'; const left: string = `[\\[({'"<«‘“]`; const right: string = `[\\])}'">»’”]`; const cjk = '[' + [hiragana, katakana, kanji].join('') + ']'; const latin = '[A-Za-z0-9\u00C0-\u00FF\u0100-\u017F\u0180-\u024F\u1E00-\u1EFF]' + '|' + punct; this.quarterPatterns = [ '(' + cjk + ')(' + latin + '|' + left + ')', '(' + latin + '|' + right + ')(' + cjk + ')', '(・)(' + cjk + ')', '(' + latin + '|' + cjk + ')([・])', '([:])([『])', '(' + cjk + ')([:])' ]; this.halfPatterns = [ '([、。,.)」』])(' + left + '|' + latin + '|' + cjk + ')', '(' + latin + '|' + cjk + ')([(「『])' ]; } transform(element: Node): void { [Space.Quarter, Space.Half].forEach(space => { let patterns = (space == Space.Quarter) ? this.quarterPatterns : this.halfPatterns; patterns.forEach(pattern=> { findAndReplaceDOMText(element, { find: new RegExp(pattern, 'ig'), replace: '$1<' + `${space}` + '>$2' }) }); findAndReplaceDOMText(element, { find: `<${space}>`, replace: () => { let newElement = document.createElement('span'); newElement.className = space; return newElement; } }); // Required to keep space before <code></code> document.querySelectorAll(`* > span.${space}:first-child`).forEach(child => { let p = child.parentNode; if (p.firstChild.nodeType == TextAutospace.ELEMENT_NODE) { let newElement = document.createElement('span'); newElement.className = space; p.parentNode.insertBefore(newElement, p); p.querySelector(`span.${space}:first-child`).remove(); } }); element.normalize(); }); } } document.addEventListener('DOMContentLoaded', event => { document.body.querySelectorAll('p, li, h1, h2, h3, h4, h5').forEach(element => { let t = new TextAutospace(); t.transform(element); }); }); main.scss $jp-font: 'source-han-sans-cjk-ja'; $western-font: 'Roboto'; body { -webkit-font-smoothing: antialiased; font-family: $western-font, $jp-font, sans-serif; font-feature-settings: 'palt'; font-weight: 400; } .quarter { &::after { content: ' '; display: inline; font-family: 'source-han-sans-cjk-ja'; letter-spacing: -0.1rem; } } .half { &::after { content: ' '; display: inline; font-family: 'source-han-sans-cjk-ja'; } } code { .quarter, .half { display: none; } } pre { .quarter, .half { display: none; } } kbd { .quarter, .half { display: none; } } samp { .quarter, .half { display: none; } } ol > .quarter, ul > .quarter, ul > .half, ul > .half { display: none; }

Viewing all articles
Browse latest Browse all 8764

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>