-
Notifications
You must be signed in to change notification settings - Fork 2
Description
!> Use implicit and() with care.
?> if in doubt, use the explicit and() functional style as this clarifies which functions are sub-clauses of other functions.Source: https://terminusdb.org/docs/woql-explanation/#code-fluent-style-conjunction
Code:
terminusdb-docs-static/schema/all_documents.json
Line 3636 in 7b0ba7b
| "value": "### WOQL fluent vs. functional style\n\nWOQL supports both **fluent** and **functional** styles for writing queries. The fluent style is recommended for simplifying complex compound query expressions.\n\n#### The fluent style\n\nMany WOQL expressions accept a sub-query as an argument. WOQL enables appending sub-queries to the initial function as a new function. Queries in this style are easier to read and write. Visual parameter matching is easier to perform when checking for query correctness. A simple example below.\n\n#### Code: Fluent style WOQL\n\n```\nselect(a, b).triple(c, d, e)\n```\n\n#### The functional style\n\nSub-queries are contained within the initial function. The example below is the functional style equivalent of the fluent style example.\n\n#### Code: Functional style WOQL\n\n```\nselect(a, b, triple(c, d, e))\n```\n\n#### Conjunctions\n\nFluent queries are parsed left to right. Functions to the right of another function are considered sub-queries of the first function, with one important exception - **conjunction**.\n\n#### Functional style conjunction\n\nThe functional style of expressing conjunction using the WOQL `and()` function is straightforward and is often more useful for clarity:\n\n#### Code: Functional style conjunction\n\n```\nand(triple(a, b, c), triple(d, e, f))\n```\n\n#### Fluid style conjunction\n\nConjunction expressed in fluent style enables the use of any of the three variations shown below.\n\n#### Code: Fluent style conjunction\n\n```\n// Fluent style 1\nand(triple(a, b, c)).triple(d, e, f)\n\n// Fluent style 2\ntriple(a, b, c).and().triple(d, e, f)\n\n// Fluent style 3\ntriple(a, b, c).triple(d, e, f)\n```\n\n#### Implicit and()\n\nIn the example above, fluent style 3 is more concise and unambiguous where WOQL functions that are chained together do not take sub-clauses (or commands.) As conjunction is frequently used, this concise form, where the `and()` is implicit, is more convenient in many situations.\n\n!> Use implicit `and()` with care.\n\n?> if in doubt, use the explicit `and()` functional style as this clarifies which functions are sub-clauses of other functions.\n\nThe conjunction is always applied to the function immediately to the left of the period `.` in the chain, and not to any functions further up the chain. If used improperly with clauses that take sub-clauses, it will produce improperly specified queries, especially with negation (`not`) and optional functions (`opt`).\n\nFor example, consider the following three queries. The first two are equivalent. However, the first query is incorrect and easy to misinterpret when the intended expression is that shown in the third query.\n\n#### Code: Fluent style implicit conjunction\n\n```\ntriple(a, b, c).opt().triple(d, e, f).triple(g, h, i)\n```\n\n#### Code: Functional style explicit conjunction\n\n```\nand(\n triple(a, b, c),\n opt(\n and(\n triple(d, e, f),\n triple(g, h, i)\n )\n )\n)\n```\n\n#### Code: Fluent style explicit conjunction\n\n```\nand(\n triple(a, b, c),\n opt().triple(d, e, f),\n triple(g, h, i)\n)\n```\n\n### WOQL and JSON-LD\n\nWOQL uses JSON-LD and a formally specified [ontology](/docs/glossary/#ontology) to define the language and transmit queries.\n\nJSON-LD is sometimes tedious for us to read and write. Therefore, WOQL.js is designed to be as easy as possible for developers to write. All WOQL.js queries are translated into the equivalent JSON-LD format for transmission over networks.\n\n#### The WOQLQuery object\n\nThe WOQL.js `json()` function translates any WOQL query to its JSON-LD format, and JSON-LD to its WOQL.js equivalent - a `WOQLQuery()` object.\n\nAs shown in the example below, if passed a JSON-LD (`json_ld`) argument, WOQL.js (`wjs`) will generate the equivalent `WOQLQuery()` object. If an argument is not provided, WOQL.js will return the JSON-LD equivalent of the `WOQLQuery()` object.\n\n#### Code: Using WOQLQuery() and json()\n\n```javascript\nlet wjs = new WOQLQuery().json(json_ld)\njson_ld == wjs.json()\n```\n\n#### Embedding JSON-LD in WOQL.js\n\nIt is possible to use JSON-LD interchangeably within WOQL.js. Wherever a WOQL function or argument can be accepted directly in WOQL.js, the JSON-LD equivalent can also be supplied. For example, the following two WOQL statements are identical.\n\nThere should never be a situation that necessitates using JSON-LD directly. WOQL.js expresses all queries that are expressible in the underlying JSON-LD. However, it can be convenient to embed JSON-LD in queries in some cases.\n\n#### Code: Interchangeable WOQL and JSON-LD\n\n```\ntriple(a, b, 1) == triple(a, b, {\"@type\": \"xsd:integer\", \"@value\": 1})\n```\n\n### WOQL variables\n\nWOQL allows variables or constants to be substituted for any argument to all its functions, except for the resource identifier functions: `using`, `with`, `into`, `from`. These functions are used for specifying the graphs against which operations such as queries are carried out.\n\n#### Unification\n\nWOQL uses the formal-logical approach to variables known as unification borrowed from the Prolog engine that implements WOQL within TerminusDB.\n\n#### Unification in variables\n\nUnification in variables means each valid value for a variable, as constrained by the totality of the query, will produce a new row in the results. For multiple variables, the rows returned are the cartesian product of all the possible combinations of variable values in the query.\n\n#### Unification in functions\n\nUnification in functions enables most WOQL functions to serve as both pattern matchers and pattern generators, depending on whether a variable or constant is provided as an argument. If a variable is provided, WOQL will generate all possible valid solutions which fill the variable value. If a constant is provided, WOQL will match only those solutions with exactly that value. Except for resource identifiers, WOQL functions accept either variables or constants in virtually all of their arguments.\n\n#### Expressing variables\n\nIn WOQL.js, there are two distinct ways of expressing variables within queries. All are semantically equivalent. The first is generally preferred as it is easier to type and easier to distinguish variables from constants at a glance due to the lack of quotation marks around the variables\n\n#### Code: WOQL variables using let\n\n```javascript\nlet [a, b, c] = vars('a', 'b', 'c')\ntriple(a, b, c)\n```\n\n#### Code: WOQL variables using prefix v:\n\n```\ntriple('v:a', 'v:b', 'v:c')\n```\n\n### WOQL prefixes\n\nInternally, TerminusDB uses strict [RDF](/docs/glossary/#rdf) rules to represent all data. This means all identifiers and properties are represented by [IRIs](/docs/glossary/#iri) (a superset of URLs.)\n\n#### Shorthand prefixes\n\nHowever, IRIs are difficult to remember and tedious to type. RDF generally solves this problem by allowing prefixed shorthand forms. For example, `\"http://obscure.w3c.url/with/embedded/dates#type\"` is shortened to `\"rdf:type\"`.\n\n#### Prefixes @base and @schema\n\nTerminusDB also defines the two **optional** prefixes listed below. These enable users to write expressions such as `\"@base:X\"` or `\"@schema:X\"` and ensure expressions always resolve to valid IRIs in all databases.\n\n* The `\"@base\"` prefix for instance-data IRIs.\n* The `\"@schema\"` prefix for schema IRIs.\n\n#### Automatic prefixes\n\nWOQL goes a step beyond supporting prefixes by automatically applying prefixes where possible, enabling users to specify prefixes only when necessary. The default prefixes are applied as follows:\n\n* `\"@base\"` applies to **woql:subject** (first argument to triple) where **instance data IRIs** are normally required.\n* `\"@schema\"` applies to **woql:predicate** and other arguments (`sub`, `type`) where **schema elements** are normally required.\n* When standard predicates are used without a prefix, the standard correct prefixes are applied.\n* `label`\n* `type`\n* `comment`\n* `subClassOf`\n* `domain`\n* `range`\n* Otherwise, if no prefix is applied a string is assumed.\n\n### Further Reading\n\n#### WOQL Reference\n\n[JavaScript](/docs/javascript/) and [Python](/docs/python/) WOQL Reference guides\n\n#### How-to guides\n\nSee the [How-to Guides](/docs/use-the-clients/) for further examples of using WOQL.\n\n#### Documents\n\n[Documents](/docs/documents-explanation/) in a knowledge graph and how to use them." |
How to fix
To render !> and ?> blocks in Markdoc as informational and warning blocks, you need to set up custom tags and their processing. Here's how you can do it:
📚 1. Setting Up Custom Tags
In Markdoc, you can configure custom tags to handle specific syntactic constructs like !> and ?>.
📚 2. Example Configuration
Here's an example configuration that allows you to use !> and ?> to create info and warning blocks:
🔖 Markdoc Configuration
// Example configuration for Markdoc
const config = {
nodes: {
paragraph: {
transform(node, config) {
const content = node.transformChildren(config);
const text = content[0]?.content || "";
if (text.startsWith("!>")) {
return {
type: "info",
attributes: { title: "Information" },
content: [text.slice(2).trim()],
};
} else if (text.startsWith("?>")) {
return {
type: "warning",
attributes: { title: "Warning" },
content: [text.slice(2).trim()],
};
}
return { type: "paragraph", content };
},
},
},
tags: {
info: {
render: "Info",
attributes: {
title: { type: String },
},
},
warning: {
render: "Warning",
attributes: {
title: { type: String },
},
},
},
};📚 3. Using in Markdoc
Now you can use !> and ?> in your Markdoc file:
!> This is an informational message.?> This is a warning message.📚 4. Defining Components for Rendering
As in the previous example, you'll need to define Info and Warning components in your framework (e.g., React) to render these blocks:
function Info({ title, children }) {
return (
<div className="info-block">
<strong>{title}</strong>
<p>{children}</p>
</div>
);
}
function Warning({ title, children }) {
return (
<div className="warning-block">
<strong>{title}</strong>
<p>{children}</p>
</div>
);
}📚 5. Styling
Add appropriate styles for the classes .info-block and .warning-block in your CSS.
Now your !> and ?> blocks will be correctly rendered as informational and warning blocks.