Link.Foundation.Links.Notation
0.20.0
dotnet add package Link.Foundation.Links.Notation --version 0.20.0
NuGet\Install-Package Link.Foundation.Links.Notation -Version 0.20.0
<PackageReference Include="Link.Foundation.Links.Notation" Version="0.20.0" />
<PackageVersion Include="Link.Foundation.Links.Notation" Version="0.20.0" />
<PackageReference Include="Link.Foundation.Links.Notation" />
paket add Link.Foundation.Links.Notation --version 0.20.0
#r "nuget: Link.Foundation.Links.Notation, 0.20.0"
#:package Link.Foundation.Links.Notation@0.20.0
#addin nuget:?package=Link.Foundation.Links.Notation&version=0.20.0
#tool nuget:?package=Link.Foundation.Links.Notation&version=0.20.0
Links Notation Parser for C#
C# implementation of the Links Notation parser using Pegasus parser generator and Platform.Collections.
Installation
Package Manager
Install-Package Link.Foundation.Links.Notation
.NET CLI
dotnet add package Link.Foundation.Links.Notation
PackageReference
<PackageReference Include="Link.Foundation.Links.Notation" Version="0.9.0" />
Build from Source
Clone the repository and build:
git clone https://github.com/link-foundation/links-notation.git
cd links-notation/csharp
dotnet build Link.Foundation.Links.Notation.sln
Test
Run tests:
dotnet test
Usage
Basic Parsing
using Link.Foundation.Links.Notation;
// Create parser
var parser = new Parser();
// Parse Links Notation format string
string input = @"papa (lovesMama: loves mama)
son lovesMama
daughter lovesMama
all (love mama)";
var links = parser.Parse(input);
// Access parsed links
foreach (var link in links)
{
Console.WriteLine(link.ToString());
}
Converting Back to String
using Link.Foundation.Links.Notation;
// Format links back to string
string formatted = links.Format();
Console.WriteLine(formatted);
Working with Links
// Create link programmatically
var link = new Link<string>("id", new[] { "value1", "value2" });
// Access link properties
Console.WriteLine($"ID: {link.Id}");
foreach (var value in link.Values)
{
Console.WriteLine($"Value: {value}");
}
Advanced Usage with Generic Types
// Using numeric link addresses
var parser = new Parser<ulong>();
var numericLinks = parser.Parse("(1: 2 3)");
// Working with custom address types
var customParser = new Parser<Guid>();
Streaming Parsing
StreamParser accepts arbitrary chunks and raises LinkParsed only for
complete top-level records. Disable collection for bounded-memory event use.
var stream = new StreamParser { Collect = false };
stream.LinkParsed += Console.WriteLine;
stream.Write("profile:\n name Ada\n");
stream.Finish("next link");
ParseChunks and ParseChunksAsync expose native enumerable adapters. The
parser also provides Position, Drain, Reset, and MaxBufferSize.
Syntax Examples
Doublets (2-tuple)
papa (lovesMama: loves mama)
son lovesMama
daughter lovesMama
all (love mama)
Triplets (3-tuple)
papa has car
mama has house
(papa and mama) are happy
N-tuples with References
(linksNotation: links notation)
(This is a linksNotation as well)
(linksNotation supports (unlimited number (of references) in each link))
Multi-line Groups
A parenthesized group opens a nested context: its body starts fresh at indentation level zero and follows the same rules as the root document, so a line break inside parentheses is structure rather than decoration.
value (
id "1"
label "one"
)
The document above parses to (value ((id 1) (label one))) - two children, each
a link of its own - rather than to one flat list in which the boundary between
id and label would be lost. A body that stays on a single line still
collapses to a single link, so (a b c) is unchanged.
var links = new Parser().Parse(@"value (
id ""1""
label ""one""
)");
Console.WriteLine(links[0]); // (value ((id 1) (label one)))
Comments
A # hides the rest of the line it stands on, so a document can carry prose
about itself:
# the machines this deploys to
deploy: staging # only staging, for now
Both comments are gone by the time the document is read, leaving the single
link (deploy: staging). A # only opens a comment where a reference could
begin, so a # inside a token (issue#1047) and a # inside a delimited
reference ("#") stay ordinary characters.
A formatter keeps the same rule from the other side: a reference that begins
with a # is written quoted ('#tag'), so a document it writes reads back as
itself.
Comments are on by default, and a parser can be told to read # as an ordinary
character again, for documents written before comments existed:
var links = new Parser().Parse("# the machines this deploys to\ndeploy: staging # only staging, for now\n");
Console.WriteLine(links[0]); // (deploy: staging)
var plain = new Parser(comments: false);
Console.WriteLine(plain.Parse("# a b\n")[0]); // (# a b)
API Reference
Classes
- Parser<TLinkAddress>: Main parser class for converting strings to links
(
new Parser(comments: false)reads#as an ordinary character) - Link<TLinkAddress>: Represents a single link with ID and values
- LinksGroup<TLinkAddress>: Container for grouping related links
- ParseException: Thrown when a document does not parse
Error Handling
Parse throws a ParseException whose message says where the document stopped
making sense and quotes the offending line with a caret under it:
try
{
new Parser().Parse("ci_gate x\nstage: rust: nextest\n");
}
catch (ParseException error)
{
Console.Error.WriteLine(error.Message);
Console.Error.WriteLine($"{error.Line}:{error.Column} (offset {error.Offset})");
}
Syntax error at line 2, column 12: unexpected ":"
2 | stage: rust: nextest
| ^
ParseException derives from FormatException, so callers that already catch
FormatException keep working, and carries Offset, Line, Column, Found,
LineText, Summary and Snippet for callers that report errors themselves.
Extension Methods
- IListExtensions.Format(): Converts list of links back to string format
- ILinksGroupListExtensions: Additional operations for link groups
Maintenance
Linting and Formatting
Check code formatting:
dotnet format --verify-no-changes --verbosity diagnostic
Auto-fix formatting:
dotnet format
Pre-commit Hooks
This project uses pre-commit hooks. To set up pre-commit hooks locally:
# From repository root
pip install pre-commit
pre-commit install
Note: C# formatting checks are integrated into the CI pipeline using
dotnet format.
Dependencies
- .NET 10.0
- Microsoft.CSharp (4.7.0)
- Pegasus (4.1.0)
- Platform.Collections (0.3.2)
Maintenance
Code Formatting
This project uses dotnet format for code formatting.
Format all files
dotnet format
Check formatting (without modifying files)
dotnet format --verify-no-changes
These checks are also enforced in CI. Pull requests with formatting issues will fail the format check.
Documentation
For complete API documentation, visit: Link.Foundation.Links.Notation Documentation
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Pegasus (>= 4.1.0)
- Platform.Collections (>= 0.4.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Link.Foundation.Links.Notation:
| Package | Downloads |
|---|---|
|
Foundation.Data.Doublets.Cli
Public library exposing the parser, query processors, decorators, named/pinned types, persistent transformation triggers, and LiNo I/O used by the clink CLI. |
|
|
Lino.Objects.Codec
A library to encode/decode objects to/from links notation |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.20.0 | 99 | 9/15/2026 |
| 0.19.0 | 134 | 9/5/2026 |
| 0.18.0 | 110 | 9/5/2026 |
| 0.17.0 | 107 | 9/5/2026 |
| 0.16.1 | 341 | 8/28/2026 |
| 0.16.0 | 116 | 8/28/2026 |
| 0.15.0 | 114 | 8/28/2026 |
| 0.13.0 | 1,381 | 12/1/2025 |
| 0.12.0 | 453 | 11/18/2025 |
| 0.11.2 | 214 | 10/31/2025 |
| 0.11.1 | 224 | 10/31/2025 |
| 0.11.0 | 180 | 10/18/2025 |
| 0.9.0 | 176 | 10/18/2025 |
Add incremental StreamParser APIs with events and lazy enumerable adapters.