Files
0qln bff34658b8 appendix: 23 Code-Ausschnitte aus dem Houston-Repository
Pin nixpkgs to the revision used by itc.componentware: the channel version
ships a latexminted that crashes on Python 3.14, which made every listing
fail and sent latexmk into an endless error prompt. Also force
nonstopmode/halt-on-error so a broken listing can never loop again.
2026-08-25 21:38:22 +02:00

50 lines
1.7 KiB
C#

namespace Houston.Services;
public class IniParser
{
public async Task<IniDocument> ParseAsync(TextReader reader, CancellationToken cancellationToken)
{
var sections = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
var current = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
sections[String.Empty] = current;
while (await reader.ReadLineAsync(cancellationToken) is { } line)
{
var trimmed = line.Trim();
// Skip blank lines and comments
if (trimmed.Length == 0 || trimmed[0] is ';' or '#')
continue;
if (trimmed.StartsWith('[') && trimmed.EndsWith(']'))
{
var name = trimmed[1..^1].Trim();
if (!sections.TryGetValue(name, out current!))
sections[name] = current = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
continue;
}
var separator = trimmed.IndexOf('=');
if (separator < 0)
continue;
var key = trimmed[..separator].Trim();
if (key.Length == 0)
continue;
// Last value wins for duplicate keys within a section.
current[key] = trimmed[(separator + 1)..].Trim();
}
return new(sections);
}
/// <summary>
/// Parses INI content from a string.
/// </summary>
public Task<IniDocument> ParseAsync(string content, CancellationToken cancellationToken)
{
using var reader = new StringReader(content);
return ParseAsync(reader, cancellationToken);
}