August 25, 2026

C# to Javascript Conversion Using AI

I asked AI (Code Haiku 4.5) to convert a C# class to Javascript. AI seems to excel at small conversions task like this. The class takes the lines of a SRT subtitle file and converts them to a VTT file. VTT has an optional additional title and note headers so I allows these to be set in the constructor. Note that it just deals with the file as a IEnumerable. Opening the file and streaming it to an instance of this class would be the resposibility of another class, which makes this very easy to test. It is also I think, a nice example of the power of an Iterator function/method and what can be achieved with them. Note that this class does not fix the Cue timings if they are out of order, etc.. Also the class could be tidied up quite a bit: _lineNumber is not required, the ParseState could be set in the Iterator. Well here is the C# version

public class SrtToVttConvertor
{
    private int _lineNumber = 0;
    private ParseState _parseState = ParseState.Starting;
    private readonly string _title = "";
    private readonly string _note = "";

    public SrtToVttConvertor(string title = "", string note = "")
    { 
        _title = title ?? "";
        _note = note ?? "";
    }

    private enum ParseState
    {
        None = 0,
        Starting = 1,
        SearchCue = 2,
        Subtitles = 3
    }


    public IEnumerable<string> Convert(IEnumerable<string> lines)
    {
        foreach (var line in lines)
        {
            _lineNumber++;
            string temp = "";

            switch (_parseState)
            {
                case ParseState.Starting: // Output the start of the WEBVTT file
                    {
                        temp = "WEBVTT " + _title;
                        yield return temp.TrimEnd();
                        yield return "";
                        if (!string.IsNullOrWhiteSpace(_note))
                        {
                            yield return "NOTE " + _note;
                            yield return "";
                        }
                        _parseState = ParseState.SearchCue;
                        break;
                    }

                case ParseState.SearchCue: // Seach for a cue (timings) line (ignore the cue number line)
                    if (line.Contains("-->"))
                    {
                        yield return line.Replace(',', '.').Trim(); // "00:04:08,624 --> 00:04:09,833" Becomes "00:04:08.624 --> 00:04:09.833"
                        _parseState = ParseState.Subtitles;
                    }
                    break;

                case ParseState.Subtitles: // After cue line add all non-blank lines until another blank line is reached
                    if (string.IsNullOrWhiteSpace(line))
                    {
                        yield return "";
                        _parseState = ParseState.SearchCue;
                    }
                    else
                    {
                        yield return line.Trim();
                    }
                    break;
            }
        }
    }
}

I was not even sure whether Javascript had Enumerators, it does they are called generators. Here is what it came up with:

class SrtToVttConvertor {
    #lineNumber;
    #parseState;
    #title;
    #note;

    static ParseState = {
        None: 0,
        Starting: 1,
        SearchCue: 2,
        Subtitles: 3
    };

    constructor(title = "", note = "") {
        this.#lineNumber = 0;
        this.#parseState = SrtToVttConvertor.ParseState.Starting;
        this.#title = title ?? "";
        this.#note = note ?? "";
    }

    *convert(lines) {
        for (const line of lines) {
            this.#lineNumber++;
            let temp = "";

            switch (this.#parseState) {
                case SrtToVttConvertor.ParseState.Starting:
                    temp = "WEBVTT " + this.#title;
                    yield temp.trimEnd();
                    yield "";
                    if (this.#note.trim().length > 0) {
                        yield "NOTE " + this.#note;
                        yield "";
                    }
                    this.#parseState = SrtToVttConvertor.ParseState.SearchCue;
                    break;

                case SrtToVttConvertor.ParseState.SearchCue:
                    if (line.includes("-->")) {
                        yield line.replaceAll(',', '.').trim();
                        this.#parseState = SrtToVttConvertor.ParseState.Subtitles;
                    }
                    break;

                case SrtToVttConvertor.ParseState.Subtitles:
                    if (line.trim().length === 0) {
                        yield "";
                        this.#parseState = SrtToVttConvertor.ParseState.SearchCue;
                    } else {
                        yield line.trim();
                    }
                    break;
            }
        }
    }
}

// Usage:
const converter = new SrtToVttConvertor("My Video", "Subtitle note");
const vttLines = [...converter.convert(srtLines)];

No comments: