-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathknow-construct
executable file
·153 lines (120 loc) · 4.82 KB
/
know-construct
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/python3
import argparse
import sys
from rdflib import Graph, Literal, BNode, URIRef
from PKB4Unix.construction import *
from PKB4Unix.conf import *
argparser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description='Construct a graph based on a template or RDF schema',
epilog='''
== Template language ==
Values:
<prefix> a namespace prefix. Syntax as in SPARQL
<count> number of instances to be assigned to a variable.
This can be an integer for a fixed count, * for any
number >= 0 and + for any number > 0.
<variable> A SPARQL variable name including the inition ? or $.
<class> Normally rdfs:class. If it does not contain a ":", then
it is considered a name not corresponding to a class.
Usually, a section with the same class should also be
present.
<prompt> Shown to the user when she's to fill in the value. It is
optional and may contain whitespaces, since its always at
the end of an instruction.
Sections:
A section is introduced with a line
[<class>] <variable> <prompt>
Except namespace declarations, everything must be inside a section.
The first section of a template file is used at the beginning. The
user is asked for the <variable> by showing <prompt>.
Instructions:
NS <prefix> <namespace>
Declares the namespace <namespace> with prefix <prefix>
NODE <count> <variable> <prompt>
Declares <variable> to be any node. <prompt> is shown to
the user to set the variable.
LITERAL <count> <variable> [<datatype or language>] <prompt>
Declares <variable> to be a literal. <prompt> is shown to the user
in order to determine the value.
<datatype or language> provides the (recommended) datatype or
language. It is of the form ^^datatypeuri or @language. Examples
are '^^xsd:date' and '@en'. The part [<datatype or language>] is
optional.
RESOURCE <count> <variable> [<class>] <prompt>
Declares <variable> to ba a resource. [<class>] is optional. If
given, the user has the option to just provide an URI or to create
the resource according to the template given in the
[<class>]-section should such a section exist. [<class>] <prompt>
are both shown to the user.
Hint: Provide [<class>] if a resource is supposed to be of a
certain rdfs:Class, even if you don't provide a corresponding section.
BNODE <count> <variable> [<class>] <prompt>
Assigns a fresh blank node the the variable. If [<class>] is given
and a corresponding section exists, the user is given the choice
to construct information about the blank node according to the
section.
INSERT {
<quads>
}
Lists the tripples to be inserted into the graph. The syntax of
<quads> is the same as Quads in the SPARQL syntax. If a section
does not contains an INSERT instruction, it will not add any
triples. This is still useful if it calls other sections to
construct.
Example:
NS wf: http://www.w3.org/2005/01/wf/flow#
[wf:Open] ?task An open task
RESOURCE 1 ?tracker [wf:Tracker] tracked by
INSERT {
?task a wf:Open .
?task wf:tracker ?tracker .
}
[wf:Tracker] ?tracker Tracker
LITERAL 1 ?description Description
INSERT {
?tracker a wf:Tracker .
?tracker wf:description ?description .
}
'''
)
argparser.add_argument('template', nargs='?',
help='Construct according to template given in FILE')
argparser.add_argument('-o', '--output', metavar='FILE', dest='outfile', nargs=1,
help=('File the graph should be written to. If omitted, it will be written to STDOUT.'))
argparser.add_argument('-s', '--section', dest='section', metavar='SECTION',
help='Choose section to use. BY default, the first one from the template file is used')
args = argparser.parse_args()
print("""Available commands:
! CMD
Executes CMD in a shell
| CMD
Executes CMD in a shell and takes output as value
@
Same as `| know edit --null`
""", file=sys.stderr)
if args.outfile:
dest = open(args.outfile, mode='wb')
else:
dest = sys.stdout.buffer
sys.stdout = sys.stderr
g = Graph()
parser = Parser(lambda: TerminalSection(sys.stderr))
template = open(args.template, mode='r')
lineiter = iter(template.readline, '')
(sections, firstsection) = parser.parse(lineiter)
if args.section:
try:
name = firstsection.expand(args.section)
firstsection = sections[name]
except PrefixNotFound:
print("Prefix used in section name not defined", file=sys.stderr)
exit(1)
except KeyError:
print("Section not found", file=sys.stderr)
exit(1)
except NotPName:
print("Invalid section name given at command line", file=sys.stderr)
exit(1)
firstsection.construct(g, sections)
g.serialize(dest, format=DEFAULT_FORMAT)