diff options
-rw-r--r-- | api/japanese.ts | 11 | ||||
-rw-r--r-- | api/sentence.ts | 2 | ||||
-rw-r--r-- | util/string.ts | 8 | ||||
-rw-r--r-- | util/wrap.ts | 41 |
4 files changed, 57 insertions, 5 deletions
diff --git a/api/japanese.ts b/api/japanese.ts index 9319cdd..ffbc773 100644 --- a/api/japanese.ts +++ b/api/japanese.ts @@ -3,20 +3,23 @@ import { escape } from "https://deno.land/std@0.192.0/html/entities.ts"; import "../util/string.ts"; import "../util/japanese.ts"; import "../util/array.ts"; +import { Wrap } from "../util/wrap.ts"; const formatters = { "HTML": tokens => tokens.reduce((out, token) => { - if (token.ruby) out += `<ruby>${escape(token.writing)}<rt>${escape(token.reading)}</rt></ruby>`; - else out += token.writing; + if (token.ruby) { + out += (escape(token.writing) + + escape(token.reading).wrap(Wrap.HTML.rubyText)).wrap(Wrap.HTML.ruby); + } else out += token.writing; return out; }, ""), "parenthesis": tokens => tokens.reduce((out, token) => { - if (token.ruby) out += `${token.writing}(${token.reading}) `; + if (token.ruby) out += token.writing + token.reading.wrap(Wrap.parenthesis) + " "; else out += token.writing; return out; }, ""), "refold-tools": tokens => tokens.reduce((out, token) => { - if (token.ruby) out += `[${token.writing}](${token.reading})`; + if (token.ruby) out += token.writing.wrap(Wrap.bracket) + token.reading.wrap(Wrap.parenthesis); else out += token.writing; return out; }, ""), diff --git a/api/sentence.ts b/api/sentence.ts index d0cc434..cde66a5 100644 --- a/api/sentence.ts +++ b/api/sentence.ts @@ -1,6 +1,6 @@ import { ParseResult } from "../language/types.ts"; import APIBase from "./base.ts"; -import Japanese, { JapaneseFormatter } from "./japanese.ts"; +import { JapaneseFormatter } from "./japanese.ts"; import Word from "./word.ts"; export default class Sentence extends APIBase { diff --git a/util/string.ts b/util/string.ts index bb6bc0f..b362f06 100644 --- a/util/string.ts +++ b/util/string.ts @@ -1,4 +1,5 @@ import { TokenTags, parseTags } from "../language/tags.ts"; +import { Wrapper } from "./wrap.ts"; declare global { interface String { @@ -49,6 +50,9 @@ declare global { /** @summary replace last instance of `searchString` with `replaceValue` */ replaceLast(searchString: string, replaceValue: string): string; + + /** @summary wrap string using Wrapper */ + wrap(wrapper: Wrapper): string; } } @@ -150,3 +154,7 @@ String.prototype.replaceLast = function(find, replace) { return this.substring(0, i) + replace + this.substring(i + find.length); } +String.prototype.wrap = function(wrapper) { + return wrapper[0] + this + wrapper[1]; +} + diff --git a/util/wrap.ts b/util/wrap.ts new file mode 100644 index 0000000..761a1f0 --- /dev/null +++ b/util/wrap.ts @@ -0,0 +1,41 @@ +export type Wrapper = [string, string]; + +/** @summary make Wrapper that starts and ends with `input` */ +export function WrapWith(input: string): Wrapper { + return [input, input]; +} + +/** @summary make Wrapper that starts and ends with XML tags with name `tagName` */ +export function WrapTag(tagName: string): Wrapper { + return [`<${tagName}>`, `</${tagName}>`]; +} + +// this type is internal to this file +type WrapType = { [K: string]: Wrapper | WrapType }; + +export const Wrap = { + /** @prop (input) */ + parenthesis: ["(", ")"], + /** @prop [input] */ + bracket: ["[", "]"], + /** @prop \{input\} */ + brace: ["{", "}"], + /** @prop HTML-specifics */ + HTML: { + /** @prop \<b>input\</b> */ + bold: WrapTag("b"), + /** @prop \<i>input\</i> */ + italic: WrapTag("i"), + /** @prop \<span>input\</span> */ + span: WrapTag("span"), + /** @prop \<ruby>input\</ruby> */ + ruby: WrapTag("ruby"), + /** @prop \<rt>input\</rt> */ + rubyText: WrapTag("rt"), + }, + /** @prop \*input\* */ + asterisk: WrapWith("*"), + /** @prop \_input\_ */ + underscore: WrapWith("_"), +} satisfies WrapType; + |