palt-typesetting 0.2.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +16 -18
  2. package/bundle/typesetter.min.js +1 -6
  3. package/bundle/typesetter.min.js.map +4 -4
  4. package/dist/apply-style.d.ts +3 -2
  5. package/dist/apply-style.d.ts.map +1 -1
  6. package/dist/apply-style.js +37 -34
  7. package/dist/html-processor.d.ts +1 -1
  8. package/dist/html-processor.d.ts.map +1 -1
  9. package/dist/html-processor.js +88 -55
  10. package/dist/index.d.ts +3 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +97 -61
  13. package/dist/insert-separators.d.ts +3 -3
  14. package/dist/insert-separators.d.ts.map +1 -1
  15. package/dist/insert-separators.js +40 -40
  16. package/dist/style/typesetting.css +40 -0
  17. package/dist/{utils-regex.d.ts → util-regex.d.ts} +3 -1
  18. package/dist/util-regex.d.ts.map +1 -0
  19. package/dist/util-regex.js +20 -0
  20. package/dist/util-tags.d.ts +9 -0
  21. package/dist/util-tags.d.ts.map +1 -0
  22. package/dist/util-tags.js +55 -0
  23. package/dist/{utils-text-classes.d.ts → util-text-classes.d.ts} +3 -2
  24. package/dist/util-text-classes.d.ts.map +1 -0
  25. package/dist/util-text-classes.js +98 -0
  26. package/dist/win-browser.js +4 -4
  27. package/dist/win.js +6 -6
  28. package/package.json +16 -11
  29. package/{dist/types → types}/index.d.ts +0 -5
  30. package/dist/apply-style.js.map +0 -1
  31. package/dist/bundle.d.ts +0 -2
  32. package/dist/bundle.d.ts.map +0 -1
  33. package/dist/bundle.js.map +0 -1
  34. package/dist/html-processor.js.map +0 -1
  35. package/dist/index.js.map +0 -1
  36. package/dist/insert-separators.js.map +0 -1
  37. package/dist/utils-regex.d.ts.map +0 -1
  38. package/dist/utils-regex.js +0 -10
  39. package/dist/utils-regex.js.map +0 -1
  40. package/dist/utils-tags.d.ts +0 -8
  41. package/dist/utils-tags.d.ts.map +0 -1
  42. package/dist/utils-tags.js +0 -44
  43. package/dist/utils-tags.js.map +0 -1
  44. package/dist/utils-text-classes.d.ts.map +0 -1
  45. package/dist/utils-text-classes.js +0 -78
  46. package/dist/utils-text-classes.js.map +0 -1
  47. package/dist/win-browser.js.map +0 -1
  48. package/dist/win.js.map +0 -1
  49. /package/{dist/types → types}/linebreak.d.ts +0 -0
@@ -1,5 +1,6 @@
1
- import { TypesettingOptions } from './types';
1
+ import { TypesettingOptions } from '../types';
2
2
  declare const applyStyleToText: (currentNodeValue: string, nextNodeValue: string, options: TypesettingOptions) => string;
3
3
  declare const applyStyleToSegment: (currentSegment: string, nextSegment: string, options: TypesettingOptions) => string;
4
- export { applyStyleToText, applyStyleToSegment };
4
+ declare const applyKerningToSegment: (currentSegment: string, nextSegment: string, options: TypesettingOptions) => string;
5
+ export { applyStyleToText, applyStyleToSegment, applyKerningToSegment };
5
6
  //# sourceMappingURL=apply-style.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"apply-style.d.ts","sourceRoot":"","sources":["../src/apply-style.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAQ5C,QAAA,MAAM,gBAAgB,qBAAsB,MAAM,iBAAiB,MAAM,WAAW,kBAAkB,KAAG,MAOxG,CAAA;AAUD,QAAA,MAAM,mBAAmB,mBAAoB,MAAM,eAAe,MAAM,WAAW,kBAAkB,KAAG,MAmBvG,CAAA;AA8BD,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,CAAA"}
1
+ {"version":3,"file":"apply-style.d.ts","sourceRoot":"","sources":["../src/apply-style.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAQ7C,QAAA,MAAM,gBAAgB,qBAAsB,MAAM,iBAAiB,MAAM,WAAW,kBAAkB,KAAG,MAOxG,CAAA;AAUD,QAAA,MAAM,mBAAmB,mBAAoB,MAAM,eAAe,MAAM,WAAW,kBAAkB,KAAG,MAiBvG,CAAA;AAUD,QAAA,MAAM,qBAAqB,mBAAoB,MAAM,eAAe,MAAM,WAAW,kBAAkB,KAAG,MAmBzG,CAAA;AAED,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,CAAA"}
@@ -1,40 +1,43 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.applyStyleToSegment = exports.applyStyleToText = void 0;
4
- const utils_text_classes_1 = require("./utils-text-classes");
5
- const utils_tags_1 = require("./utils-tags");
1
+ import { isBreakable } from "./insert-separators";
2
+ import { CharClass, LanguageClass } from "./util-text-classes";
3
+ import { applyWrapperStyle, applyLatinStyle, applyNoBreaksStyle, createKerning } from "./util-tags";
4
+ import * as util from "./util-regex";
6
5
  const applyStyleToText = (currentNodeValue, nextNodeValue, options) => {
7
- if (currentNodeValue === ' ') {
8
- return currentNodeValue;
9
- }
10
- return (0, utils_tags_1.applyWrapperStyle)(currentNodeValue, options.classNamePrefix, options.useWordBreak);
6
+ if (currentNodeValue === " ") {
7
+ return currentNodeValue;
8
+ }
9
+ return applyWrapperStyle(currentNodeValue, options.useWordBreak);
11
10
  };
12
- exports.applyStyleToText = applyStyleToText;
13
11
  const applyStyleToSegment = (currentSegment, nextSegment, options) => {
14
- if (currentSegment === ' ') {
15
- return currentSegment;
16
- }
17
- const kernedSegment = applyKerningToSegment(currentSegment, nextSegment, options);
18
- if (options.wrapLatin && utils_text_classes_1.LanguageClass.isLatin(currentSegment)) {
19
- return (0, utils_tags_1.applyLatinStyle)(kernedSegment, options.classNamePrefix);
20
- }
21
- if (options.noSpaceBetweenNoBreaks && utils_text_classes_1.CharClass.shouldNotBreak(currentSegment)) {
22
- return (0, utils_tags_1.applyNoBreakStyle)(kernedSegment, options.classNamePrefix);
23
- }
24
- return kernedSegment;
12
+ if (currentSegment === " ") {
13
+ return currentSegment;
14
+ }
15
+ if (options.wrapLatin && LanguageClass.isLatin(currentSegment)) {
16
+ return currentSegment.replace(util.latinRegex, (match) => applyLatinStyle(match));
17
+ }
18
+ if (options.noSpaceBetweenNoBreaks && CharClass.shouldNotBreak(currentSegment)) {
19
+ return currentSegment.replace(util.noBreakRulesRegex, (match) => applyNoBreaksStyle(match));
20
+ }
21
+ return currentSegment;
25
22
  };
26
- exports.applyStyleToSegment = applyStyleToSegment;
27
23
  const applyKerningToSegment = (currentSegment, nextSegment, options) => {
28
- const chars = [...currentSegment];
29
- const kernedChars = chars.map((currentChar, i) => {
30
- const nextChar = chars[i + 1] || nextSegment[0] || '';
31
- const kerningRule = options.kerningRules.find(rule => rule.between[0] === currentChar && rule.between[1] === nextChar);
32
- if (kerningRule) {
33
- const kerningValue = typeof kerningRule.value === 'number' ? kerningRule.value : parseInt(kerningRule.value, 10);
34
- return currentChar + (0, utils_tags_1.createKerningSpan)(kerningValue, options.classNamePrefix);
35
- }
36
- return currentChar;
37
- });
38
- return kernedChars.join('');
24
+ const chars = [...currentSegment];
25
+ const kernedChars = chars.map((currentChar, i) => {
26
+ const nextChar = chars[i + 1] || nextSegment[0] || "";
27
+ const kerningRule = options.kerningRules.find(
28
+ (rule) => rule.between[0] === currentChar && rule.between[1] === nextChar
29
+ );
30
+ if (kerningRule) {
31
+ const kerningValue = typeof kerningRule.value === "number" ? kerningRule.value : parseInt(kerningRule.value, 10);
32
+ const breakable = options.useWordBreak ? false : isBreakable(currentChar, nextChar);
33
+ return currentChar + createKerning(kerningValue, breakable);
34
+ }
35
+ return currentChar;
36
+ });
37
+ return kernedChars.join("");
38
+ };
39
+ export {
40
+ applyKerningToSegment,
41
+ applyStyleToSegment,
42
+ applyStyleToText
39
43
  };
40
- //# sourceMappingURL=apply-style.js.map
@@ -1,4 +1,4 @@
1
- import type { TransformFunction, TypesettingOptions } from './types';
1
+ import type { TransformFunction, TypesettingOptions } from '../types';
2
2
  declare class HTMLProcessor {
3
3
  private transformFunctions;
4
4
  private options;
@@ -1 +1 @@
1
- {"version":3,"file":"html-processor.d.ts","sourceRoot":"","sources":["../src/html-processor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAOpE,cAAM,aAAa;IACjB,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,OAAO,CAAoB;gBAEvB,kBAAkB,EAAE,iBAAiB,EAAE,EAAE,OAAO,EAAE,kBAAkB;IAahF,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAmBjD,OAAO,CAAC,WAAW;IAyBnB,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,WAAW,CASlB;CACF;AAQD,QAAA,MAAM,eAAe,SAAU,MAAM,aAEpC,CAAA;AAQD,QAAA,MAAM,YAAY,YAAa,WAAW,KAAG,IAAI,EAahD,CAAA;AAED,eAAe,aAAa,CAAA;AAC5B,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"html-processor.d.ts","sourceRoot":"","sources":["../src/html-processor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAOrE,cAAM,aAAa;IACjB,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,OAAO,CAAoB;gBAEvB,kBAAkB,EAAE,iBAAiB,EAAE,EAAE,OAAO,EAAE,kBAAkB;IAahF,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAmBjD,OAAO,CAAC,WAAW;IAyBnB,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,WAAW,CASlB;CACF;AAQD,QAAA,MAAM,eAAe,SAAU,MAAM,aAEpC,CAAA;AAQD,QAAA,MAAM,YAAY,YAAa,WAAW,KAAG,IAAI,EAahD,CAAA;AAED,eAAe,aAAa,CAAA;AAC5B,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,CAAA"}
@@ -1,64 +1,97 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getTextNodes = exports.parseFromString = void 0;
7
- const win_1 = __importDefault(require("./win"));
1
+ import win from "./win";
8
2
  class HTMLProcessor {
9
- constructor(transformFunctions, options) {
10
- this.replaceNode = (node, transformedHtml) => {
11
- const range = win_1.default.document.createRange();
12
- range.selectNode(node);
13
- const fragment = range.createContextualFragment(transformedHtml);
14
- if (node.parentNode) {
15
- node.parentNode.insertBefore(fragment, node);
16
- node.parentNode.removeChild(node);
17
- }
18
- };
19
- this.transformFunctions = transformFunctions;
20
- this.options = options;
21
- }
22
- processHtmlWithFunctions(srcHtml) {
23
- if (srcHtml === '') {
24
- return srcHtml;
25
- }
26
- return this.transformFunctions.reduce((currentHtml, transformFunction) => this.processHtml(currentHtml, transformFunction), srcHtml);
3
+ constructor(transformFunctions, options) {
4
+ /**
5
+ * 指定されたノードを、新しいHTMLコンテンツで置き換えます。
6
+ *
7
+ * @param node - 置き換えるノード。
8
+ * @param transformedHtml - ノードに挿入される変換後のHTMLコンテンツ。
9
+ */
10
+ this.replaceNode = (node, transformedHtml) => {
11
+ const range = win.document.createRange();
12
+ range.selectNode(node);
13
+ const fragment = range.createContextualFragment(transformedHtml);
14
+ if (node.parentNode) {
15
+ node.parentNode.insertBefore(fragment, node);
16
+ node.parentNode.removeChild(node);
17
+ }
18
+ };
19
+ this.transformFunctions = transformFunctions;
20
+ this.options = options;
21
+ }
22
+ /**
23
+ * 与えられたHTML文字列に対して、指定された変換関数の配列を順番に適用し、
24
+ * 変換されたHTMLを生成します。
25
+ *
26
+ * @param srcHtml - 変換を適用する元のHTML文字列。
27
+ * @param functions - 順番に適用する変換関数の配列。
28
+ * @return 変換後のHTML文字列。
29
+ */
30
+ processHtmlWithFunctions(srcHtml) {
31
+ if (srcHtml === "") {
32
+ return srcHtml;
27
33
  }
28
- processHtml(html, transformFunction) {
29
- if (html === '') {
30
- return html;
31
- }
32
- const doc = parseFromString(html);
33
- const textNodes = getTextNodes(doc.body);
34
- textNodes.forEach((currentNode, index) => {
35
- const nextNode = textNodes[index + 1] || null;
36
- const transformedHtml = this.getTransformedHtml(currentNode, nextNode, transformFunction);
37
- this.replaceNode(currentNode, transformedHtml);
38
- });
39
- return doc.body.innerHTML;
40
- }
41
- getTransformedHtml(currentNode, nextNode, transformFunction) {
42
- const transformedHtml = transformFunction(currentNode.nodeValue || '', nextNode ? nextNode.nodeValue || '' : '', this.options);
43
- return transformedHtml;
34
+ return this.transformFunctions.reduce(
35
+ (currentHtml, transformFunction) => this.processHtml(currentHtml, transformFunction),
36
+ srcHtml
37
+ );
38
+ }
39
+ /**
40
+ * HTML文字列を解析し、特定の変換関数を使用してその内容を変換し、
41
+ * 変換されたHTMLを文字列として返します。
42
+ *
43
+ * @param html - 解析および変換するHTML文字列。
44
+ * @param transformFunction - 各テキストノードに適用される変換関数。
45
+ * @return 変換後のHTML内容を含む文字列。テキストが空の場合は、そのまま返されます。
46
+ */
47
+ processHtml(html, transformFunction) {
48
+ if (html === "") {
49
+ return html;
44
50
  }
51
+ const doc = parseFromString(html);
52
+ const textNodes = getTextNodes(doc.body);
53
+ textNodes.forEach((currentNode, index) => {
54
+ const nextNode = textNodes[index + 1] || null;
55
+ const transformedHtml = this.getTransformedHtml(currentNode, nextNode, transformFunction);
56
+ this.replaceNode(currentNode, transformedHtml);
57
+ });
58
+ return doc.body.innerHTML;
59
+ }
60
+ /**
61
+ * 与えられたノードと、その次のノードに基づいて変換されたHTMLを生成します。
62
+ *
63
+ * @param currentNode - 現在のノード。
64
+ * @param nextNode - 次のノード、または存在しない場合は null。
65
+ * @param transformFunction - ノードの値を変換するための関数。
66
+ * @return 変換されたHTMLコンテンツを含む文字列。
67
+ */
68
+ getTransformedHtml(currentNode, nextNode, transformFunction) {
69
+ const transformedHtml = transformFunction(
70
+ currentNode.nodeValue || "",
71
+ nextNode ? nextNode.nodeValue || "" : "",
72
+ this.options
73
+ );
74
+ return transformedHtml;
75
+ }
45
76
  }
46
77
  const parseFromString = (html) => {
47
- return new win_1.default.DOMParser().parseFromString(html, 'text/html');
78
+ return new win.DOMParser().parseFromString(html, "text/html");
48
79
  };
49
- exports.parseFromString = parseFromString;
50
80
  const getTextNodes = (element) => {
51
- const walk = win_1.default.document.createTreeWalker(element, win_1.default.NodeFilter.SHOW_TEXT);
52
- let textNode = walk.nextNode();
53
- const textNodes = [];
54
- while (textNode) {
55
- if (textNode.nodeValue && textNode.nodeValue.trim() !== '') {
56
- textNodes.push(textNode);
57
- }
58
- textNode = walk.nextNode();
81
+ const walk = win.document.createTreeWalker(element, win.NodeFilter.SHOW_TEXT);
82
+ let textNode = walk.nextNode();
83
+ const textNodes = [];
84
+ while (textNode) {
85
+ if (textNode.nodeValue && textNode.nodeValue.trim() !== "") {
86
+ textNodes.push(textNode);
59
87
  }
60
- return textNodes;
88
+ textNode = walk.nextNode();
89
+ }
90
+ return textNodes;
91
+ };
92
+ var html_processor_default = HTMLProcessor;
93
+ export {
94
+ html_processor_default as default,
95
+ getTextNodes,
96
+ parseFromString
61
97
  };
62
- exports.getTextNodes = getTextNodes;
63
- exports.default = HTMLProcessor;
64
- //# sourceMappingURL=html-processor.js.map
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import HTMLProcessor from './html-processor';
2
- import type { TypesettingOptions } from './types';
2
+ import type { TypesettingOptions } from '../types';
3
3
  declare class Typesetter extends HTMLProcessor {
4
- static defaultOptions: TypesettingOptions;
4
+ static getDefaultOptions(): TypesettingOptions;
5
5
  private isIntlSegmenterSupported;
6
6
  constructor(options?: Partial<TypesettingOptions>);
7
7
  private static validateOptions;
@@ -11,4 +11,5 @@ declare class Typesetter extends HTMLProcessor {
11
11
  renderToSelector(selector: string | null): void;
12
12
  }
13
13
  export default Typesetter;
14
+ export type { TypesettingOptions, KerningRule } from '../types';
14
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,kBAAkB,CAAA;AAI5C,OAAO,KAAK,EAAE,kBAAkB,EAAe,MAAM,SAAS,CAAA;AAM9D,cAAM,UAAW,SAAQ,aAAa;IAIpC,MAAM,CAAC,cAAc,EAAE,kBAAkB,CAQxC;IAKD,OAAO,CAAC,wBAAwB,CAAS;gBAE7B,OAAO,GAAE,OAAO,CAAC,kBAAkB,CAAM;IA2BrD,OAAO,CAAC,MAAM,CAAC,eAAe;IAkB9B,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAiBjC,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAc/B,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,EAAE,GAAG,IAAI,GAAG,IAAI;IAqB5D,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;CAQhD;AAED,eAAe,UAAU,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,kBAAkB,CAAA;AAI5C,OAAO,KAAK,EAAE,kBAAkB,EAAe,MAAM,UAAU,CAAA;AAM/D,cAAM,UAAW,SAAQ,aAAa;IAIpC,MAAM,CAAC,iBAAiB,IAAI,kBAAkB;IAc9C,OAAO,CAAC,wBAAwB,CAAS;gBAE7B,OAAO,GAAE,OAAO,CAAC,kBAAkB,CAAM;IA2BrD,OAAO,CAAC,MAAM,CAAC,eAAe;IAkB9B,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAiBjC,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAc/B,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,EAAE,GAAG,IAAI,GAAG,IAAI;IAqB5D,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;CAQhD;AAED,eAAe,UAAU,CAAA;AACzB,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA"}
package/dist/index.js CHANGED
@@ -1,73 +1,109 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const html_processor_1 = __importDefault(require("./html-processor"));
7
- const insert_separators_1 = __importDefault(require("./insert-separators"));
8
- const apply_style_1 = require("./apply-style");
9
- const win_1 = __importDefault(require("./win"));
10
- class Typesetter extends html_processor_1.default {
11
- constructor(options = {}) {
12
- const transformFunctions = [apply_style_1.applyStyleToText, insert_separators_1.default, apply_style_1.applyStyleToSegment];
13
- const validatedOptions = Typesetter.validateOptions(options);
14
- super(transformFunctions, validatedOptions);
15
- this.isIntlSegmenterSupported = typeof Intl.Segmenter !== 'undefined';
16
- if (!this.isIntlSegmenterSupported) {
17
- console.warn(`
1
+ import HTMLProcessor from "./html-processor";
2
+ import insertSeparatorsToText from "./insert-separators";
3
+ import { applyStyleToText, applyStyleToSegment, applyKerningToSegment } from "./apply-style";
4
+ import win from "./win";
5
+ class Typesetter extends HTMLProcessor {
6
+ /**
7
+ * Typesetter のデフォルトの設定を返します。
8
+ */
9
+ static getDefaultOptions() {
10
+ return {
11
+ useWordBreak: true,
12
+ wrapLatin: true,
13
+ noSpaceBetweenNoBreaks: true,
14
+ insertThinSpaces: true,
15
+ thinSpaceWidth: "0.2em",
16
+ kerningRules: []
17
+ };
18
+ }
19
+ constructor(options = {}) {
20
+ const transformFunctions = [applyStyleToText, insertSeparatorsToText, applyStyleToSegment, applyKerningToSegment];
21
+ const validatedOptions = Typesetter.validateOptions(options);
22
+ super(transformFunctions, validatedOptions);
23
+ this.isIntlSegmenterSupported = typeof Intl.Segmenter !== "undefined";
24
+ if (!this.isIntlSegmenterSupported) {
25
+ console.warn(`
18
26
  Intl.Segmenter is not supported in this environment.
19
27
  The original HTML string will be returned.
20
28
  For more information, see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter
21
29
  `);
22
- }
23
30
  }
24
- static validateOptions(options) {
25
- if (options.kerningRules) {
26
- options.kerningRules = options.kerningRules.filter(Typesetter.isValidKerningRule);
27
- }
28
- return Object.assign(Object.assign({}, Typesetter.defaultOptions), options);
31
+ }
32
+ /**
33
+ * 与えられたオプションを検証し、修正されたオプションを返します。
34
+ *
35
+ * @param options - 検証するオプション。
36
+ * @return 修正されたオプション。
37
+ */
38
+ static validateOptions(options) {
39
+ if (options.kerningRules) {
40
+ options.kerningRules = options.kerningRules.filter(Typesetter.isValidKerningRule);
41
+ }
42
+ return {
43
+ ...Typesetter.getDefaultOptions(),
44
+ ...options
45
+ };
46
+ }
47
+ /**
48
+ * カーニングルールが適切かどうかを検証します。
49
+ *
50
+ * @param kerningRule - 検証するカーニングルール。
51
+ * @return ルールが有効な場合はtrue、そうでない場合はfalse。
52
+ */
53
+ static isValidKerningRule(kerningRule) {
54
+ if (kerningRule.between[0].length !== 1 || kerningRule.between[1].length !== 1) {
55
+ console.warn(
56
+ `Kerning rule between '${kerningRule.between[0]}' and '${kerningRule.between[1]}' must be single characters.`
57
+ );
58
+ return false;
29
59
  }
30
- static isValidKerningRule(kerningRule) {
31
- if (kerningRule.between[0].length !== 1 || kerningRule.between[1].length !== 1) {
32
- console.warn(`Kerning rule between '${kerningRule.between[0]}' and '${kerningRule.between[1]}' must be single characters.`);
33
- return false;
34
- }
35
- return true;
60
+ return true;
61
+ }
62
+ /**
63
+ * 与えられたHTML文字列を処理し、指定されたスタイルと区切り文字を適用した結果を返します。
64
+ *
65
+ * @param srcHtml - 処理するHTML文字列。
66
+ * @return 処理後のHTML文字列。
67
+ */
68
+ render(srcHtml) {
69
+ if (!this.isIntlSegmenterSupported || !srcHtml) {
70
+ return srcHtml;
36
71
  }
37
- render(srcHtml) {
38
- if (!this.isIntlSegmenterSupported || !srcHtml) {
39
- return srcHtml;
40
- }
41
- return this.processHtmlWithFunctions(srcHtml);
72
+ return this.processHtmlWithFunctions(srcHtml);
73
+ }
74
+ /**
75
+ * 与えられたElementまたはElementの配列に対して、スタイルと区切り文字を適用します。
76
+ * 各要素のinnerHTMLを取得し、変換処理を適用した後、変換されたHTMLで元の内容を置き換えます。
77
+ *
78
+ * @param elements - スタイルを適用するElementまたはHTMLElementの配列。
79
+ */
80
+ renderToElements(elements) {
81
+ if (!this.isIntlSegmenterSupported || !elements) {
82
+ return;
42
83
  }
43
- renderToElements(elements) {
44
- if (!this.isIntlSegmenterSupported || !elements) {
45
- return;
46
- }
47
- if (!Array.isArray(elements)) {
48
- elements = [elements];
49
- }
50
- elements.forEach(element => {
51
- const processedHtml = this.render(element.innerHTML);
52
- element.innerHTML = processedHtml;
53
- });
84
+ if (!Array.isArray(elements)) {
85
+ elements = [elements];
54
86
  }
55
- renderToSelector(selector) {
56
- if (!this.isIntlSegmenterSupported || !selector) {
57
- return;
58
- }
59
- const elements = win_1.default.document.querySelectorAll(selector);
60
- this.renderToElements(Array.from(elements));
87
+ elements.forEach((element) => {
88
+ const processedHtml = this.render(element.innerHTML);
89
+ element.innerHTML = processedHtml;
90
+ });
91
+ }
92
+ /**
93
+ * 指定されたCSSセレクタに一致するすべての要素にスタイルを適用します。
94
+ * document.querySelectorAllを使用して要素を取得し、それぞれに対してスタイル適用処理を行います。
95
+ *
96
+ * @param selector - スタイルを適用する要素を選択するCSSセレクタ。
97
+ */
98
+ renderToSelector(selector) {
99
+ if (!this.isIntlSegmenterSupported || !selector) {
100
+ return;
61
101
  }
102
+ const elements = win.document.querySelectorAll(selector);
103
+ this.renderToElements(Array.from(elements));
104
+ }
62
105
  }
63
- Typesetter.defaultOptions = {
64
- classNamePrefix: 'typeset',
65
- useWordBreak: true,
66
- wrapLatin: true,
67
- noSpaceBetweenNoBreaks: true,
68
- insertThinSpaces: true,
69
- thinSpaceWidth: '50%',
70
- kerningRules: [],
106
+ var src_default = Typesetter;
107
+ export {
108
+ src_default as default
71
109
  };
72
- exports.default = Typesetter;
73
- //# sourceMappingURL=index.js.map
@@ -1,9 +1,9 @@
1
- import { TypesettingOptions } from './types';
1
+ import { TypesettingOptions } from '../types';
2
2
  declare const insertSeparatorsToText: (currentText: string, nextText: string, options: TypesettingOptions) => string;
3
3
  declare const createSegments: (src: string) => string[];
4
4
  declare const addSeparatorsToSegment: (current: string, next: string | undefined, options: TypesettingOptions) => string;
5
- declare const shouldAddWbr: (current: string, next: string) => boolean | null;
6
5
  declare const shouldAddThinSpace: (current: string, next: string) => boolean;
6
+ declare const isBreakable: (current: string, next: string) => boolean;
7
7
  export default insertSeparatorsToText;
8
- export { createSegments, addSeparatorsToSegment, shouldAddWbr, shouldAddThinSpace };
8
+ export { createSegments, addSeparatorsToSegment, shouldAddThinSpace, isBreakable };
9
9
  //# sourceMappingURL=insert-separators.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"insert-separators.d.ts","sourceRoot":"","sources":["../src/insert-separators.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAQ5C,QAAA,MAAM,sBAAsB,gBAAiB,MAAM,YAAY,MAAM,WAAW,kBAAkB,KAAG,MAWpG,CAAA;AAOD,QAAA,MAAM,cAAc,QAAS,MAAM,KAAG,MAAM,EAG3C,CAAA;AAQD,QAAA,MAAM,sBAAsB,YAAa,MAAM,qCAAsB,kBAAkB,KAAG,MAUzF,CAAA;AAQD,QAAA,MAAM,YAAY,YAAa,MAAM,QAAQ,MAAM,KAAG,OAAO,GAAG,IAK/D,CAAA;AAQD,QAAA,MAAM,kBAAkB,YAAa,MAAM,QAAQ,MAAM,KAAG,OAE3D,CAAA;AAED,eAAe,sBAAsB,CAAA;AACrC,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,YAAY,EAAE,kBAAkB,EAAE,CAAA"}
1
+ {"version":3,"file":"insert-separators.d.ts","sourceRoot":"","sources":["../src/insert-separators.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAQ7C,QAAA,MAAM,sBAAsB,gBAAiB,MAAM,YAAY,MAAM,WAAW,kBAAkB,KAAG,MAWpG,CAAA;AAOD,QAAA,MAAM,cAAc,QAAS,MAAM,KAAG,MAAM,EAG3C,CAAA;AAQD,QAAA,MAAM,sBAAsB,YAAa,MAAM,qCAAsB,kBAAkB,KAAG,MAezF,CAAA;AAQD,QAAA,MAAM,kBAAkB,YAAa,MAAM,QAAQ,MAAM,KAAG,OAE3D,CAAA;AAQD,QAAA,MAAM,WAAW,YAAa,MAAM,QAAQ,MAAM,KAAG,OAKpD,CAAA;AAED,eAAe,sBAAsB,CAAA;AACrC,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,WAAW,EAAE,CAAA"}
@@ -1,47 +1,47 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.shouldAddThinSpace = exports.shouldAddWbr = exports.addSeparatorsToSegment = exports.createSegments = void 0;
7
- const linebreak_1 = __importDefault(require("linebreak"));
8
- const utils_text_classes_1 = require("./utils-text-classes");
9
- const utils_tags_1 = require("./utils-tags");
1
+ import LineBreaker from "linebreak";
2
+ import { CharClass, LanguageClass } from "./util-text-classes";
3
+ import { createWbr, createThinSpace } from "./util-tags";
10
4
  const insertSeparatorsToText = (currentText, nextText, options) => {
11
- const currentSegments = createSegments(currentText);
12
- const nextSegments = createSegments(nextText);
13
- const formattedText = currentSegments.reduce((accumulatedText, segment, index, array) => {
14
- const current = segment;
15
- const next = array[index + 1] || nextSegments[0];
16
- return accumulatedText + addSeparatorsToSegment(current, next, options);
17
- }, '');
18
- return formattedText;
5
+ const currentSegments = createSegments(currentText);
6
+ const nextSegments = createSegments(nextText);
7
+ const formattedText = currentSegments.reduce((accumulatedText, segment, index, array) => {
8
+ const current = segment;
9
+ const next = array[index + 1] || nextSegments[0];
10
+ return accumulatedText + addSeparatorsToSegment(current, next, options);
11
+ }, "");
12
+ return formattedText;
19
13
  };
20
14
  const createSegments = (src) => {
21
- const segmenter = new Intl.Segmenter('ja-JP', { granularity: 'word' });
22
- return Array.from(segmenter.segment(src), ({ segment }) => segment);
23
- };
24
- exports.createSegments = createSegments;
25
- const addSeparatorsToSegment = (current, next = '', options) => {
26
- if (!next)
27
- return current;
28
- const addWbr = options.useWordBreak && shouldAddWbr(current, next);
29
- const addSpace = options.insertThinSpaces && shouldAddThinSpace(current, next);
30
- return (current +
31
- (addSpace ? (0, utils_tags_1.createThinSpaceSpan)(options.thinSpaceWidth, options.classNamePrefix) : '') +
32
- (addWbr ? utils_tags_1.wbr : ''));
15
+ const segmenter = new Intl.Segmenter("ja-JP", { granularity: "word" });
16
+ return Array.from(segmenter.segment(src), ({ segment }) => segment);
33
17
  };
34
- exports.addSeparatorsToSegment = addSeparatorsToSegment;
35
- const shouldAddWbr = (current, next) => {
36
- const combinedText = current.slice(-1) + next.slice(0, 1);
37
- const lb = new linebreak_1.default(combinedText);
38
- const breakOpportunity = lb.nextBreak();
39
- return breakOpportunity && breakOpportunity.position === 1;
18
+ const addSeparatorsToSegment = (current, next = "", options) => {
19
+ if (!next)
20
+ return current;
21
+ const addThinSpace = options.insertThinSpaces && shouldAddThinSpace(current, next);
22
+ const breakable = isBreakable(current, next);
23
+ if (addThinSpace) {
24
+ return current + createThinSpace(options.thinSpaceWidth, breakable);
25
+ }
26
+ if (options.useWordBreak && breakable) {
27
+ return current + createWbr();
28
+ }
29
+ return current;
40
30
  };
41
- exports.shouldAddWbr = shouldAddWbr;
42
31
  const shouldAddThinSpace = (current, next) => {
43
- return utils_text_classes_1.LanguageClass.shouldAddThinSpace(current, next) || utils_text_classes_1.CharClass.shouldAddThinSpace(current, next);
32
+ return LanguageClass.shouldAddThinSpace(current, next) || CharClass.shouldAddThinSpace(current, next);
33
+ };
34
+ const isBreakable = (current, next) => {
35
+ const combinedText = current.slice(-1) + next.slice(0, 1);
36
+ const lb = new LineBreaker(combinedText);
37
+ const breakOpportunity = lb.nextBreak();
38
+ return breakOpportunity ? breakOpportunity.position === 1 : false;
39
+ };
40
+ var insert_separators_default = insertSeparatorsToText;
41
+ export {
42
+ addSeparatorsToSegment,
43
+ createSegments,
44
+ insert_separators_default as default,
45
+ isBreakable,
46
+ shouldAddThinSpace
44
47
  };
45
- exports.shouldAddThinSpace = shouldAddThinSpace;
46
- exports.default = insertSeparatorsToText;
47
- //# sourceMappingURL=insert-separators.js.map
@@ -0,0 +1,40 @@
1
+ @font-face {
2
+ /*
3
+ * カスタムフォント: 1/10000 UPM 幅の Space と No-Break Space を定義。
4
+ * 注意:完全なゼロ幅スペースを使用すると、Safari では letter-spacing が無視される。
5
+ * @sharapeco による貢献に感謝します。{@link https://gist.github.com/sharapeco/1dd7f4433dad07648e1325e1fa5926ee}
6
+ */
7
+ font-family: ling-one;
8
+ src: url('data:font/woff2;base64,AAEAAAAKAIAAAwAgT1MvMhG03xcAAAEoAAAAYGNtYXAADABzAAABkAAAADRnbHlmJAM2GwAAAcwAAAAYaGVhZCLbfFwAAACsAAAANmhoZWEnEvkrAAAA5AAAACRobXR4AAEAAAAAAYgAAAAIbG9jYQAMABgAAAHEAAAACG1heHAAcQAiAAABCAAAACBuYW1lBbsdPAAAAeQAAACKcG9zdHQrY6cAAAJwAAAALQABAAAAAQAAsWqD8F8PPPUAAycQAAAAAOHcugAAAAAA4edeTwAAAAAAAQABAAAABwACAAAAAAAAAAEAACcQ+DAAAAB9AAAAfAABAAEAAAAAAAAAAAAAAAAAAAABAAEAAAADAAMAAQAAAAAAAQACAB4ABgAAAGQAAAAAAAAAAwB9AZAABQAIGWQXcAAAAu4ZZBdwAAANrAAyC7gAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc3N6bQBAACAAIB9A+DAH0CcQB9AAAAABAAAAABOIG1gAAAAgAAAAAQAAAAAAAAAAAAIAAAADAAAAFAADAAEAAAAUAAQAIAAAAAQABAABAAAAIP//AAAAIP///+EAAQAAAAAAAAAMAAwADAABAAAAAAABAAEAAgAANRcjAQEBAQAAAAAAAAYATgADAAEECQABAAgAAAADAAEECQACAAIACAADAAEECQADAB4ACgADAAEECQAEAAwAKAADAAEECQAFAAgANAADAAEECQAGAAwAKABMAGkAbgBnADEAMQAuADAAOwBzAHMAegBtADsATABpAG4AZwAtADEATABpAG4AZwAtADEAdgAxAC4AMAAAAAIAAAAAAAD/tQAyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMBAgRuYnNwAAAA')
9
+ format('woff2');
10
+ }
11
+
12
+ /*
13
+ * Safari のリーダーモード対応
14
+ * See: {@link https://github.com/yamatoiizuka/palt-typesetting/issues/96}
15
+ */
16
+ .typeset wbr {
17
+ visibility: hidden;
18
+ }
19
+
20
+ .typeset-word-break {
21
+ word-break: keep-all;
22
+ overflow-wrap: anywhere;
23
+ }
24
+
25
+ .typeset-thin-space,
26
+ .typeset-kerning {
27
+ letter-spacing: 0; /* 親要素から継承される letter-spacing の影響を無視します。 */
28
+ user-select: none; /* ユーザーによるテキストのコピーを無効にします。 */
29
+ }
30
+
31
+ .typeset-thin-space::after,
32
+ .typeset-kerning::after {
33
+ content: attr(data-content); /* Space または No-Break Space */
34
+ font-family: ling-one; /* カスタムフォントのスペースを使用します。 */
35
+ line-height: 0; /* 空白による行の高さの影響を無視します。 */
36
+ }
37
+
38
+ .typeset-no-breaks {
39
+ letter-spacing: 0; /* 親要素から継承される letter-spacing の影響を無視します。 */
40
+ }
@@ -3,5 +3,7 @@ export declare const japaneseRegex: RegExp;
3
3
  export declare const openingsRegex: RegExp;
4
4
  export declare const closingsRegex: RegExp;
5
5
  export declare const middleDotsRegex: RegExp;
6
+ export declare const commasRegex: RegExp;
7
+ export declare const periodsRegex: RegExp;
6
8
  export declare const noBreakRulesRegex: RegExp;
7
- //# sourceMappingURL=utils-regex.d.ts.map
9
+ //# sourceMappingURL=util-regex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util-regex.d.ts","sourceRoot":"","sources":["../src/util-regex.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,QAC4E,CAAA;AAKnG,eAAO,MAAM,aAAa,QAAwD,CAAA;AAKlF,eAAO,MAAM,aAAa,QAA8B,CAAA;AAKxD,eAAO,MAAM,aAAa,QAA8B,CAAA;AAKxD,eAAO,MAAM,eAAe,QAAU,CAAA;AAKtC,eAAO,MAAM,WAAW,QAAQ,CAAA;AAKhC,eAAO,MAAM,YAAY,QAAQ,CAAA;AAKjC,eAAO,MAAM,iBAAiB,QAE7B,CAAA"}