Java implementation of the Links Notation parser.
Add the dependency to your pom.xml:
<dependency>
<groupId>io.github.link-foundation</groupId>
<artifactId>links-notation</artifactId>
<version>0.19.0</version>
</dependency>Add the dependency to your build.gradle:
implementation 'io.github.link-foundation:links-notation:0.19.0'For contributors working on the source code:
cd java
mvn installBuild the project:
mvn clean compileRun tests:
mvn testimport io.github.linkfoundation.linksnotation.Parser;
import io.github.linkfoundation.linksnotation.Link;
import java.util.List;
public class Example {
public static void main(String[] args) throws Exception {
// Create parser
Parser parser = new Parser();
// Parse Lino format string
String input = """
papa (lovesMama: loves mama)
son lovesMama
daughter lovesMama
all (love mama)
""";
List<Link> result = parser.parse(input);
// Access parsed structure
for (Link link : result) {
System.out.println(link.toString());
}
}
}import io.github.linkfoundation.linksnotation.Link;
import java.util.Arrays;
import java.util.List;
// Create links programmatically
Link child1 = new Link("child1");
Link child2 = new Link("child2");
Link parent = new Link("parent", Arrays.asList(child1, child2));
System.out.println(parent.toString()); // (parent: child1 child2)
// Access link properties
System.out.println("ID: " + parent.getId());
System.out.println("Values: " + parent.getValues());import io.github.linkfoundation.linksnotation.Parser;
import io.github.linkfoundation.linksnotation.Link;
import io.github.linkfoundation.linksnotation.LinksGroup;
// Handle nested structures
String input = """
parent
child1
child2
grandchild1
grandchild2
""";
Parser parser = new Parser();
List<Link> parsed = parser.parse(input);
// Work with groups
LinksGroup group = new LinksGroup(parsed);
System.out.println(group.format());papa (lovesMama: loves mama)
son lovesMama
daughter lovesMama
all (love mama)
papa has car
mama has house
(papa and mama) are happy
(linksNotation: links notation)
(This is a linksNotation as well)
(linksNotation supports (unlimited number (of references) in each link))
parent
child1
child2
grandchild1
grandchild2
3:
papa
loves
mama
This is equivalent to:
(3: papa loves mama)
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.
String input = """
value (
id "1"
label "one"
)
""";
List<Link> links = new Parser().parse(input);
System.out.println(links.get(0).format(false)); // (value ((id 1) (label one)))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:
String document = "# the machines this deploys to\ndeploy: staging # only staging, for now\n";
System.out.println(new Parser().parse(document).get(0).format(false)); // (deploy: staging)
System.out.println(new Parser(false).parse("# a b\n").get(0).format(false)); // (# a b)Main parser class for converting strings to links.
Parser()- Create a new parser with default optionsParser(int maxInputSize, int maxDepth)- Create a parser with custom limitsParser(boolean comments)- Create a parser that reads#as an ordinary character whencommentsisfalseParser(int maxInputSize, int maxDepth, boolean comments)- Create a parser with bothparse(String input)- Parse a Lino string and return links
Represents a single link with ID and values.
Link()- Create an empty linkLink(String id)- Create a link with an IDLink(String id, List<Link> values)- Create a link with ID and valuesgetId()- Get link identifiergetValues()- Get array of child values/linkstoString()- Convert link to string formatformat(boolean lessParentheses)- Format with optional parentheses reductionequals(Object other)- Check equality with another Linkstatic formatLinks(List<Link> links)- Format a list of links
Container for grouping related links.
LinksGroup()- Create an empty groupLinksGroup(List<Link> links)- Create a group with linksadd(Link link)- Add a link to the groupgetLinks()- Get the list of linkssize()- Get number of linksisEmpty()- Check if group is emptyformat()- Format the group as a string
Exception thrown when parsing fails.
src/main/java/io/github/linkfoundation/linksnotation/Link.java- Link data structuresrc/main/java/io/github/linkfoundation/linksnotation/LinksGroup.java- Links group containersrc/main/java/io/github/linkfoundation/linksnotation/Parser.java- Parser implementationsrc/main/java/io/github/linkfoundation/linksnotation/ParseException.java- Parse exceptionsrc/test/java/- Test files
This project uses Google Java Format via Spotless:
mvn spotless:applyCheck formatting:
mvn spotless:check- Java 21 or higher
- Maven 3.6+
- Group ID:
io.github.link-foundation - Artifact ID:
links-notation - License: Unlicense (see LICENSE)