Skip to content

Commit

Permalink
New feature : Replacer
Browse files Browse the repository at this point in the history
Add override in assembler
  • Loading branch information
qluana7 committed Nov 9, 2021
1 parent 9121755 commit 5f03ca9
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 4 deletions.
4 changes: 3 additions & 1 deletion mod.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
export { Hangul } from "./src/entities/hangul.ts"
export { Converter } from "./src/entities/converter.ts"
export { Assembler } from "./src/entities/assembler.ts"
export { InteractLists, ComplexInteractionLists } from "./src/entities/interactList.ts"
export { HangulBuilder } from "./src/entities/hangulBuilder.ts"
export { Replacer, Infection } from "./src/entities/replacer.ts"

export { InteractLists, ComplexInteractionLists } from "./src/entities/interactList.ts"
export { Range } from "./src/modules/random.ts"

export type { StringType } from "./src/entities/stringType.ts"
Expand Down
15 changes: 12 additions & 3 deletions src/entities/assembler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { assemble, disassemble } from "../modules/assemble.ts"
import { Hangul } from "./hangul.ts"

/**
* Provide hangul assemble and disassemble function.
Expand All @@ -14,13 +15,21 @@ export class Assembler {
return assemble((str as string[]).reduce((p, c) => p + c));
}

/**
* This will disassemble hangul.
* @example Assembler.disassemble(new Hangul('안')) //['ㅇ','ㅏ','ㄴ']
* @param han The hangul class to disassemble
* @returns Disassembled hangul
*/
static disassemble(han: Hangul): string[]
/**
* This will disassemble hangul.
* @example Assembler.disassemble('안') // ['ㅇ','ㅏ','ㄴ']
* @param str The string value which want to disassemble
* @param str The string value to disassemble
* @returns Disassembled hangul
*/
static disassemble(str: string): string[] {
return disassemble(str);
static disassemble(str: string): string[]
static disassemble(obj: Hangul | string): string[] {
return disassemble(obj instanceof Hangul ? obj.toString() : obj);
}
}
15 changes: 15 additions & 0 deletions src/entities/hangul.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { StringType,
import { random,
RandomOption } from "../modules/random.ts"
import { Converter } from "./converter.ts";
import { Infection } from "./replacer.ts";
import { Initial, Neutral, Final } from "./interactList.ts";

function insert(origin: string, ind: number, value: string): string {
return [origin.slice(0, ind), value, origin.slice(ind)].join('');
Expand All @@ -20,10 +22,13 @@ export class Hangul {
*/
constructor(s: string) {
this.content = s;
this.infection = new Infection<Initial | Neutral | Final>(s, l => l);
}

private content: string;

private infection: Infection<Initial | Neutral | Final>;

/**
* Convert string of this class to Korean
* @returns Korean string
Expand Down Expand Up @@ -91,6 +96,16 @@ export class Hangul {
return Hangul.getType(this.content);
}

/** Refer `Replacer.infect` */
infect(from: Initial | Neutral | Final, to: Initial | Neutral | Final): void {
this.infection.replacer = undefined;
this.infection.from = from;
this.infection.to = to;
this.infection.infect();

this.content = this.infection.toString();
}

/**
* Convert specific value to Korean.
* @example Hangul.engToKor(new Hangul('dks')) // '안'
Expand Down
154 changes: 154 additions & 0 deletions src/entities/replacer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { Hangul } from "./hangul.ts"
import { Assembler } from "./assembler.ts"

import {
Initial,
Neutral,
Final
} from "./interactList.ts"

/**
* Provides static method replacing characters in disassembled korean
*/
export class Replacer {
/**
* Replace first character using replace function.
* @param input The string or Hangul class to replace
* @param replacer The replace function. The letter value will replace as return value.
*/
static infect<T extends Initial | Neutral | Final>(input: Hangul | string, replacer: (letter: T) => T): Hangul
/**
* Replace first character that match with `from` to `to`.
* @param input The string or Hangul class to replace
* @param from The korean character that you want to select.
* @param to The korean character to replace.
*/
static infect<T extends Initial | Neutral | Final>(input: Hangul | string, from: T, to: T): Hangul
/**
* Replace first character that included in `from` to `to`.
* @param input The string or Hangul class to replace
* @param from The korean character array that you want to select.
* @param to The korean character to replace.
*/
static infect<T extends Initial | Neutral | Final>(input: Hangul | string, from: T[], to: T): Hangul
static infect<T extends Initial | Neutral | Final>(input: Hangul | string, para1: any, para2?: T): Hangul {
const inf =
para1 instanceof Function
? new Infection(input, para1)
: new Infection(input, para1, para2);

inf.infect();
return new Hangul(inf.toString());
}

/**
* Replace all characters using replace function.
* @param input The string or Hangul class to replace
* @param replacer The replace function. The letter value will replace as return value.
*/
static replaceAll<T extends Initial | Neutral | Final>(input: Hangul | string, replacer: (letter: T) => T): Hangul
/**
* Replace all characters that match with `from` to `to`.
* @param input The string or Hangul class to replace
* @param from The korean character that you want to select.
* @param to The korean character to replace.
*/
static replaceAll<T extends Initial | Neutral | Final>(input: Hangul | string, from: T, to: T): Hangul
/**
* Replace all characters that included in `from` to `to`.
* @param input The string or Hangul class to replace
* @param from The korean character array that you want to select.
* @param to The korean character to replace.
*/
static replaceAll<T extends Initial | Neutral | Final>(input: Hangul | string, from: T[], to: T): Hangul
static replaceAll<T extends Initial | Neutral | Final>(input: Hangul | string, para1: any, para2?: T): Hangul {
const inf =
para1 instanceof Function
? new Infection(input, para1)
: new Infection(input, para1, para2);

for (;!inf.isInfector;) inf.infect();

return new Hangul(inf.toString());
}
}

/**
* Provides that sequentially replace function for single object.
*/
export class Infection<T extends Initial | Neutral | Final> {
/**
* Declare new `Infection` class with replace function.
* @param str Original string or Hangul class
* @param replacer The replace function. The letter value will replace as return value.
*/
constructor(str: Hangul | string, replacer: (letter: T) => T)
/**
* Declare new `Infection` class with `from` and `to`
* @param str Original string or Hangul class
* @param from The korean character that you want to select.
* @param to The korean character to replace.
*/
constructor(str: Hangul | string, from: T, to: T)
/**
* Declare new `Infection` class with `from` and `to`
* @param str Original string or Hangul class
* @param from The korean character array that you want to select.
* @param to The korean character to replace.
*/
constructor(str: Hangul | string, from: T[], to: T)
constructor(str: Hangul | string, para1: T | T[] | Function, para2?: T) {
this.word = str instanceof Hangul ? str.toString() : str;

if (para1 instanceof Function) {
this.replacer = para1 as (letter: T) => T;
} else {
this.from = para1;
this.to = para2 as T;
}
}

private word: string;

/** The replace function. The letter value will replace as return value. */
replacer?: (letter: T) => T;

/** The korean character or array that you want to select. */
from?: T | T[];
/** The korean character to replace. */
to?: T;

/** Whether all value that match with `from` replace to `to` */
isInfector: boolean = false;
/** The count of how many values have been replaced. */
infectCount: number = 0;

/** Replace first value that match with `from` to `to` */
infect(): void {
const w = Assembler.disassemble(this.word);

if (this.replacer !== undefined) {
for(let i = 0; i < w.length; i++) {
if (!/[ㄱ-ㅣ]/.test(w[i])) continue;
if (this.replacer(w[i] as T) !== w[i]) { w[i] = this.replacer(w[i] as T); break; }
}

if (w.map(l => this.replacer!(l as T)).every((v, ind) => v === w[ind])) this.isInfector = true;
} else {
for (let i = 0; i < w.length; i++) {
if (!/[ㄱ-ㅣ]/.test(w[i])) continue;
if ((this.from as T[]).includes(w[i] as T)) { w[i] = this.to!; break; }
}

if (w.every(v => !this.from!.includes(v as T))) this.isInfector = true;
}

this.infectCount++;
this.word = Assembler.assemble(w);
}

/** return current string. */
toString(): string {
return this.word;
}
}
28 changes: 28 additions & 0 deletions test/replacer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {
Hangul,
Replacer,
Infection
} from "../mod.ts"

const word = new Hangul('안녕하세요');

console.log("word:", word.toString());
console.log("replacerAll:", Replacer.replaceAll(word, k => {
if (k == 'ㅇ') return 'ㅁ';
return k;
}).toString());
console.log("replaceAll:", Replacer.replaceAll(word, 'ㅇ', 'ㅁ').toString());
console.log("replaceAll:", Replacer.replaceAll(word, ['ㅇ', 'ㄴ'], 'ㅁ').toString());
console.log("infect:", Replacer.infect(word, 'ㅇ', 'ㅁ').toString());

const inf = new Infection(word, 'ㅇ', 'ㅁ');

for (console.log(inf.toString(), inf.infectCount); !inf.isInfector; console.log(inf.toString(), inf.infectCount)) {
inf.infect();
}

console.log("infection:", inf);

word.infect('ㅇ', 'ㅁ');
word.infect('ㅇ', 'ㅁ');
console.log("word:", word);

0 comments on commit 5f03ca9

Please sign in to comment.