Link.Foundation.Links.Notation 0.27.0

dotnet add package Link.Foundation.Links.Notation --version 0.27.0
                    
NuGet\Install-Package Link.Foundation.Links.Notation -Version 0.27.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.27.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.27.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.27.0
                    
#r "nuget: Link.Foundation.Links.Notation, 0.27.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.27.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.27.0
                    
Install as a Cake Addin
#tool nuget:?package=Link.Foundation.Links.Notation&version=0.27.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.

Nesting Limit

Parser.MaxDepth is how deep links may nest (default: Parser.DefaultMaxDepth, 64, the same in every implementation). Every parenthesized group and every indentation level is one level, and the lines of a document start at level 0, so with new Parser(comments: true, maxDepth: 1) (a) is accepted while ((a)), (a (b)) and a group on an indented line are refused. A document nested deeper is refused with a ParseException whose MaxDepth is set, rather than recursed into until the stack runs out, and which points at the group or the line that is one level too deep:

Nesting too deep at line 1, column 4: nesting depth exceeds the maximum of 3
1 | ((((a))))
  |    ^

MaxDepth is null for any other error. StreamParser reports the same error as a StreamParseException whose ParseError is the ParseException and whose Line, Column and Offset are counted from the start of the stream.

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

Version 1 codecs support raw packets and the marker-point LiNo mapping. See the shared specification and cross-language example for APIs and options.

Exact Unicode identifiers and values round-trip with the reference literal contract introduced in 0.24.0, including mixed quotes, empty strings, controls and multiline text.

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.27.0 31 10/16/2026
0.26.0 225 10/12/2026
0.25.2 160 10/11/2026
0.25.1 123 10/8/2026
0.25.0 79 10/8/2026
0.24.0 85 10/8/2026
0.23.0 228 10/6/2026
0.22.0 361 9/29/2026
0.21.3 119 9/25/2026
0.21.2 101 9/25/2026
0.21.1 109 9/25/2026
0.21.0 104 9/25/2026
0.20.0 133 9/15/2026
0.19.0 152 9/5/2026
0.18.0 126 9/5/2026
0.17.0 125 9/5/2026
0.16.1 374 8/28/2026
0.16.0 127 8/28/2026
0.15.0 128 8/28/2026
0.13.0 1,391 12/1/2025
Loading failed

Build and test with the latest release of every dependency and toolchain.