Fonto specific examples
This page contains a list of XPath and XQuery examples that use functions that are unique to Fonto. These examples can therefore not be run in the playground and can not be used in other applications or programming languages that support XPath or XQuery.
Text content
Sometimes you need the text content of a given node or range. Getting the text content of a given node is fairly simple. You could write something like the following example.
Text contents
XQuery
string(.)
However, you will encounter one problem when using this solution. It will not take schema configuration into account. It will happily return the text contents of all descendants of a given node.
The platform provides two XQuery functions called curated-text-in-node and curated-text-in-range to solve this problem. These functions do take schema configuration into account.
The Blueprint
How do they work?
These functions return the curated text. Any text under detached (e.g. footnotes) and removed nodes will not be returned. Newline characters will be inserted in places where a boundary from inline context to block context is crossed. This happens, for example, when crossing the border of an element configured as block. Newline characters will also be inserted when a break element is encountered.
Result without newlines
You can remove the inserted newlines afterwards if you don't want them in the resulting string. You can use the normalize-space function for this. This function replaces leading and trailing whitespace from a given string. It replaces sequences of whitespace characters with a single space character.
Example with normalize-space
XQuery
fonto:curated-text-in-node(.) => normalize-space()
Runnable example of the normalize-space function
XQuery
normalize-space(" 123
456 ")
Usage examples
You have to include the module import before you can use this function. Refer to the examples below to see how to do this.
You can use javascript template literals when adding the module import. This allows you to use newlines in your queries. Refer to the examples below to see how to do this.
The curated-text-in-range function can be used in places where the text content of the current selection needs to be obtained.
Usage example in add-on using evaluateXPath
JavaScript
import evaluateXPath from 'fontoxml-selectors/src/evaluateXPath.js';
import evaluateXPathToString from 'fontoxml-selectors/src/evaluateXPathToString.js';
import readOnlyBlueprint from 'fontoxml-blueprints/src/readOnlyBlueprint.js';
import selectionManager from 'fontoxml-selection/src/selectionManager.js';
function textFromSelection () {
return evaluateXPathToString(
`import module namespace fonto = "http://www.fontoxml.com/functions";
fonto:curated-text-in-range($startContainer, $startOffset, $endContainer, $endOffset)`,
null, // We don't use the context node
readOnlyBlueprint,
{
startContainer: selectionManager.getStartContainer(),
startOffset: selectionManager.getStartOffset(),
endContainer: selectionManager.getEndContainer(),
endOffset: selectionManager.getEndOffset()
}
);
}
An alternative version of the example above. Here we use the use
Usage example in add-on using useXPath
JavaScript
function SelectedText({ selection }) {
const selectedText = useXPath(`
import module namespace fonto = "http://www.fontoxml.com/functions";
fonto:curated-text-in-range($startContainer, $startOffset, $endContainer, $endOffset)`,
{ variables: selection });
return <Text>{selectedText}</Text>;
}
function useSelection() {
const [selection, setSelection] = useState(null);
useEffect(() => {
return selectionManager.selectionChangeNotifier.addCallback(() => {
setSelection(selectionManager.hasSelection() ? {
startContainer: selectionManager.getStartContainer(),
startOffset selectionManager.getStartOffset(),
endContainer: selectionManager.getEndContainer(),
endOffset selectionManager.getEndOffset()
} : null);
});
});
return selection;
}
function Selection() {
const selection = useSelection();
// There may not always be a selection, use something like the following to prevent invoking the XPath function with invalid arguments
return selection ? <SelectedText selection={selection} /> : <Text>(no selection)</Text>;
}
The curated-text-in-node function can also be used in title queries. You don't want the contents of elements like footnotes to be included in the resulting title.
Usage example in element configuration
JavaScript
configureAsSheetFrame(sxModule, 'self::topic', 'topic', {
titleQuery: `import module namespace fonto = "http://www.fontoxml.com/functions";
fonto:curated-text-in-node(./title)`
});