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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Link.Foundation.Links.Notation" Version="0.20.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Link.Foundation.Links.Notation" Version="0.20.0" />
                    
Directory.Packages.props
<PackageReference Include="Link.Foundation.Links.Notation" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Link.Foundation.Links.Notation --version 0.20.0
                    
#r "nuget: Link.Foundation.Links.Notation, 0.20.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Link.Foundation.Links.Notation@0.20.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Link.Foundation.Links.Notation&version=0.20.0
                    
Install as a Cake Addin
#tool nuget:?package=Link.Foundation.Links.Notation&version=0.20.0
                    
Install as a Cake Tool

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);
// 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.