Complete redo of content indexing and querying (#517)
Complete redo of data store Introduces live queries and live templates
This commit is contained in:
@@ -22,5 +22,5 @@ export const AttributeNameTag = Tag.define();
|
||||
export const AttributeValueTag = Tag.define();
|
||||
|
||||
export const TaskTag = Tag.define();
|
||||
export const TaskMarkerTag = Tag.define();
|
||||
export const TaskMarkTag = Tag.define();
|
||||
export const TaskStateTag = Tag.define();
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
@top Program { Expression }
|
||||
|
||||
@precedence {
|
||||
mulop @left
|
||||
addop @left
|
||||
binop @left
|
||||
and @left
|
||||
or @left
|
||||
}
|
||||
|
||||
@skip {
|
||||
space
|
||||
}
|
||||
|
||||
commaSep<content> { content ("," content)* }
|
||||
|
||||
kw<term> { @specialize[@name={term}]<Identifier, term> }
|
||||
|
||||
|
||||
Query {
|
||||
TagIdentifier ( WhereClause | LimitClause | OrderClause | SelectClause | RenderClause )*
|
||||
}
|
||||
|
||||
WhereClause { kw<"where"> Expression }
|
||||
LimitClause { kw<"limit"> Expression }
|
||||
OrderClause { Order commaSep<OrderBy> }
|
||||
OrderBy { Expression OrderDirection? }
|
||||
SelectClause { kw<"select"> commaSep<Select> }
|
||||
RenderClause { kw<"render"> PageRef }
|
||||
|
||||
Select { Identifier | Expression kw<"as"> Identifier }
|
||||
|
||||
OrderDirection {
|
||||
OrderKW
|
||||
}
|
||||
|
||||
Value { Number | String | Bool | Regex | kw<"null"> | List }
|
||||
|
||||
Attribute {
|
||||
LVal "." Identifier
|
||||
}
|
||||
|
||||
Call {
|
||||
Identifier "(" commaSep<Expression> ")" | Identifier "(" ")"
|
||||
}
|
||||
|
||||
LVal {
|
||||
Identifier
|
||||
| Attribute
|
||||
}
|
||||
|
||||
ParenthesizedExpression { "(" Expression ")" }
|
||||
|
||||
LogicalExpression {
|
||||
Expression !and kw<"and"> Expression
|
||||
| Expression !or kw<"or"> Expression
|
||||
}
|
||||
|
||||
Expression {
|
||||
Value
|
||||
| LVal
|
||||
| ParenthesizedExpression
|
||||
| LogicalExpression
|
||||
| BinExpression
|
||||
| Call
|
||||
}
|
||||
|
||||
BinExpression {
|
||||
Expression !binop "<" Expression
|
||||
| Expression !binop "<=" Expression
|
||||
| Expression !binop "=" Expression
|
||||
| Expression !binop "!=" Expression
|
||||
| Expression !binop ">=" Expression
|
||||
| Expression !binop ">" Expression
|
||||
| Expression !binop "=~" Expression
|
||||
| Expression !binop "!=~" Expression
|
||||
| Expression !binop InKW Expression
|
||||
|
||||
| Expression !mulop "*" Expression
|
||||
| Expression !mulop "/" Expression
|
||||
| Expression !mulop "%" Expression
|
||||
| Expression !addop "+" Expression
|
||||
| Expression !addop "-" Expression
|
||||
}
|
||||
|
||||
List { "[" commaSep<Expression> "]" }
|
||||
|
||||
|
||||
Bool {
|
||||
BooleanKW
|
||||
}
|
||||
|
||||
|
||||
@tokens {
|
||||
space { std.whitespace+ }
|
||||
|
||||
TagIdentifier { @asciiLetter (@asciiLetter | @digit | "-" | "_" | "/" )* }
|
||||
|
||||
Identifier { @asciiLetter (@asciiLetter | @digit | "-" | "_")* }
|
||||
|
||||
String {
|
||||
("\"" | "“" | "”") ![\"”“]* ("\"" | "“" | "”")
|
||||
}
|
||||
PageRef {
|
||||
"[" "[" ![\]]* "]" "]"
|
||||
}
|
||||
Order { "order by" }
|
||||
Regex { "/" ( ![/\\\n\r] | "\\" _ )* "/"? }
|
||||
|
||||
Number { std.digit+ }
|
||||
|
||||
BooleanKW { "true" | "false" }
|
||||
|
||||
InKW { "in" }
|
||||
|
||||
OrderKW { "asc" | "desc" }
|
||||
|
||||
@precedence { Order, BooleanKW, InKW, OrderKW, Identifier, Number }
|
||||
}
|
||||
@@ -23,9 +23,9 @@ class MultiStatusTaskParser implements LeafBlockParser {
|
||||
leaf,
|
||||
cx.elt("Task", leaf.start, leaf.start + leaf.content.length, [
|
||||
cx.elt("TaskState", leaf.start, leaf.start + 2 + this.status.length, [
|
||||
cx.elt("TaskMarker", leaf.start, leaf.start + 1),
|
||||
cx.elt("TaskMark", leaf.start, leaf.start + 1),
|
||||
cx.elt(
|
||||
"TaskMarker",
|
||||
"TaskMark",
|
||||
leaf.start + 1 + this.status.length,
|
||||
leaf.start + 2 + this.status.length,
|
||||
),
|
||||
@@ -43,7 +43,7 @@ class MultiStatusTaskParser implements LeafBlockParser {
|
||||
export const TaskList: MarkdownConfig = {
|
||||
defineNodes: [
|
||||
{ name: "Task", block: true, style: t.list },
|
||||
{ name: "TaskMarker", style: t.atom },
|
||||
{ name: "TaskMark", style: t.atom },
|
||||
{ name: "TaskState", style: TaskStateTag },
|
||||
],
|
||||
parseBlock: [{
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
||||
import {LRParser} from "@lezer/lr"
|
||||
const spec_Identifier = {__proto__:null,null:20, and:32, or:34}
|
||||
export const parser = LRParser.deserialize({
|
||||
version: 14,
|
||||
states: "%jOVQPOOOOQO'#Cb'#CbOVQPO'#CgOOQO'#C_'#C_OqQQO'#C^O#UQQO'#ChOOQO'#Ch'#ChOVQPO'#CjQ$lQQOOOOQO'#C^'#C^O%pQQO'#CvO%}QPO,59RO&SQPO,59TO&XQPO,59[O&`QQO,59UOVQPO,59YOVQPO,59YOVQPO,59YOVQPO,59VOVQPO,59VOVQPO'#CqO&gQPO,59bOOQO1G.m1G.mOOQO1G.o1G.oO&rQPO1G.vOOQO1G.v1G.vOOQO1G.p1G.pO(RQQO1G.tOOQO1G.t1G.tO(]QQO1G.tO)tQQO1G.qO){QQO1G.qO*SQQO,59]OOQO-E6o-E6oOOQO7+$b7+$b",
|
||||
stateData: "*g~OhOS~OSROTROVPOWROXTOYROiQOnVO~Om[O`QXaQXcQXfQXpQXqQXrQXsQXtQXuQXvQXwQXxQXyQXzQX{QX|QXkQXlQXoQX~On]O`[Xa[Xc[Xf[Xm[Xp[Xq[Xr[Xs[Xt[Xu[Xv[Xw[Xx[Xy[Xz[X{[X|[Xk[Xl[Xo[X~O`bOacOc_Op_Oq_Or_Os_Ot_Ou_Ov_Ow_Ox`Oy`Oz`O{aO|aO~OkdOljXojX~P$lOlfO~OXgO~OoiO~PVOojO~P$lOkdOljaoja~OorO~Ox`Oy`Oz`O`biabicbifbipbiqbirbisbitbiubivbiwbikbilbiobi~O{aO|aO~P&wO{bi|bi~P&wOc_Op_Oq_Or_Os_Ot_Ou_Ov_Ow_Ox`Oy`Oz`O{aO|aOa_if_ik_il_io_i~O`_i~P(gO`bO~P(gOkealeaoea~P$lOVcXSX~",
|
||||
goto: "#hkPPl!YPP!fPPPP!f!r#O!Y!YPP!YP!Y#[PPPP#bQWOSYQ]Q^VQk_Ql`QmaQnbQocRpdeXOQV]_`abcdeROQV]_`abcdeSOQV]_`abcdeUOQV]_`abcdQeYRqeQZQRh]",
|
||||
nodeNames: "⚠ Program Expression Value Number String Bool BooleanKW Regex Identifier null List LVal Attribute ParenthesizedExpression LogicalExpression and or BinExpression InKW Call",
|
||||
maxTerm: 44,
|
||||
skippedNodes: [0],
|
||||
repeatNodeCount: 1,
|
||||
tokenData: "/j~RuX^#fpq#fqr$Zrs$nuv%fxy%kyz%pz{%u{|%z|}&P}!O&U!O!P&Z!P!Q&`!Q![)Q!^!_)Y!_!`)g!`!a)t!c!}*R!}#O*g#P#Q*l#T#Y*R#Y#Z*q#Z#]*R#]#^-b#^#h*R#h#i.d#i#o*R#y#z#f$f$g#f#BY#BZ#f$IS$I_#f$Ip$Iq$n$Iq$Ir$n$I|$JO#f$JT$JU#f$KV$KW#f&FU&FV#f~#kYh~X^#fpq#f#y#z#f$f$g#f#BY#BZ#f$IS$I_#f$I|$JO#f$JT$JU#f$KV$KW#f&FU&FV#f~$^P!_!`$a~$fPs~#r#s$i~$nOw~~$qWOr$nrs%Zs$Ip$n$Ip$Iq%Z$Iq$Ir%Z$Ir;'S$n;'S;=`%`<%lO$n~%`OT~~%cP;=`<%l$n~%kOz~~%pOn~~%uOo~~%zOx~~&PO{~~&UOk~~&ZO|~~&`Om~R&gXyQWPOY'SZ]'S^!P'S!P!Q't!Q#O'S#O#P'y#P;'S'S;'S;=`(z<%lO'SP'XXWPOY'SZ]'S^!P'S!P!Q't!Q#O'S#O#P'y#P;'S'S;'S;=`(z<%lO'SP'yOWPP'|RO;'S'S;'S;=`(V;=`O'SP([YWPOY'SZ]'S^!P'S!P!Q't!Q#O'S#O#P'y#P;'S'S;'S;=`(z;=`<%l'S<%lO'SP(}P;=`<%l'S~)VPS~!Q![)Q~)_Pp~!_!`)b~)gOq~~)lPr~#r#s)o~)tOv~~)yPu~!_!`)|~*ROt~~*WTX~}!O*R!Q![*R!c!}*R#R#S*R#T#o*R~*lOi~~*qOl~~*vUX~}!O*R!Q![*R!c!}*R#R#S*R#T#U+Y#U#o*R~+_VX~}!O*R!Q![*R!c!}*R#R#S*R#T#`*R#`#a+t#a#o*R~+yVX~}!O*R!Q![*R!c!}*R#R#S*R#T#g*R#g#h,`#h#o*R~,eVX~}!O*R!Q![*R!c!}*R#R#S*R#T#X*R#X#Y,z#Y#o*R~-RTV~X~}!O*R!Q![*R!c!}*R#R#S*R#T#o*R~-gVX~}!O*R!Q![*R!c!}*R#R#S*R#T#b*R#b#c-|#c#o*R~.TTc~X~}!O*R!Q![*R!c!}*R#R#S*R#T#o*R~.iVX~}!O*R!Q![*R!c!}*R#R#S*R#T#f*R#f#g/O#g#o*R~/TVX~}!O*R!Q![*R!c!}*R#R#S*R#T#i*R#i#j,`#j#o*R",
|
||||
tokenizers: [0, 1],
|
||||
topRules: {"Program":[0,1]},
|
||||
specialized: [{term: 9, get: value => spec_Identifier[value] || -1}],
|
||||
tokenPrec: 431
|
||||
})
|
||||
@@ -0,0 +1,19 @@
|
||||
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
||||
export const
|
||||
Program = 1,
|
||||
Expression = 2,
|
||||
Value = 3,
|
||||
Number = 4,
|
||||
String = 5,
|
||||
Bool = 6,
|
||||
BooleanKW = 7,
|
||||
Regex = 8,
|
||||
Identifier = 9,
|
||||
List = 11,
|
||||
LVal = 12,
|
||||
Attribute = 13,
|
||||
ParenthesizedExpression = 14,
|
||||
LogicalExpression = 15,
|
||||
BinExpression = 18,
|
||||
InKW = 19,
|
||||
Call = 20
|
||||
@@ -1,16 +1,18 @@
|
||||
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
||||
import {LRParser} from "@lezer/lr"
|
||||
const spec_Identifier = {__proto__:null,where:12, null:28, and:40, or:42, limit:52, select:66, as:70, render:74}
|
||||
export const parser = LRParser.deserialize({
|
||||
version: 14,
|
||||
states: "&`OVQPOOOmQQO'#C^QOQPOOOtQPO'#C`OyQPO'#ClO!OQPO'#CnO!TQPO'#CqO!YQPO'#CsOOQO'#Cv'#CvO!bQQO,58xO!iQQO'#CcO#WQQO'#CbOOQO,58z,58zOOQO,59W,59WO#oQQO,59YO$ZQQO'#D`OOQO,59],59]OOQO,59_,59_OOQO-E6t-E6tO$rQQO,58}OtQPO'#CxO%ZQQO,58|OOQO'#Cp'#CpOOQO1G.t1G.tO%rQPO'#CyO%wQQO,59zOOQO'#Cg'#CgO$rQQO'#CjOOQO'#Cd'#CdOOQO1G.i1G.iOOQO,59d,59dOOQO-E6v-E6vOOQO,59e,59eOOQO-E6w-E6wO&`QPO'#DRO&hQPO,59UO$rQQO'#CwO&mQPO,59mOOQO1G.p1G.pOOQO,59c,59cOOQO-E6u-E6u",
|
||||
stateData: "&u~OpOS~ORPO~OTROaSOcTOfUOhVO~OnQX~P[ORYO~OX]O~OR^O~OR_O~OYaOiaO~OnQa~P[OqcOxcOycOzcO{cO|cO}cO!OcO!PcO~O_dOTUXaUXcUXfUXhUXnUX~O!QfO!RfOTbaabacbafbahbanba~OvhOT!SXa!SXc!SXf!SXh!SXn!SX~OXlOYlO[lO]lOrjOsjOtkO~O_dOTUaaUacUafUahUanUa~ORpO~OvhOT!Saa!Sac!Saf!Sah!San!Sa~OvtOwuX~OwvO~OvtOwua~O",
|
||||
goto: "#g!TPP!UP!XP!]!`!fPP!oPP!oP!XP!XP!t!XP!XPP!w!}#T#ZPPPPPPP#aPPPPPPPPPPPP#dRQOTWPXR[RQZRRndQmcQrkRwtVlcktRg^QXPRbXQurRxuQeZRoeQi_RqiRskR`U",
|
||||
nodeNames: "⚠ Program Query Name WhereClause Where LogicalExpr FilterExpr Value Number String Bool Regex Null List And LimitClause Limit OrderClause Order OrderDirection SelectClause Select RenderClause Render PageRef",
|
||||
maxTerm: 50,
|
||||
states: ")lOVQPOOOmQQO'#C^QOQPOOOtQQO'#CwOOQO'#DT'#DTO!`QQO,58xOtQQO'#C`OtQQO'#CuO!gQQO'#C|O#RQPO'#DQOOQO'#Cg'#CgOtQQO'#CkOOQO'#Cd'#CdO#WQSO'#CcO&_QSO'#ClOOQO'#Cl'#ClOtQQO'#CnO(VQSO'#CyOOQO'#Cc'#CcO(sQQO'#DpOOQO,59c,59cOOQO-E7R-E7RO)[QSO,58zO)rQSO,59aO*YQSO'#ClO*sQSO'#DOO*zQQO'#DqOOQO,59h,59hOOQO,59l,59lO+cQSO'#D]O+pQPO,59VO+uQQO,59XO+zQQO,59`O,RQSO,59YOtQQO,59^OtQQO,59^OtQQO,59^OOQO'#Cz'#CzOOQO,59e,59eOtQQO,59ZOtQQO,59ZOtQQO'#DVO,YQQO,5:[O,qQQO,59jO!gQQO'#DWO,vQQO,5:]OtQQO'#DUO-_QPO,59wOOQO1G.q1G.qOOQO1G.s1G.sO-jQPO1G.zOOQO1G.z1G.zOOQO1G.t1G.tO/`QSO1G.xOOQO1G.x1G.xO/jQSO1G.xO1hQSO1G.uO1oQSO1G.uOOQO,59q,59qOOQO-E7T-E7TOOQO1G/U1G/UOOQO,59r,59rOOQO-E7U-E7UO1vQSO,59pOOQO-E7S-E7SOOQO7+$f7+$f",
|
||||
stateData: "2]~O}OS~ORPO~OUUOjVOlROqWOuXO~O{QX~P[OT^OX[OY[O[YO][O^[O!OZO!T`O~O{Qa~P[OThOX[OY[O[YO][O^[O!OZO!T`O~OvlO~O!SoOUVXdVXeVXgVXjVXlVXoVXqVXuVX{VX!QVX!VVX!WVX!XVX!YVX!ZVX![VX!]VX!^VX!_VX!`VX!aVX!bVX!cVXsVX!RVX!UVX~O!TpOd`Xe`Xg`X!S`X!V`X!W`X!X`X!Y`X!Z`X![`X!]`X!^`X!_`X!``X!a`X!b`X!c`Xs`X~OU`Xj`Xl`Xo`Xq`Xu`X{`X!Q`X!R`X!U`X~P%QOdwOexOgrO!VrO!WrO!XrO!YrO!ZrO![rO!]rO!^rO!_sO!`sO!asO!btO!ctO~OouOUmXjmXlmXqmXumX{mX!QmX~P'RO!QyOU!dXj!dXl!dXq!dXu!dX{!dX~OUSajSalSaqSauSa{Sa~P'ROUiajialiaqiauia{ia~P'ROUrXjrXlrXqrXurX{rX!QrX~P%QOs{O~P'RO!Q|OU!eXj!eXl!eXq!eXu!eX{!eX~O!Q!OO!R!PX!U!PX~P'RO!R!QO~OT!RO~O!U!TO~PtO!U!UO~P'RO!QyOU!daj!dal!daq!dau!da{!da~OT!^O~O!Q|OU!eaj!eal!eaq!eau!ea{!ea~O!Q!OO!R!Pa!U!Pa~O!U!cO~O!_sO!`sO!asOUfidfiefigfijfilfiofiqfiufi{fi!Qfi!Vfi!Wfi!Xfi!Yfi!Zfi![fi!]fi!^fisfi!Rfi!Ufi~O!btO!ctO~P-oO!bfi!cfi~P-oOgrO!VrO!WrO!XrO!YrO!ZrO![rO!]rO!^rO!_sO!`sO!asO!btO!ctOUciecijcilciociqciuci{ci!Qcisci!Rci!Uci~Odci~P/tOdwO~P/tO!Qxa!Rxa!Uxa~P'ROl[goTXo~",
|
||||
goto: "&S!fPP!gP!jPP!n#gPP#xPPP#x$Z$l#g#gPP#gP#g!jP!jP$}%TP!jP%WP!jPP%^%d%j%pPPPP%vPPPPPPPPPPPPPPPPPP%|&PRQOTSPTSaRyQfUQgVSiW|SmZpQq`Q!VrQ!WsQ!XtQ!YwQ!ZxR!a!OobRUVWZ`prstwxy|!Oo[RUVWZ`prstwxy|!Oo]RUVWZ`prstwxy|!Oo_RUVWZ`prstwxy|!OQcRR![yRvaQjWR!_|QTPReTQ!PmR!b!PQzcR!]zQ}jR!`}QnZR!SpRdRRkW",
|
||||
nodeNames: "⚠ Program Query TagIdentifier WhereClause Identifier where Expression Value Number String Bool BooleanKW Regex null List LVal Attribute ParenthesizedExpression LogicalExpression and or BinExpression InKW Call LimitClause limit OrderClause Order OrderBy OrderDirection OrderKW SelectClause select Select as RenderClause render PageRef",
|
||||
maxTerm: 67,
|
||||
skippedNodes: [0],
|
||||
repeatNodeCount: 4,
|
||||
tokenData: "C`~R|X^#{pq#{qr$prs%T|}%{}!O&Q!P!Q&c!Q![(a!^!_(i!_!`(v!`!a)T!c!}&Q!}#O)b#P#Q*_#R#S&Q#T#U*d#U#W&Q#W#X,y#X#Y&Q#Y#Z.u#Z#]&Q#]#^1V#^#`&Q#`#a2R#a#b&Q#b#c4f#c#d6b#d#f&Q#f#g9X#g#h<T#h#i?P#i#k&Q#k#l@{#l#o&Q#y#z#{$f$g#{#BY#BZ#{$IS$I_#{$Ip$Iq%T$Iq$Ir%T$I|$JO#{$JT$JU#{$KV$KW#{&FU&FV#{~$QYp~X^#{pq#{#y#z#{$f$g#{#BY#BZ#{$IS$I_#{$I|$JO#{$JT$JU#{$KV$KW#{&FU&FV#{~$sP!_!`$v~${Pz~#r#s%O~%TO!O~~%WWOr%Trs%ps$Ip%T$Ip$Iq%p$Iq$Ir%p$Ir;'S%T;'S;=`%u<%lO%T~%uOY~~%xP;=`<%l%T~&QOv~P&VSRP}!O&Q!c!}&Q#R#S&Q#T#o&Q~&hX[~OY&cZ]&c^!P&c!P!Q'T!Q#O&c#O#P'Y#P;'S&c;'S;=`(Z<%lO&c~'YO[~~']RO;'S&c;'S;=`'f;=`O&c~'kY[~OY&cZ]&c^!P&c!P!Q'T!Q#O&c#O#P'Y#P;'S&c;'S;=`(Z;=`<%l&c<%lO&c~(^P;=`<%l&c~(fPX~!Q![(a~(nPq~!_!`(q~(vOx~~({Py~#r#s)O~)TO}~~)YP|~!_!`)]~)bO{~R)gPtQ!}#O)jP)mTO#P)j#P#Q)|#Q;'S)j;'S;=`*X<%lO)jP*PP#P#Q*SP*XOiPP*[P;=`<%l)j~*dOw~R*iWRP}!O&Q!c!}&Q#R#S&Q#T#b&Q#b#c+R#c#g&Q#g#h+}#h#o&QR+WURP}!O&Q!c!}&Q#R#S&Q#T#W&Q#W#X+j#X#o&QR+qS_QRP}!O&Q!c!}&Q#R#S&Q#T#o&QR,SURP}!O&Q!c!}&Q#R#S&Q#T#V&Q#V#W,f#W#o&QR,mS!RQRP}!O&Q!c!}&Q#R#S&Q#T#o&QR-OURP}!O&Q!c!}&Q#R#S&Q#T#X&Q#X#Y-b#Y#o&QR-gURP}!O&Q!c!}&Q#R#S&Q#T#g&Q#g#h-y#h#o&QR.OURP}!O&Q!c!}&Q#R#S&Q#T#V&Q#V#W.b#W#o&QR.iS!QQRP}!O&Q!c!}&Q#R#S&Q#T#o&QR.zTRP}!O&Q!c!}&Q#R#S&Q#T#U/Z#U#o&QR/`URP}!O&Q!c!}&Q#R#S&Q#T#`&Q#`#a/r#a#o&QR/wURP}!O&Q!c!}&Q#R#S&Q#T#g&Q#g#h0Z#h#o&QR0`URP}!O&Q!c!}&Q#R#S&Q#T#X&Q#X#Y0r#Y#o&QR0ySsQRP}!O&Q!c!}&Q#R#S&Q#T#o&QR1[URP}!O&Q!c!}&Q#R#S&Q#T#b&Q#b#c1n#c#o&QR1uS!PQRP}!O&Q!c!}&Q#R#S&Q#T#o&QR2WURP}!O&Q!c!}&Q#R#S&Q#T#]&Q#]#^2j#^#o&QR2oURP}!O&Q!c!}&Q#R#S&Q#T#a&Q#a#b3R#b#o&QR3WURP}!O&Q!c!}&Q#R#S&Q#T#]&Q#]#^3j#^#o&QR3oURP}!O&Q!c!}&Q#R#S&Q#T#h&Q#h#i4R#i#o&QR4YSaQRP}!O&Q!c!}&Q#R#S&Q#T#o&QR4kURP}!O&Q!c!}&Q#R#S&Q#T#i&Q#i#j4}#j#o&QR5SURP}!O&Q!c!}&Q#R#S&Q#T#`&Q#`#a5f#a#o&QR5kURP}!O&Q!c!}&Q#R#S&Q#T#`&Q#`#a5}#a#o&QR6USRP]Q}!O&Q!c!}&Q#R#S&Q#T#o&QR6gURP}!O&Q!c!}&Q#R#S&Q#T#f&Q#f#g6y#g#o&QR7OURP}!O&Q!c!}&Q#R#S&Q#T#W&Q#W#X7b#X#o&QR7gURP}!O&Q!c!}&Q#R#S&Q#T#X&Q#X#Y7y#Y#o&QR8OURP}!O&Q!c!}&Q#R#S&Q#T#f&Q#f#g8b#g#o&QR8gTRPpq8v}!O&Q!c!}&Q#R#S&Q#T#o&QQ8yP#U#V8|Q9PP#m#n9SQ9XOcQR9^URP}!O&Q!c!}&Q#R#S&Q#T#X&Q#X#Y9p#Y#o&QR9uURP}!O&Q!c!}&Q#R#S&Q#T#b&Q#b#c:X#c#o&QR:^URP}!O&Q!c!}&Q#R#S&Q#T#W&Q#W#X:p#X#o&QR:uURP}!O&Q!c!}&Q#R#S&Q#T#X&Q#X#Y;X#Y#o&QR;^URP}!O&Q!c!}&Q#R#S&Q#T#f&Q#f#g;p#g#o&QR;wSRPhQ}!O&Q!c!}&Q#R#S&Q#T#o&QR<YURP}!O&Q!c!}&Q#R#S&Q#T#X&Q#X#Y<l#Y#o&QR<qURP}!O&Q!c!}&Q#R#S&Q#T#`&Q#`#a=T#a#o&QR=YURP}!O&Q!c!}&Q#R#S&Q#T#X&Q#X#Y=l#Y#o&QR=qURP}!O&Q!c!}&Q#R#S&Q#T#V&Q#V#W>T#W#o&QR>YURP}!O&Q!c!}&Q#R#S&Q#T#h&Q#h#i>l#i#o&QR>sSRPfQ}!O&Q!c!}&Q#R#S&Q#T#o&QR?UURP}!O&Q!c!}&Q#R#S&Q#T#f&Q#f#g?h#g#o&QR?mURP}!O&Q!c!}&Q#R#S&Q#T#i&Q#i#j@P#j#o&QR@UURP}!O&Q!c!}&Q#R#S&Q#T#X&Q#X#Y@h#Y#o&QR@oSrQRP}!O&Q!c!}&Q#R#S&Q#T#o&QRAQURP}!O&Q!c!}&Q#R#S&Q#T#[&Q#[#]Ad#]#o&QRAiURP}!O&Q!c!}&Q#R#S&Q#T#X&Q#X#YA{#Y#o&QRBQURP}!O&Q!c!}&Q#R#S&Q#T#f&Q#f#gBd#g#o&QRBiURP}!O&Q!c!}&Q#R#S&Q#T#X&Q#X#YB{#Y#o&QRCSSRPTQ}!O&Q!c!}&Q#R#S&Q#T#o&Q",
|
||||
tokenizers: [0, 1],
|
||||
tokenData: "8k~RzX^#upq#uqr$jrs$}uv%uxy%zyz&Pz{&U{|&Z|}&`}!O&e!O!P&j!P!Q&o!Q![)a!^!_)i!_!`)v!`!a*T!c!}*b!}#O+d#P#Q,a#T#U,f#U#W*b#W#X.c#X#Y*b#Y#Z/S#Z#]*b#]#^2^#^#c*b#c#d3j#d#h*b#h#i7Z#i#o*b#y#z#u$f$g#u#BY#BZ#u$IS$I_#u$Ip$Iq$}$Iq$Ir$}$I|$JO#u$JT$JU#u$KV$KW#u&FU&FV#u~#zY}~X^#upq#u#y#z#u$f$g#u#BY#BZ#u$IS$I_#u$I|$JO#u$JT$JU#u$KV$KW#u&FU&FV#u~$mP!_!`$p~$uP!Y~#r#s$x~$}O!^~~%QWOr$}rs%js$Ip$}$Ip$Iq%j$Iq$Ir%j$Ir;'S$};'S;=`%o<%lO$}~%oOY~~%rP;=`<%l$}~%zO!a~~&PO!T~~&UO!U~~&ZO!_~~&`O!b~~&eO!Q~~&jO!c~~&oO!S~U&vX!`S]QOY'cZ]'c^!P'c!P!Q(T!Q#O'c#O#P(Y#P;'S'c;'S;=`)Z<%lO'cQ'hX]QOY'cZ]'c^!P'c!P!Q(T!Q#O'c#O#P(Y#P;'S'c;'S;=`)Z<%lO'cQ(YO]QQ(]RO;'S'c;'S;=`(f;=`O'cQ(kY]QOY'cZ]'c^!P'c!P!Q(T!Q#O'c#O#P(Y#P;'S'c;'S;=`)Z;=`<%l'c<%lO'cQ)^P;=`<%l'c~)fPX~!Q![)a~)nP!V~!_!`)q~)vO!W~~){P!X~#r#s*O~*TO!]~~*YP![~!_!`*]~*bO!Z~V*iURPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#o*bP+QURP}!O*{!P!Q*{!Q![*{!c!}*{#R#S*{#T#o*{R+iP!OQ!}#O+lP+oTO#P+l#P#Q,O#Q;'S+l;'S;=`,Z<%lO+lP,RP#P#Q,UP,ZOvPP,^P;=`<%l+l~,fO!R~V,mWRPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#g*b#g#h-V#h#o*bV-^WRPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#V*b#V#W-v#W#o*bV.PURPoSTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#o*bV.jWRPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#X*b#X#Y,f#Y#o*bV/ZVRPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#U/p#U#o*bV/wWRPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#`*b#`#a0a#a#o*bV0hWRPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#g*b#g#h1Q#h#o*bV1XWRPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#X*b#X#Y1q#Y#o*bV1zURP[QTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#o*bV2eWRPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#b*b#b#c2}#c#o*bV3WURPgSTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#o*bV3qWRPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#f*b#f#g4Z#g#o*bV4bWRPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#W*b#W#X4z#X#o*bV5RWRPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#X*b#X#Y5k#Y#o*bV5rWRPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#f*b#f#g6[#g#o*bV6cVRPTUpq6x}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#o*bU6{P#U#V7OU7RP#m#n7UU7ZOlUV7bWRPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#f*b#f#g7z#g#o*bV8RWRPTU}!O*b!P!Q*{!Q![*b!c!}*b#R#S*b#T#i*b#i#j1Q#j#o*b",
|
||||
tokenizers: [0, 1, 2],
|
||||
topRules: {"Program":[0,1]},
|
||||
tokenPrec: 0
|
||||
specialized: [{term: 5, get: value => spec_Identifier[value] || -1}],
|
||||
tokenPrec: 787
|
||||
})
|
||||
|
||||
@@ -2,26 +2,31 @@
|
||||
export const
|
||||
Program = 1,
|
||||
Query = 2,
|
||||
Name = 3,
|
||||
TagIdentifier = 3,
|
||||
WhereClause = 4,
|
||||
Where = 5,
|
||||
LogicalExpr = 6,
|
||||
FilterExpr = 7,
|
||||
Identifier = 5,
|
||||
Expression = 7,
|
||||
Value = 8,
|
||||
Number = 9,
|
||||
String = 10,
|
||||
Bool = 11,
|
||||
Regex = 12,
|
||||
Null = 13,
|
||||
List = 14,
|
||||
And = 15,
|
||||
LimitClause = 16,
|
||||
Limit = 17,
|
||||
OrderClause = 18,
|
||||
Order = 19,
|
||||
OrderDirection = 20,
|
||||
SelectClause = 21,
|
||||
Select = 22,
|
||||
RenderClause = 23,
|
||||
Render = 24,
|
||||
PageRef = 25
|
||||
BooleanKW = 12,
|
||||
Regex = 13,
|
||||
List = 15,
|
||||
LVal = 16,
|
||||
Attribute = 17,
|
||||
ParenthesizedExpression = 18,
|
||||
LogicalExpression = 19,
|
||||
BinExpression = 22,
|
||||
InKW = 23,
|
||||
Call = 24,
|
||||
LimitClause = 25,
|
||||
OrderClause = 27,
|
||||
Order = 28,
|
||||
OrderBy = 29,
|
||||
OrderDirection = 30,
|
||||
OrderKW = 31,
|
||||
SelectClause = 32,
|
||||
Select = 34,
|
||||
RenderClause = 36,
|
||||
PageRef = 38
|
||||
|
||||
@@ -73,23 +73,6 @@ Before
|
||||
End
|
||||
`;
|
||||
|
||||
Deno.test("Test directive parser", () => {
|
||||
const lang = buildMarkdown([]);
|
||||
let tree = parse(lang, directiveSample);
|
||||
// console.log("tree", JSON.stringify(tree, null, 2));
|
||||
assertEquals(renderToText(tree), directiveSample);
|
||||
|
||||
tree = parse(lang, nestedDirectiveExample);
|
||||
// console.log("tree", JSON.stringify(tree, null, 2));
|
||||
assertEquals(renderToText(tree), nestedDirectiveExample);
|
||||
|
||||
const orderByExample = `<!-- #query page order by lastModified -->
|
||||
|
||||
<!-- /query -->`;
|
||||
tree = parse(lang, orderByExample);
|
||||
console.log("Tree", JSON.stringify(tree, null, 2));
|
||||
});
|
||||
|
||||
const inlineAttributeSample = `
|
||||
Hello there [a link](http://zef.plus)
|
||||
[age: 100]
|
||||
|
||||
@@ -142,7 +142,7 @@ export const Highlight: MarkdownConfig = {
|
||||
],
|
||||
};
|
||||
|
||||
export const attributeStartRegex = /^\[(\w+)(::?\s*)/;
|
||||
export const attributeStartRegex = /^\[([\w\$]+)(::?\s*)/;
|
||||
|
||||
export const Attribute: MarkdownConfig = {
|
||||
defineNodes: [
|
||||
@@ -252,16 +252,17 @@ const directiveStart = /^\s*<!--\s*#([a-z]+)\s*(.*?)-->\s*/;
|
||||
const directiveEnd = /^\s*<!--\s*\/(.*?)-->\s*/;
|
||||
|
||||
import { parser as directiveParser } from "./parse-query.js";
|
||||
import { parser as expressionParser } from "./parse-expression.js";
|
||||
import { Table } from "./table_parser.ts";
|
||||
|
||||
const highlightingDirectiveParser = directiveParser.configure({
|
||||
export const highlightingDirectiveParser = directiveParser.configure({
|
||||
props: [
|
||||
styleTags({
|
||||
"Name": t.variableName,
|
||||
"String": t.string,
|
||||
"Number": t.number,
|
||||
"PageRef": ct.WikiLinkTag,
|
||||
"Where Limit Select Render Order OrderDirection And": t.keyword,
|
||||
"where limit select render Order OrderKW and or as InKW": t.keyword,
|
||||
}),
|
||||
],
|
||||
});
|
||||
@@ -294,6 +295,14 @@ export const Directive: MarkdownConfig = {
|
||||
cx.parsedPos + line.text.length + 1,
|
||||
[cx.elt(queryParseTree, frontStart + fullMatch.indexOf(arg))],
|
||||
));
|
||||
} else if (directive === "eval") {
|
||||
const expressionParseTree = expressionParser.parse(arg);
|
||||
elts.push(cx.elt(
|
||||
"DirectiveStart",
|
||||
cx.parsedPos,
|
||||
cx.parsedPos + line.text.length + 1,
|
||||
[cx.elt(expressionParseTree, frontStart + fullMatch.indexOf(arg))],
|
||||
));
|
||||
} else {
|
||||
elts.push(cx.elt(
|
||||
"DirectiveStart",
|
||||
@@ -432,7 +441,7 @@ export default function buildMarkdown(mdExtensions: MDExt[]): Language {
|
||||
props: [
|
||||
styleTags({
|
||||
Task: ct.TaskTag,
|
||||
TaskMarker: ct.TaskMarkerTag,
|
||||
TaskMark: ct.TaskMarkTag,
|
||||
Comment: ct.CommentTag,
|
||||
"TableDelimiter SubscriptMark SuperscriptMark StrikethroughMark":
|
||||
t.processingInstruction,
|
||||
|
||||
@@ -1,58 +1,102 @@
|
||||
@precedence { logic @left }
|
||||
@top Program { Query }
|
||||
@skip { space }
|
||||
|
||||
Query {
|
||||
Name ( WhereClause | LimitClause | OrderClause | SelectClause | RenderClause )*
|
||||
@precedence {
|
||||
mulop @left
|
||||
addop @left
|
||||
binop @left
|
||||
and @left
|
||||
or @left
|
||||
}
|
||||
|
||||
@skip {
|
||||
space
|
||||
}
|
||||
|
||||
commaSep<content> { content ("," content)* }
|
||||
|
||||
WhereClause { Where LogicalExpr }
|
||||
LimitClause { Limit Number }
|
||||
OrderClause { Order Name OrderDirection? }
|
||||
SelectClause { Select commaSep<Name> }
|
||||
RenderClause { Render (PageRef | String) }
|
||||
kw<term> { @specialize[@name={term}]<Identifier, term> }
|
||||
|
||||
|
||||
Query {
|
||||
TagIdentifier ( WhereClause | LimitClause | OrderClause | SelectClause | RenderClause )*
|
||||
}
|
||||
|
||||
WhereClause { kw<"where"> Expression }
|
||||
LimitClause { kw<"limit"> Expression }
|
||||
OrderClause { Order commaSep<OrderBy> }
|
||||
OrderBy { Expression OrderDirection? }
|
||||
SelectClause { kw<"select"> commaSep<Select> }
|
||||
RenderClause { kw<"render"> PageRef }
|
||||
|
||||
Select { Identifier | Expression kw<"as"> Identifier }
|
||||
|
||||
OrderDirection {
|
||||
"desc" | "asc"
|
||||
OrderKW
|
||||
}
|
||||
|
||||
Value { Number | String | Bool | Regex | Null | List }
|
||||
Value { Number | String | Bool | Regex | kw<"null"> | List }
|
||||
|
||||
LogicalExpr { FilterExpr (And FilterExpr)* }
|
||||
|
||||
FilterExpr {
|
||||
Name "<" Value
|
||||
| Name "<=" Value
|
||||
| Name "=" Value
|
||||
| Name "!=" Value
|
||||
| Name ">=" Value
|
||||
| Name ">" Value
|
||||
| Name "=~" Value
|
||||
| Name "!=~" Value
|
||||
| Name "in" Value
|
||||
Attribute {
|
||||
LVal "." Identifier
|
||||
}
|
||||
|
||||
List { "[" commaSep<Value> "]" }
|
||||
Call {
|
||||
Identifier "(" commaSep<Expression> ")" | Identifier "(" ")"
|
||||
}
|
||||
|
||||
LVal {
|
||||
Identifier
|
||||
| Attribute
|
||||
}
|
||||
|
||||
ParenthesizedExpression { "(" Expression ")" }
|
||||
|
||||
LogicalExpression {
|
||||
Expression !and kw<"and"> Expression
|
||||
| Expression !or kw<"or"> Expression
|
||||
}
|
||||
|
||||
Expression {
|
||||
Value
|
||||
| LVal
|
||||
| ParenthesizedExpression
|
||||
| LogicalExpression
|
||||
| BinExpression
|
||||
| Call
|
||||
}
|
||||
|
||||
BinExpression {
|
||||
Expression !binop "<" Expression
|
||||
| Expression !binop "<=" Expression
|
||||
| Expression !binop "=" Expression
|
||||
| Expression !binop "!=" Expression
|
||||
| Expression !binop ">=" Expression
|
||||
| Expression !binop ">" Expression
|
||||
| Expression !binop "=~" Expression
|
||||
| Expression !binop "!=~" Expression
|
||||
| Expression !binop InKW Expression
|
||||
|
||||
| Expression !mulop "*" Expression
|
||||
| Expression !mulop "/" Expression
|
||||
| Expression !mulop "%" Expression
|
||||
| Expression !addop "+" Expression
|
||||
| Expression !addop "-" Expression
|
||||
}
|
||||
|
||||
List { "[" commaSep<Expression> "]" }
|
||||
|
||||
|
||||
Bool {
|
||||
"true" | "false"
|
||||
BooleanKW
|
||||
}
|
||||
|
||||
|
||||
@tokens {
|
||||
space { std.whitespace+ }
|
||||
Name { (std.asciiLetter | "-" | "_")+ }
|
||||
|
||||
Where { "where" }
|
||||
Order { "order by" }
|
||||
Select { "select" }
|
||||
Render { "render" }
|
||||
Limit { "limit" }
|
||||
And { "and" }
|
||||
Null { "null" }
|
||||
TagIdentifier { @asciiLetter (@asciiLetter | @digit | "-" | "_" | "/" )* }
|
||||
|
||||
Identifier { @asciiLetter (@asciiLetter | @digit | "-" | "_")* }
|
||||
|
||||
String {
|
||||
("\"" | "“" | "”") ![\"”“]* ("\"" | "“" | "”")
|
||||
@@ -60,9 +104,16 @@ Bool {
|
||||
PageRef {
|
||||
"[" "[" ![\]]* "]" "]"
|
||||
}
|
||||
Order { "order by" }
|
||||
Regex { "/" ( ![/\\\n\r] | "\\" _ )* "/"? }
|
||||
|
||||
Number { std.digit+ }
|
||||
|
||||
// @precedence { Where, Sort, Select, Render, Limit, And, Null, Name }
|
||||
BooleanKW { "true" | "false" }
|
||||
|
||||
InKW { "in" }
|
||||
|
||||
OrderKW { "asc" | "desc" }
|
||||
|
||||
@precedence { Order, BooleanKW, InKW, OrderKW, Identifier, Number }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user