diff --git a/packages/kiri/lib/kiri/input_text/normalize.ex b/packages/kiri/lib/kiri/input_text/normalize.ex index 3ee85ec..cbf3f3d 100644 --- a/packages/kiri/lib/kiri/input_text/normalize.ex +++ b/packages/kiri/lib/kiri/input_text/normalize.ex @@ -47,10 +47,8 @@ defmodule Kiri.InputText.Normalize do @spec rewrite(InputText.t(), t()) :: InputText.t() def rewrite(builder, rules) do - text = InputText.get_text(builder) - chars = String.to_charlist(text) - text_len = length(chars) - do_rewrite(builder, rules, chars, 0, 0, text, text_len) + chars = builder |> InputText.get_text() |> String.to_charlist() + do_rewrite(builder, rules, chars, 0, 0, length(chars)) end # --- Parsing helpers --- @@ -82,13 +80,13 @@ defmodule Kiri.InputText.Normalize do end # --- Rewrite loop --- - # `text` is threaded through as a parameter and only recomputed after - # actual replacements, avoiding the O(n²) cost of rebuilding the string - # on every character iteration. + # Iteration is driven by the original charlist (`[cp | rest]`), not the + # modified text. `offset` tracks the cumulative length delta so that + # `InputText.replace` receives correct positions. - defp do_rewrite(builder, _rules, [], _i, _offset, _text, _text_len), do: builder + defp do_rewrite(builder, _rules, [], _i, _offset, _text_len), do: builder - defp do_rewrite(builder, rules, [cp | rest] = chars, i, offset, text, text_len) do + defp do_rewrite(builder, rules, [cp | rest] = chars, i, offset, text_len) do max_key_len = Map.get(rules.key_lengths, cp, 0) remaining = text_len - (i + offset) @@ -97,7 +95,6 @@ defmodule Kiri.InputText.Normalize do builder = InputText.replace(builder, i + offset, i + match_len + offset, replacement) rep_len = count_codepoints_fast(replacement) new_text_len = text_len + rep_len - match_len - text = InputText.get_text(builder) do_rewrite( builder, @@ -105,34 +102,31 @@ defmodule Kiri.InputText.Normalize do Enum.drop(rest, match_len - 1), i + match_len, offset + rep_len - match_len, - text, new_text_len ) :not_replaced -> - normalize_char(builder, rules, cp, rest, i, offset, text, text_len) + normalize_char(builder, rules, cp, rest, i, offset, text_len) end end - defp normalize_char(builder, rules, cp, rest, i, offset, text, text_len) do + defp normalize_char(builder, rules, cp, rest, i, offset, text_len) do nfkc = nfkc_replacement(cp, rules.ignore_normalize_set) case nfkc do nil -> - do_rewrite(builder, rules, rest, i + 1, offset, text, text_len) + do_rewrite(builder, rules, rest, i + 1, offset, text_len) <<^cp::utf8>> -> - do_rewrite(builder, rules, rest, i + 1, offset, text, text_len) + do_rewrite(builder, rules, rest, i + 1, offset, text_len) <<_single_cp::utf8>> -> builder = InputText.replace(builder, i + offset, i + 1 + offset, nfkc) - text = InputText.get_text(builder) - do_rewrite(builder, rules, rest, i + 1, offset, text, text_len) + do_rewrite(builder, rules, rest, i + 1, offset, text_len) _ -> rep_len = count_codepoints_fast(nfkc) builder = InputText.replace(builder, i + offset, i + 1 + offset, nfkc) - text = InputText.get_text(builder) do_rewrite( builder, @@ -140,7 +134,6 @@ defmodule Kiri.InputText.Normalize do rest, i + 1, offset + rep_len - 1, - text, text_len + rep_len - 1 ) end diff --git a/packages/kiri/lib/mix/tasks/kiri.convert.ex b/packages/kiri/lib/mix/tasks/kiri.convert.ex index b044f4e..32cba10 100644 --- a/packages/kiri/lib/mix/tasks/kiri.convert.ex +++ b/packages/kiri/lib/mix/tasks/kiri.convert.ex @@ -18,6 +18,8 @@ defmodule Mix.Tasks.Kiri.Convert do use Mix.Task + alias Kiri.Dictionary.Converter + @shortdoc "Convert a Sudachi .dic to .kiri format" @impl Mix.Task @@ -40,7 +42,7 @@ defmodule Mix.Tasks.Kiri.Convert do Mix.shell().info("Converting #{dic_path} -> #{output_dir}") - case Kiri.Dictionary.Converter.convert(dic_path, output_dir, convert_opts) do + case Converter.convert(dic_path, output_dir, convert_opts) do :ok -> Mix.shell().info("Done. Output written to #{output_dir}/")