Initial commit.
This commit is contained in:
commit
283c42bf8f
592 changed files with 26392 additions and 0 deletions
139
docsrc/Makefile
Normal file
139
docsrc/Makefile
Normal file
|
@ -0,0 +1,139 @@
|
|||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = ../doc
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean ddoc_html html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
|
||||
################################################################################
|
||||
# DDOC GENERATION CODE
|
||||
################################################################################
|
||||
ddoc_html :
|
||||
cd ../ && ./autoddoc.py
|
||||
################################################################################
|
||||
# DDOC GENERATION CODE END
|
||||
################################################################################
|
||||
|
||||
html: ddoc_html
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/DYAML.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/DYAML.qhc"
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/DYAML"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/DYAML"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
make -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
65
docsrc/articles/spec_differences.rst
Normal file
65
docsrc/articles/spec_differences.rst
Normal file
|
@ -0,0 +1,65 @@
|
|||
.. highlight:: yaml
|
||||
|
||||
=====================================================
|
||||
Differences between D:YAML and the YAML specification
|
||||
=====================================================
|
||||
|
||||
There are some differences between D:YAML and the YAML 1.1 specification. Some
|
||||
are caused by difficulty of implementation of some features, such as multiple
|
||||
Unicode encodings within single stream, and some by unnecessary restrictions or
|
||||
ambiguities in the specification.
|
||||
|
||||
Still, D:YAML tries to be as close to the specification as possible. D:YAML should
|
||||
never load documents with different meaning than according to the specification,
|
||||
and documents that fail to load should be very rare (for instance, very few
|
||||
files use multiple Unicode encodings).
|
||||
|
||||
|
||||
--------------------------
|
||||
List of known differences:
|
||||
--------------------------
|
||||
|
||||
Differences that can cause valid YAML documents not to load:
|
||||
|
||||
* At the moment, all mappings in the internal representation are ordered,
|
||||
and a comparison for equality between equal mappings with differing order
|
||||
will return false. This will be fixed once Phobos has a usable map type or
|
||||
D associative arrays work with variants.
|
||||
* No support for byte order marks and multiple Unicode encodings in a stream.
|
||||
* Plain scalars in flow context cannot contain ``,``, ``:`` and ``?``.
|
||||
This might change with ``:`` in the future.
|
||||
See http://pyyaml.org/wiki/YAMLColonInFlowContext for details.
|
||||
* The specification does not restrict characters for anchors and
|
||||
aliases. This may lead to problems, for instance, the document::
|
||||
|
||||
[ *alias, value ]
|
||||
|
||||
can be interpteted in two ways, as::
|
||||
|
||||
[ "value" ]
|
||||
|
||||
and::
|
||||
|
||||
[ *alias , "value" ]
|
||||
|
||||
Therefore we restrict aliases and anchors to ASCII alphanumeric characters.
|
||||
* The specification is confusing about tabs in plain scalars. We don't use tabs
|
||||
in plain scalars at all.
|
||||
* There is no support for recursive data structures in DYAML.
|
||||
|
||||
Other differences:
|
||||
|
||||
* Indentation is ignored in the flow context, which is less restrictive than the
|
||||
specification. This allows code such as::
|
||||
|
||||
key: {
|
||||
}
|
||||
|
||||
* Indentation rules for quoted scalars are loosed: They don't need to adhere
|
||||
indentation as ``"`` and ``'`` clearly mark the beginning and the end of them.
|
||||
* We allow ``_`` in tag handles.
|
||||
* Right now, two mappings with the same contents but different orderings are
|
||||
considered unequal, even if they are unordered mappings. This is because all
|
||||
mappings are ordered in the D:YAML implementation. This should change in
|
||||
future, once D associative arrays work with variant types or a map class or
|
||||
struct appears in Phobos.
|
19
docsrc/autoddoc_index.dd
Normal file
19
docsrc/autoddoc_index.dd
Normal file
|
@ -0,0 +1,19 @@
|
|||
Ddoc
|
||||
|
||||
$(P
|
||||
This is the complete API documentation for D:YAML. It describes all classes,
|
||||
methods and global functions provided by the library. This is not the best place
|
||||
to start learning how to use D:YAML. Rather, it should serve as a reference when
|
||||
you need detailed information about every bit of D:YAML functionality. You can
|
||||
find more introductory material in D:YAML $(LINK2 ../index.html, tutorials).
|
||||
)
|
||||
|
||||
$(P
|
||||
In this API documentation, each D:YAML module is documented separately. However,
|
||||
to use D:YAML, you don't need to import these modules. All you need to do is
|
||||
import the $(I yaml) module, which will import all needed modules.
|
||||
)
|
||||
|
||||
Macros:
|
||||
TITLE=$(PROJECT_NAME) $(PROJECT_VERSION) API documentation
|
||||
|
236
docsrc/conf.py
Normal file
236
docsrc/conf.py
Normal file
|
@ -0,0 +1,236 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# D:YAML documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sun Jul 24 15:16:35 2011.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = []
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'D:YAML'
|
||||
copyright = (u'2011, Ferdinand Majerech. Based on PyYAML http://www.pyyaml.org '
|
||||
'by Kirill Simonov')
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.1'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
html_theme_options =\
|
||||
{
|
||||
"footerbgcolor" : "#1f252b",
|
||||
"footertextcolor" : "#ccc",
|
||||
"sidebarbgcolor" : "#1f252b",
|
||||
"sidebarlinkcolor" : "#ddd",
|
||||
"relbarbgcolor" : "#303333",
|
||||
"relbartextcolor" : "#ccc",
|
||||
"bgcolor" : "#f6f6f6",
|
||||
"textcolor" : "black",
|
||||
"linkcolor" : "#006",
|
||||
"visitedlinkcolor" : "#606",
|
||||
"headbgcolor" : "#f6f6f6",
|
||||
"headtextcolor" : "#633",
|
||||
"headlinkcolor" : "#006",
|
||||
"codebgcolor" : "fcfcfc",
|
||||
"codetextcolor" : "000066",
|
||||
"bodyfont" : "Verdana, \"Deja Vu\", \"Bitstream Vera Sans\", sans-serif",
|
||||
"headfont" : "Georgia, \"Times New Roman\", Times, serif"
|
||||
}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
html_logo = "logo210.png"
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
html_sidebars = {"**" : ["localtoc.html"]}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
html_domain_indices = False
|
||||
|
||||
# If false, no index is generated.
|
||||
html_use_index = False
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'DYAMLdoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
#latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'DYAML.tex', u'D:YAML Documentation',
|
||||
u'Ferdinand Majerech', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'dyaml', u'D:YAML Documentation',
|
||||
[u'Ferdinand Majerech'], 1)
|
||||
]
|
21
docsrc/index.rst
Normal file
21
docsrc/index.rst
Normal file
|
@ -0,0 +1,21 @@
|
|||
================================
|
||||
Welcome to D:YAML documentation!
|
||||
================================
|
||||
|
||||
`API Documentation <api/index.html>`_
|
||||
|
||||
Tutorials:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
tutorials/getting_started
|
||||
tutorials/custom_types
|
||||
tutorials/yaml_syntax
|
||||
|
||||
Articles:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
articles/spec_differences
|
BIN
docsrc/logo128.png
Normal file
BIN
docsrc/logo128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
docsrc/logo210.png
Normal file
BIN
docsrc/logo210.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
227
docsrc/tutorials/custom_types.rst
Normal file
227
docsrc/tutorials/custom_types.rst
Normal file
|
@ -0,0 +1,227 @@
|
|||
======================
|
||||
Custom YAML data types
|
||||
======================
|
||||
|
||||
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
|
||||
*tags*. That is the topic of this tutorial.
|
||||
|
||||
Each YAML node has a tag specifying its type. For instance: strings use the tag
|
||||
``tag:yaml.org,2002:str``. Tags of most default types are *implicitly resolved*
|
||||
during parsing, so you don't need to specify tag for each float, integer, etc.
|
||||
It is also possible to implicitly resolve custom tags, as we will show later.
|
||||
|
||||
|
||||
-----------
|
||||
Constructor
|
||||
-----------
|
||||
|
||||
D:YAML uses the *Constructor* class to process each node to hold data type
|
||||
corresponding to its tag. *Constructor* stores a function for each supported
|
||||
tag to process it. These functions can be supplied by the user using the
|
||||
*addConstructor()* method. *Constructor* is then passed to *Loader*, which will
|
||||
parse YAML input.
|
||||
|
||||
We will implement support for an RGB color type. It is implemented as the
|
||||
following struct:
|
||||
|
||||
.. code-block:: d
|
||||
|
||||
struct Color
|
||||
{
|
||||
ubyte red;
|
||||
ubyte green;
|
||||
ubyte blue;
|
||||
}
|
||||
|
||||
First, we need a function to construct our data type. It must take two *Mark*
|
||||
structs, which store position of the node in the file, and either a *string*, an
|
||||
array of *Node* or of *Node.Pair*, depending on whether we're constructing our
|
||||
value from a scalar, sequence, or mapping, respectively. In this tutorial, we
|
||||
have functions to construct a color from a scalar, using HTML-like format,
|
||||
RRGGBB, or from a mapping, where we use the following format:
|
||||
{r:RRR, g:GGG, b:BBB} . Code of these functions:
|
||||
|
||||
.. code-block:: d
|
||||
|
||||
Color constructColorScalar(Mark start, Mark end, string value)
|
||||
{
|
||||
if(value.length != 6)
|
||||
{
|
||||
throw new ConstructorException("Invalid color: " ~ value, start, end);
|
||||
}
|
||||
//We don't need to check for uppercase chars this way.
|
||||
value = value.toLower();
|
||||
|
||||
//Get value of a hex digit.
|
||||
uint hex(char c)
|
||||
{
|
||||
if(!std.ascii.isHexDigit(c))
|
||||
{
|
||||
throw new ConstructorException("Invalid color: " ~ value, start, end);
|
||||
}
|
||||
|
||||
if(std.ascii.isDigit(c))
|
||||
{
|
||||
return c - '0';
|
||||
}
|
||||
return c - 'a' + 10;
|
||||
}
|
||||
|
||||
Color result;
|
||||
result.red = cast(ubyte)(16 * hex(value[0]) + hex(value[1]));
|
||||
result.green = cast(ubyte)(16 * hex(value[2]) + hex(value[3]));
|
||||
result.blue = cast(ubyte)(16 * hex(value[4]) + hex(value[5]));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Color constructColorMapping(Mark start, Mark end, Node.Pair[] pairs)
|
||||
{
|
||||
int r, g, b;
|
||||
r = g = b = -1;
|
||||
bool error = pairs.length != 3;
|
||||
|
||||
foreach(ref pair; pairs)
|
||||
{
|
||||
//Key might not be a string, and value might not be an int,
|
||||
//so we need to check for that
|
||||
try
|
||||
{
|
||||
switch(pair.key.get!string)
|
||||
{
|
||||
case "r": r = pair.value.get!int; break;
|
||||
case "g": g = pair.value.get!int; break;
|
||||
case "b": b = pair.value.get!int; break;
|
||||
default: error = true;
|
||||
}
|
||||
}
|
||||
catch(NodeException e)
|
||||
{
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(error || r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255)
|
||||
{
|
||||
throw new ConstructorException("Invalid color", start, end);
|
||||
}
|
||||
|
||||
return Color(cast(ubyte)r, cast(ubyte)g, cast(ubyte)b);
|
||||
}
|
||||
|
||||
Next, we need some YAML code using our new tag. Create a file called input.yaml
|
||||
with the following contents:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
scalar-red: !color FF0000
|
||||
scalar-orange: !color FFFF00
|
||||
mapping-red: !color-mapping {r: 255, g: 0, b: 0}
|
||||
mapping-orange:
|
||||
!color-mapping
|
||||
r: 255
|
||||
g: 255
|
||||
b: 0
|
||||
|
||||
You can see that we're using tag ``!color`` for scalar colors, and
|
||||
``!color-mapping`` for colors expressed as mappings.
|
||||
|
||||
Finally, the code to put it all together:
|
||||
|
||||
.. code-block:: d
|
||||
|
||||
void main()
|
||||
{
|
||||
auto red = Color(255, 0, 0);
|
||||
auto orange = Color(255, 255, 0);
|
||||
|
||||
try
|
||||
{
|
||||
auto constructor = new Constructor;
|
||||
//both functions handle the same tag, but one handles scalar, one mapping.
|
||||
constructor.addConstructor("!color", &constructColorScalar);
|
||||
constructor.addConstructor("!color-mapping", &constructColorMapping);
|
||||
|
||||
auto loader = new Loader("input.yaml", constructor, new Resolver);
|
||||
|
||||
auto root = loader.loadSingleDocument();
|
||||
|
||||
if(root["scalar-red"].get!Color == red &&
|
||||
root["mapping-red"].get!Color == red &&
|
||||
root["scalar-orange"].get!Color == orange &&
|
||||
root["mapping-orange"].get!Color == orange)
|
||||
{
|
||||
writeln("SUCCESS");
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch(YAMLException e)
|
||||
{
|
||||
writeln(e.msg);
|
||||
}
|
||||
|
||||
writeln("FAILURE");
|
||||
}
|
||||
|
||||
First, we create a *Constructor* and pass functions to handle the ``!color``
|
||||
and ``!color-mapping`` tag. We construct a *Loader* using the *Constructor*.
|
||||
We also need a *Resolver*, but for now we just default-construct it. We then
|
||||
load the YAML document, and finally, read the colors using *get()* method to
|
||||
test if they were loaded as expected.
|
||||
|
||||
You can find the source code for what we've done so far in the
|
||||
``examples/constructor`` directory in the D:YAML package.
|
||||
|
||||
|
||||
--------
|
||||
Resolver
|
||||
--------
|
||||
|
||||
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 *Resolver* class to add implicit tag
|
||||
resolution for the Color data type (in its scalar form).
|
||||
|
||||
We use the *addImplicitResolver* method of *Resolver*, 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 *Resolver* to the constructor
|
||||
of *Loader*.
|
||||
|
||||
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.
|
||||
|
||||
Add this to your code to add implicit resolution of ``!color``.
|
||||
|
||||
.. code-block:: d
|
||||
|
||||
//code from the previous example...
|
||||
|
||||
auto resolver = new Resolver;
|
||||
resolver.addImplicitResolver("!color", std.regex.regex("[0-9a-fA-F]{6}",
|
||||
"0123456789abcdefABCDEF"));
|
||||
|
||||
auto loader = new Loader("input.yaml", constructor, resolver);
|
||||
|
||||
//code from the previous example...
|
||||
|
||||
Now, change contents of input.dyaml to this:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
scalar-red: FF0000
|
||||
scalar-orange: FFFF00
|
||||
mapping-red: !color-mapping {r: 255, g: 0, b: 0}
|
||||
mapping-orange:
|
||||
!color-mapping
|
||||
r: 255
|
||||
g: 255
|
||||
b: 0
|
||||
|
||||
We no longer need to specify the tag for scalar color values. Compile and test
|
||||
the example. If everything went as expected, it should report success.
|
||||
|
||||
You can find the complete code in the ``examples/resolver`` directory in the
|
||||
D:YAML package.
|
168
docsrc/tutorials/getting_started.rst
Normal file
168
docsrc/tutorials/getting_started.rst
Normal file
|
@ -0,0 +1,168 @@
|
|||
===============
|
||||
Getting started
|
||||
===============
|
||||
|
||||
Welcome to D:YAML! D:YAML is a `YAML <http://en.wikipedia.org/wiki/YAML>`_ parser
|
||||
library for the `D programming language <http://d-p-l.org>`_. This tutorial will
|
||||
explain how to set D:YAML up and use it in your projects.
|
||||
|
||||
This is meant to be the **simplest possible** introduction to D:YAML. Some of the
|
||||
information present might already be known to you. Only basic usage is covered.
|
||||
More advanced usage is described in other tutorials.
|
||||
|
||||
|
||||
----------
|
||||
Setting up
|
||||
----------
|
||||
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Install the DMD compiler
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Digital Mars D compiler, or DMD, is the most commonly used D compiler. You can
|
||||
find its newest version `here <http://www.digitalmars.com/d/download.html>`_.
|
||||
Download the version of DMD for your operating system and install it.
|
||||
|
||||
.. note::
|
||||
Other D compilers exist, such as
|
||||
`GDC <http://bitbucket.org/goshawk/gdc/wiki/Home>`_ and
|
||||
`LDC <http://www.dsource.org/projects/ldc/>`_.
|
||||
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.
|
||||
|
||||
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Download and compile D:YAML
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The newest version of D:YAML can be found `here <TODO>`_. Download a source
|
||||
archive, extract it, and move to the extracted directory.
|
||||
|
||||
D:YAML uses a modified version of the `CDC <http://dsource.org/projects/cdc/>`_
|
||||
script for compilation. To compile D:YAML, you first need to build CDC.
|
||||
Do this by typing the following command into the console::
|
||||
|
||||
dmd cdc.d
|
||||
|
||||
Now you can use CDC to compile D:YAML.
|
||||
To do this on Unix/Linux, use the following command::
|
||||
|
||||
./cdc
|
||||
|
||||
On Windows::
|
||||
|
||||
cdc.exe
|
||||
|
||||
This will compile the library to a file called ``libdyaml.a`` on Unix/Linux or
|
||||
``libdyaml.lib`` on Windows.
|
||||
|
||||
|
||||
-------------------------
|
||||
Your first D:YAML project
|
||||
-------------------------
|
||||
|
||||
Create a directory for your project and in that directory, create a file called
|
||||
``input.yaml`` with the following contents:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Hello World :
|
||||
- Hello
|
||||
- World
|
||||
Answer: 42
|
||||
|
||||
This will serve as input for our example.
|
||||
|
||||
Now we need to parse it. Create a file called "main.d". Paste following code
|
||||
into the file:
|
||||
|
||||
.. code-block:: d
|
||||
|
||||
import std.stdio;
|
||||
import yaml;
|
||||
|
||||
void main()
|
||||
{
|
||||
yaml.Node root = yaml.load("input.yaml");
|
||||
foreach(string word; root["Hello World"])
|
||||
{
|
||||
writeln(word);
|
||||
}
|
||||
writeln("The answer is ", root["Answer"].get!int);
|
||||
}
|
||||
|
||||
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Explanation of the code
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
First, we import the *yaml* module. This is the only module you need to import
|
||||
to use D:YAML - it automatically imports all needed modules.
|
||||
|
||||
Next we load the file using the *yaml.load()* function - this loads the file as
|
||||
**one** YAML document and throws *YAMLException*, D:YAML exception type, if the
|
||||
file could not be parsed or does not contain exactly one document. Note that we
|
||||
don't do any error checking here in order to keep the example as simple as
|
||||
possible.
|
||||
|
||||
*yaml.Node* 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 "Hello World"
|
||||
and "Answer". We iterate over the first, as it is a sequence, and use the
|
||||
*yaml.Node.get()* method on the second to get its value as an integer.
|
||||
|
||||
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 *YAMLException*.
|
||||
|
||||
You can iterate over subnodes using yaml.Node 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 *string* type,
|
||||
so we iterate over the "Hello World" sequence as an array of strings. If it is
|
||||
not possible to convert to iterated type, a *YAMLException* is thrown. For
|
||||
instance, if we specified *int* here, we would get an error, as "Hello"
|
||||
cannot be converted to an integer.
|
||||
|
||||
The *yaml.Node.get()* 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
|
||||
needed, throwing *YAMLException* if not possible.
|
||||
|
||||
|
||||
^^^^^^^^^
|
||||
Compiling
|
||||
^^^^^^^^^
|
||||
|
||||
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
|
||||
``-I`` 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 ``-L-L``
|
||||
option, and link with D:YAML using the ``-L-l`` 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.
|
||||
|
||||
For example, if you extracted D:YAML to ``/home/xxx/dyaml`` and compiled it in
|
||||
that directory, your project is in ``/home/xxx/dyaml-project``, and you are
|
||||
currently in that directory, you can compile the project with the following
|
||||
command on Unix/Linux::
|
||||
|
||||
dmd -I../dyaml -L-L../dyaml -L-ldyaml main.d
|
||||
|
||||
And the following on Windows::
|
||||
|
||||
dmd -I../dyaml ../dyaml/libdyaml.lib main.d
|
||||
|
||||
This will produce an executable called ``main`` or ``main.exe`` in your
|
||||
directory. When you run it, it should produce the following output::
|
||||
|
||||
Hello
|
||||
World
|
||||
The answer is 42
|
||||
|
||||
|
||||
^^^^^^^^^^
|
||||
Conclusion
|
||||
^^^^^^^^^^
|
||||
|
||||
You should now have a basic idea about how to use D:YAML. To learn more, look at
|
||||
the `API documentation <../api/index.html>`_ and other tutorials. You can find code for this
|
||||
example in the ``example/getting_started`` directory in the package.
|
273
docsrc/tutorials/yaml_syntax.rst
Normal file
273
docsrc/tutorials/yaml_syntax.rst
Normal file
|
@ -0,0 +1,273 @@
|
|||
===========
|
||||
YAML syntax
|
||||
===========
|
||||
|
||||
This is an introduction to the most common YAML constructs. For more detailed
|
||||
information, see `PyYAML documentation <http://pyyaml.org/wiki/PyYAMLDocumentation>`_,
|
||||
which this article is based on,
|
||||
`Chapter 2 of the YAML specification <http://yaml.org/spec/1.1/#id857168>`_
|
||||
or the `Wikipedia page <http://en.wikipedia.org/wiki/YAML>`_.
|
||||
|
||||
YAML is a data serialization format designed to be as human readable as
|
||||
possible. YAML is a recursive acronym for "YAML Ain't Markup Language".
|
||||
|
||||
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
|
||||
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
|
||||
Python code), or nesting of brackets and braces (flow context, similar to JSON).
|
||||
YAML comments begin with ``#`` and continue until the end of line.
|
||||
|
||||
|
||||
---------
|
||||
Documents
|
||||
---------
|
||||
|
||||
A YAML stream consists of one or more documents starting with ``---`` and
|
||||
optionally ending with ``...`` . If there is only one document, ``---`` can be
|
||||
left out.
|
||||
|
||||
Single document with no explicit start or end:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- Red
|
||||
- Green
|
||||
- Blue
|
||||
|
||||
Same document with explicit start and end:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
- Red
|
||||
- Green
|
||||
- Blue
|
||||
...
|
||||
|
||||
A stream containing multiple documents:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
- Red
|
||||
- Green
|
||||
- Blue
|
||||
---
|
||||
- Linux
|
||||
- BSD
|
||||
---
|
||||
answer : 42
|
||||
|
||||
|
||||
---------
|
||||
Sequences
|
||||
---------
|
||||
|
||||
Sequences are arrays of nodes of any type, similar e.g. to Python lists.
|
||||
In block context, each item begins with hyphen+space "- ". In flow context,
|
||||
sequences have syntax similar to D arrays.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
#Block context
|
||||
- Red
|
||||
- Green
|
||||
- Blue
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
#Flow context
|
||||
[Red, Green, Blue]
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
#Nested
|
||||
-
|
||||
- Red
|
||||
- Green
|
||||
- Blue
|
||||
-
|
||||
- Linux
|
||||
- BSD
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
#Nested flow
|
||||
[[Red, Green, Blue], [Linux, BSD]]
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
#Nested in a mapping
|
||||
Colors:
|
||||
- Red
|
||||
- Green
|
||||
- Blue
|
||||
Operating systems:
|
||||
- Linux
|
||||
- BSD
|
||||
|
||||
|
||||
--------
|
||||
Mappings
|
||||
--------
|
||||
|
||||
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 ": ". In flow context, mappings have syntax similar
|
||||
to D associative arrays, but with braces instead of brackets:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
#Block context
|
||||
CPU: Athlon
|
||||
GPU: Radeon
|
||||
OS: Linux
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
#Flow context
|
||||
{CPU: Athlon, GPU: Radeon, OS: Linux}
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
#Nested
|
||||
PC:
|
||||
CPU: Athlon
|
||||
GPU: Radeon
|
||||
OS: Debian
|
||||
Phone:
|
||||
CPU: Cortex
|
||||
GPU: PowerVR
|
||||
OS: Android
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
#Nested flow
|
||||
{PC: {CPU: Athlon, GPU: Radeon, OS: Debian},
|
||||
Phone: {CPU: Cortex, GPU: PowerVR, OS: Android}}
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
#Nested in a sequence
|
||||
- CPU: Athlon
|
||||
GPU: Radeon
|
||||
OS: Debian
|
||||
- CPU: Cortex
|
||||
GPU: PowerVR
|
||||
OS: Android
|
||||
|
||||
Complex keys start with question mark+space "? ".
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
#Nested in a sequence
|
||||
? [CPU, GPU]: [Athlon, Radeon]
|
||||
OS: Debian
|
||||
|
||||
|
||||
-------
|
||||
Scalars
|
||||
-------
|
||||
|
||||
Scalars are simple values such as integers, strings, timestamps and so on.
|
||||
There are multiple scalar styles.
|
||||
|
||||
Plain scalars use no quotes, start with the first non-space and end with the
|
||||
last non-space character:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
scalar: Plain scalar
|
||||
|
||||
Single quoted scalars start and end with single quotes. A single quote is
|
||||
represented by a pair of single quotes ''.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
scalar: 'Single quoted scalar ending with some spaces '
|
||||
|
||||
Double quoted scalars support C-style escape sequences.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
scalar: "Double quoted scalar \n with some \\ escape sequences"
|
||||
|
||||
Block scalars are convenient for multi-line values. They start either with
|
||||
``|`` or with ``>``. With ``|``, the newlines in the scalar are preserved.
|
||||
With ``>``, the newlines between two non-empty lines are removed.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
scalar: |
|
||||
Newlines are preserved
|
||||
First line
|
||||
Second line
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
scalar: >
|
||||
Newlines are folded
|
||||
This is still the first paragraph
|
||||
|
||||
This is the second
|
||||
paragraph
|
||||
|
||||
|
||||
-------------------
|
||||
Anchors and aliases
|
||||
-------------------
|
||||
|
||||
Anchors and aliases can reduce size of YAML code by allowing you to define a
|
||||
value once, assign an anchor to it and use alias referring to that anchor
|
||||
anywhere else you need that value. It is possible to use this to create
|
||||
recursive data structures and some parsers support this; however, D:YAML does
|
||||
not (this might change in the future, but it is unlikely).
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Person: &AD
|
||||
gender: male
|
||||
name: Arthur Dent
|
||||
Clone: *AD
|
||||
|
||||
|
||||
----
|
||||
Tags
|
||||
----
|
||||
|
||||
Tags are identifiers that specify data types of YAML nodes. Most default YAML
|
||||
tags are resolved implicitly, so there is no need to specify them. D:YAML also
|
||||
supports implicit resolution for custom, user specified tags.
|
||||
|
||||
Explicitly specified tags:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
answer: !!int "42"
|
||||
name: !!str "Arthur Dent"
|
||||
|
||||
Implicit tags:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
answer: 42 #int
|
||||
name: Arthur Dent #string
|
||||
|
||||
This table shows D types stored in *yaml.Node* default YAML tags are converted to.
|
||||
Some of these might change in the future (especially !!map and !!set).
|
||||
|
||||
====================== ================
|
||||
YAML tag D type
|
||||
====================== ================
|
||||
!!null yaml.YAMLNull
|
||||
!!bool bool
|
||||
!!int long
|
||||
!!float real
|
||||
!!binary ubyte[]
|
||||
!!timestamp datetime.SysTime
|
||||
!!map, !!omap, !!pairs Node.Pair[]
|
||||
!!seq, !!set Node[]
|
||||
!!str string
|
||||
====================== ================
|
Loading…
Add table
Add a link
Reference in a new issue