Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions .github/workflows/csharp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ name: csharp

on:
push:
branches: main
branches: main
paths:
- 'csharp/**'
- '.github/workflows/csharp.yml'
pull_request:
paths:
- 'csharp/**'
- '.github/workflows/csharp.yml'
Expand Down Expand Up @@ -65,7 +69,7 @@ jobs:
pushToNuget:
runs-on: ubuntu-latest
needs: [test]
if: ${{ needs.findChangedCsFiles.outputs.isCsFilesChanged == 'true' }}
if: ${{ needs.findChangedCsFiles.outputs.isCsFilesChanged == 'true' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
steps:
- uses: actions/checkout@v3
with:
Expand Down Expand Up @@ -105,7 +109,7 @@ jobs:
publishRelease:
runs-on: ubuntu-latest
needs: [pushToNuget, publishDocumentation]
if: ${{ needs.findChangedCsFiles.outputs.isCsFilesChanged == 'true' && needs.pushToNuget.result == 'success' }}
if: ${{ needs.findChangedCsFiles.outputs.isCsFilesChanged == 'true' && needs.pushToNuget.result == 'success' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
steps:
- uses: actions/checkout@v3
with:
Expand Down Expand Up @@ -157,7 +161,7 @@ $PACKAGE_RELEASE_NOTES"
generatePdfWithCode:
runs-on: ubuntu-latest
needs: [test]
if: ${{ needs.findChangedCsFiles.outputs.isCsFilesChanged == 'true' }}
if: ${{ needs.findChangedCsFiles.outputs.isCsFilesChanged == 'true' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
steps:
- uses: actions/checkout@v3
with:
Expand Down Expand Up @@ -205,7 +209,7 @@ $PACKAGE_RELEASE_NOTES"
publishDocumentation:
runs-on: ubuntu-latest
needs: [test, generatePdfWithCode]
if: ${{ needs.findChangedCsFiles.outputs.isCsFilesChanged == 'true' }}
if: ${{ needs.findChangedCsFiles.outputs.isCsFilesChanged == 'true' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
steps:
- uses: actions/checkout@v3
with:
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ name: js

on:
push:
branches: main
branches: main
paths:
- 'js/**'
- '.github/workflows/js.yml'
pull_request:
paths:
- 'js/**'
- '.github/workflows/js.yml'
Expand Down Expand Up @@ -63,7 +67,7 @@ jobs:

publishToNpm:
needs: [test, findChangedJsFiles]
if: ${{ needs.findChangedJsFiles.outputs.isJsFilesChanged == 'true' }}
if: ${{ needs.findChangedJsFiles.outputs.isJsFilesChanged == 'true' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -103,7 +107,7 @@ jobs:
publishRelease:
runs-on: ubuntu-latest
needs: [publishToNpm]
if: ${{ needs.findChangedJsFiles.outputs.isJsFilesChanged == 'true' && needs.publishToNpm.result == 'success' }}
if: ${{ needs.findChangedJsFiles.outputs.isJsFilesChanged == 'true' && needs.publishToNpm.result == 'success' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
steps:
- uses: actions/checkout@v3
with:
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ name: rust

on:
push:
branches: main
branches: main
paths:
- 'rust/**'
- '.github/workflows/rust.yml'
pull_request:
paths:
- 'rust/**'
- '.github/workflows/rust.yml'
Expand Down Expand Up @@ -78,7 +82,7 @@ jobs:

publishToCratesIO:
needs: [test, findChangedRustFiles]
if: ${{ needs.findChangedRustFiles.outputs.isRustFilesChanged == 'true' }}
if: ${{ needs.findChangedRustFiles.outputs.isRustFilesChanged == 'true' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -149,7 +153,7 @@ jobs:
publishRelease:
runs-on: ubuntu-latest
needs: [publishToCratesIO]
if: ${{ needs.findChangedRustFiles.outputs.isRustFilesChanged == 'true' && needs.publishToCratesIO.result == 'success' }}
if: ${{ needs.findChangedRustFiles.outputs.isRustFilesChanged == 'true' && needs.publishToCratesIO.result == 'success' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
steps:
- uses: actions/checkout@v3
with:
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,23 @@ I'm a friendly AI.
parentheses may be ommitted if the whole line is a single link
```

#### Indented Syntax

Links can also use indented syntax for better readability:

```lino
3:
papa
loves
mama
```

This is equivalent to:

```lino
(3: papa loves mama)
```

So that means that *this* text is also links notation. So most of the
text in the world already may be parsed as links notation. That makes
links notation the most easy an natural/intuitive/native one.
Expand Down
201 changes: 201 additions & 0 deletions csharp/Platform.Protocols.Lino.Tests/IndentedIdSyntaxTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
using System;
using Xunit;

namespace Platform.Protocols.Lino.Tests
{
public static class IndentedIdSyntaxTests
{
[Fact]
public static void BasicIndentedIdSyntaxTest()
{
var indentedSyntax = @"3:
papa
loves
mama";
var inlineSyntax = "(3: papa loves mama)";

var parser = new Parser();
var indentedResult = parser.Parse(indentedSyntax);
var inlineResult = parser.Parse(inlineSyntax);

var indentedFormatted = indentedResult.Format();
var inlineFormatted = inlineResult.Format();

Assert.Equal(inlineFormatted, indentedFormatted);
Assert.Equal("(3: papa loves mama)", indentedFormatted);
}

[Fact]
public static void IndentedIdSyntaxWithSingleValueTest()
{
var input = @"greeting:
hello";

var parser = new Parser();
var result = parser.Parse(input);
var formatted = result.Format();

Assert.Equal("(greeting: hello)", formatted);
Assert.Single(result);
Assert.Equal("greeting", result[0].Id);
Assert.Single(result[0].Values);
Assert.Equal("hello", result[0].Values[0].Id);
}

[Fact]
public static void IndentedIdSyntaxWithMultipleValuesTest()
{
var input = @"action:
run
fast
now";

var parser = new Parser();
var result = parser.Parse(input);
var formatted = result.Format();

Assert.Equal("(action: run fast now)", formatted);
Assert.Single(result);
Assert.Equal("action", result[0].Id);
Assert.Equal(3, result[0].Values.Count);
}

[Fact]
public static void IndentedIdSyntaxWithNumericIdTest()
{
var input = @"42:
answer
to
everything";

var parser = new Parser();
var result = parser.Parse(input);
var formatted = result.Format();

Assert.Equal("(42: answer to everything)", formatted);
}

[Fact]
public static void IndentedIdSyntaxWithQuotedIdTest()
{
var input = @"""complex id"":
value1
value2";

var parser = new Parser();
var result = parser.Parse(input);
var formatted = result.Format();

Assert.Equal("('complex id': value1 value2)", formatted);
}

[Fact]
public static void MultipleIndentedIdLinksTest()
{
var input = @"first:
a
b
second:
c
d";

var parser = new Parser();
var result = parser.Parse(input);
var formatted = result.Format();

Assert.Equal(2, result.Count);
Assert.Contains("(first: a b)", formatted);
Assert.Contains("(second: c d)", formatted);
}

[Fact]
public static void MixedIndentedAndRegularSyntaxTest()
{
var input = @"first:
a
b
(second: c d)
third value";

var parser = new Parser();
var result = parser.Parse(input);

Assert.Equal(3, result.Count);

var formatted = result.Format();
Assert.Contains("(first: a b)", formatted);
Assert.Contains("(second: c d)", formatted);
Assert.Contains("third value", formatted);
}

[Fact]
public static void UnsupportedColonOnlySyntaxShouldFailTest()
{
var input = @":
papa
loves
mama";

var parser = new Parser();
Assert.Throws<FormatException>(() => parser.Parse(input));
}

[Fact]
public static void EmptyIndentedIdTest()
{
var input = "empty:";

var parser = new Parser();
var result = parser.Parse(input);

Assert.Single(result);
Assert.Equal("empty", result[0].Id);
Assert.True(result[0].Values == null || result[0].Values.Count == 0);

var formatted = result.Format();
Assert.Equal("(empty)", formatted);
}

[Fact]
public static void EquivalenceTestComprehensiveTest()
{
var testCases = new[]
{
new { Indented = "test:\n one", Inline = "(test: one)" },
new { Indented = "x:\n a\n b\n c", Inline = "(x: a b c)" },
new { Indented = "\"quoted\":\n value", Inline = "(\"quoted\": value)" }
};

var parser = new Parser();

foreach (var testCase in testCases)
{
var indentedResult = parser.Parse(testCase.Indented);
var inlineResult = parser.Parse(testCase.Inline);

var indentedFormatted = indentedResult.Format();
var inlineFormatted = inlineResult.Format();

Assert.Equal(inlineFormatted, indentedFormatted);
}
}

[Fact]
public static void IndentedIdWithDeeperNestingTest()
{
var input = @"root:
child1
child2
grandchild";

var parser = new Parser();
var result = parser.Parse(input);

Assert.NotEmpty(result);

var rootLink = result[0];
Assert.Equal("root", rootLink.Id);
Assert.Equal(2, rootLink.Values.Count);
}
}
}
Loading
Loading