diff --git a/src/mmt-api/resources/mmt-web/stex/queries.html b/src/mmt-api/resources/mmt-web/stex/queries.html
new file mode 100644
index 0000000000..24a86da88c
--- /dev/null
+++ b/src/mmt-api/resources/mmt-web/stex/queries.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
sTeX Queries
+
+
Queries:
+
+
+
+
+
Custom SPARQL Query:(See
here for the ontology used)
+
+
+
+
Result:
+
{{n.short}}
{{n.long}}
+
+
+
\ No newline at end of file
diff --git a/src/mmt-api/resources/mmt-web/stex/queries.js b/src/mmt-api/resources/mmt-web/stex/queries.js
new file mode 100644
index 0000000000..af0834b166
--- /dev/null
+++ b/src/mmt-api/resources/mmt-web/stex/queries.js
@@ -0,0 +1,42 @@
+angular.module('QueryApp', []).controller('QueryViewer', [ '$scope', '$http', function($scope, $http) {
+
+
+
+ $scope.query_test = function() {
+ document.getElementById("query_return").innerHTML = "Loading...";
+ $http.get('/:sTeX/query/test').success(function(data) {
+ document.getElementById("query_return").innerHTML = JSON.stringify(data,null,2);
+ });
+ };
+
+
+
+ $scope.query_all = function() {
+ document.getElementById("query_return").innerHTML = "Loading...";
+ $http.get('/:sTeX/query/all').success(function(data) {
+ document.getElementById("query_return").innerHTML = JSON.stringify(data,null,2);
+ });
+ };
+ $scope.query_all_undefined = function() {
+ document.getElementById("query_return").innerHTML = "Loading...";
+ $http.get('/:sTeX/query/all_undefined').success(function(data) {
+ document.getElementById("query_return").innerHTML = JSON.stringify(data,null,2);
+ });
+ };
+ $scope.query_all_with_data = function() {
+ document.getElementById("query_return").innerHTML = "Loading...";
+ $http.get('/:sTeX/query/all_with_data').success(function(data) {
+ document.getElementById("query_return").innerHTML = JSON.stringify(data,null,2);
+ });
+ };
+ $scope.do_query = function(s) {
+ document.getElementById("query_return").innerHTML = "Loading...";
+ $http.post('/:query/sparql',s).success(function(data) {
+ document.getElementById("query_return").innerHTML = JSON.stringify(data,null,2);
+ });
+ };
+ $scope.queryString ="SELECT ?x WHERE { \n (|||)+ ?x .\n ?x .\n}";
+ $scope.query_custom = function() {
+ $scope.do_query($scope.queryString)
+ };
+}]);
\ No newline at end of file
diff --git a/src/mmt-api/src/main/info/kwarc/mmt/api/ontology/ULO.scala b/src/mmt-api/src/main/info/kwarc/mmt/api/ontology/ULO.scala
index f911e6fdbc..81a478d37a 100644
--- a/src/mmt-api/src/main/info/kwarc/mmt/api/ontology/ULO.scala
+++ b/src/mmt-api/src/main/info/kwarc/mmt/api/ontology/ULO.scala
@@ -592,8 +592,8 @@ object ULO {
object RDFStore {
val memory = URI.scheme("mmt") colon "memory"
- def archive(id:String) = iri(memory.toString + "/archive#" + id)
- def archiveId(iri: IRI) = if (iri.getNamespace == memory.toString + "/archive") {
+ def archive(id:String) = iri(memory.toString + "archive#" + id)
+ def archiveId(iri: IRI) = if (iri.getNamespace == memory.toString + "archive") {
Some(iri.getLocalName)
} else None
import org.eclipse.rdf4j.rio.RDFFormat
@@ -976,7 +976,10 @@ object SPARQL {
sealed trait Object {
def toObjString : String
}
- sealed trait Subject extends this.Object
+ sealed trait SubjectT extends this.Object
+ case class Subject(s:String) extends SubjectT {
+ def toObjString = "<" + s + ">"
+ }
private case class Trans(p:Predicate) extends Predicate {
def predString: String = p.predString + "+"
@@ -998,17 +1001,17 @@ object SPARQL {
}
implicit def asPred(u:ULOPredicate): Predicate = UloPred(u)
- private case class PathO(p:Path) extends Subject {
+ private case class PathO(p:Path) extends SubjectT {
override def toObjString: String = "<" + pathToIri(p).toString + ">"
}
private case class IriO(i:IRI) extends Object {
override def toObjString: String = "<" + i.toString + ">"
}
- case class V(s:String) extends Subject with Predicate {
+ case class V(s:String) extends SubjectT with Predicate {
def toObjString = s"?$s"
def predString: String = s"?$s"
}
- implicit def pathtosubject(p:Path): Subject = PathO(p)
+ implicit def pathtosubject(p:Path): SubjectT = PathO(p)
implicit def classtoobject(p: ULOClass): Object = IriO(p.toIri)
private case class SelectWhere(vars:List[String],where:SparqlQuery) extends SparqlQuery {
@@ -1018,10 +1021,10 @@ object SPARQL {
def WHERE(q : SparqlQuery): SparqlQuery = SelectWhere(`var`.toList,q)
}
import org.eclipse.rdf4j.sparqlbuilder.core.query.Queries._
- case class T(subject: Subject,predicate: this.Predicate,`object`:this.Object) extends SparqlQuery {
+ case class T(subject: SubjectT, predicate: this.Predicate, `object`:this.Object) extends SparqlQuery {
def queryString: String = s"${subject.toObjString} ${predicate.predString} ${`object`.toObjString} ."
}
- case class HASTYPE(subject: Subject,`object`:this.Object) extends SparqlQuery {
+ case class HASTYPE(subject: SubjectT, `object`:this.Object) extends SparqlQuery {
override def queryString: String = s"${subject.toObjString} ${`object`.toObjString} ."
}
diff --git a/src/mmt-stex/src/info/kwarc/mmt/stex/Extensions/QueryExtension.scala b/src/mmt-stex/src/info/kwarc/mmt/stex/Extensions/QueryExtension.scala
new file mode 100644
index 0000000000..24cf4c873d
--- /dev/null
+++ b/src/mmt-stex/src/info/kwarc/mmt/stex/Extensions/QueryExtension.scala
@@ -0,0 +1,83 @@
+package info.kwarc.mmt.stex.Extensions
+
+import info.kwarc.mmt.api.{GlobalName, Path}
+import info.kwarc.mmt.api.ontology.SPARQL.T
+import info.kwarc.mmt.api.ontology.ULO
+import info.kwarc.mmt.api.utils.{JSONArray, JSONNull, JSONObject, JSONString}
+import info.kwarc.mmt.api.web.ServerResponse.{JsonResponse, ResourceResponse}
+import info.kwarc.mmt.api.web.{ServerRequest, ServerResponse}
+import info.kwarc.mmt.stex.STeXServer
+
+trait QueryExtension { this : STeXServer =>
+ protected def queryRequest(request: ServerRequest): ServerResponse = {
+ request.path.lastOption match {
+ case Some("all") =>
+ JsonResponse(JSONArray(getAll.map(p => JSONString(p.toString)) :_*))
+ case Some("all_undefined") =>
+ JsonResponse(JSONArray(undefineds.map(p => JSONString(p.toString)): _*))
+ case Some("all_with_data") =>
+ JsonResponse(JSONArray(symbols_with_stuff.map(p =>
+ JSONObject(
+ ("path", JSONString(p._1.toString)),
+ ("macro", p._2.map(s => JSONString("\\" + s)).getOrElse(JSONNull)),
+ //("notations", JSONArray(p._3.map(JSONString): _*))
+ )):_*))
+ case Some("test") =>
+ JsonResponse(JSONArray(test.map(p => JSONString(p.toString)): _*))
+ case _ =>
+ ResourceResponse("stex/queries.html")
+ }
+ }
+
+ private lazy val archives = controller.backend.getArchives.filter { a =>
+ a.properties.get("format").contains("stex")
+ }
+
+ private lazy val getAll: List[Path] = { // TODO hacky; should be more systematic
+ archives.flatMap(a => {
+ import info.kwarc.mmt.api.ontology.SPARQL._
+ controller.depstore.query(
+ SELECT("x") WHERE (
+ (
+ T(Subject(s"mmt://memory/archive#${a.id}"), ULO.contains, V("y")) UNION
+ T(Subject(s"mmt://memory//archive#${a.id}"), ULO.contains, V("y"))
+ ) AND
+ T(V("y"),(ULO.contains | ULO.declares | ULO.specifies)+,V("x")) AND
+ HASTYPE(V("x"),ULO.constant)
+ )
+ ).getPaths.filter(p => !p.asInstanceOf[GlobalName].module.parent.last.endsWith(".omdoc"))
+ })
+ }
+
+ private def symbols_with_stuff: List[(Path,Option[String])] = {
+ getAll.map{p =>
+ (p,
+ controller.getO(p).flatMap(SHTMLContentManagement.getMacroName),
+ //SHTMLContentManagement.getNotations(p.asInstanceOf[GlobalName])(controller).map{n => n.notation.toString}
+ )
+ }
+ }
+
+ private def undefineds: List[Path] = {
+ getAll.filter{p =>
+ import info.kwarc.mmt.api.ontology.SPARQL._
+ controller.depstore.query(
+ SELECT("x") WHERE (
+ T(p,ULO.docref,V("x")) UNION T(V("x"),ULO.defines,p)
+ )
+ ).getPaths.isEmpty
+ }
+ }
+
+ private def test: List[Path] = {
+ archives.flatMap(a => {
+ import info.kwarc.mmt.api.ontology.SPARQL._
+ controller.depstore.query(
+ SELECT("x") WHERE (
+ T(Subject(s"mmt://memory/archive#${a.id}"), ULO.contains, V("x")) UNION
+ T(Subject(s"mmt://memory//archive#${a.id}"), ULO.contains, V("x"))
+ )
+ ).getPaths
+ })
+ }
+}
diff --git a/src/mmt-stex/src/info/kwarc/mmt/stex/STeXServer.scala b/src/mmt-stex/src/info/kwarc/mmt/stex/STeXServer.scala
index e7250c275d..157f218e69 100644
--- a/src/mmt-stex/src/info/kwarc/mmt/stex/STeXServer.scala
+++ b/src/mmt-stex/src/info/kwarc/mmt/stex/STeXServer.scala
@@ -8,7 +8,7 @@ import info.kwarc.mmt.api.presentation.Presenter
import info.kwarc.mmt.api.utils.time.Time
import info.kwarc.mmt.api.utils.{File, FilePath, JSON, JSONArray, JSONObject, JSONString, MMTSystem, XMLEscaping}
import info.kwarc.mmt.api.web.{ServerExtension, ServerRequest, ServerResponse}
-import info.kwarc.mmt.stex.Extensions.{Definienda, ExportExtension, FrontendExtension, NotationExtractor, OMDocHTML, OMDocSHTMLRules, SHTMLBrowser, SHTMLContentManagement, SHTMLDocumentServer, STeXRelationals}
+import info.kwarc.mmt.stex.Extensions.{Definienda, ExportExtension, FrontendExtension, NotationExtractor, OMDocHTML, OMDocSHTMLRules, QueryExtension, SHTMLBrowser, SHTMLContentManagement, SHTMLDocumentServer, STeXRelationals}
import info.kwarc.mmt.stex.lsp.{MathHubServer, RemoteLSP, STeXLSPServer, SearchResultServer}
import info.kwarc.mmt.stex.rules.MathStructureFeature
import info.kwarc.mmt.stex.vollki.{FullsTeXGraph, JupyterBookArchive, VirtualArchive, VollKi}
@@ -24,7 +24,8 @@ case class ErrorReturn(s : String) extends Throwable {
}
-class STeXServer extends ServerExtension("sTeX") with OMDocSHTMLRules with SHTMLDocumentServer with SHTMLBrowser with OMDocHTML with ExportExtension with FrontendExtension {
+class STeXServer extends ServerExtension("sTeX") with OMDocSHTMLRules with SHTMLDocumentServer with SHTMLBrowser
+ with OMDocHTML with ExportExtension with FrontendExtension with QueryExtension {
def ctrl = controller
def getArchives = controller.backend.getStores.collect {
case a : Archive if a.properties.get("format").contains("stex") => a
@@ -101,6 +102,7 @@ class STeXServer extends ServerExtension("sTeX") with OMDocSHTMLRules with SHTML
lazy val htmlpres = new MMTsTeXPresenter(texPresenter,xhtmlPresenter)
override def apply(request: ServerRequest): ServerResponse = try {
+ if (request.path.startsWith(List(":sTeX","query"))) return queryRequest(request.copy(path=request.path.drop(2)))
request.path.lastOption match {
case Some("document" | "pdf" | "fullhtml" | "documentTop" | "fulldocument" | "fragment" | "rawfragment" | "symbol" | "declaration" |
"variable" | "css" | "sections" | "definienda" | "lo" | "loraw") =>