Updated the API documentation.

Updated examples based on the new Loader API.
(Dumper API still needs examples)
This commit is contained in:
Ferdinand Majerech 2011-10-14 10:34:53 +02:00
parent 21001b36b9
commit 765b74ffca
48 changed files with 4555 additions and 1978 deletions

View file

@ -47,10 +47,10 @@
<div class="section" id="custom-yaml-data-types">
<h1>Custom YAML data types<a class="headerlink" href="#custom-yaml-data-types" title="Permalink to this headline"></a></h1>
<p>Often you will want to serialize complex data types such as classes. You can use
functions to process nodes; e.g. a mapping containing class data members indexed
by name. Alternatively, YAML supports custom data types using identifiers called
<em>tags</em>. That is the topic of this tutorial.</p>
<p>Often you might want to serialize complex data types such as classes. You can
use functions to process nodes such as a mapping containing class data members
indexed by name. Alternatively, YAML supports custom data types using
identifiers called <em>tags</em>. That is the topic of this tutorial.</p>
<p>Each YAML node has a tag specifying its type. For instance: strings use the tag
<tt class="docutils literal"><span class="pre">tag:yaml.org,2002:str</span></tt>. Tags of most default types are <em>implicitly resolved</em>
during parsing, so you don&#8217;t need to specify tag for each float, integer, etc.
@ -59,9 +59,9 @@ It is also possible to implicitly resolve custom tags, as we will show later.</p
<h2>Constructor<a class="headerlink" href="#constructor" title="Permalink to this headline"></a></h2>
<p>D:YAML uses the <em>Constructor</em> class to process each node to hold data type
corresponding to its tag. <em>Constructor</em> stores a function for each supported
tag to process it. These functions can be supplied by the user using the
<em>addConstructor()</em> method. <em>Constructor</em> is then passed to <em>Loader</em>, which will
parse YAML input.</p>
tag to process it. These functions are supplied by the user using the
<em>addConstructor()</em> method. <em>Constructor</em> is then passed to <em>Loader</em>, which
parses YAML input.</p>
<p>We will implement support for an RGB color type. It is implemented as the
following struct:</p>
<div class="highlight-d"><div class="highlight"><pre><span class="k">struct</span> <span class="n">Color</span>
@ -146,7 +146,7 @@ RRGGBB, or from a mapping, where we use the following format:
<span class="p">}</span>
</pre></div>
</div>
<p>Next, we need some YAML code using our new tag. Create a file called input.yaml
<p>Next, we need some YAML data using our new tag. Create a file called input.yaml
with the following contents:</p>
<div class="highlight-yaml"><div class="highlight"><pre><span class="l-Scalar-Plain">scalar-red</span><span class="p-Indicator">:</span> <span class="kt">!color</span> <span class="l-Scalar-Plain">FF0000</span>
<span class="l-Scalar-Plain">scalar-orange</span><span class="p-Indicator">:</span> <span class="kt">!color</span> <span class="l-Scalar-Plain">FFFF00</span>
@ -173,9 +173,10 @@ with the following contents:</p>
<span class="n">constructor</span><span class="p">.</span><span class="n">addConstructor</span><span class="p">(</span><span class="s">&quot;!color&quot;</span><span class="p">,</span> <span class="p">&amp;</span><span class="n">constructColorScalar</span><span class="p">);</span>
<span class="n">constructor</span><span class="p">.</span><span class="n">addConstructor</span><span class="p">(</span><span class="s">&quot;!color-mapping&quot;</span><span class="p">,</span> <span class="p">&amp;</span><span class="n">constructColorMapping</span><span class="p">);</span>
<span class="k">auto</span> <span class="n">loader</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Loader</span><span class="p">(</span><span class="s">&quot;input.yaml&quot;</span><span class="p">,</span> <span class="n">constructor</span><span class="p">,</span> <span class="k">new</span> <span class="n">Resolver</span><span class="p">);</span>
<span class="k">auto</span> <span class="n">loader</span> <span class="p">=</span> <span class="n">Loader</span><span class="p">(</span><span class="s">&quot;input.yaml&quot;</span><span class="p">);</span>
<span class="n">loader</span><span class="p">.</span><span class="n">constructor</span> <span class="p">=</span> <span class="n">constructor</span><span class="p">;</span>
<span class="k">auto</span> <span class="n">root</span> <span class="p">=</span> <span class="n">loader</span><span class="p">.</span><span class="n">loadSingleDocument</span><span class="p">();</span>
<span class="k">auto</span> <span class="n">root</span> <span class="p">=</span> <span class="n">loader</span><span class="p">.</span><span class="n">load</span><span class="p">();</span>
<span class="k">if</span><span class="p">(</span><span class="n">root</span><span class="p">[</span><span class="s">&quot;scalar-red&quot;</span><span class="p">].</span><span class="n">get</span><span class="p">!</span><span class="n">Color</span> <span class="p">==</span> <span class="n">red</span> <span class="p">&amp;&amp;</span>
<span class="n">root</span><span class="p">[</span><span class="s">&quot;mapping-red&quot;</span><span class="p">].</span><span class="n">get</span><span class="p">!</span><span class="n">Color</span> <span class="p">==</span> <span class="n">red</span> <span class="p">&amp;&amp;</span>
@ -196,23 +197,21 @@ with the following contents:</p>
</pre></div>
</div>
<p>First, we create a <em>Constructor</em> and pass functions to handle the <tt class="docutils literal"><span class="pre">!color</span></tt>
and <tt class="docutils literal"><span class="pre">!color-mapping</span></tt> tag. We construct a <em>Loader</em> using the <em>Constructor</em>.
We also need a <em>Resolver</em>, but for now we just default-construct it. We then
load the YAML document, and finally, read the colors using <em>get()</em> method to
test if they were loaded as expected.</p>
and <tt class="docutils literal"><span class="pre">!color-mapping</span></tt> tag. We construct a <em>Loader*m and pass the *Constructor</em>
to it. We then load the YAML document, and finally, read the colors using
<em>get()</em> method to test if they were loaded as expected.</p>
<p>You can find the source code for what we&#8217;ve done so far in the
<tt class="docutils literal"><span class="pre">examples/constructor</span></tt> directory in the D:YAML package.</p>
</div>
<div class="section" id="resolver">
<h2>Resolver<a class="headerlink" href="#resolver" title="Permalink to this headline"></a></h2>
<p>Specifying tag for every color value can be tedious. D:YAML can implicitly
resolve tag of a scalar using a regular expression. This is how default types,
e.g. int, are resolved. We will use the <em>Resolver</em> class to add implicit tag
resolve scalar tags using regular expressions. This is how default types such as
int are resolved. We will use the <em>Resolver</em> class to add implicit tag
resolution for the Color data type (in its scalar form).</p>
<p>We use the <em>addImplicitResolver</em> method of <em>Resolver</em>, passing the tag, regular
expression the value must match to resolve to this tag, and a string of possible
starting characters of the value. Then we pass the <em>Resolver</em> to the constructor
of <em>Loader</em>.</p>
starting characters of the value. Then we pass the <em>Resolver</em> to <em>Loader</em>.</p>
<p>Note that resolvers added first override ones added later. If no resolver
matches a scalar, YAML string tag is used. Therefore our custom values must not
be resolvable as any non-string YAML data type.</p>
@ -223,12 +222,15 @@ be resolvable as any non-string YAML data type.</p>
<span class="n">resolver</span><span class="p">.</span><span class="n">addImplicitResolver</span><span class="p">(</span><span class="s">&quot;!color&quot;</span><span class="p">,</span> <span class="n">std</span><span class="p">.</span><span class="n">regex</span><span class="p">.</span><span class="n">regex</span><span class="p">(</span><span class="s">&quot;[0-9a-fA-F]{6}&quot;</span><span class="p">,</span>
<span class="s">&quot;0123456789abcdefABCDEF&quot;</span><span class="p">));</span>
<span class="k">auto</span> <span class="n">loader</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Loader</span><span class="p">(</span><span class="s">&quot;input.yaml&quot;</span><span class="p">,</span> <span class="n">constructor</span><span class="p">,</span> <span class="n">resolver</span><span class="p">);</span>
<span class="k">auto</span> <span class="n">loader</span> <span class="p">=</span> <span class="n">Loader</span><span class="p">(</span><span class="s">&quot;input.yaml&quot;</span><span class="p">);</span>
<span class="n">loader</span><span class="p">.</span><span class="n">constructor</span> <span class="p">=</span> <span class="n">constructor</span><span class="p">;</span>
<span class="n">loader</span><span class="p">.</span><span class="n">resolver</span> <span class="p">=</span> <span class="n">resolver</span><span class="p">;</span>
<span class="c1">//code from the previous example...</span>
</pre></div>
</div>
<p>Now, change contents of input.dyaml to this:</p>
<p>Now, change contents of input.yaml to this:</p>
<div class="highlight-yaml"><div class="highlight"><pre><span class="l-Scalar-Plain">scalar-red</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">FF0000</span>
<span class="l-Scalar-Plain">scalar-orange</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">FFFF00</span>
<span class="l-Scalar-Plain">mapping-red</span><span class="p-Indicator">:</span> <span class="kt">!color-mapping</span> <span class="p-Indicator">{</span><span class="nv">r</span><span class="p-Indicator">:</span> <span class="nv">255</span><span class="p-Indicator">,</span> <span class="nv">g</span><span class="p-Indicator">:</span> <span class="nv">0</span><span class="p-Indicator">,</span> <span class="nv">b</span><span class="p-Indicator">:</span> <span class="nv">0</span><span class="p-Indicator">}</span>
@ -282,8 +284,8 @@ D:YAML package.</p>
</div>
<div class="footer">
&copy; Copyright 2011, Ferdinand Majerech. Based on PyYAML http://www.pyyaml.org by Kirill Simonov.
Last updated on Aug 16, 2011.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.1.
Last updated on Oct 14, 2011.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
</div>
</body>
</html>

View file

@ -64,9 +64,8 @@ Download the version of DMD for your operating system and install it.</p>
<p class="first admonition-title">Note</p>
<p class="last">Other D compilers exist, such as
<a class="reference external" href="http://bitbucket.org/goshawk/gdc/wiki/Home">GDC</a> and
<a class="reference external" href="http://www.dsource.org/projects/ldc/">LDC</a>.
Setting up with either one of them should be similar to DMD,
however, at the moment they are not as up to date as DMD.</p>
<a class="reference external" href="http://www.dsource.org/projects/ldc/">LDC</a>. Setting up with either one of
them should be similar to DMD, but they are not yet as stable as DMD.</p>
</div>
</div>
<div class="section" id="download-and-compile-d-yaml">
@ -109,7 +108,7 @@ into the file:</p>
<span class="kt">void</span> <span class="n">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">yaml</span><span class="p">.</span><span class="n">Node</span> <span class="n">root</span> <span class="p">=</span> <span class="n">yaml</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="s">&quot;input.yaml&quot;</span><span class="p">);</span>
<span class="n">Node</span> <span class="n">root</span> <span class="p">=</span> <span class="n">Loader</span><span class="p">(</span><span class="s">&quot;input.yaml&quot;</span><span class="p">).</span><span class="n">load</span><span class="p">();</span>
<span class="k">foreach</span><span class="p">(</span><span class="nb">string</span> <span class="n">word</span><span class="p">;</span> <span class="n">root</span><span class="p">[</span><span class="s">&quot;Hello World&quot;</span><span class="p">])</span>
<span class="p">{</span>
<span class="n">writeln</span><span class="p">(</span><span class="n">word</span><span class="p">);</span>
@ -122,27 +121,28 @@ into the file:</p>
<h3>Explanation of the code<a class="headerlink" href="#explanation-of-the-code" title="Permalink to this headline"></a></h3>
<p>First, we import the <em>yaml</em> module. This is the only module you need to import
to use D:YAML - it automatically imports all needed modules.</p>
<p>Next we load the file using the <em>yaml.load()</em> function - this loads the file as
<strong>one</strong> YAML document and throws <em>YAMLException</em>, D:YAML exception type, if the
<p>Next we load the file using the <em>Loader.load()</em> method. <em>Loader</em> is the struct
used for parsing YAML documents, and <em>load()</em> is a method that loads the file as
<strong>one</strong> YAML document, or throws <em>YAMLException</em>, D:YAML exception type, if the
file could not be parsed or does not contain exactly one document. Note that we
don&#8217;t do any error checking here in order to keep the example as simple as
possible.</p>
<p><em>yaml.Node</em> represents a node in a YAML document. It can be a sequence (array),
<p><em>Node</em> represents a node in a YAML document. It can be a sequence (array),
mapping (associative array) or a scalar (value). Here the root node is a
mapping, and we use the index operator to get subnodes with keys &#8220;Hello World&#8221;
and &#8220;Answer&#8221;. We iterate over the first, as it is a sequence, and use the
<em>yaml.Node.get()</em> method on the second to get its value as an integer.</p>
<em>Node.get()</em> method on the second to get its value as an integer.</p>
<p>You can iterate over a mapping or sequence as if it was an associative or normal
array. If you try to iterate over a scalar, it will throw a <em>YAMLException</em>.</p>
<p>You can iterate over subnodes using yaml.Node as the iterated type, or specify
<p>You can iterate over subnodes using <em>Node</em> as the iterated type, or specify
the type subnodes are expected to have. D:YAML will automatically convert
iterated subnodes to that type if possible. Here we specify the <em>string</em> type,
so we iterate over the &#8220;Hello World&#8221; sequence as an array of strings. If it is
not possible to convert to iterated type, a <em>YAMLException</em> is thrown. For
instance, if we specified <em>int</em> here, we would get an error, as &#8220;Hello&#8221;
cannot be converted to an integer.</p>
<p>The <em>yaml.Node.get()</em> method is used to get value of a scalar node as specified
type. D:YAML will try to return the scalar as specified type, converting if
<p>The <em>Node.get()</em> method is used to get value of a scalar node, allowing to
specify type. D:YAML will try to return the scalar as this type, converting if
needed, throwing <em>YAMLException</em> if not possible.</p>
</div>
<div class="section" id="compiling">
@ -150,15 +150,14 @@ needed, throwing <em>YAMLException</em> if not possible.</p>
<p>To compile your project, you must give DMD the directories containing import
modules and the library. You also need to tell it to link with D:YAML. The import
directory should be the D:YAML package directory. You can specify it using the
<tt class="docutils literal"><span class="pre">-I</span></tt> option of DMD. The library directory should point to where you put the
compiled D:YAML library. On Unix/Linux you can specify it using the <tt class="docutils literal"><span class="pre">-L-L</span></tt>
option, and link with D:YAML using the <tt class="docutils literal"><span class="pre">-L-l</span></tt> option. On Windows, the import
directory is used as the library directory. To link with the library on Windows,
just add the path to it relative to the current directory.</p>
<p>For example, if you extracted D:YAML to <tt class="docutils literal"><span class="pre">/home/xxx/dyaml</span></tt> and compiled it in
that directory, your project is in <tt class="docutils literal"><span class="pre">/home/xxx/dyaml-project</span></tt>, and you are
currently in that directory, you can compile the project with the following
command on Unix/Linux:</p>
<tt class="docutils literal"><span class="pre">-I</span></tt> option of DMD. The library directory should be where you put the compiled
D:YAML library. On Unix/Linux you can specify it using the <tt class="docutils literal"><span class="pre">-L-L</span></tt> option, and
link with D:YAML using the <tt class="docutils literal"><span class="pre">-L-l</span></tt> option. On Windows, the import directory is
used as the library directory. To link with the library on Windows, just add the
path to it relative to the current directory.</p>
<p>For example, if you extracted and compiled D:YAML in <tt class="docutils literal"><span class="pre">/home/xxx/dyaml</span></tt>, your
project is in <tt class="docutils literal"><span class="pre">/home/xxx/dyaml-project</span></tt>, and you are currently in that
directory, you can compile the project with the following command on Unix/Linux:</p>
<div class="highlight-python"><pre>dmd -I../dyaml -L-L../dyaml -L-ldyaml main.d</pre>
</div>
<p>And the following on Windows:</p>
@ -225,8 +224,8 @@ example in the <tt class="docutils literal"><span class="pre">example/getting_st
</div>
<div class="footer">
&copy; Copyright 2011, Ferdinand Majerech. Based on PyYAML http://www.pyyaml.org by Kirill Simonov.
Last updated on Aug 16, 2011.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.1.
Last updated on Oct 14, 2011.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
</div>
</body>
</html>

View file

@ -52,20 +52,19 @@ information, see <a class="reference external" href="http://pyyaml.org/wiki/PyYA
which this article is based on,
<a class="reference external" href="http://yaml.org/spec/1.1/#id857168">Chapter 2 of the YAML specification</a>
or the <a class="reference external" href="http://en.wikipedia.org/wiki/YAML">Wikipedia page</a>.</p>
<p>YAML is a data serialization format designed to be as human readable as
possible. YAML is a recursive acronym for &#8220;YAML Ain&#8217;t Markup Language&#8221;.</p>
<p>YAML is a data serialization format designed for human readability. YAML is a
recursive acronym for &#8220;YAML Ain&#8217;t Markup Language&#8221;.</p>
<p>YAML is similar to JSON, and in fact, JSON is a subset of YAML 1.2; but YAML has
some more advanced features and is easier to read. However, YAML is also more
some more advanced features and is easier to read. However, it is also more
difficult to parse (and probably somewhat slower). Data is stored in mappings
(associative arrays), sequences (lists) and scalars (single values). Data
structure hierarchy either depends on indentation (block context, similar to
structure hierarchy depends either on indentation (block context, similar to
Python code), or nesting of brackets and braces (flow context, similar to JSON).
YAML comments begin with <tt class="docutils literal"><span class="pre">#</span></tt> and continue until the end of line.</p>
<div class="section" id="documents">
<h2>Documents<a class="headerlink" href="#documents" title="Permalink to this headline"></a></h2>
<p>A YAML stream consists of one or more documents starting with <tt class="docutils literal"><span class="pre">---</span></tt> and
optionally ending with <tt class="docutils literal"><span class="pre">...</span></tt> . If there is only one document, <tt class="docutils literal"><span class="pre">---</span></tt> can be
left out.</p>
optionally ending with <tt class="docutils literal"><span class="pre">...</span></tt> . <tt class="docutils literal"><span class="pre">---</span></tt> can be left out for the first document.</p>
<p>Single document with no explicit start or end:</p>
<div class="highlight-yaml"><div class="highlight"><pre><span class="p-Indicator">-</span> <span class="l-Scalar-Plain">Red</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">Green</span>
@ -96,7 +95,7 @@ left out.</p>
<div class="section" id="sequences">
<h2>Sequences<a class="headerlink" href="#sequences" title="Permalink to this headline"></a></h2>
<p>Sequences are arrays of nodes of any type, similar e.g. to Python lists.
In block context, each item begins with hyphen+space &#8220;- &#8220;. In flow context,
In block context, each item begins with hyphen+space &#8220;- &#8221;. In flow context,
sequences have syntax similar to D arrays.</p>
<div class="highlight-yaml"><div class="highlight"><pre><span class="c1">#Block context</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">Red</span>
@ -137,7 +136,7 @@ sequences have syntax similar to D arrays.</p>
<h2>Mappings<a class="headerlink" href="#mappings" title="Permalink to this headline"></a></h2>
<p>Mappings are associative arrays where each key and value can be of any type,
similar e.g. to Python dictionaries. In block context, keys and values are
separated by colon+space &#8220;: &#8220;. In flow context, mappings have syntax similar
separated by colon+space &#8221;: &#8221;. In flow context, mappings have syntax similar
to D associative arrays, but with braces instead of brackets:</p>
<div class="highlight-yaml"><div class="highlight"><pre><span class="c1">#Block context</span>
<span class="l-Scalar-Plain">CPU</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Athlon</span>
@ -174,7 +173,7 @@ to D associative arrays, but with braces instead of brackets:</p>
<span class="l-Scalar-Plain">OS</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Android</span>
</pre></div>
</div>
<p>Complex keys start with question mark+space &#8220;? &#8220;.</p>
<p>Complex keys start with question mark+space &#8221;? &#8221;.</p>
<div class="highlight-yaml"><div class="highlight"><pre><span class="c1">#Nested in a sequence</span>
<span class="p-Indicator">?</span> <span class="p-Indicator">[</span><span class="nv">CPU</span><span class="p-Indicator">,</span> <span class="nv">GPU</span><span class="p-Indicator">]:</span> <span class="p-Indicator">[</span><span class="nv">Athlon</span><span class="p-Indicator">,</span> <span class="nv">Radeon</span><span class="p-Indicator">]</span>
<span class="l-Scalar-Plain">OS</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Debian</span>
@ -331,8 +330,8 @@ Some of these might change in the future (especially !!map and !!set).</p>
</div>
<div class="footer">
&copy; Copyright 2011, Ferdinand Majerech. Based on PyYAML http://www.pyyaml.org by Kirill Simonov.
Last updated on Aug 16, 2011.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.1.
Last updated on Oct 14, 2011.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
</div>
</body>
</html>