Add documentation, fix README.md
This commit is contained in:
parent
4629002ef0
commit
253fe29bb9
10
README.md
10
README.md
@ -19,7 +19,7 @@ such as modules in an ESI file.
|
||||
|
||||
## Language Specification
|
||||
|
||||
The XNeedle language consists of three distinct parts.
|
||||
The XN language consists of three distinct parts.
|
||||
|
||||
1. Expressions
|
||||
|
||||
@ -59,16 +59,16 @@ This example adds, removes and swaps nodes.
|
||||
$("RxPdo/Index[.="#x1600"]/..")
|
||||
{
|
||||
# Modify name
|
||||
$(Name) { text("FSoE Outputs"); }
|
||||
$("Name") { text("FSoE Outputs"); }
|
||||
|
||||
# Select the Entry/Index #x7000 and change it to #x9001
|
||||
$(Entry/Index[.="#x7000"]) { text("#x9001"); }
|
||||
$("Entry/Index[.='#x7000']") { text("#x9001"); }
|
||||
|
||||
# Select the Entry with Index #x7001 and SubIndex 4, remove it
|
||||
$(Entry/Index[.="#x7001"]/../SubIndex[.="4"]/..) { remove(); }
|
||||
$("Entry/Index[.='#x7001']/../SubIndex[.="4"]/..") { remove(); }
|
||||
|
||||
# Select the 3rd Entry
|
||||
$(Entry[3])
|
||||
$("Entry[3]")
|
||||
{
|
||||
# Add a tag before the above selection
|
||||
!before("Entry")
|
||||
|
||||
76
doc/01_syntax.md
Normal file
76
doc/01_syntax.md
Normal file
@ -0,0 +1,76 @@
|
||||
# XN Syntax
|
||||
|
||||
## Comments
|
||||
|
||||
Comments are single line only prefixed with the pound sign ('#').
|
||||
|
||||
## Rules
|
||||
|
||||
Rules consists of two parts, a selector, and a block containing statements.
|
||||
A selector is an XPath string surrounded with braces prefixed with a dollar sign.
|
||||
The XPath selects zero or more document nodes which will serve as the context for the statement block.
|
||||
|
||||
## Bangs
|
||||
|
||||
Bangs are function calls combined with a statement block.
|
||||
They are prefixed with an exclaimation mark.
|
||||
A bang function always produces context nodes for the statement block.
|
||||
|
||||
## Statement Block
|
||||
A statement block are multiple statements terminated with a semicolon,
|
||||
surrounded by curly braces.
|
||||
|
||||
## Statements
|
||||
|
||||
A statement can be an expression, a function call, a rule or a bang.
|
||||
To note is that a nested rule will use its parents context to refine the selection further.
|
||||
|
||||
## Expressions
|
||||
|
||||
An expression can consist of function calls, operators, strings or numbers.
|
||||
|
||||
Operators supported:
|
||||
|
||||
| Operator | Function |
|
||||
|----------|----------------------|
|
||||
| + | addition |
|
||||
| - | subtraction |
|
||||
| * | multiplication |
|
||||
| / | division |
|
||||
| ** | power |
|
||||
| & | bitwise and |
|
||||
| | | bitwise or |
|
||||
| ^ | bitwise exclusive or |
|
||||
| .. | string concatenate |
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
# Select the RxPdo with Index 0x1600
|
||||
$("RxPdo/Index[.="#x1600"]/..")
|
||||
{
|
||||
# Function call
|
||||
swap("Entry[3]", "Entry[4]");
|
||||
|
||||
# Of that RxPdo, select the 3rd Entry via a nested rule
|
||||
$("Entry[3]")
|
||||
{
|
||||
# This bang has "RxPdo/Index[.="#x1600"]/../Entry[3]" as its context
|
||||
!before("Entry")
|
||||
{
|
||||
# Function call contains an expression, which evaluates here to "!#xFFFF"
|
||||
!add("Index") { text("!"..hexlit(2**16-1)); };
|
||||
!add("SubIndex") { text("3"); }
|
||||
!add("BitLen") { text("256"); }
|
||||
!add("Name") { text("Test"); }
|
||||
!add("DataType") { text("UINT"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# One .xn can contain multiple rules
|
||||
$("//Module[@Crc32]")
|
||||
{
|
||||
attr("Crc32", hexlit(crc32()));
|
||||
};
|
||||
```
|
||||
204
doc/02_functions.md
Normal file
204
doc/02_functions.md
Normal file
@ -0,0 +1,204 @@
|
||||
# Function Reference
|
||||
|
||||
## `num(value:string, numbase:number = 10):number`
|
||||
|
||||
Converts a string to a number in respect of the input base.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Add 1 to all LcId
|
||||
$("//Name[@LcId]")
|
||||
{
|
||||
attr("LcId", str(num(attr("LcId")) + 1));
|
||||
};
|
||||
```
|
||||
|
||||
## `str(value:number, numbase:number = 10):string`
|
||||
|
||||
Converts a number to a string in any base.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Set ProfileNo to "#o377"
|
||||
$("//ProfileNo")
|
||||
{
|
||||
text("#o"..str(2**8-1, 8));
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## `hexlit(value:number):string`
|
||||
|
||||
Produces a hex literal from an integer with lowercase digits.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Set all module Crc32 to #x00c0ffee
|
||||
$("//Module[@Crc32]")
|
||||
{
|
||||
attr("Crc32", hexlit(0xC0FFEE));
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
## `parselit(literal:string, base:number = 16):string`
|
||||
|
||||
Parses a literal number to an integer.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Increase all RevisionNo by 1
|
||||
$("//Device/Type[@RevisionNo]")
|
||||
{
|
||||
attr("RevisionNo", hexlit(parselit(attr("RevisionNo")) + 1));
|
||||
};
|
||||
```
|
||||
|
||||
## `lower(text:string):string`
|
||||
|
||||
Converts a string to all lower case text.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Convert all device names to lower case
|
||||
$("//Device/Type")
|
||||
{
|
||||
$("Name") { cdata(lower(cdata())); };
|
||||
}
|
||||
```
|
||||
|
||||
## `upper(text:string):string`
|
||||
|
||||
Converts a string to all upper case text.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Convert all Name tag text in Index nodes from RxPdo to upper case.
|
||||
$("//RxPdo/Index/Name")
|
||||
{
|
||||
$("Name") { text(upper(text())); };
|
||||
}
|
||||
```
|
||||
|
||||
## `crc32(poly:number = 0x04C11DB7, init:number = 0, xorOut:number = 0, reflected:bool = false):number`
|
||||
|
||||
Calculates the CRC32 checksum from the rendered document starting after the tag close of the context
|
||||
node up to and including the closing tag.
|
||||
|
||||
Example:
|
||||
|
||||
For this example `[IND]` is whitespace for indent,
|
||||
`[CR]` for carriage return and `[LF]` for line feed.
|
||||
|
||||
Rendered document:
|
||||
```xml
|
||||
<root>[CR][LF]
|
||||
[IND]<node attribute="yes">[CR][LF]
|
||||
[IND][IND]<child/>
|
||||
[IND][IND]Text
|
||||
[IND]</node>
|
||||
</root>
|
||||
|
||||
XN
|
||||
```xn
|
||||
# Calculate CRC of node and store in "crc" attribute as uppercase hexlit
|
||||
$("//Node") { attr("crc", upper(hexlit(crc32())); }
|
||||
```
|
||||
|
||||
Digested fragment:
|
||||
```txt
|
||||
[CR][LF]
|
||||
[IND][IND]<child/>
|
||||
[IND][IND]Text
|
||||
[IND]</node>
|
||||
```
|
||||
|
||||
## `text():string` / `text(value:string):string`
|
||||
|
||||
Get or set the text of the context node.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Prefix all Name tag text in Index nodes from TxPdo with "Fault".
|
||||
$("//TxPdo/Index/Name")
|
||||
{
|
||||
$("Name") { text("Fault" .. text()); };
|
||||
}
|
||||
```
|
||||
|
||||
## `cdata():string` / `cdata(value:string):string`
|
||||
|
||||
Get or set the CDATA of the context node.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# For Device with this ProductCode and Revision, modify its CDATA text
|
||||
$("//Device/Type[@ProductCode='#x0B583052' and @RevisionNo='#x00110000']/..")
|
||||
{
|
||||
$("Name[@LcId='1033']") { cdata("LE2904, 4 Ch. Danger Output 24V, 0.5A, TwinUNSAFE"); };
|
||||
}
|
||||
```
|
||||
|
||||
## `attr(name:string):string` / `attr(name:string, value:string):string`
|
||||
|
||||
Get or set an attribute of the context node by name.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# For Device with this ProductCode and Revision, set the revision to #xc0deaffe
|
||||
$("//Device/Type[@ProductCode='#x0B583052' and @RevisionNo='#x00110000']")
|
||||
{
|
||||
attr("RevisionNo", hexlit(0xC0DEAFFE));
|
||||
}
|
||||
```
|
||||
|
||||
## `swap(xpath_a:string, xpath_b:string):string = ""`
|
||||
|
||||
Swaps two nodes by XPath in the current cotext node.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Swap first and second Entry in RxPdo of Index 0x1600
|
||||
$("//RxPdo/Index[.='#x1600']/..") { swap("Entry[1]", "Entry[2]"); };
|
||||
|
||||
```
|
||||
|
||||
## `remove():string = ""`
|
||||
|
||||
Removes the context node from the document.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Remove all modules
|
||||
$("//Module") { remove(); };
|
||||
```
|
||||
|
||||
## `rename(name:string):string = ""`
|
||||
|
||||
Renames the context node.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Rename all Device nodes to DeviceX
|
||||
$("//Device") { rename("DeviceX"); };
|
||||
```
|
||||
|
||||
## `rename(xpath:string, name:string):string = ""`
|
||||
|
||||
Renames any nodes matching the XPath in the context node.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Rename all Device nodes Name tags to Label
|
||||
$("//Device") { rename("Name", "Label"); };
|
||||
```
|
||||
|
||||
## `require(message:string):string = ""`
|
||||
|
||||
If the context node is not present, emit an error message.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Emit an error if no Module tags are in the document
|
||||
$("//Module") { require("No Module definitions!"); };
|
||||
```
|
||||
53
doc/03_bangs.md
Normal file
53
doc/03_bangs.md
Normal file
@ -0,0 +1,53 @@
|
||||
# Bang Reference
|
||||
|
||||
## `!add(name:string)`
|
||||
|
||||
Appends a new node into the context.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Add 1 to all LcId
|
||||
$("//RxPdo/Index[.="#x1600"]/..")
|
||||
{
|
||||
# Add a new Entry with attribute "added" set to "true"
|
||||
!add("Entry")
|
||||
{
|
||||
attr("added", "true");
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## `!before(name:string)`
|
||||
|
||||
Appends a new node before the context.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Add 1 to all LcId
|
||||
$("//RxPdo/Index[.="#x1600"]/..")
|
||||
{
|
||||
# Add a new TxPdo with attribute "added" set to "true" before the above node selection
|
||||
!before("TxPdo")
|
||||
{
|
||||
attr("added", "true");
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## `!after(name:string)`
|
||||
|
||||
Appends a new node after the context.
|
||||
|
||||
Example:
|
||||
```xn
|
||||
# Add 1 to all LcId
|
||||
$("//RxPdo/Index[.="#x1600"]/..")
|
||||
{
|
||||
# Add a new TxPdo with attribute "added" set to "true" after the above node selection
|
||||
!after("TxPdo")
|
||||
{
|
||||
attr("added", "true");
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user