From 348da5df31e6f04066ab2500450dd16477dff1cc Mon Sep 17 00:00:00 2001 From: niksedk Date: Tue, 13 Oct 2026 05:06:04 +0200 Subject: [PATCH] Add SE5 Fix encoding errors plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Repairs UTF-8 text that was read with the wrong code page (mojibake): résumé -> résumé, don’t -> don’t, also when lowercased afterwards (rã©sumã©). Western, Central European, Cyrillic, Greek, Turkish and Baltic code pages with auto-detect; checkable before/after preview. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/fix-encoding-errors.yml | 196 ++++++++++ README.md | 1 + .../EncodingFixerTests.cs | 140 +++++++ .../FixEncodingErrors.Tests.csproj | 27 ++ .../MainViewModelTests.cs | 101 +++++ se5/FixEncodingErrors/App.axaml | 8 + se5/FixEncodingErrors/App.axaml.cs | 12 + se5/FixEncodingErrors/ChangeItem.cs | 26 ++ se5/FixEncodingErrors/EncodingFixer.cs | 349 ++++++++++++++++++ .../FixEncodingErrors.csproj | 27 ++ se5/FixEncodingErrors/MainViewModel.cs | 253 +++++++++++++ se5/FixEncodingErrors/MainWindow.axaml | 323 ++++++++++++++++ se5/FixEncodingErrors/MainWindow.axaml.cs | 58 +++ se5/FixEncodingErrors/Program.cs | 16 + se5/FixEncodingErrors/README.md | 71 ++++ se5/FixEncodingErrors/SubtitleTextBlock.cs | 201 ++++++++++ se5/FixEncodingErrors/TextDiff.cs | 138 +++++++ se5/FixEncodingErrors/app.manifest | 10 + se5/FixEncodingErrors/docs/screenshot.png | Bin 0 -> 114208 bytes se5/FixEncodingErrors/plugin.json | 12 + 20 files changed, 1969 insertions(+) create mode 100644 .github/workflows/fix-encoding-errors.yml create mode 100644 se5/FixEncodingErrors.Tests/EncodingFixerTests.cs create mode 100644 se5/FixEncodingErrors.Tests/FixEncodingErrors.Tests.csproj create mode 100644 se5/FixEncodingErrors.Tests/MainViewModelTests.cs create mode 100644 se5/FixEncodingErrors/App.axaml create mode 100644 se5/FixEncodingErrors/App.axaml.cs create mode 100644 se5/FixEncodingErrors/ChangeItem.cs create mode 100644 se5/FixEncodingErrors/EncodingFixer.cs create mode 100644 se5/FixEncodingErrors/FixEncodingErrors.csproj create mode 100644 se5/FixEncodingErrors/MainViewModel.cs create mode 100644 se5/FixEncodingErrors/MainWindow.axaml create mode 100644 se5/FixEncodingErrors/MainWindow.axaml.cs create mode 100644 se5/FixEncodingErrors/Program.cs create mode 100644 se5/FixEncodingErrors/README.md create mode 100644 se5/FixEncodingErrors/SubtitleTextBlock.cs create mode 100644 se5/FixEncodingErrors/TextDiff.cs create mode 100644 se5/FixEncodingErrors/app.manifest create mode 100644 se5/FixEncodingErrors/docs/screenshot.png create mode 100644 se5/FixEncodingErrors/plugin.json diff --git a/.github/workflows/fix-encoding-errors.yml b/.github/workflows/fix-encoding-errors.yml new file mode 100644 index 00000000..214b057e --- /dev/null +++ b/.github/workflows/fix-encoding-errors.yml @@ -0,0 +1,196 @@ +name: Build FixEncodingErrors (SE5) + +on: + push: + branches: [main] + paths: + - 'se5/FixEncodingErrors/**' + - 'se5/FixEncodingErrors.Tests/**' + - 'se5/Plugin-Shared/**' + - '.github/workflows/fix-encoding-errors.yml' + pull_request: + paths: + - 'se5/FixEncodingErrors/**' + - 'se5/FixEncodingErrors.Tests/**' + - 'se5/Plugin-Shared/**' + - '.github/workflows/fix-encoding-errors.yml' + workflow_dispatch: + inputs: + release: + description: 'Publish a GitHub release. Bumps the minor in plugin.json and commits it back.' + type: boolean + default: false + version: + description: 'Optional explicit version (e.g. 1.2.0). Overrides the auto-minor-bump.' + required: false + type: string + +permissions: + contents: write + +jobs: + prepare: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.set.outputs.version }} + tag: ${{ steps.set.outputs.tag }} + ref: ${{ steps.set.outputs.ref }} + release: ${{ steps.set.outputs.release }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Resolve version (and bump on release) + id: set + run: | + set -e + current=$(jq -r .version se5/FixEncodingErrors/plugin.json) + release_flag="false" + ref="${{ github.sha }}" + version="$current" + tag="" + + if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.release }}" = "true" ]; then + release_flag="true" + if [ -n "${{ inputs.version }}" ]; then + version="${{ inputs.version }}" + else + IFS=. read -r major minor patch <<< "$current" + version="$major.$((minor + 1)).0" + fi + + tmp=$(mktemp) + jq --arg v "$version" '.version = $v' se5/FixEncodingErrors/plugin.json > "$tmp" + mv "$tmp" se5/FixEncodingErrors/plugin.json + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add se5/FixEncodingErrors/plugin.json + git commit -m "Bump FixEncodingErrors to $version [skip ci]" + + # Retry-with-rebase: if a concurrent release dispatched for a different + # plugin won the push first, pull --rebase and try again. + attempts=0 + while ! git push 2>/tmp/push.err; do + attempts=$((attempts + 1)) + if [ "$attempts" -ge 5 ]; then + echo "Failed to push after $attempts attempts:" >&2 + cat /tmp/push.err >&2 + exit 1 + fi + echo "Push rejected (attempt $attempts), pulling --rebase and retrying..." + git pull --rebase --no-edit + done + ref=$(git rev-parse HEAD) + + IFS=. read -r major minor patch <<< "$version" + tag="se5-fix-encoding-errors-v$major.$minor" + fi + + echo "version=$version" >> "$GITHUB_OUTPUT" + echo "tag=$tag" >> "$GITHUB_OUTPUT" + echo "ref=$ref" >> "$GITHUB_OUTPUT" + echo "release=$release_flag" >> "$GITHUB_OUTPUT" + + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup .NET 8 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0.x' + + - name: Test + run: dotnet test se5/FixEncodingErrors.Tests/FixEncodingErrors.Tests.csproj -c Release + + build: + needs: [prepare, test] + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - rid: win-x64 + os: windows + exe: FixEncodingErrors.exe + - rid: win-arm64 + os: windows + exe: FixEncodingErrors.exe + - rid: linux-x64 + os: linux + exe: FixEncodingErrors + - rid: linux-arm64 + os: linux + exe: FixEncodingErrors + - rid: osx-x64 + os: macos + exe: FixEncodingErrors + - rid: osx-arm64 + os: macos + exe: FixEncodingErrors + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ needs.prepare.outputs.ref }} + + - name: Setup .NET 8 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0.x' + + - name: Publish self-contained (${{ matrix.rid }}) + working-directory: se5/FixEncodingErrors + run: | + dotnet publish FixEncodingErrors.csproj \ + -c Release \ + -r ${{ matrix.rid }} \ + --self-contained true \ + -p:DebugType=None \ + -p:DebugSymbols=false \ + -o staging/FixEncodingErrors + + - name: Rewrite plugin.json for ${{ matrix.os }} + working-directory: se5/FixEncodingErrors + run: | + jq ' + del(.runtime, .entry) | + .executables = { "${{ matrix.os }}": "${{ matrix.exe }}" } + ' plugin.json > staging/FixEncodingErrors/plugin.json + + - name: Package zip + working-directory: se5/FixEncodingErrors/staging + run: zip -r "$GITHUB_WORKSPACE/FixEncodingErrors-${{ matrix.rid }}.zip" FixEncodingErrors + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: FixEncodingErrors-${{ matrix.rid }} + path: FixEncodingErrors-${{ matrix.rid }}.zip + + release: + name: Publish GitHub Release + needs: [prepare, build] + if: needs.prepare.outputs.release == 'true' + runs-on: ubuntu-latest + steps: + - name: Download all zips + uses: actions/download-artifact@v4 + with: + path: dist + pattern: FixEncodingErrors-* + merge-multiple: true + + - name: Create release and upload zips + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create "${{ needs.prepare.outputs.tag }}" dist/FixEncodingErrors-*.zip \ + --repo "${{ github.repository }}" \ + --target "${{ needs.prepare.outputs.ref }}" \ + --title "FixEncodingErrors v${{ needs.prepare.outputs.version }}" \ + --notes "Self-contained FixEncodingErrors plugin builds for win/linux/osx (x64 + arm64)." diff --git a/README.md b/README.md index 8e11d54b..e99b97d5 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ index [`se5-plugins.json`](se5-plugins.json). | [ARTE check](se5/ArteCheck) | Checks and fixes EBU STL teletext subtitles for ARTE delivery. | | [American to British](se5/AmericanToBritish) | Converts American English spellings to British English. | | [British to American](se5/BritishToAmerican) | Converts British English spellings to American English. | +| [Fix encoding errors](se5/FixEncodingErrors) | Repairs UTF-8 text read with the wrong code page: résumé → résumé, don’t → don’t. | | [Haxor](se5/Haxor) | Translates text to "haxor" - the minimal reference plugin. | | [Italic each line](se5/ItalicEachLine) | Switches italic tags between one tag per subtitle and a tag on each line. | | [Persian Subtitle Fixes](se5/PersianErrors) | Fixes common errors in Persian (Farsi) subtitles - 1,500+ rules in 12 groups. | diff --git a/se5/FixEncodingErrors.Tests/EncodingFixerTests.cs b/se5/FixEncodingErrors.Tests/EncodingFixerTests.cs new file mode 100644 index 00000000..9d482704 --- /dev/null +++ b/se5/FixEncodingErrors.Tests/EncodingFixerTests.cs @@ -0,0 +1,140 @@ +using SubtitleEdit.Plugins.FixEncodingErrors; +using System.Text; + +namespace FixEncodingErrors.Tests; + +public class EncodingFixerTests +{ + static EncodingFixerTests() => Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + + /// What a UTF-8 text looks like after being read with . + private static string Break(string text, int codePage = 1252) => + Encoding.GetEncoding(codePage).GetString(Encoding.UTF8.GetBytes(text)); + + [Theory] + [InlineData("résumé", "résumé")] + [InlineData("don’t", "don’t")] + [InlineData("“Quoteâ€\u009D", "“Quote”")] + [InlineData("“Quoteâ€", "“Quote”")] // 0x9D lost + [InlineData("25°C", "25°C")] + [InlineData("Hello", "Hello")] + [InlineData("Wait à bientôt", "Wait à bientôt")] // A0 turned into a space + [InlineData("😀 hi", "😀 hi")] + public void FixesWestern(string broken, string expected) + { + Assert.Equal(expected, EncodingFixer.Fix(broken, 1252, confirmed: true)); + } + + [Theory] + [InlineData("cache of such communiquã©s,", "cache of such communiqués,")] + [InlineData("and dust off my rã©sumã©.", "and dust off my résumé.")] + [InlineData("madame la secrã©taire.", "madame la secrétaire.")] + public void FixesTextLowercasedAfterItBroke(string broken, string expected) + { + // Ed's Madam Secretary subtitles: © alone tells the subtitle is broken. + Assert.Equal(expected, EncodingFixer.Fix(broken, 1252, confirmed: false)); + } + + [Theory] + [InlineData("Ça va? Où êtes-vous? À bientôt, Œdipe!")] + [InlineData("Größe, Übermaß, naïve, Señor, Ñandú, Ærø")] + [InlineData("“Smart quotes” – dashes — and… ellipsis ‘ok’ 😀")] + public void RoundTripsWestern(string text) + { + Assert.Equal(text, EncodingFixer.Fix(Break(text), 1252, confirmed: true)); + } + + [Theory] + [InlineData("Привет, как дела? Всё хорошо.", 1251)] + [InlineData("Příliš žluťoučký kůň úpěl ďábelské ódy.", 1250)] + [InlineData("Καλημέρα κόσμε", 1253)] + [InlineData("Günaydın, nasılsın? Şimdi değil.", 1254)] + public void RoundTripsOtherCodePages(string text, int codePage) + { + // Detection may pick a code page that reads the same bytes the same way (1252/1254 for Turkish). + var broken = Break(text, codePage); + var detected = EncodingFixer.Detect(new[] { broken }).CodePage; + Assert.Equal(text, EncodingFixer.Fix(broken, detected, confirmed: true)); + Assert.Equal(text, EncodingFixer.Fix(broken, codePage, confirmed: true)); + } + + [Fact] + public void DetectsCyrillic() + { + Assert.Equal(1251, EncodingFixer.Detect(new[] { Break("Привет, как дела?", 1251) }).CodePage); + } + + [Theory] + [InlineData("Привет, как дела?")] + [InlineData("Καλημέρα κόσμε")] + [InlineData("שלום עולם")] + [InlineData("مرحبا بالعالم")] + public void FixesOtherScriptsMisreadAsWestern(string text) + { + var broken = Break(text); + Assert.Equal(1252, EncodingFixer.Detect(new[] { broken }).CodePage); + Assert.Equal(text, EncodingFixer.Fix(broken, 1252, EncodingFixer.IsBroken(new[] { broken }, 1252))); + } + + [Fact] + public void FixesDoubleBroken() + { + Assert.Equal("café", EncodingFixer.Fix(Break(Break("café")), 1252, confirmed: true)); + } + + [Theory] + [InlineData("Não”")] + [InlineData("A minha irmã… e a mãe")] + [InlineData("«Não»")] + [InlineData("Irmã Lúcia")] + [InlineData("Ça coûte 25 €, café»")] + [InlineData("Plain ASCII text")] + public void LeavesRealTextAlone(string text) + { + Assert.Equal(0, EncodingFixer.CountTelling(new[] { text }, 1252)); + Assert.Equal(text, EncodingFixer.Fix(text, 1252, confirmed: false)); + } + + [Theory] + [InlineData("Привет, Сёма! В доме.")] + [InlineData("Příliš žluťoučký kůň")] + public void LeavesRealTextAloneInItsOwnCodePage(string text) + { + Assert.Equal(1252, EncodingFixer.Detect(new[] { text }).CodePage); + Assert.Equal(text, EncodingFixer.Fix(text, 1252, confirmed: false)); + } + + [Fact] + public void AmbiguousMatchNeedsConfirmation() + { + // "Ö" (Ö) at a word end could be real text; fixed once the subtitle is known to be broken. + Assert.Equal("BÖ", EncodingFixer.Fix("BÖ", 1252, confirmed: false)); + Assert.Equal("BÖ", EncodingFixer.Fix("BÖ", 1252, confirmed: true)); + Assert.True(EncodingFixer.IsBroken(new[] { "Österreich", "café" }, 1252)); + Assert.False(EncodingFixer.IsBroken(new[] { "Österreich" }, 1252)); + } + + [Fact] + public void DetectsWesternForEd() + { + var lines = new[] { "and dust off my rã©sumã©.", "I'll send you his rã©sumã©." }; + Assert.Equal(1252, EncodingFixer.Detect(lines).CodePage); + Assert.Equal(4, EncodingFixer.CountTelling(lines, 1252)); + } + + [Fact] + public void RealMacedonianIsNotBroken() + { + // ј, џ, ќ, ѓ are continuation bytes in Windows-1251: "ој" must not become Greek "μ", "рџ" not "п". + var lines = new[] { "Тој е мојот брат.", "Џорџ веќе учење, која боја." }; + Assert.False(EncodingFixer.IsBroken(lines, 1251)); + Assert.Equal(1252, EncodingFixer.Detect(lines).CodePage); + Assert.All(lines, l => Assert.Equal(l, EncodingFixer.Fix(l, 1251, confirmed: false))); + } + + [Fact] + public void KeepsTagsAndLineBreaks() + { + Assert.Equal("résumé\r\n{\\an8}café", EncodingFixer.Fix("résumé\r\n{\\an8}café", 1252, confirmed: false)); + } +} diff --git a/se5/FixEncodingErrors.Tests/FixEncodingErrors.Tests.csproj b/se5/FixEncodingErrors.Tests/FixEncodingErrors.Tests.csproj new file mode 100644 index 00000000..4bb38f49 --- /dev/null +++ b/se5/FixEncodingErrors.Tests/FixEncodingErrors.Tests.csproj @@ -0,0 +1,27 @@ + + + + net8.0 + enable + enable + false + + + + + + + + + + + + + + + + + + + + diff --git a/se5/FixEncodingErrors.Tests/MainViewModelTests.cs b/se5/FixEncodingErrors.Tests/MainViewModelTests.cs new file mode 100644 index 00000000..48ea9ec8 --- /dev/null +++ b/se5/FixEncodingErrors.Tests/MainViewModelTests.cs @@ -0,0 +1,101 @@ +using SubtitleEdit.Plugins.FixEncodingErrors; +using SubtitleEdit.Plugins.Shared; + +namespace FixEncodingErrors.Tests; + +public class MainViewModelTests +{ + private static PluginRequest Request(params string[] texts) => new() + { + Subtitle = new PluginSubtitle + { + Format = "Advanced Sub Station Alpha", + Paragraphs = texts.Select((t, i) => new PluginParagraph { StartMs = i * 1000, EndMs = i * 1000 + 900, Text = t, Style = "Top", Actor = "A" }).ToList(), + }, + }; + + [Fact] + public void ListsBrokenLines() + { + var vm = new MainViewModel(Request("and dust off my rã©sumã©.", "Plain", "don’t")); + + Assert.Equal(0, vm.SelectedEncoding.CodePage); + Assert.Equal(1252, vm.EffectiveEncoding.CodePage); + Assert.Equal(new[] { 0, 2 }, vm.Changes.Select(c => c.Index)); + Assert.Equal("and dust off my résumé.", vm.Changes[0].After); + } + + [Fact] + public void ConfirmedSubtitleFixesAmbiguousMatches() + { + // "BÖ" alone is left; with a clear "é" elsewhere in the subtitle it is fixed too. + Assert.Empty(new MainViewModel(Request("BÖ")).Changes); + Assert.Equal(2, new MainViewModel(Request("BÖ", "café")).Changes.Count); + } + + [Fact] + public void ResponseKeepsParagraphFieldsAndSkipsUnchecked() + { + var vm = new MainViewModel(Request("café", "résumé")); + vm.Changes[1].IsSelected = false; + + var response = vm.BuildResponse(); + + Assert.Equal(PluginStatus.Ok, response.Status); + var paragraphs = response.Subtitle!.Paragraphs!; + Assert.Equal("café", paragraphs[0].Text); + Assert.Equal("résumé", paragraphs[1].Text); + Assert.All(paragraphs, p => Assert.Equal("Top", p.Style)); + } + + [Fact] + public void SelectedLinesScope() + { + var request = Request("café", "résumé"); + request.SelectedIndices = new List { 1 }; + var vm = new MainViewModel(request); + + Assert.True(vm.SelectedLinesOnly); + Assert.Equal(1, Assert.Single(vm.Changes).Index); + + vm.AllLines = true; + Assert.Equal(2, vm.Changes.Count); + } + + [Fact] + public void PickedCodePageIsRemembered() + { + var vm = new MainViewModel(Request("café")); + vm.SelectedEncoding = vm.EncodingOptions.Single(e => e.CodePage == 1251); + Assert.Empty(vm.Changes); + + var cancel = vm.BuildCancelResponse(); + var request = Request("café"); + request.Settings = cancel.Settings; + request.SettingsVersion = cancel.SettingsVersion; + Assert.Equal(1251, new MainViewModel(request).SelectedEncoding.CodePage); + } + + [Fact] + public void NothingSelectedCancels() + { + var vm = new MainViewModel(Request("café")); + vm.SelectNoneCommand.Execute(null); + + Assert.Equal(PluginStatus.Cancelled, vm.BuildResponse().Status); + } + + [Fact] + public void LegacyRequestUsesSubRip() + { + var vm = new MainViewModel(new PluginRequest + { + Subtitle = new PluginSubtitle { SubRip = "1\n00:00:01,000 --> 00:00:02,000\nrésumé\n" }, + }); + + var response = vm.BuildResponse(); + + Assert.Equal("SubRip", response.Subtitle!.Format); + Assert.Contains("résumé", response.Subtitle.Native); + } +} diff --git a/se5/FixEncodingErrors/App.axaml b/se5/FixEncodingErrors/App.axaml new file mode 100644 index 00000000..8e90aac7 --- /dev/null +++ b/se5/FixEncodingErrors/App.axaml @@ -0,0 +1,8 @@ + + + + + diff --git a/se5/FixEncodingErrors/App.axaml.cs b/se5/FixEncodingErrors/App.axaml.cs new file mode 100644 index 00000000..259a12a6 --- /dev/null +++ b/se5/FixEncodingErrors/App.axaml.cs @@ -0,0 +1,12 @@ +using Avalonia.Controls; +using Avalonia.Markup.Xaml; +using SubtitleEdit.Plugins.Shared; + +namespace SubtitleEdit.Plugins.FixEncodingErrors; + +public partial class App : PluginApp +{ + public override void Initialize() => AvaloniaXamlLoader.Load(this); + + protected override Window CreateMainWindow(PluginRequest request) => new MainWindow(request); +} diff --git a/se5/FixEncodingErrors/ChangeItem.cs b/se5/FixEncodingErrors/ChangeItem.cs new file mode 100644 index 00000000..24421fe1 --- /dev/null +++ b/se5/FixEncodingErrors/ChangeItem.cs @@ -0,0 +1,26 @@ +using CommunityToolkit.Mvvm.ComponentModel; + +namespace SubtitleEdit.Plugins.FixEncodingErrors; + +/// One subtitle line with broken characters. +public sealed partial class ChangeItem : ObservableObject +{ + [ObservableProperty] private bool _isSelected = true; + + public ChangeItem(int index, string before, string after, string timeRange) + { + Index = index; + Before = before; + After = after; + TimeRange = timeRange; + (BeforeSegments, AfterSegments) = TextDiff.Compute(before.Replace("\r\n", "\n"), after.Replace("\r\n", "\n")); + } + + public int Index { get; } + public string Before { get; } + public string After { get; } + public string Number => "#" + (Index + 1); + public string TimeRange { get; } + public IReadOnlyList BeforeSegments { get; } + public IReadOnlyList AfterSegments { get; } +} diff --git a/se5/FixEncodingErrors/EncodingFixer.cs b/se5/FixEncodingErrors/EncodingFixer.cs new file mode 100644 index 00000000..0b162835 --- /dev/null +++ b/se5/FixEncodingErrors/EncodingFixer.cs @@ -0,0 +1,349 @@ +using System.Text; + +namespace SubtitleEdit.Plugins.FixEncodingErrors; + +/// A single-byte code page that UTF-8 text may have been misread with. +public sealed record SourceEncoding(int CodePage, string Name) +{ + public override string ToString() => Name; +} + +/// +/// Repairs UTF-8 text that was decoded with a single-byte code page and saved again ("mojibake"): +/// résumé → résumé, don’t → don’t. Each character is mapped back to its byte +/// in the code page and runs of bytes that form valid UTF-8 are decoded. Also handles text that was lowercased +/// after it broke (rã©sumã©), a lost 0x9D byte (†→ ”) and a byte order mark +/// read as text (). +/// +public static class EncodingFixer +{ + public static readonly IReadOnlyList Encodings = new[] + { + new SourceEncoding(1252, "Western (Windows-1252)"), + new SourceEncoding(1250, "Central European (Windows-1250)"), + new SourceEncoding(1251, "Cyrillic (Windows-1251)"), + new SourceEncoding(1253, "Greek (Windows-1253)"), + new SourceEncoding(1254, "Turkish (Windows-1254)"), + new SourceEncoding(1257, "Baltic (Windows-1257)"), + }; + + private const int MaxPasses = 3; + + // Punctuation that also follows a real accented letter at the end of a word ("Não”", "irmã…"): + // a two-character match ending in one of these is only fixed when there is other evidence. + private const string AmbiguousFollowers = "…‘’“”–—«»‹›„‚•· "; + + // Letters (to char.IsLetter) that are still telling as the second character: ú, õ, ö in Western. + private const string TellingLetters = "ªµº"; + + // Share of the code page's non-ASCII characters that must be part of matches before a subtitle counts as + // broken. Broken text is nearly all matches; real Macedonian has a few look-alikes (ој, ње) among normal letters. + private const double MinCoverage = 0.3; + + /// + /// What a two-byte character decoded from a code page may be: its own script plus Latin-1 symbols + /// (°, «, », ...), and the lead bytes a lowercased letter is tried as. + /// + private sealed record Script((int From, int To)[] TwoByteRanges, byte[] LowercasedLeads); + + private static readonly Script Latin = new(new[] { (0xA0, 0x24F) }, new byte[] { 0xC3, 0xC4, 0xC5 }); + + // Western PCs misread everything, so Windows-1252 also decodes to Greek, Cyrillic, Hebrew and Arabic. + private static readonly Script Western = new(new[] { (0xA0, 0x24F), (0x370, 0x52F), (0x590, 0x6FF) }, new byte[] { 0xC3, 0xC4, 0xC5 }); + private static readonly Script Cyrillic = new(new[] { (0xA0, 0xBF), (0x400, 0x52F) }, new byte[] { 0xD0, 0xD1 }); + private static readonly Script Greek = new(new[] { (0xA0, 0xBF), (0x370, 0x3FF) }, new byte[] { 0xCE, 0xCF }); + + private static Script ScriptOf(int codePage) => codePage switch + { + 1252 => Western, + 1251 => Cyrillic, + 1253 => Greek, + _ => Latin, + }; + + private static readonly Dictionary> Maps = new(); + private static readonly object MapsLock = new(); + + static EncodingFixer() => Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + + /// + /// The code page with the most unambiguous matches among those the texts look broken for, or Windows-1252. + /// + public static SourceEncoding Detect(IEnumerable texts) + { + var list = texts as IReadOnlyCollection ?? texts.ToList(); + var best = Encodings[0]; + var bestCount = 0; + foreach (var encoding in Encodings) + { + var analysis = Analyze(list, encoding.CodePage); + if (analysis.IsBroken && analysis.Telling > bestCount) + { + best = encoding; + bestCount = analysis.Telling; + } + } + + return best; + } + + /// + /// Whether the texts look broken for the code page: unambiguous matches (like é or ’), and + /// matches make up a good share of the non-ASCII characters. Then ambiguous matches are fixed too. + /// + public static bool IsBroken(IEnumerable texts, int codePage) => Analyze(texts, codePage).IsBroken; + + /// Number of unambiguous matches in the texts. + public static int CountTelling(IEnumerable texts, int codePage) => Analyze(texts, codePage).Telling; + + private readonly record struct Analysis(int Telling, int MatchedChars, int NonAsciiChars) + { + public bool IsBroken => Telling > 0 && MatchedChars >= NonAsciiChars * MinCoverage; + } + + private static Analysis Analyze(IEnumerable texts, int codePage) + { + var map = GetMap(codePage); + var script = ScriptOf(codePage); + int telling = 0, matched = 0, nonAscii = 0; + foreach (var text in texts) + { + if (string.IsNullOrEmpty(text)) + { + continue; + } + + for (var i = 0; i < text.Length; i++) + { + if (text[i] >= 0x80 && map.ContainsKey(text[i])) + { + nonAscii++; + } + + if (TryMatch(text, i, map, script, out var match)) + { + telling += match.Telling ? 1 : 0; + matched += match.Length; + for (var k = 1; k < match.Length; k++) + { + nonAscii += text[i + k] >= 0x80 && map.ContainsKey(text[i + k]) ? 1 : 0; + } + + i += match.Length - 1; + } + } + } + + return new Analysis(telling, matched, nonAscii); + } + + /// + /// Fixes one text. With (the subtitle ) ambiguous matches are + /// fixed as well; without, only the unambiguous ones. + /// Repeats for text that was broken more than once. + /// + public static string Fix(string text, int codePage, bool confirmed) + { + if (string.IsNullOrEmpty(text)) + { + return text; + } + + var map = GetMap(codePage); + var script = ScriptOf(codePage); + for (var pass = 0; pass < MaxPasses; pass++) + { + // Text broken twice is broken once after the first pass; go again only when that is clear, + // so correct text ("Всё") is never decoded a second time. + if (pass > 0 && CountTelling(new[] { text }, codePage) == 0) + { + break; + } + + var fixedText = FixOnce(text, map, script, confirmed); + if (fixedText == text) + { + break; + } + + text = fixedText; + } + + return text; + } + + private static string FixOnce(string text, Dictionary map, Script script, bool confirmed) + { + StringBuilder? sb = null; + var copied = 0; + for (var i = 0; i < text.Length; i++) + { + if (!TryMatch(text, i, map, script, out var match)) + { + continue; + } + + if (!match.Telling && !confirmed) + { + continue; + } + + sb ??= new StringBuilder(text.Length); + sb.Append(text, copied, i - copied).Append(match.Replacement); + i += match.Length - 1; + copied = i + 1; + } + + if (sb == null) + { + return text; + } + + sb.Append(text, copied, text.Length - copied); + return sb.ToString(); + } + + private readonly record struct Match(int Length, string Replacement, bool Telling); + + private static bool TryMatch(string text, int i, Dictionary map, Script script, out Match match) + { + match = default; + var c = text[i]; + if (c < 0x80 || !map.TryGetValue(c, out var lead)) + { + return false; + } + + if (lead >= 0xC2 && lead <= 0xF4 && TryDecode(text, i, lead, map, script, lowercased: false, out match)) + { + return true; + } + + // Lowercased after it broke: "é" → "ã©". Only the leads of the code page's letters are tried, and the + // result must be a letter. + var upper = char.ToUpperInvariant(c); + if (upper != c && map.TryGetValue(upper, out var upperLead) && Array.IndexOf(script.LowercasedLeads, upperLead) >= 0 && + TryDecode(text, i, upperLead, map, script, lowercased: true, out match) && char.IsLetter(match.Replacement, 0)) + { + return true; + } + + // "â€" with the third byte (0x9D, undefined in Windows-1252) lost: the closing quote ”. + if (lead == 0xE2 && i + 1 < text.Length && map.TryGetValue(text[i + 1], out var second) && second == 0x80 && + (i + 2 >= text.Length || !map.TryGetValue(text[i + 2], out var third) || third < 0x80 || third > 0xBF)) + { + match = new Match(2, "”", true); + return true; + } + + // "à " / " " where the second byte (A0, a no-break space) became a normal space: "à", " ". + if (c is 'Â' or 'Ã' && lead is 0xC2 or 0xC3 && i + 1 < text.Length && text[i + 1] == ' ') + { + match = new Match(2, c == 'Â' ? " " : "à", false); + return true; + } + + return false; + } + + private static bool TryDecode(string text, int i, byte lead, Dictionary map, Script script, bool lowercased, out Match match) + { + match = default; + var continuationCount = lead >= 0xF0 ? 3 : lead >= 0xE0 ? 2 : 1; + if (i + continuationCount >= text.Length) + { + return false; + } + + var codePoint = lead & (0x3F >> continuationCount); + for (var k = 1; k <= continuationCount; k++) + { + if (!map.TryGetValue(text[i + k], out var b) || b < 0x80 || b > 0xBF) + { + return false; + } + + codePoint = (codePoint << 6) | (b & 0x3F); + } + + string replacement; + switch (continuationCount) + { + case 1: + if (!script.TwoByteRanges.Any(r => codePoint >= r.From && codePoint <= r.To)) + { + return false; // C1 controls, or another script: real "ој" is not Greek "μ" + } + + replacement = ((char)codePoint).ToString(); + break; + case 2: + if (codePoint == 0xFEFF) + { + replacement = string.Empty; // byte order mark + } + else if (codePoint < 0x800 || codePoint >= 0x2E80 || codePoint is >= 0xD800 and <= 0xDFFF) + { + // Not valid, or CJK and beyond: a real "é…" is far likelier than a lone CJK character. + return false; + } + else + { + replacement = ((char)codePoint).ToString(); + } + + break; + default: + if (codePoint is < 0x1F000 or > 0x1FAFF) + { + return false; // only emoji + } + + replacement = char.ConvertFromUtf32(codePoint); + break; + } + + if (lowercased) + { + replacement = replacement.ToLowerInvariant(); + } + + var follower = text[i + 1]; + var telling = continuationCount > 1 || + (!char.IsLetter(follower) || TellingLetters.Contains(follower)) && + !AmbiguousFollowers.Contains(follower) && !char.IsWhiteSpace(follower); + match = new Match(continuationCount + 1, replacement, telling); + return true; + } + + private static Dictionary GetMap(int codePage) + { + lock (MapsLock) + { + if (Maps.TryGetValue(codePage, out var cached)) + { + return cached; + } + + var encoding = Encoding.GetEncoding(codePage, EncoderFallback.ExceptionFallback, DecoderFallback.ReplacementFallback); + var map = new Dictionary(); + for (var b = 0x80; b <= 0xFF; b++) + { + var decoded = encoding.GetString(new[] { (byte)b }); + if (decoded.Length == 1 && decoded[0] != '�') + { + map.TryAdd(decoded[0], (byte)b); + } + } + + // Bytes the code page leaves undefined are often decoded as Latin-1 C1 controls (Windows-1252 0x9D "”"). + for (var b = 0x80; b <= 0x9F; b++) + { + map.TryAdd((char)b, (byte)b); + } + + Maps[codePage] = map; + return map; + } + } +} diff --git a/se5/FixEncodingErrors/FixEncodingErrors.csproj b/se5/FixEncodingErrors/FixEncodingErrors.csproj new file mode 100644 index 00000000..c5de7eb0 --- /dev/null +++ b/se5/FixEncodingErrors/FixEncodingErrors.csproj @@ -0,0 +1,27 @@ + + + + WinExe + net8.0 + enable + enable + FixEncodingErrors + SubtitleEdit.Plugins.FixEncodingErrors + true + app.manifest + + + + + + + + + + + + + + + + diff --git a/se5/FixEncodingErrors/MainViewModel.cs b/se5/FixEncodingErrors/MainViewModel.cs new file mode 100644 index 00000000..f8232a4b --- /dev/null +++ b/se5/FixEncodingErrors/MainViewModel.cs @@ -0,0 +1,253 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using SubtitleEdit.Plugins.Shared; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Text.Json; + +namespace SubtitleEdit.Plugins.FixEncodingErrors; + +public sealed partial class MainViewModel : ObservableObject +{ + private const int SettingsVersion = 1; + + private readonly PluginRequest _request; + private readonly bool _legacyRequest; + private readonly List _paragraphs; + private readonly long _videoOffsetMs; + private readonly SourceEncoding _detected; + private bool _loading; + + [ObservableProperty] private SourceEncoding _selectedEncoding; + [ObservableProperty] private bool _selectedLinesOnly; + [ObservableProperty] private int _selectedCount; + + public MainViewModel(PluginRequest request) + { + _request = request; + _videoOffsetMs = request.Rules?.VideoOffsetMs ?? 0; + _legacyRequest = request.Subtitle.Paragraphs == null; + _paragraphs = _legacyRequest + ? SubRipParser.Parse(request.Subtitle.SubRip) + .Select(b => new PluginParagraph { StartMs = b.StartMs, EndMs = b.EndMs, Text = b.Text }).ToList() + : request.Subtitle.Paragraphs!.Select(p => p.Clone()).ToList(); + SelectedIndices = request.SelectedIndices.Where(i => i >= 0 && i < _paragraphs.Count).Distinct().Order().ToList(); + + var detected = EncodingFixer.Detect(_paragraphs.Select(p => p.Text ?? string.Empty)); + AutoEncoding = new SourceEncoding(0, "Auto-detect - " + detected.Name); + _detected = detected; + EncodingOptions = new[] { AutoEncoding }.Concat(EncodingFixer.Encodings).ToList(); + _selectedEncoding = AutoEncoding; + + _loading = true; + LoadSettings(); + _loading = false; + Analyze(); + } + + public ObservableCollection Changes { get; } = new(); + public IReadOnlyList EncodingOptions { get; } + public SourceEncoding AutoEncoding { get; } + + /// The code page used: the detected one when Auto is picked. + public SourceEncoding EffectiveEncoding => SelectedEncoding.CodePage == 0 ? _detected : SelectedEncoding; + public IReadOnlyList SelectedIndices { get; } + + public string SubtitleInfo + { + get + { + var name = string.IsNullOrEmpty(_request.Subtitle.FileName) ? "Untitled" : Path.GetFileName(_request.Subtitle.FileName); + var format = string.IsNullOrEmpty(_request.Subtitle.Format) ? string.Empty : $" · {_request.Subtitle.Format}"; + return $"{name}{format} · {_paragraphs.Count:N0} lines"; + } + } + + public bool HasSelectedLines => SelectedIndices.Count > 0; + public string SelectedLinesText => SelectedIndices.Count == 1 ? "Selected line (1)" : $"Selected lines ({SelectedIndices.Count:N0})"; + public bool AllLines { get => !SelectedLinesOnly; set => SelectedLinesOnly = !value; } + public int ChangeCount => Changes.Count; + public bool HasChanges => Changes.Count > 0; + public bool IsClean => Changes.Count == 0; + public bool CanApply => SelectedCount > 0; + public string CleanText => $"No broken characters found for {EffectiveEncoding.Name}."; + + public string StatusText => Changes.Count == 0 + ? $"{LinesInScope:N0} lines checked" + : $"{SelectedCount:N0} of {Changes.Count:N0} lines selected"; + + private int LinesInScope => SelectedLinesOnly && HasSelectedLines ? SelectedIndices.Count : _paragraphs.Count; + + partial void OnSelectedEncodingChanged(SourceEncoding value) + { + OnPropertyChanged(nameof(EffectiveEncoding)); + OnPropertyChanged(nameof(CleanText)); + Analyze(); + } + + partial void OnSelectedLinesOnlyChanged(bool value) + { + OnPropertyChanged(nameof(AllLines)); + Analyze(); + } + + + partial void OnSelectedCountChanged(int value) + { + OnPropertyChanged(nameof(CanApply)); + OnPropertyChanged(nameof(StatusText)); + } + + private IEnumerable IndicesInScope => + SelectedLinesOnly && HasSelectedLines ? SelectedIndices : Enumerable.Range(0, _paragraphs.Count); + + private void Analyze() + { + if (_loading) + { + return; + } + + // The whole subtitle (not only the lines in scope) decides whether it is broken. + var codePage = EffectiveEncoding.CodePage; + var confirmed = EncodingFixer.IsBroken(_paragraphs.Select(p => p.Text ?? string.Empty), codePage); + Changes.Clear(); + foreach (var index in IndicesInScope) + { + var text = _paragraphs[index].Text ?? string.Empty; + var after = EncodingFixer.Fix(text, codePage, confirmed); + if (after != text) + { + var item = new ChangeItem(index, text, after, FormatTimeRange(_paragraphs[index])); + item.PropertyChanged += (_, e) => + { + if (e.PropertyName == nameof(ChangeItem.IsSelected)) + { + SelectedCount = Changes.Count(c => c.IsSelected); + } + }; + Changes.Add(item); + } + } + + SelectedCount = Changes.Count; + OnPropertyChanged(nameof(ChangeCount)); + OnPropertyChanged(nameof(HasChanges)); + OnPropertyChanged(nameof(IsClean)); + OnPropertyChanged(nameof(StatusText)); + } + + [RelayCommand] + private void SelectAll() => SetSelection(_ => true); + + [RelayCommand] + private void SelectNone() => SetSelection(_ => false); + + [RelayCommand] + private void InvertSelection() => SetSelection(c => !c.IsSelected); + + private void SetSelection(Func selected) + { + foreach (var change in Changes) + { + change.IsSelected = selected(change); + } + } + + /// The response for OK: the selected lines, fixed. + public PluginResponse BuildResponse() + { + var selected = Changes.Where(c => c.IsSelected).ToList(); + if (selected.Count == 0) + { + return BuildCancelResponse(); + } + + var texts = _paragraphs.Select(p => p.Text ?? string.Empty).ToArray(); + foreach (var change in selected) + { + texts[change.Index] = change.After; + } + + PluginSubtitle subtitle; + if (_legacyRequest) + { + subtitle = new PluginSubtitle + { + Format = "SubRip", + Native = SubRipParser.Serialize(_paragraphs.Select((p, i) => new SrtBlock + { + StartMs = (long)Math.Round(p.StartMs), + EndMs = (long)Math.Round(p.EndMs), + Text = texts[i], + }).ToList()), + }; + } + else + { + subtitle = new PluginSubtitle + { + Format = _request.Subtitle.Format, + Paragraphs = _paragraphs.Select((p, i) => + { + var copy = p.Clone(); + copy.Text = texts[i]; + return copy; + }).ToList(), + }; + } + + return new PluginResponse + { + Status = PluginStatus.Ok, + Message = selected.Count == 1 ? "Fix encoding errors: 1 line fixed." : $"Fix encoding errors: {selected.Count:N0} lines fixed.", + UndoDescription = "Fix encoding errors", + Subtitle = subtitle, + Settings = BuildSettings(), + SettingsVersion = SettingsVersion, + }; + } + + public PluginResponse BuildCancelResponse() => + new() { Status = PluginStatus.Cancelled, Settings = BuildSettings(), SettingsVersion = SettingsVersion }; + + private JsonElement BuildSettings() + { + var payload = new Dictionary + { + ["codePage"] = SelectedEncoding.CodePage, + ["selectedLinesOnly"] = SelectedLinesOnly, + }; + return JsonSerializer.SerializeToElement(payload); + } + + private void LoadSettings() + { + // Lines selected in Subtitle Edit mean "work on these" - default to them. + SelectedLinesOnly = HasSelectedLines; + if (_request.SettingsVersion != SettingsVersion || _request.Settings is not { ValueKind: JsonValueKind.Object } settings) + { + return; + } + + if (settings.TryGetProperty("codePage", out var codePage) && codePage.TryGetInt32(out var value) && + EncodingOptions.FirstOrDefault(e => e.CodePage == value) is { } encoding) + { + SelectedEncoding = encoding; + } + + if (settings.TryGetProperty("selectedLinesOnly", out var selectedOnly) && selectedOnly.ValueKind is JsonValueKind.True or JsonValueKind.False) + { + SelectedLinesOnly = selectedOnly.GetBoolean() && HasSelectedLines; + } + } + + private string FormatTimeRange(PluginParagraph p) => + $"{FormatTime(p.StartMs + _videoOffsetMs)} → {FormatTime(p.EndMs + _videoOffsetMs)}"; + + private static string FormatTime(double ms) + { + var time = TimeSpan.FromMilliseconds(Math.Max(0, ms)); + return string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}:{2:00},{3:000}", (int)time.TotalHours, time.Minutes, time.Seconds, time.Milliseconds); + } +} diff --git a/se5/FixEncodingErrors/MainWindow.axaml b/se5/FixEncodingErrors/MainWindow.axaml new file mode 100644 index 00000000..acbf304b --- /dev/null +++ b/se5/FixEncodingErrors/MainWindow.axaml @@ -0,0 +1,323 @@ + + + + + + + + + + + + + + + + + + + + Cascadia Mono, Consolas, Menlo, DejaVu Sans Mono, monospace + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/se5/FixEncodingErrors/MainWindow.axaml.cs b/se5/FixEncodingErrors/MainWindow.axaml.cs new file mode 100644 index 00000000..6453982f --- /dev/null +++ b/se5/FixEncodingErrors/MainWindow.axaml.cs @@ -0,0 +1,58 @@ +using Avalonia.Controls; +using Avalonia.Input; +using Avalonia.Interactivity; +using Avalonia.Markup.Xaml; +using SubtitleEdit.Plugins.Shared; + +namespace SubtitleEdit.Plugins.FixEncodingErrors; + +public partial class MainWindow : Window +{ + private readonly MainViewModel _vm; + + public MainWindow() : this(new PluginRequest()) { } + + public MainWindow(PluginRequest request) + { + AvaloniaXamlLoader.Load(this); + _vm = new MainViewModel(request); + DataContext = _vm; + App.Response = _vm.BuildCancelResponse(); + KeyDown += OnKeyDown; + } + + protected override void OnOpened(EventArgs e) + { + base.OnOpened(e); + this.BringToForeground(); + } + + private void OnKeyDown(object? sender, KeyEventArgs e) + { + if (e.Key == Key.Escape) + { + e.Handled = true; + OnCancel(sender, e); + } + } + + private void OnCancel(object? sender, RoutedEventArgs e) + { + App.Response = _vm.BuildCancelResponse(); + Close(); + } + + private void OnOk(object? sender, RoutedEventArgs e) + { + try + { + App.Response = _vm.BuildResponse(); + } + catch (Exception exception) + { + App.Response = new PluginResponse { Status = PluginStatus.Error, Message = "Fix encoding errors failed: " + exception.Message }; + } + + Close(); + } +} diff --git a/se5/FixEncodingErrors/Program.cs b/se5/FixEncodingErrors/Program.cs new file mode 100644 index 00000000..e7c28d11 --- /dev/null +++ b/se5/FixEncodingErrors/Program.cs @@ -0,0 +1,16 @@ +using Projektanker.Icons.Avalonia; +using Projektanker.Icons.Avalonia.MaterialDesign; +using SubtitleEdit.Plugins.Shared; +using System; + +namespace SubtitleEdit.Plugins.FixEncodingErrors; + +public static class Program +{ + [STAThread] + public static int Main(string[] args) + { + IconProvider.Current.Register(); + return PluginBootstrap.Run(args); + } +} diff --git a/se5/FixEncodingErrors/README.md b/se5/FixEncodingErrors/README.md new file mode 100644 index 00000000..ae7a7896 --- /dev/null +++ b/se5/FixEncodingErrors/README.md @@ -0,0 +1,71 @@ +# Fix encoding errors (Subtitle Edit 5 plugin) + +Repairs UTF-8 text that was read with the wrong code page and saved again +("mojibake"): + +| Broken | Fixed | +|---|---| +| `résumé`, `communiqués` | `résumé`, `communiqués` | +| `don’t`, `“Hiâ€` | `don’t`, `“Hi”` | +| `25°`, `😀` | `25°`, `😀` | +| `rã©sumã©` (lowercased after it broke) | `résumé` | +| `Привет` (Western) / `Привет` (Cyrillic) | `Привет` | + +Often seen in subtitles extracted from MKV/MP4 files: Matroska text tracks are +UTF-8, so a track muxed from an SRT that was misread somewhere along the way +keeps the broken characters, and Subtitle Edit shows exactly what is stored. + +![Fix encoding errors](docs/screenshot.png) + +Built on Avalonia and the shared [`Plugin-Shared`](../Plugin-Shared/) library. + +## How it works + +Each character is mapped back to its byte in the code page the text was misread +with, and runs of bytes that form valid UTF-8 are decoded. Code pages: +Western (1252), Central European (1250), Cyrillic (1251), Greek (1253), +Turkish (1254) and Baltic (1257). *Auto-detect* picks the one with the most +clear matches. + +Also handled: + +- Text lowercased after it broke - `é` became `ã©`, so the lead byte is + tried as its uppercase letter. +- A lost `0x9D` byte (undefined in Windows-1252): `â€` → `”`. +- A no-break space turned into a normal space: `à ` → `à`. +- A byte order mark read as text: `` is removed. +- Text broken twice (`é`) is fixed in more passes. + +### Avoiding false fixes + +- A two-character match must decode to a script the text could be in: Latin, + plus Greek, Cyrillic, Hebrew and Arabic for Western (a Western PC misreads + everything); Cyrillic for 1251 and Greek for 1253. So real Macedonian `ој` + never turns into Greek `μ`. +- Matches ending in punctuation that can follow a real accented letter + (`Não”`, `irmã…`, `«Não»`) are *ambiguous*. They are fixed only when the + subtitle is clearly broken: it has unambiguous matches like `é` or `’`, and + matches make up at least 30% of its non-ASCII characters. +- Three-byte matches that would decode to CJK are skipped; four-byte matches + must be emoji. + +Checked against all Subtitle Edit UI translations and word lists (about 360,000 +lines in 35 languages): with *Auto-detect*, the only change was a line that +really is broken. + +## UI + +- *Text was misread as* - Auto-detect or a fixed code page; remembered. +- *All lines* / *Selected lines* - lines selected in Subtitle Edit are the + default scope. +- Every changed line is a checkable before/after card with the changed + characters highlighted. *OK* applies the checked lines as one + "Fix encoding errors" undo step. + +Works on the lines exactly as Subtitle Edit holds them, so styles, actors and +other fields of formats like ASSA are kept (falls back to SubRip on older SE +versions). + +## Build + +See `.github/workflows/fix-encoding-errors.yml`. diff --git a/se5/FixEncodingErrors/SubtitleTextBlock.cs b/se5/FixEncodingErrors/SubtitleTextBlock.cs new file mode 100644 index 00000000..b9dd6df7 --- /dev/null +++ b/se5/FixEncodingErrors/SubtitleTextBlock.cs @@ -0,0 +1,201 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Documents; +using Avalonia.Media; +using System.Text; + +namespace SubtitleEdit.Plugins.FixEncodingErrors; + +/// +/// Shows one side of a . With off the raw text is shown with +/// tags colored and changed text tinted; with it on the tags are hidden and italic text is drawn in italics. +/// +public sealed class SubtitleTextBlock : TextBlock +{ + public static readonly StyledProperty?> SegmentsProperty = + AvaloniaProperty.Register?>(nameof(Segments)); + + public static readonly StyledProperty RenderedProperty = + AvaloniaProperty.Register(nameof(Rendered)); + + private static readonly IBrush RemovedBrush = new SolidColorBrush(Color.Parse("#55E5484D")); + private static readonly IBrush AddedBrush = new SolidColorBrush(Color.Parse("#552FA36B")); + private static readonly IBrush TagBrush = new SolidColorBrush(Color.Parse("#EA580C")); + private static readonly IBrush ItalicBrush = new SolidColorBrush(Color.Parse("#22EA580C")); + + static SubtitleTextBlock() + { + SegmentsProperty.Changed.AddClassHandler((block, _) => block.Rebuild()); + RenderedProperty.Changed.AddClassHandler((block, _) => block.Rebuild()); + } + + public IReadOnlyList? Segments + { + get => GetValue(SegmentsProperty); + set => SetValue(SegmentsProperty, value); + } + + public bool Rendered + { + get => GetValue(RenderedProperty); + set => SetValue(RenderedProperty, value); + } + + protected override Type StyleKeyOverride => typeof(TextBlock); + + private void Rebuild() + { + var segments = Segments ?? Array.Empty(); + Inlines = Rendered ? BuildRendered(string.Concat(segments.Select(s => s.Text))) : BuildRaw(segments); + } + + /// Raw text: tags in the tag color, removed/added text on a tint. + private static InlineCollection BuildRaw(IReadOnlyList segments) + { + var inlines = new InlineCollection(); + var inTag = false; + foreach (var segment in segments) + { + var background = segment.Kind switch + { + DiffKind.Removed => RemovedBrush, + DiffKind.Added => AddedBrush, + _ => null, + }; + + var run = new StringBuilder(); + var runIsTag = inTag; + void Flush() + { + if (run.Length > 0) + { + var inline = new Run(run.ToString()) { Background = background }; + if (runIsTag) + { + inline.Foreground = TagBrush; + inline.FontWeight = FontWeight.SemiBold; + } + + inlines.Add(inline); + run.Clear(); + } + } + + foreach (var c in segment.Text) + { + if (c == '\r') + { + continue; + } + + if (c == '\n') + { + Flush(); + if (background != null) + { + // A changed line break would otherwise be invisible. + inlines.Add(new Run("↵") { Background = background, Foreground = TagBrush }); + } + + inlines.Add(new LineBreak()); + continue; + } + + var isTag = inTag || c == '<'; + if (isTag != runIsTag) + { + Flush(); + runIsTag = isTag; + } + + run.Append(c); + if (c == '<') + { + inTag = true; + } + else if (c == '>') + { + inTag = false; + Flush(); + runIsTag = false; + } + } + + Flush(); + } + + return inlines; + } + + /// Rendered text: tags hidden, <i> drawn in italics on a soft tint, <b>/<u> applied too. + private static InlineCollection BuildRendered(string text) + { + var inlines = new InlineCollection(); + var italic = 0; + var bold = 0; + var underline = 0; + var run = new StringBuilder(); + void Flush() + { + if (run.Length > 0) + { + var inline = new Run(run.ToString()) + { + FontStyle = italic > 0 ? FontStyle.Italic : FontStyle.Normal, + FontWeight = bold > 0 ? FontWeight.Bold : FontWeight.Normal, + }; + if (underline > 0) + { + inline.TextDecorations = Avalonia.Media.TextDecorations.Underline; + } + + if (italic > 0) + { + inline.Background = ItalicBrush; + } + + inlines.Add(inline); + run.Clear(); + } + } + + for (var i = 0; i < text.Length; i++) + { + var c = text[i]; + if (c == '\r') + { + continue; + } + + if (c == '\n') + { + Flush(); + inlines.Add(new LineBreak()); + continue; + } + + var end = c is '<' or '{' ? text.IndexOf(c == '<' ? '>' : '}', i) : -1; + if (end < 0) + { + run.Append(c); + continue; + } + + Flush(); + var tag = text.Substring(i, end - i + 1).ToLowerInvariant(); + i = end; + switch (tag) + { + case "": italic++; break; + case "": italic = Math.Max(0, italic - 1); break; + case "": bold++; break; + case "": bold = Math.Max(0, bold - 1); break; + case "": underline++; break; + case "": underline = Math.Max(0, underline - 1); break; + } + } + + Flush(); + return inlines; + } +} diff --git a/se5/FixEncodingErrors/TextDiff.cs b/se5/FixEncodingErrors/TextDiff.cs new file mode 100644 index 00000000..6c6a2f96 --- /dev/null +++ b/se5/FixEncodingErrors/TextDiff.cs @@ -0,0 +1,138 @@ +namespace SubtitleEdit.Plugins.FixEncodingErrors; + +public enum DiffKind +{ + Same, + Removed, + Added, +} + +public sealed record DiffSegment(string Text, DiffKind Kind); + +/// Character diff (LCS) used to highlight what a fix changed. +public static class TextDiff +{ + private const int MaxCells = 1_000_000; + + /// Returns the segments of the old text (same/removed) and of the new text (same/added). + public static (List Before, List After) Compute(string before, string after) + { + // Same number of lines: diff line by line, so line breaks never pair up with the wrong line. + var beforeLines = before.Split('\n'); + var afterLines = after.Split('\n'); + if (beforeLines.Length > 1 && beforeLines.Length == afterLines.Length) + { + var beforeSegments = new List(); + var afterSegments = new List(); + for (var i = 0; i < beforeLines.Length; i++) + { + if (i > 0) + { + Add(beforeSegments, "\n", DiffKind.Same); + Add(afterSegments, "\n", DiffKind.Same); + } + + var (b, a) = ComputeLine(beforeLines[i], afterLines[i]); + b.ForEach(segment => Add(beforeSegments, segment.Text, segment.Kind)); + a.ForEach(segment => Add(afterSegments, segment.Text, segment.Kind)); + } + + return (beforeSegments, afterSegments); + } + + return ComputeLine(before, after); + } + + private static (List Before, List After) ComputeLine(string before, string after) + { + var prefix = 0; + while (prefix < before.Length && prefix < after.Length && before[prefix] == after[prefix]) + { + prefix++; + } + + var suffix = 0; + while (suffix < before.Length - prefix && suffix < after.Length - prefix && + before[before.Length - 1 - suffix] == after[after.Length - 1 - suffix]) + { + suffix++; + } + + var a = before.Substring(prefix, before.Length - prefix - suffix); + var b = after.Substring(prefix, after.Length - prefix - suffix); + var beforeSegments = new List(); + var afterSegments = new List(); + Add(beforeSegments, before[..prefix], DiffKind.Same); + Add(afterSegments, after[..prefix], DiffKind.Same); + + if ((long)a.Length * b.Length > MaxCells) + { + Add(beforeSegments, a, DiffKind.Removed); + Add(afterSegments, b, DiffKind.Added); + } + else + { + Lcs(a, b, beforeSegments, afterSegments); + } + + Add(beforeSegments, before[(before.Length - suffix)..], DiffKind.Same); + Add(afterSegments, after[(after.Length - suffix)..], DiffKind.Same); + return (beforeSegments, afterSegments); + } + + private static void Lcs(string a, string b, List beforeSegments, List afterSegments) + { + var lengths = new int[a.Length + 1, b.Length + 1]; + for (var i = a.Length - 1; i >= 0; i--) + { + for (var j = b.Length - 1; j >= 0; j--) + { + lengths[i, j] = a[i] == b[j] + ? lengths[i + 1, j + 1] + 1 + : Math.Max(lengths[i + 1, j], lengths[i, j + 1]); + } + } + + int x = 0, y = 0; + while (x < a.Length && y < b.Length) + { + if (a[x] == b[y]) + { + Add(beforeSegments, a[x].ToString(), DiffKind.Same); + Add(afterSegments, b[y].ToString(), DiffKind.Same); + x++; + y++; + } + else if (lengths[x + 1, y] >= lengths[x, y + 1]) + { + Add(beforeSegments, a[x].ToString(), DiffKind.Removed); + x++; + } + else + { + Add(afterSegments, b[y].ToString(), DiffKind.Added); + y++; + } + } + + Add(beforeSegments, a[x..], DiffKind.Removed); + Add(afterSegments, b[y..], DiffKind.Added); + } + + private static void Add(List segments, string text, DiffKind kind) + { + if (text.Length == 0) + { + return; + } + + if (segments.Count > 0 && segments[^1].Kind == kind) + { + segments[^1] = segments[^1] with { Text = segments[^1].Text + text }; + } + else + { + segments.Add(new DiffSegment(text, kind)); + } + } +} diff --git a/se5/FixEncodingErrors/app.manifest b/se5/FixEncodingErrors/app.manifest new file mode 100644 index 00000000..e68fabca --- /dev/null +++ b/se5/FixEncodingErrors/app.manifest @@ -0,0 +1,10 @@ + + + + + + true/pm + PerMonitorV2 + + + diff --git a/se5/FixEncodingErrors/docs/screenshot.png b/se5/FixEncodingErrors/docs/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..2bac684c548becf188b350f0f50dad8de37fd0aa GIT binary patch literal 114208 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