Skip to content

Commit

Permalink
ルビ置換を簡素化
Browse files Browse the repository at this point in the history
  • Loading branch information
miyaji255 committed Apr 4, 2024
1 parent c82b434 commit acdfb43
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 42 deletions.
2 changes: 1 addition & 1 deletion Epub/KoeBook.Epub/Models/Paragraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ public sealed class Paragraph : Element
{
public ScriptLine? ScriptLine { get; set; }
public Audio? Audio => ScriptLine?.Audio;
public string? Text { get; set; }
public string Text { get; set; } = "";
}
49 changes: 10 additions & 39 deletions Epub/KoeBook.Epub/Services/AnalyzerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,31 +39,16 @@ public async ValueTask<BookScripts> AnalyzeAsync(BookProperties bookProperties,
}
_epubDocumentStoreService.Register(document, cancellationToken);

var scriptLines = new List<ScriptLine>();
foreach (var chapter in document.Chapters)
{
foreach (var section in chapter.Sections)
var scriptLines = document.Chapters.SelectMany(c => c.Sections)
.SelectMany(s => s.Elements)
.OfType<Paragraph>()
.Select(p =>
{
foreach (var element in section.Elements)
{
if (element is Paragraph paragraph)
{
var line = paragraph.Text;
// rubyタグがあればルビのdictionaryに登録
var rubyDict = ExtractRuby(line).ToDictionary();
// ルビを置換
var line = ReplaceBaseTextWithRuby(p.Text);

foreach (var ruby in rubyDict)
_rubyReplacements.TryAdd(ruby.Key, ruby.Value);
// ルビを置換
line = ReplaceBaseTextWithRuby(line, rubyDict);

var scriptLine = new ScriptLine(line, "", "");
paragraph.ScriptLine = scriptLine;
scriptLines.Add(scriptLine);
}
}
}
}
return p.ScriptLine = new ScriptLine(line, "", "");
}).ToList();

// 800文字以上になったら1チャンクに分ける
var chunks = new List<string>();
Expand All @@ -85,24 +70,10 @@ public async ValueTask<BookScripts> AnalyzeAsync(BookProperties bookProperties,
return bookScripts;
}

private static IEnumerable<KeyValuePair<string, string>> ExtractRuby(string text)
{
return RubyRegex()
.Matches(text)
.Select(m => KeyValuePair.Create(m.Groups[1].Value, m.Groups[2].Value));
}

private static string ReplaceBaseTextWithRuby(string text, Dictionary<string, string> rubyDict)
private static string ReplaceBaseTextWithRuby(string text)
{
// 元のテキストからルビタグをすべてルビテキストに置き換える
var resultText = text;
foreach (var pair in rubyDict)
{
var rubyTag = $"<ruby><rb>{pair.Key}</rb><rp>(</rp><rt>{pair.Value}</rt><rp>)</rp></ruby>";
resultText = resultText.Replace(rubyTag, pair.Value);
}

return resultText;
return RubyRegex().Replace(text, m => m.Groups[2].Value);
}

[GeneratedRegex("<ruby><rb>(.*?)</rb><rp>(</rp><rt>(.*?)</rt><rp>)</rp></ruby>")]
Expand Down
32 changes: 32 additions & 0 deletions KoeBook.Test/Epub/AnalyzerServiceTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Runtime.CompilerServices;
using KoeBook.Epub.Services;

namespace KoeBook.Test.Epub;

public class AnalyzerServiceTest
{
[Theory]
[InlineData("aa", "aa")]
[InlineData("<ruby><rb>漢字</rb><rp>(</rp><rt>かんじ</rt><rp>)</rp></ruby>", "かんじ")]
[InlineData("ああ<ruby><rb>漢字</rb><rp>(</rp><rt>かんじ</rt><rp>)</rp></ruby>あああ", "ああかんじあああ")]
[InlineData("""
ああ<ruby><rb>漢字</rb><rp>(</rp><rt>かんじ</rt><rp>)</rp></ruby>あああ
ああ<ruby><rb>漢字</rb><rp>(</rp><rt>かんじ</rt><rp>)</rp></ruby>あああ
ああ<ruby><rb>漢字1</rb><rp>(</rp><rt>かんじ1</rt><rp>)</rp></ruby>あああ
""", "ああかんじあああ\nああかんじあああ\nああかんじ1あああ")]
[InlineData("<ruby><rb>佐久平</rb><rp>《</rp><rt>さくだいら</rt><rp>》</rp></ruby> <ruby><rb>啓介</rb><rp>《</rp><rt>けいすけ</rt><rp>》</rp></ruby>",
"<ruby><rb>佐久平</rb><rp>《</rp><rt>さくだいら</rt><rp>》</rp></ruby> <ruby><rb>啓介</rb><rp>《</rp><rt>けいすけ</rt><rp>》</rp></ruby>")]
[InlineData("<ruby><rb>漢字</rb>\n<rp>(</rp><rt>かんじ</rt><rp>)</rp></ruby>", "<ruby><rb>漢字</rb>\n<rp>(</rp><rt>かんじ</rt><rp>)</rp></ruby>")]
public void ReplaceBaseTextWithRuby(string input, string expected)
{
var result = AnalyzerServiceProxy.ReplaceBaseTextWithRuby(null, input);

Assert.Equal(expected, result);
}
}

file static class AnalyzerServiceProxy
{
[UnsafeAccessor(UnsafeAccessorKind.StaticMethod)]
public static extern string ReplaceBaseTextWithRuby(AnalyzerService? _, string text);
}
4 changes: 2 additions & 2 deletions KoeBook.Test/Epub/EpubDocumentTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public void EnsureParagraph()
var element = Assert.Single(section.Elements);
var paragraph = Assert.IsType<Paragraph>(element);
Assert.Null(paragraph.Audio);
Assert.Null(paragraph.Text);
Assert.Empty(paragraph.Text);
Assert.Null(paragraph.ClassName);

// 空でないときは無視
Expand Down Expand Up @@ -129,7 +129,7 @@ public void EnsureParagraph()
element = Assert.Single(document.Chapters[0].Sections[1].Elements);
paragraph = Assert.IsType<Paragraph>(element);
Assert.Null(paragraph.Audio);
Assert.Null(paragraph.Text);
Assert.Empty(paragraph.Text);
Assert.Null(paragraph.ClassName);

// インデックスは正しく指定する必要がある
Expand Down

0 comments on commit acdfb43

Please sign in to comment.