DevBase.Format
1.7.4
dotnet add package DevBase.Format --version 1.7.4
NuGet\Install-Package DevBase.Format -Version 1.7.4
<PackageReference Include="DevBase.Format" Version="1.7.4" />
<PackageVersion Include="DevBase.Format" Version="1.7.4" />
<PackageReference Include="DevBase.Format" />
paket add DevBase.Format --version 1.7.4
#r "nuget: DevBase.Format, 1.7.4"
#:package DevBase.Format@1.7.4
#addin nuget:?package=DevBase.Format&version=1.7.4
#tool nuget:?package=DevBase.Format&version=1.7.4
DevBase.Format
DevBase.Format parses lyric and configuration text formats for .NET 9.0. Use FileParser<P, T> to parse either an in-memory string or a file on disk.
Installation
dotnet add package DevBase.Format
Supported formats
| Format | Parser | Result |
|---|---|---|
| LRC | LrcParser |
AList<TimeStampedLyric> |
| ELRC | ElrcParser |
AList<RichTimeStampedLyric> |
| RLRC | RlrcParser |
AList<RawLyric> |
| SRT | SrtParser |
AList<RichTimeStampedLyric> |
| KLyrics | KLyricsParser |
AList<RichTimeStampedLyric> |
| MML JSON | MmlParser |
AList<TimeStampedLyric> |
| RMML JSON | RmmlParser |
AList<RichTimeStampedLyric> |
| Apple XML | AppleXmlParser |
AList<RawLyric> |
| Apple LRC XML | AppleLrcXmlParser |
AList<TimeStampedLyric> |
| Apple Rich XML | AppleRichXmlParser |
AList<RichTimeStampedLyric> |
| ENV | EnvParser |
ATupleList<string, string> |
LrcParser, ElrcParser, and RlrcParser are reversible and also implement Revert and TryRevert.
Parser examples
Every example uses the same FileParser<P, T> API for both a source string and a disk file. ParseFromDisk reads the file; callers do not need to read it themselves first.
LRC
Leading and trailing whitespace around each source line is trimmed. Metadata-style lines are ignored rather than returned as metadata objects.
using DevBase.Format;
using DevBase.Format.Formats.LrcFormat;
using DevBase.Format.Structure;
using DevBase.Generics;
string lrcContent = @"
[00:12.00]First line
[00:15.50]Second line
[00:20.00]Third line
";
var parser = new FileParser<LrcParser, AList<TimeStampedLyric>>();
AList<TimeStampedLyric> lyrics = parser.ParseFromString(lrcContent);
AList<TimeStampedLyric> lyricsFromFile = parser.ParseFromDisk("song.lrc");
ELRC
ELRC stores a line's start/end time and individual word timings.
using DevBase.Format;
using DevBase.Format.Formats.ElrcFormat;
using DevBase.Format.Structure;
using DevBase.Generics;
string elrcContent = @"
[00:00:12.000] - [00:00:13.000] First line
[
[00:00:12.000] - [00:00:12.500] First
[00:00:12.500] - [00:00:13.000] line
]
";
var parser = new FileParser<ElrcParser, AList<RichTimeStampedLyric>>();
AList<RichTimeStampedLyric> lyrics = parser.ParseFromString(elrcContent);
AList<RichTimeStampedLyric> lyricsFromFile = parser.ParseFromDisk("song.elrc");
RLRC
RLRC is a list of raw lyric lines.
using DevBase.Format;
using DevBase.Format.Formats.RlrcFormat;
using DevBase.Format.Structure;
using DevBase.Generics;
string rlrcContent = "First line\nSecond line";
var parser = new FileParser<RlrcParser, AList<RawLyric>>();
AList<RawLyric> lyrics = parser.ParseFromString(rlrcContent);
AList<RawLyric> lyricsFromFile = parser.ParseFromDisk("song.rlrc");
SRT
SrtParser produces rich lyrics, including both a start and an end time.
using DevBase.Format;
using DevBase.Format.Formats.SrtFormat;
using DevBase.Format.Structure;
using DevBase.Generics;
string srtContent = "1\n00:00:12,000 --> 00:00:15,000\nFirst subtitle\n\n";
var parser = new FileParser<SrtParser, AList<RichTimeStampedLyric>>();
AList<RichTimeStampedLyric> subtitles = parser.ParseFromString(srtContent);
AList<RichTimeStampedLyric> subtitlesFromFile = parser.ParseFromDisk("movie.srt");
KLyrics
using DevBase.Format;
using DevBase.Format.Formats.KLyricsFormat;
using DevBase.Format.Structure;
using DevBase.Generics;
string kLyricsContent = "[12000,1000](0,500)First(0,500)line";
var parser = new FileParser<KLyricsParser, AList<RichTimeStampedLyric>>();
AList<RichTimeStampedLyric> lyrics = parser.ParseFromString(kLyricsContent);
AList<RichTimeStampedLyric> lyricsFromFile = parser.ParseFromDisk("song.klyrics");
MML JSON
MmlParser currently keeps only entries whose text matches the library's metadata-style pattern. Ordinary lyric text such as First line is filtered out; the example below reflects the parser's current behavior.
using DevBase.Format;
using DevBase.Format.Formats.MmlFormat;
using DevBase.Format.Structure;
using DevBase.Generics;
string mmlContent = """
[{"text":"[ar:Artist]","time":{"total":1250,"minutes":0,"seconds":1,"hundredths":25}}]
""";
var parser = new FileParser<MmlParser, AList<TimeStampedLyric>>();
AList<TimeStampedLyric> lyrics = parser.ParseFromString(mmlContent);
AList<TimeStampedLyric> lyricsFromFile = parser.ParseFromDisk("song.mml");
RMML JSON
using DevBase.Format;
using DevBase.Format.Formats.RmmlFormat;
using DevBase.Format.Structure;
using DevBase.Generics;
string rmmlContent = """
[{"ts":12.0,"te":13.0,"l":[{"c":"First","o":0},{"c":" line","o":1}],"x":"First line"}]
""";
var parser = new FileParser<RmmlParser, AList<RichTimeStampedLyric>>();
AList<RichTimeStampedLyric> lyrics = parser.ParseFromString(rmmlContent);
AList<RichTimeStampedLyric> lyricsFromFile = parser.ParseFromDisk("song.rmml");
Apple XML
Apple XML uses TTML with itunes:timing="None" and produces raw lyric lines.
using DevBase.Format;
using DevBase.Format.Formats.AppleXmlFormat;
using DevBase.Format.Structure;
using DevBase.Generics;
string appleXmlContent = """
<tt xmlns="http://www.w3.org/ns/ttml" xmlns:itunes="http://music.apple.com/lyric-ttml-internal" itunes:timing="None">
<body><div><p>First line</p></div></body>
</tt>
""";
var parser = new FileParser<AppleXmlParser, AList<RawLyric>>();
AList<RawLyric> lyrics = parser.ParseFromString(appleXmlContent);
AList<RawLyric> lyricsFromFile = parser.ParseFromDisk("song-raw.xml");
Apple LRC XML
Apple LRC XML uses TTML with itunes:timing="Line" and produces timestamped lines.
using DevBase.Format;
using DevBase.Format.Formats.AppleLrcXmlFormat;
using DevBase.Format.Structure;
using DevBase.Generics;
string appleLrcXmlContent = """
<tt xmlns="http://www.w3.org/ns/ttml" xmlns:itunes="http://music.apple.com/lyric-ttml-internal" itunes:timing="Line">
<body><div><p begin="00:00:12.000" end="00:00:13.000">First line</p></div></body>
</tt>
""";
var parser = new FileParser<AppleLrcXmlParser, AList<TimeStampedLyric>>();
AList<TimeStampedLyric> lyrics = parser.ParseFromString(appleLrcXmlContent);
AList<TimeStampedLyric> lyricsFromFile = parser.ParseFromDisk("song-line.xml");
Apple Rich XML
Apple Rich XML uses TTML with itunes:timing="Word" and produces word-timed lyrics.
using DevBase.Format;
using DevBase.Format.Formats.AppleRichXmlFormat;
using DevBase.Format.Structure;
using DevBase.Generics;
string appleRichXmlContent = """
<tt xmlns="http://www.w3.org/ns/ttml" xmlns:itunes="http://music.apple.com/lyric-ttml-internal" itunes:timing="Word">
<body><div><p begin="00:00:12.000" end="00:00:13.000"><span begin="00:00:12.000" end="00:00:12.500">First</span><span begin="00:00:12.500" end="00:00:13.000">line</span></p></div></body>
</tt>
""";
var parser = new FileParser<AppleRichXmlParser, AList<RichTimeStampedLyric>>();
AList<RichTimeStampedLyric> lyrics = parser.ParseFromString(appleRichXmlContent);
AList<RichTimeStampedLyric> lyricsFromFile = parser.ParseFromDisk("song-word.xml");
ENV
EnvParser returns an ATupleList<string, string>. Its current grammar expects quoted word values.
using DevBase.Format;
using DevBase.Format.Formats.EnvFormat;
using DevBase.Generics;
string envContent = @"
DB_HOST=""localhost""
API_KEY=""secret123""
";
var parser = new FileParser<EnvParser, ATupleList<string, string>>();
ATupleList<string, string> config = parser.ParseFromString(envContent);
ATupleList<string, string> configFromFile = parser.ParseFromDisk(".env");
string dbHost = config.Get(0).Item2;
string apiKey = config.Get(1).Item2;
Safe parsing
FileParser<P, T> creates a fresh parser with strict error handling enabled. To receive false for validation failures routed through FileFormat.Error instead of a ParsingException, use the concrete parser and set StrictErrorHandling to false.
using DevBase.Format.Formats.LrcFormat;
using DevBase.Format.Structure;
using DevBase.Generics;
const string lrcContent = "[00:12.00]First line";
var parser = new LrcParser { StrictErrorHandling = false };
if (parser.TryParse(lrcContent, out AList<TimeStampedLyric> lyrics))
Console.WriteLine($"Parsed {lyrics.Length} lines");
else
Console.WriteLine("Failed to parse LRC lyrics");
Reverting parsed formats
Use the concrete reversible parser to serialize parsed data. SRT does not currently support reversion.
using DevBase.Format.Formats.LrcFormat;
using DevBase.Format.Structure;
using DevBase.Generics;
const string lrcContent = "[00:12.00]First line";
var parser = new LrcParser();
AList<TimeStampedLyric> lyrics = parser.Parse(lrcContent);
string lrcContentAgain = parser.Revert(lyrics);
if (parser.TryRevert(lyrics, out string reverted))
Console.WriteLine(reverted);
Implement a custom parser
using DevBase.Format;
using DevBase.Generics;
var parser = new FileParser<PlainTextParser, AList<string>>();
AList<string> result = parser.ParseFromString("line1\nline2\nline3");
public class PlainTextParser : FileFormat<string, AList<string>>
{
public override AList<string> Parse(string input)
{
AList<string> lines = new AList<string>();
foreach (string line in input.Split('\n'))
{
string trimmed = line.Trim();
if (!string.IsNullOrEmpty(trimmed))
lines.Add(trimmed);
}
return lines;
}
public override bool TryParse(string input, out AList<string> parsed)
{
parsed = Parse(input);
return !parsed.IsEmpty();
}
}
Data structures and extensions
| Class | Purpose |
|---|---|
TimeStampedLyric |
Text plus a start time |
RichTimeStampedLyric |
Text plus start/end times and timed words |
RichTimeStampedWord |
A word plus start/end times |
RawLyric |
A raw lyric line |
using DevBase.Format.Extensions;
using DevBase.Format.Structure;
using DevBase.Generics;
AList<TimeStampedLyric> timedLyrics = new AList<TimeStampedLyric>();
string plainText = timedLyrics.ToPlainText();
AList<RawLyric> rawLyrics = timedLyrics.ToRawLyrics();
AList<RichTimeStampedLyric> richLyrics = new AList<RichTimeStampedLyric>();
AList<TimeStampedLyric> simplifiedLyrics = richLyrics.ToTimeStampedLyrics();
Timestamp utility
using DevBase.Format.Utilities;
if (TimeUtils.TryParseTimeStamp("00:12.50", out TimeSpan time))
Console.WriteLine(time);
TimeSpan anotherTime = TimeUtils.ParseTimeStamp("00:12.50");
Integration with DevBase.Api
When the DevBase.Api package or project is also referenced, Deezer.GetLyrics returns both raw lyric text and parsed timestamped lyrics.
using DevBase.Api.Apis.Deezer;
using DevBase.Format.Structure;
using DevBase.Generics;
var deezer = new Deezer();
(string rawLyrics, AList<TimeStampedLyric> lyrics) = await deezer.GetLyrics("123456");
foreach (TimeStampedLyric line in lyrics)
Console.WriteLine($"[{line.StartTime}] {line.Text}");
Target framework
- .NET 9.0
License
MIT License — see the repository license.
Repository
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- DevBase (>= 1.4.1)
- Newtonsoft.Json (>= 13.0.4)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on DevBase.Format:
| Package | Downloads |
|---|---|
|
DevBase.Api
DevBase.Api is designed to connect to certain api endpoints including Replicate.com, Tidal and Deezer |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.7.4 | 35 | 8/8/2026 |
| 1.7.3 | 394 | 12/24/2025 |
| 1.7.2 | 232 | 12/23/2025 |
| 1.7.1 | 618 | 1/4/2024 |
| 1.7.0 | 446 | 1/4/2024 |
| 1.6.9 | 450 | 1/4/2024 |
| 1.6.8 | 459 | 1/1/2024 |
| 1.6.7 | 506 | 1/1/2024 |
| 1.6.6 | 476 | 1/1/2024 |
| 1.6.5 | 553 | 12/23/2023 |
| 1.6.2 | 496 | 12/21/2023 |
| 1.6.1 | 551 | 12/19/2023 |
| 1.5.1 | 606 | 12/7/2023 |
| 1.5.0 | 627 | 12/6/2023 |
| 1.4.1 | 567 | 12/1/2023 |
| 1.3.1 | 547 | 11/30/2023 |
| 1.3.0 | 556 | 11/30/2023 |
| 1.2.1 | 1,585 | 4/13/2023 |
| 1.2.0 | 885 | 3/18/2023 |
| 1.0.0 | 960 | 3/15/2023 |