wikilink with semantic syntax :)

This commit is contained in:
sneakers-the-rat 2022-11-13 11:37:23 -08:00
parent 10b514473f
commit 4f239ea0d7
2 changed files with 60 additions and 6 deletions

View file

@ -41,6 +41,14 @@ class TestStr:
"[[^{1,3}Link#With section]]", "[[^{1,3}Link#With section]]",
Wikilink("Link", nback=NBack(1,3), section="With section") Wikilink("Link", nback=NBack(1,3), section="With section")
) )
implicit = (
"[[Predicate:singlecol::Object]]",
Wikilink(predicate="Predicate:singlecol", object="Object")
)
explicit = (
"[[Link#Section::Predicate:singlecol::Object]]",
Wikilink(link="Link", section="Section", predicate="Predicate:singlecol", object="Object")
)
def pad_garbage(string:str) -> str: def pad_garbage(string:str) -> str:
@ -135,9 +143,15 @@ def test_section(test_string, expected):
assert len(wl) == 1 assert len(wl) == 1
assert wl[0] == expected assert wl[0] == expected
@pytest.mark.parametrize(
def test_triplet_full(): "test_string,expected",
pass [TestStr.implicit, TestStr.explicit])
def test_triplets(test_string, expected):
test_string = pad_garbage(test_string)
wl = Wikilink.parse(test_string)
# pdb.set_trace()
assert len(wl) == 1
assert wl[0] == expected
def test_triplet_implicit_single(): def test_triplet_implicit_single():
"""Test an implicit triplet in a single message""" """Test an implicit triplet in a single message"""

View file

@ -62,13 +62,17 @@ class NBack:
# combine into matches # combine into matches
nb_wildcard = caret.suppress() + "*" nb_wildcard = caret.suppress() + "*"
nb_wildcard.set_name("NBack - Wildcard")
# start or end can be omitted if comma is present # start or end can be omitted if comma is present
nb_full = nb_range + pp.Optional(integer("start")) + comma + pp.Optional(integer("end")) + rcurly nb_full = nb_range + pp.Optional(integer("start")) + comma + pp.Optional(integer("end")) + rcurly
nb_full.set_name("NBack - Fully Specified")
# if no comma present, it's just an end # if no comma present, it's just an end
nb_end = nb_range + integer("end") + rcurly nb_end = nb_range + integer("end") + rcurly
nb_end.set_name("NBack - End Specified")
# combine into full nback parser # combine into full nback parser
nback = pp.Group(nb_wildcard('wildcard') | nb_full | nb_end | caret("one")).set_results_name("nback") nback = pp.Group(nb_wildcard('wildcard') | nb_full | nb_end | caret("one")).set_results_name("nback")
nback.set_name("NBack Prefix")
return nback return nback
def __eq__(self, other:'NBack'): def __eq__(self, other:'NBack'):
@ -123,7 +127,7 @@ class Wikilink(Pattern):
def __init__( def __init__(
self, self,
link: str, link: Optional[str] = None,
nback: Optional[Union[NBack, tuple, dict]] = None, nback: Optional[Union[NBack, tuple, dict]] = None,
predicate: Optional[str] = None, predicate: Optional[str] = None,
object: Optional[str] = None, object: Optional[str] = None,
@ -160,14 +164,50 @@ class Wikilink(Pattern):
nback = NBack.make_parser() nback = NBack.make_parser()
# main wikilink subject text # main wikilink subject text
link = pp.Word(pp.printables+ " ", excludeChars="#[]{}|") #link = pp.Word(pp.printables+ " ", excludeChars="#[]{}|:") + pp.Optional(pp.Literal(':')) + pp.Optional(pp.Word(pp.printables+ " ", excludeChars="#[]{}|:"))
# allow single, but not double colons
# "Look for a printable character and an optional colon that isn't a double colon,
# combine those. Then look for one or more instances of that, and combine that."
link = pp.Combine(
pp.OneOrMore(
pp.Combine(
pp.Word(pp.printables+ " ", excludeChars="#[]{}|:").set_name("Link Body") + \
pp.Optional(
pp.Literal(':')+ ~pp.Literal(':')
).set_name('Single Colon')
)
)
)
link.set_name("Wikilink - Body")
# optional page section # optional page section
hash = pp.Literal("#").suppress() hash = pp.Literal("#").suppress()
section = hash + link section = hash + link
section.set_name("Section")
# combined they make a fully qualified link#section link
link_full = link("link") + pp.Optional(section("section"))
link_full.set_name("Wikilink - Full")
#### SMW
# Predicate::Object with implicit subject
smw_delimiter = pp.Literal('::').suppress()
implicit_semantic = link("predicate") + smw_delimiter + link("object")
# or
# Link::Predicate::Object with explicit subject
explicit_semantic = link_full + smw_delimiter + implicit_semantic
### Combine link bodies
# optionally matching depending on the form
link_bodies = explicit_semantic.set_name('Explicit Semantic Link') | implicit_semantic.set_name('Implicit Semantic Link') | link_full
# link_bodies = implicit_semantic
# Combine all # Combine all
parser = lbracket + pp.Optional(nback) + link("link") + pp.Optional(section("section")) + rbracket #parser = lbracket + pp.Optional(nback) + link_full + rbracket
parser = lbracket + pp.Optional(nback) + link_bodies + rbracket
parser.set_name('Wikilink Parser')
return parser return parser
@classmethod @classmethod