[parsing] Further improve mention parser logic, add more tests
This commit is contained in:
parent
fd5a524a8c
commit
3dc14f5bfe
2 changed files with 45 additions and 19 deletions
|
@ -134,24 +134,20 @@ module private MfmParser =
|
|||
let aggregateTextInline nodes =
|
||||
nodes |> aggregateText |> List.map (fun x -> x :?> MfmInlineNode)
|
||||
|
||||
let domainFirstComponent =
|
||||
many1Chars (satisfy isAsciiLetter <|> satisfy isDigit <|> anyOf "_-")
|
||||
|
||||
let domainComponent =
|
||||
many1Chars (satisfy isAsciiLetter <|> satisfy isDigit <|> anyOf "._-")
|
||||
many1Chars (
|
||||
satisfy isAsciiLetterOrNumber
|
||||
<|> pchar '_'
|
||||
<|> attempt (
|
||||
pchar '-'
|
||||
.>> (previousCharSatisfies isAsciiLetterOrNumber
|
||||
<|> nextCharSatisfies isAsciiLetterOrNumber)
|
||||
)
|
||||
)
|
||||
|
||||
let domainStart = (satisfy isAsciiLetter <|> satisfy isDigit)
|
||||
|
||||
let domainFull =
|
||||
domainStart .>>. domainFirstComponent .>>. pchar '.' .>>. many1 domainComponent
|
||||
|
||||
let domainAggregate1 (a: char, b: string) = string a + b
|
||||
let domainAggregate2 (a: char * string, b: char) = (domainAggregate1 a) + string b
|
||||
|
||||
let domainAggregate (x: (char * string) * char, y: string list) =
|
||||
domainAggregate2 x + (String.concat "" y)
|
||||
|
||||
let domain = domainFull |>> domainAggregate
|
||||
let domain =
|
||||
domainComponent .>>. (many <| attempt (skipChar '.' >>. domainComponent))
|
||||
|>> fun (a, b) -> String.concat "." <| Seq.append [ a ] b
|
||||
|
||||
let acct (user: string, host: string option) =
|
||||
match host with
|
||||
|
@ -230,7 +226,10 @@ module private MfmParser =
|
|||
let mentionNode =
|
||||
previousCharSatisfiesNot isNotWhitespace
|
||||
>>. skipString "@"
|
||||
>>. many1Chars (satisfy isAsciiLetter <|> satisfy isDigit <|> anyOf "._-")
|
||||
>>. many1Chars (
|
||||
satisfy isAsciiLetterOrNumber
|
||||
<|> attempt (anyOf "._-" .>> nextCharSatisfies isAsciiLetterOrNumber)
|
||||
)
|
||||
.>>. opt (skipChar '@' >>. domain)
|
||||
.>> (lookAhead
|
||||
<| choice
|
||||
|
|
|
@ -66,10 +66,13 @@ public class MfmTests
|
|||
[TestMethod]
|
||||
public void TestMention()
|
||||
{
|
||||
const string input = "test @test test";
|
||||
const string input = "test @test test @test@instance.tld";
|
||||
List<MfmNode> expected =
|
||||
[
|
||||
new MfmTextNode("test "), new MfmMentionNode("test", "test", null), new MfmTextNode(" test")
|
||||
new MfmTextNode("test "),
|
||||
new MfmMentionNode("test", "test", null),
|
||||
new MfmTextNode(" test "),
|
||||
new MfmMentionNode("test@instance.tld", "test", "instance.tld")
|
||||
];
|
||||
var res = Mfm.parse(input);
|
||||
|
||||
|
@ -90,6 +93,30 @@ public class MfmTests
|
|||
MfmSerializer.Serialize(res).Should().BeEquivalentTo(input);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestMentionTrailingDot()
|
||||
{
|
||||
const string input = "@test@asdf.com.";
|
||||
List<MfmNode> expected = [new MfmMentionNode("test@asdf.com", "test", "asdf.com"), new MfmTextNode(".")];
|
||||
var res = Mfm.parse(input);
|
||||
|
||||
AssertionOptions.FormattingOptions.MaxDepth = 100;
|
||||
res.ToList().Should().Equal(expected, MfmNodeEqual);
|
||||
MfmSerializer.Serialize(res).Should().BeEquivalentTo(input);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestMentionTrailingDotLocal()
|
||||
{
|
||||
const string input = "@test.";
|
||||
List<MfmNode> expected = [new MfmMentionNode("test", "test", null), new MfmTextNode(".")];
|
||||
var res = Mfm.parse(input);
|
||||
|
||||
AssertionOptions.FormattingOptions.MaxDepth = 100;
|
||||
res.ToList().Should().Equal(expected, MfmNodeEqual);
|
||||
MfmSerializer.Serialize(res).Should().BeEquivalentTo(input);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestCodeBlock()
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue