Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions .github/workflows/word-censor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
name: Build WordCensor (SE5)

on:
push:
branches: [main]
paths:
- 'se5/WordCensor/**'
- 'se5/Plugin-Shared/**'
- '.github/workflows/word-censor.yml'
pull_request:
paths:
- 'se5/WordCensor/**'
- 'se5/Plugin-Shared/**'
- '.github/workflows/word-censor.yml'
workflow_dispatch:
inputs:
tag:
description: 'Release tag to publish the zips under (e.g. se5-word-censor-v1.0). Leave empty to build artifacts only.'
required: false
type: string

jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- rid: win-x64
os: windows
exe: WordCensor.exe
- rid: win-arm64
os: windows
exe: WordCensor.exe
- rid: linux-x64
os: linux
exe: WordCensor
- rid: linux-arm64
os: linux
exe: WordCensor
- rid: osx-x64
os: macos
exe: WordCensor
- rid: osx-arm64
os: macos
exe: WordCensor

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup .NET 8
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'

- name: Publish self-contained (${{ matrix.rid }})
working-directory: se5/WordCensor
run: |
dotnet publish WordCensor.csproj \
-c Release \
-r ${{ matrix.rid }} \
--self-contained true \
-p:DebugType=None \
-p:DebugSymbols=false \
-o staging/WordCensor

- name: Rewrite plugin.json for ${{ matrix.os }}
working-directory: se5/WordCensor
run: |
jq '
del(.runtime, .entry) |
.executables = { "${{ matrix.os }}": "${{ matrix.exe }}" }
' plugin.json > staging/WordCensor/plugin.json

- name: Package zip
working-directory: se5/WordCensor/staging
run: zip -r "$GITHUB_WORKSPACE/WordCensor-${{ matrix.rid }}.zip" WordCensor

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: WordCensor-${{ matrix.rid }}
path: WordCensor-${{ matrix.rid }}.zip

release:
name: Publish GitHub Release
needs: build
if: github.event_name == 'workflow_dispatch' && github.event.inputs.tag != ''
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download all zips
uses: actions/download-artifact@v4
with:
path: dist
pattern: WordCensor-*
merge-multiple: true

- name: Create release and upload zips
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "${{ github.event.inputs.tag }}" dist/WordCensor-*.zip \
--repo "${{ github.repository }}" \
--target "${{ github.sha }}" \
--title "WordCensor ${{ github.event.inputs.tag }}" \
--notes "Self-contained WordCensor plugin builds for win/linux/osx (x64 + arm64)."
17 changes: 17 additions & 0 deletions se5-plugins.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
{
"plugins": [
{
"name": "Word censor",
"description": "Censors offensive words by replacing the first half of each match with random grawlix characters (#@!$%). Optionally highlights censored words in red.",
"version": "1.0.0",
"author": "Subtitle Edit",
"url": "https://github.com/SubtitleEdit/plugins/tree/main/se5/WordCensor",
"date": "2026-05-17",
"minSeVersion": "5.0.0",
"downloads": {
"win-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-word-censor-v1.0/WordCensor-win-x64.zip",
"win-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-word-censor-v1.0/WordCensor-win-arm64.zip",
"linux-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-word-censor-v1.0/WordCensor-linux-x64.zip",
"linux-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-word-censor-v1.0/WordCensor-linux-arm64.zip",
"osx-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-word-censor-v1.0/WordCensor-osx-x64.zip",
"osx-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-word-censor-v1.0/WordCensor-osx-arm64.zip"
}
},
{
"name": "British to American",
"description": "Converts British English spellings to American English in the subtitle. Shows a checkable preview of every proposed change.",
Expand Down
8 changes: 8 additions & 0 deletions se5/WordCensor/App.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SubtitleEdit.Plugins.WordCensor.App"
RequestedThemeVariant="Default">
<Application.Styles>
<FluentTheme />
</Application.Styles>
</Application>
12 changes: 12 additions & 0 deletions se5/WordCensor/App.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using SubtitleEdit.Plugins.Shared;

namespace SubtitleEdit.Plugins.WordCensor;

public partial class App : PluginApp
{
public override void Initialize() => AvaloniaXamlLoader.Load(this);

protected override Window CreateMainWindow(PluginRequest request) => new MainWindow(request);
}
79 changes: 79 additions & 0 deletions se5/WordCensor/BadWords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
anal
anus
arse
ass
ballsack
balls
bastard
bitch
biatch
bloody
blowjob
blow job
bollock
bollok
boner
boob
bugger
bum
butt
buttplug
clitoris
cock
coon
crap
cunt
damn
dick
dildo
dyke
fag
feck
fellate
fellatio
felching
fuck
fucking
fucked
f u c k
fudgepacker
fudge packer
flange
goddamn
god damn
hell
homo
jerk
jizz
knobend
knob end
labia
lmao
lmfao
muff
nigger
nigga
omg
penis
piss
poop
prick
pube
pussy
queer
scrotum
sex
shit
s hit
sh1t
slut
smegma
spunk
tit
tosser
turd
twat
vagina
wank
whore
wtf
20 changes: 20 additions & 0 deletions se5/WordCensor/ChangeProposal.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using CommunityToolkit.Mvvm.ComponentModel;

namespace SubtitleEdit.Plugins.WordCensor;

public partial class ChangeProposal : ObservableObject
{
[ObservableProperty] private bool _include = true;
[ObservableProperty] private string _censoredText;

public int LineIndex { get; }
public string LineNumber => (LineIndex + 1).ToString();
public string OriginalText { get; }

public ChangeProposal(int lineIndex, string originalText, string censoredText)
{
LineIndex = lineIndex;
OriginalText = originalText;
_censoredText = censoredText;
}
}
99 changes: 99 additions & 0 deletions se5/WordCensor/MainWindow.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="using:SubtitleEdit.Plugins.WordCensor"
x:Class="SubtitleEdit.Plugins.WordCensor.MainWindow"
mc:Ignorable="d"
Title="Word censor"
Width="720" Height="600"
MinWidth="500" MinHeight="380"
WindowStartupLocation="CenterScreen">
<DockPanel Margin="20">

<Grid DockPanel.Dock="Bottom"
ColumnDefinitions="*,Auto,Auto"
Margin="0,14,0,0">
<TextBlock Grid.Column="0"
x:Name="SummaryLabel"
VerticalAlignment="Center"
Opacity="0.75" />
<Button Grid.Column="1"
Content="Cancel"
Click="OnCancel"
MinWidth="100"
Margin="0,0,8,0" />
<Button Grid.Column="2"
x:Name="ApplyButton"
Content="Apply"
Click="OnApply"
MinWidth="100"
Classes="accent"
IsDefault="True" />
</Grid>

<StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Spacing="10" Margin="0,0,0,4">
<Button Content="Select all" Click="OnSelectAll" />
<Button Content="Select none" Click="OnSelectNone" />
<CheckBox x:Name="ColorRedCheck"
Content="Highlight censored words in red"
VerticalAlignment="Center"
Margin="12,0,0,0" />
</StackPanel>

<TextBlock DockPanel.Dock="Top"
FontSize="18"
FontWeight="SemiBold"
Text="Word censor" />

<TextBlock DockPanel.Dock="Top"
x:Name="SubtitleLabel"
Margin="0,4,0,12"
Opacity="0.7"
TextWrapping="Wrap" />

<TextBlock DockPanel.Dock="Top"
x:Name="NoChangesLabel"
FontSize="14"
Margin="0,30,0,0"
HorizontalAlignment="Center"
Opacity="0.65"
Text="No offensive words found in the selected lines."
IsVisible="False" />

<Border BorderBrush="#22808080"
BorderThickness="1"
CornerRadius="4"
Padding="0">
<ListBox x:Name="ChangesList"
Background="Transparent"
SelectionMode="Single">
<ListBox.ItemTemplate>
<DataTemplate x:DataType="local:ChangeProposal">
<Grid ColumnDefinitions="Auto,42,*" Margin="4,6">
<CheckBox Grid.Column="0"
IsChecked="{Binding Include, Mode=TwoWay}"
VerticalAlignment="Top"
Margin="0,2,0,0" />
<TextBlock Grid.Column="1"
Text="{Binding LineNumber}"
Opacity="0.55"
FontSize="12"
Margin="6,2,8,0"
VerticalAlignment="Top" />
<StackPanel Grid.Column="2" Orientation="Vertical" Spacing="2">
<TextBlock Text="{Binding OriginalText}"
TextWrapping="Wrap"
Opacity="0.55"
FontSize="12" />
<TextBlock Text="{Binding CensoredText}"
TextWrapping="Wrap"
FontWeight="SemiBold" />
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</DockPanel>
</Window>
Loading
Loading