summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2025-09-07 03:37:30 -0400
committerpommicket <pommicket@gmail.com>2025-09-07 03:37:30 -0400
commit6f2eea28605381fadf41ec49d05c664c407b9b94 (patch)
tree02bfcc8e5f7f02da176d93dcc87ef138a399d948
Initial spec
-rw-r--r--site/404.html11
-rw-r--r--site/index.html10
-rw-r--r--site/main.css7
-rw-r--r--site/spec.html583
4 files changed, 611 insertions, 0 deletions
diff --git a/site/404.html b/site/404.html
new file mode 100644
index 0000000..3f9e5ac
--- /dev/null
+++ b/site/404.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta content="width=device-width,initial-scale=1" name="viewport">
+</head>
+<body>
+ <h3>Page not found</h3>
+ <p><a href="/index.html">Main page</a></p>
+</body>
+</html>
diff --git a/site/index.html b/site/index.html
new file mode 100644
index 0000000..026778b
--- /dev/null
+++ b/site/index.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta content="width=device-width,initial-scale=1" name="viewport">
+</head>
+<body>
+ <h3>Coming soon</h3>
+</body>
+</html>
diff --git a/site/main.css b/site/main.css
new file mode 100644
index 0000000..b771e2a
--- /dev/null
+++ b/site/main.css
@@ -0,0 +1,7 @@
+td, th {
+ border: 2px solid black;
+ padding: 0.5em;
+}
+table {
+ border-collapse: collapse;
+}
diff --git a/site/spec.html b/site/spec.html
new file mode 100644
index 0000000..c3ae3fa
--- /dev/null
+++ b/site/spec.html
@@ -0,0 +1,583 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta content="width=device-width,initial-scale=1" name="viewport">
+ <link rel="stylesheet" href="/main.css">
+ <title>POM Language Specification</title>
+ <link rel="icon" href="data:,"><!--TODO-->
+</head>
+
+<body>
+<p>
+ <a href="/index.html">POM homepage</a>
+</p>
+<h1>POM Language Specification, v. 0.1.0</h1>
+<h2>Introduction</h2>
+<p>
+ POM is a “markup” language, primarily intended for software configuration,
+ and designed to be easy to parse and use.
+ The POM specification is quite strict, to avoid cases where dubious files can
+ be accepted by some parsers while being rejected by others.
+ POM files should use the <code>.pom</code> file extension to identify themselves.
+</p>
+<p>
+ Every file describes a <i>configuration</i>, which is a mapping from keys to values.
+ A <i>key</i> is a string consisting of <i>components</i> separated by dots (<code>.</code>).
+ A <i>value</i> is a string whose interpretation is entirely decided by the application.
+ Notably there is no distinction in POM’s syntax between, say, the number <code>5</code> and the string <code>5</code>.
+ A configuration, such as the one obtained from the POM file
+</p>
+<pre><code>[ingredients.sugar]
+amount = 50&nbsp;g
+type = brown
+
+[ingredients.flour]
+amount = 100&nbsp;g
+type = all-purpose
+
+[baking]
+temperature = 150&nbsp;°C
+time = 35&nbsp;min
+</code></pre>
+<p>
+ can either be seen as a simple mapping from keys to values:
+</p>
+<table>
+ <thead>
+ <tr><th>Key</th><th>Value</th></tr>
+ </thead>
+ <tbody>
+ <tr><td>ingredients.sugar.amount</td><td>50&nbsp;g</td></tr>
+ <tr><td>ingredients.sugar.type</td><td>brown</td></tr>
+ <tr><td>ingredients.flour.amount</td><td>100&nbsp;g</td></tr>
+ <tr><td>ingredients.flour.type</td><td>all-purpose</td></tr>
+ <tr><td>baking.temperature</td><td>150&nbsp;°C</td></tr>
+ <tr><td>baking.time</td><td>35&nbsp;min</td></tr>
+ </tbody>
+</table>
+<p>
+ or a tree of keys, with a value associated to each leaf node:
+</p>
+<div style="text-align:center;">
+ <svg viewBox="-281 0 500 200" style="width:80%;max-width:600px;" xmlns="http://www.w3.org/2000/svg">
+ <style>
+ text { text-anchor: middle; }
+ rect { stroke: black; fill: none; }
+ line { stroke: black; stroke-width: 1.5; }
+ </style>
+ <rect x="-30" y="6" width="60" height="20" />
+ <text x="0" y="20" font-size="12">(root)</text>
+ <line x1="-20" y1="26" x2="-118" y2="46" />
+ <line x1="20" y1="26" x2="118" y2="46" />
+ <g transform="translate(-118 46)">
+ <rect x="-45" y="0" width="90" height="20" />
+ <text x="0" y="14" font-size="12">ingredients</text>
+ <line x1="-20" y1="20" x2="-75" y2="54" />
+ <line x1="20" y1="20" x2="75" y2="54" />
+ <g transform="translate(-75 54)">
+ <rect x="-25" y="0" width="50" height="20" />
+ <text x="0" y="14" font-size="12">sugar</text>
+ <line x1="-10" y1="20" x2="-43" y2="40" />
+ <line x1="10" y1="20" x2="43" y2="40" />
+ <g transform="translate(-43 40)">
+ <rect x="-40" y="0" width="80" height="36" />
+ <text x="0" y="14" font-size="12">type</text>
+ <text x="0" y="28" font-size="12">brown</text>
+ </g>
+ <g transform="translate(43 40)">
+ <rect x="-40" y="0" width="80" height="36" />
+ <text x="0" y="14" font-size="12">amount</text>
+ <text x="0" y="28" font-size="12">50&nbsp;g</text>
+ </g>
+ </g>
+ <g transform="translate(75 54)">
+ <rect x="-25" y="0" width="50" height="20" />
+ <text x="0" y="14" font-size="12">flour</text>
+ <line x1="-10" y1="20" x2="-15" y2="40" />
+ <line x1="10" y1="20" x2="71" y2="40" />
+ <g transform="translate(-15 40)">
+ <rect x="-40" y="0" width="80" height="36" />
+ <text x="0" y="14" font-size="12">type</text>
+ <text x="0" y="28" font-size="12">all-purpose</text>
+ </g>
+ <g transform="translate(71 40)">
+ <rect x="-40" y="0" width="80" height="36" />
+ <text x="0" y="14" font-size="12">amount</text>
+ <text x="0" y="28" font-size="12">100&nbsp;g</text>
+ </g>
+ </g>
+ </g>
+ <g transform="translate(118 46)">
+ <rect x="-45" y="0" width="90" height="20" />
+ <line x1="-20" y1="20" x2="-50" y2="40" />
+ <line x1="20" y1="20" x2="50" y2="40" />
+ <text x="0" y="14" font-size="12">baking</text>
+ <g transform="translate(-50 40)">
+ <rect x="-45" y="0" width="90" height="36" />
+ <text x="0" y="14" font-size="12">temperature</text>
+ <text x="0" y="30" font-size="12">150&nbsp;°C</text>
+ </g>
+ <g transform="translate(50 40)">
+ <rect x="-45" y="0" width="90" height="36" />
+ <text x="0" y="14" font-size="12">time</text>
+ <text x="0" y="30" font-size="12">35&nbsp;min</text>
+ </g>
+ </g>
+ </svg>
+</div>
+<h2>Error handling</h2>
+<p>
+ All error conditions are described in this specification. A compliant POM parser should not
+ reject any file in any other case, outside of exceptional circumstances such as running out of memory.
+ When an error occurs, it should be reported, ideally with information about the file name and line number,
+ and the file must be entirely rejected (i.e. parsers must not attempt to preserve only the correct parts of an erroneous file).
+ Warnings may also be issued according to the judgment of the library author.
+</p>
+<h2>Text encoding</h2>
+<p>
+ All POM files are encoded using UTF-8. Both LF and CRLF line endings may be used (see below).
+ If invalid UTF-8 is encountered, including overlong sequences and UTF-16 surrogate halves (U+D800-DFFF),
+ an error occurs.
+</p>
+<h2>Valid keys/values</h2>
+<p>
+ Keys in a POM file may contain the following characters
+</p>
+<ul>
+ <li>
+ The ASCII characters <code>a</code>–<code>z</code>, <code>A</code>–<code>Z</code>, <code>0</code>–<code>9</code>, as well as each of
+ <code>./-+*_</code>.
+ </li>
+ <li>
+ Any non-ASCII code point (U+0080–10FFFF).
+ </li>
+</ul>
+<p>
+ A non-empty string containing only these characters is a valid key if and only if it does not start or end with a dot
+ and does not contain two dots in a row (<code>..</code>).
+</p>
+<p>
+ Any string of non-zero Unicode code points (U+0001–U+10FFFF) is a valid value.
+</p>
+<h2>Parsing</h2>
+<p>
+ If a “byte order mark” of <code>EF BB BF</code> appears at the start of the file,
+ it is ignored.
+ Every carriage return character (U+000D) which immediately precedes a line feed (U+000A) is deleted.
+ Then, if any control characters in the range U+0000 to U+001F other than the line feed and horizontal
+ tab (U+0009) are present in the file, an error occurs.
+</p>
+<p>
+ The <i>current-section</i> is a string variable which should be maintained during parsing. It is initally
+ equal to the empty string.
+</p>
+<p>
+ An <i>accepted-space</i> is either a space (U+0020) or horizontal tab (U+0009) character.
+</p>
+<p>
+ Parsing now proceeds line-by-line, with lines being delimited by line feed characters. For each line:
+</p>
+<ol>
+ <li>Any accepted-spaces that appear at the start of the line are removed.</li>
+ <li>
+ If the line begins with <code>#%disable warnings</code> or <code>#%enable warnings</code>,
+ warnings should be disabled/enabled if any are implemented.
+ </li>
+ <li>
+ If the line is empty or begins with <code>#</code>,
+ parsing proceeds to the next line.
+ </li>
+ <li>
+ If the line begins with <code>[</code>, it is interpreted as a <i>section header</i>. In this case:
+ <ol>
+ <li>If the line does not end with <code>]</code> optionally succeeded by any number of accepted-spaces, an error occurs.</li>
+ <li>
+ The current-section is set to the text in between the initial <code>[</code> and final <code>]</code>
+ (white space between the <code>[</code> and <code>]</code> is <em>not</em> trimmed).
+ </li>
+ <li>
+ If the new current-section is not empty and not a valid key (see above), an error occurs.
+ </li>
+ </ol>
+ </li>
+ <li>
+ Otherwise, the line is now interpreted as a key-value assignment. In this case:
+ <ol>
+ <li>If the line does not contain an equal sign (<code>=</code>), an error occurs.</li>
+ <li>
+ The <i>relative-key</i> is the text preceding the <code>=</code>, not including any space or horizontal tab characters
+ immediately before the <code>=</code>.
+ </li>
+ <li>
+ If the relative-key is not a valid key (see above), an error occurs.
+ </li>
+ <li>
+ Let <i>c</i> be the first character after the <code>=</code> and any succeeding accepted-spaces.
+ </li>
+ <li>
+ If <i>c</i> is one of <code>"'`</code> (U+0022 QUOTATION MARK, U+0027 APOSTROPHE, U+0060 GRAVE ACCENT),
+ the value is <i>quoted</i>, and spans from the first character after <i>c</i> to the next unescaped
+ instance of <i>c</i> in the file (which may be on a different line). In this case,
+ <ol>
+ <li>
+ Escape sequences are processed as described below.
+ </li>
+ <li>
+ Following the closing instance of <i>c</i>, there must be a line feed,
+ optionally preceded by any number of accepted-spaces;
+ otherwise an error occurs.
+ </li>
+ </ol>
+ </li>
+ <li>
+ Otherwise, accepted-spaces at the end of the line are removed;
+ then, the value is the text starting from <i>c</i> and ending at the next line feed.
+ </li>
+ <li>If the value is not a valid value (see above), an error occurs.</li>
+ <li>
+ The key is equal to the relative-key if the current-section is empty; otherwise, it is equal to
+ the concatenation of current-section, a dot, and the relative-key.
+ </li>
+ <li>
+ The key is assigned to the value.
+ </li>
+ </ol>
+ </li>
+</ol>
+
+<h2>Escape sequences</h2>
+
+<p>
+ POM defines the following escape sequences, which may appear in quoted values.
+ If a backslash character occurs in a quoted value but does not form
+ a defined escape sequence, an error occurs.
+</p>
+
+<table>
+ <thead>
+ <tr><th>Escape sequence</th><th>Value</th></tr>
+ </thead>
+ <tbody>
+ <tr><td><code>\n</code></td><td>Line feed (U+000A)</td></tr>
+ <tr><td><code>\r</code></td><td>Carriage return (U+000D)</td></tr>
+ <tr><td><code>\t</code></td><td>Horizontal tab (U+0009)</td></tr>
+ <tr><td><code>\\</code></td><td>Literal <code>\</code> (U+005C)</td></tr>
+ <tr><td><code>\"</code></td><td>Literal <code>"</code> (U+0022)</td></tr>
+ <tr><td><code>\'</code></td><td>Literal <code>'</code> (U+0027)</td></tr>
+ <tr><td><code>\`</code></td><td>Literal <code>`</code> (U+0060)</td></tr>
+ <tr><td><code>\,</code></td><td>Literal <code>\,</code> (U+005C U+002C)</td></tr>
+ <tr><td><code>\x</code><i>NM</i></td>
+ <td>ASCII character with code <i>NM</i>,
+ <br>interpreted as hexadecimal
+ <br>(must be in the range 01–7F).</td>
+ </tr>
+ <tr><td><code>\u{</code><i>digits</i><code>}</code></td>
+ <td>Unicode code point <i>digits</i>,<br>
+ interpreted as hexidecimal<br>
+ <i>digits</i> must be 1–6 characters long,<br>
+ and may contain leading zeros,<br>
+ but must not be zero.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2>Lists</h2>
+<p>
+ Although POM does not have a way of specially designating a value as being a list,
+ there is a recommended syntax for encoding them. Specifically, a value can be treated as a list
+ by first splitting it into comma-delimited parts (treating <code>\,</code> as a literal comma
+ in a list entry), then removing any accepted-spaces surrounding list entries. List entries may be empty.
+</p>
+<p>
+ An empty string is considered to be an empty list.
+</p>
+<p>
+ If a list's order is irrelevant and it might be large or benefit from labelling its entries,
+ a key prefix should be used instead
+ (see the <code>ingredients</code> “list” in the opening example).
+</p>
+<h3>Examples</h3>
+<table>
+ <thead>
+ <tr><th>POM line</th><th>Entry 1</th><th>Entry 2</th><th>Entry 3</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>fonts = monospace, sans-serif, serif</code></td>
+ <td><code>monospace</code></td>
+ <td><code>sans-serif</code></td>
+ <td><code>serif</code></td>
+ </tr>
+ <tr>
+ <td><code>files = " foo.txt, weird\,name,z "</code></td>
+ <td><code>foo.txt</code></td>
+ <td><code>weird,name</code></td>
+ <td><code>z</code></td>
+ </tr>
+ <tr>
+ <td><code>things = `\,,,76`</code></td>
+ <td><code>,</code></td>
+ <td><code></code></td>
+ <td><code>76</code></td>
+ </tr>
+ </tbody>
+</table>
+
+
+<h2>Merging configurations</h2>
+<p>
+ A configuration <i>B</i> can be <i>merged into</i> another configuration <i>A</i> by parsing both of them
+ and setting the value associated with a key <i>k</i> to be
+</p>
+<ol>
+ <li>The value associated with <i>k</i> in <i>B</i>, if any.</li>
+ <li>Otherwise, the value associated with <i>k</i> in <i>A</i>, if any.</li>
+</ol>
+<p>
+ (Likewise, an ordered series of configurations <i>A<sub>1</sub></i>, …, <i>A<sub>n</sub></i>
+ can be merged by merging <i>A<sub>n-1</sub></i> into <i>A<sub>n</sub></i>, then <i>A<sub>n-2</sub></i> into
+ the resulting configuration, etc.)
+</p>
+<p>
+ This is useful, for example, when you want to have a global configuration for a piece of software
+ installed on a multi-user machine where individual settings can be overriden by each user (in this case,
+ the user configuration would be merged into the global configuration).
+</p>
+
+<h2>Extensions</h2>
+<p>
+ If needed for a particular domain, an parser may accept an extended form of the POM syntax.
+ Ideally, extensions should use lines beginning with invalid key characters (e.g. <code>!&amp;%</code>)
+ so that there is no ambiguity, and the file cannot be interpreted without the extension.
+</p>
+
+<h2>Schemas</h2>
+<p>
+ A <i>schema</i> is a POM file that describes how other POM files should be formatted (i.e. what keys they should
+ include, and what values they can be associated with). A configuration can be said to <i>follow</i> a schema when it obeys
+ all of the schema’s rules.
+</p>
+<p>
+ Every schema key is of the form <i>k</i><code>.</code><i>rule</i>, where <i>k</i> is a valid key,
+ and <i>rule</i> is one of the rule names listed below.
+</p>
+<p>
+ For any valid key <i>k</i> the value of the rule <i>rule</i> is determined for <i>k</i> as follows:
+</p>
+<ul>
+ <li>Break <i>k</i> down into its <i>n</i> components.</li>
+ <li>For each schema key <i>s</i> with <i>n</i> components:
+ <ul>
+ <li>Match up the components of <i>s</i> with the components of <i>k</i>.</li>
+ <li>
+ If all the components of <i>s</i> not equal to <code>*</code> are equal to the corresponding components
+ of <code>k</code>, add <i>s</i> to the <i>candidate-list</i>.
+ </li>
+ </ul></li>
+ <li>If the candidate-list is empty, use the default value for the rule.</li>
+ <li>If the candidate-list has exactly one schema key, use the value for that key.</li>
+ <li>
+ Otherwise select the schema key in the candidate-list with the latest first <code>*</code>-component (in terms of component index),
+ preferring keys with no <code>*</code>,
+ breaking ties by the latest second <code>*</code>-component, preferring keys with only one <code>*</code>, etc.
+ Use its value for the key.
+ </li>
+</ul>
+
+<h3><code>type</code> rule</h3>
+<p>
+ Default: <code>String</code>.
+</p>
+<p>
+ This describes what values a key is allowed to be associated with.
+ The following types are defined:
+</p>
+<ul>
+ <li><code>String</code> — accepts any value</li>
+ <li><code>None</code> — accepts an unset value (special—see below)</li>
+ <li><code>Empty</code> — accepts an empty value</li>
+ <li><code>Bool</code> — accepts <code>true</code>, <code>on</code>, <code>yes</code>,
+ <code>false</code>, <code>off</code>, <code>no</code> (case-sensitive).</li>
+ <li><code>UInt</code> — accepts any unsigned
+ integer that fits in 63 [sic] bits, written in decimal or <code>0x</code>-prefixed hexadecimal.
+ A leading <code>+</code> is permitted, but <code>-0</code> is not.
+ Only 63 bits are allowed to support languages (Java) with no 64-bit unsigned integers.</li>
+ <li><code>Int</code> — accepts any (two’s complement) signed integer that fits in 64 bits,
+ written in decimal or <code>0x</code>-prefixed hexadecimal.
+ A leading <code>+</code> (or, of course, <code>-</code>) is permitted.</li>
+ <li><code>Float</code> —
+ A floating-point number, written ordinarily (e.g. <code>-1.234</code>, <code>7.</code>, <code>265</code>) or in scientific notation
+ (e.g. <code>3e5</code>, <code>3.E-5</code>, <code>-3.7e+5</code>).
+ A leading <code>+</code> (or, of course, <code>-</code>) is permitted.
+ <li><code>'</code><i>value</i><code>'</code> — accepts the literal value <i>value</i>. Note that this must be written like
+ <code>thing.type = "'special_string'"</code> in the schema. Note also that <i>value</i> cannot contain a literal apostrophe <code>'</code>. </li>
+ <li><i>T</i><code> | </code><i>U</i>, where <i>T</i>, <i>U</i> are types — accepts a value of type <i>T</i> or <i>U</i>.</li>
+ <li><code>Optional[</code><i>T</i><code>]</code>, where <i>T</i> is a type — equivalent to <i>T</i><code> | None</code>.</li>
+ <li><code>List[</code><i>T</i><code>]</code>, where <i>T</i> is a type — accepts a list of entries of type <i>T</i> (see description
+ of lists above). Nested lists are not permitted.
+ </li>
+</ul>
+
+<h3><code>allow_unknown</code> rule</h3>
+<p>
+ Default: inherited from parent (i.e. if <i>k</i> = <i>j</i><code>.</code><i>component</i>,
+ look up the <code>allow_unknown</code> rule for <i>j</i>), or <code>yes</code> if <i>k</i> has no parent (does not contain a dot).
+</p>
+<p>
+ This describes whether or the key <i>k</i> is allowed if it is not described in the schema.
+ It must be set to either <code>yes</code> or <code>no</code>.
+</p>
+<p>
+ If a key is encountered in a configuration
+ and the value of its <code>allow_unknown</code> rule is <code>no</code>, the configuration does not follow the schema.
+</p>
+<h3><code>min</code>, <code>max</code> rules</h3>
+<p>
+ This schema key's value sets the minimum/maximum value for the key's value. This must not be set if <code>type</code>
+ does not explicitly allow numeric values (i.e. it does not contain a type <code>Int</code>/<code>UInt</code>/<code>Float</code>).
+</p>
+<h3><code>maxlength</code> rule</h3>
+<p>
+ The value of this rule must be a non-negative integer no greater than 2<sup>31</sup>−1.
+ Specifies that the value of a key can be no longer than that number of UTF-8 bytes.
+</p>
+<h3><code>default</code> rule</h3>
+<p>
+ Sets the default value for a key.
+</p>
+<h3>Missing values</h3>
+<p>
+If there is a schema key <i>k</i><code>.type</code>, where <i>k</i> does not contain any <code>*</code>-components,
+and the type does not allow unset values (<code>None</code>), and there is no schema key <i>k</i><code>.default</code>,
+then a configuration must contain the key <i>k</i> to follow the schema.
+</p>
+<p>
+Additionally, if there is a schema key <i>j</i><code>.*.</code><i>k</i><code>.type</code> that does not allow unset values
+and no correspoding <code>default</code> schema key, where <i>k</i> does not contain any <code>*</code>-components, then a configuration
+which contains a key <i>x</i> matching <i>j</i><code>.*</code> must also contain the key <i>x</i><code>.</code><i>k</i>.
+</p>
+<h2>API recommendations</h2>
+<p>
+ The following functions are (lightly) recommended
+ in any general-purpose library for parsing POM files
+ (their exact names/signatures can be changed to fit the style of the language).
+</p>
+<ul>
+ <li>
+ <code>load(file: File) -&gt; Configuration</code><br>
+ Load a configuration from a file.
+ </li>
+ <li>
+ <code>load_path(path: String) -&gt; Configuration</code><br>
+ Convenience function for loading by path (may be overloaded with <code>load</code> if language supports it).
+ </li>
+ <li>
+ <code>get(conf: Configuration, key: String) -&gt; Optional&lt;String&gt;</code><br>
+ Get value associated with <code>key</code>, if any exists.
+ </li>
+ <li>
+ <code>has(conf: Configuration, key: String) -&gt; Bool</code><br>
+ Returns whether <code>key</code> is associated with any value.
+ </li>
+ <li>
+ <code>get_or_default(conf: Configuration, key: String, default: String) -&gt; String</code><br>
+ Get value associated with <code>key</code>, if any exists, returning <code>default</code> if not.
+ </li>
+ <li>
+ <code>get_int(conf: Configuration, key: String) -&gt; Optional&lt;Int&gt;</code><br>
+ <code>get_int_or_default(conf: Configuration, key: String, default: Int) -&gt; Int</code><br>
+ Get value associated with <code>key</code>, if any exists, and parse it as a signed 64-bit integer
+ (returning <code>default</code> if the key doesn’t exist).
+ Return an error if the key exists but its value is not a valid signed 64-bit integer.
+ </li>
+ <li>
+ <code>get_uint(conf: Configuration, key: String) -&gt; Optional&lt;UInt&gt;</code><br>
+ <code>get_uint_or_default(conf: Configuration, key: String, default: UInt) -&gt; UInt</code><br>
+ Get value associated with <code>key</code>, if any exists, and parse it as an unsigned 63-bit [sic] integer
+ (returning <code>default</code> if the key doesn’t exist).
+ Returns an error if the key exists but its value is not a valid unsigned 63-bit integer.
+ </li>
+ <li>
+ <code>get_float(conf: Configuration, key: String) -&gt; Optional&lt;Float&gt;</code><br>
+ <code>get_float_or_default(conf: Configuration, key: String, default: Float) -&gt; Float</code><br>
+ Get value associated with <code>key</code>, if any exists, and parse it as a 64-bit IEEE-754 double precision
+ floating-point number (returning <code>default</code> if the key doesn’t exist).
+ Returns an error if the key exists but its value is not a valid floating-point number.
+ </li>
+ <li>
+ <code>get_bool(conf: Configuration, key: String) -&gt; Optional&lt;Bool&gt;</code><br>
+ <code>get_bool_or_default(conf: Configuration, key: String, default: Bool) -&gt; Bool</code><br>
+ Get value associated with <code>key</code>, if any exists, and parse it as a boolean,
+ taking <code>true</code>, <code>on</code>, <code>yes</code> to be <code>true</code>, and
+ <code>false</code>, <code>off</code>, <code>no</code> to be <code>false</code> (case-sensitive).
+ Returns an error if the key exists but is not one of the above values.
+ </li>
+ <li>
+ <code>get_list(conf: Configuration, key: String) -&gt; List&lt;String&gt;</code><br>
+ Get value associated with <code>key</code>, if any exists, and parse it as a list,
+ returning an empty list if the key isn’t present.
+ </li>
+ <li>
+ <code>section(conf: Configuration, key: String) -&gt; Configuration</code><br>
+ Get the sub-configuration consisting of the descendants of <code>key</code>, i.e. keys starting with <code>key.</code>
+ (with the initial <code>key.</code> removed) and their corresponding values.
+ Returns an empty configuration if there are no descendants of <code>key</code>.
+ </li>
+ <li>
+ <code>check_schema(schema: Configuration, conf: Configuration) -&gt; Configuration</code> (<i>optional</i>)<br>
+ Check if configuration <code>conf</code> follows the schema <code>schema</code> (and that <code>schema</code>
+ is a valid schema),
+ returning an error with detailed information
+ if it does not. If successful, returns a configuration with default values filled out.
+ </li>
+ <li>
+ <code>merge(conf_a: Configuration, conf_b: Configuration) -&gt; Configuration</code><br>
+ Returns the result of merging <code>conf_b</code> into <code>conf_a</code>.
+ </li>
+</ul>
+
+<h2>Examples</h2>
+
+<h3>A schema for a text editor's configuration</h3>
+<pre><code>
+# don't allow unknown keys by default
+*.allow_unknown = no
+
+# must put this in your config! I can't make the decision for you!
+indent-using-spaces.type = Bool
+
+show-line-numbers.type = Bool
+show-line-numbers.default = on
+
+[tab-size]
+type = UInt
+min = 1
+default = 4
+
+[font-size]
+# allow fractional font sizes; why not!
+type = Float
+min = 0.5
+max = 100
+default = 14
+
+[plug-in]
+*.path.type = String
+# everyone be nice to the Microsoft Windows
+*.path.maxlength = 260
+# allow arbitrary keys in plug-ins' settings
+*.settings.allow_unknown = yes
+
+[file-extensions]
+C.type = List[String]
+C.default = .c, .h
+C++.type = List[String]
+C++.default = .cpp, .hpp, .cc, .hh
+C-sharp.type = List[String]
+C-sharp.default = .cs
+</code></pre>
+
+</body>
+
+</html>