.. title:: The CFG configuration format .. CFG documentation master file, created by sphinx-quickstart on Sun Apr 7 20:48:05 2019. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. .. meta:: :description: Hierarchical configuration format :keywords: CFG, configuration The CFG Configuration Format ============================ The CFG configuration format is a text format for configuration files which is similar to, and a superset of, the JSON format. It dates from before its first announcement in `2008 `_ and has the following aims: * Allow a hierarchical configuration scheme with support for key-value mappings and lists. * Support cross-references between one part of the configuration and another. * Provide a string interpolation facility to easily build up configuration values from other configuration values. * Provide the ability to compose configurations (using include and merge facilities). * Provide the ability to access real application objects safely, where supported by the platform. * Be completely declarative. It overcomes a number of drawbacks of JSON when used as a configuration format: * JSON is more verbose than necessary. * JSON doesn't allow comments. * JSON doesn't provide first-class support for dates and multi-line strings. * JSON doesn't allow trailing commas in lists and mappings. * JSON doesn't provide easy cross-referencing, interpolation, or composition. More details of the design motivation are to be found in the section entitled :ref:`requirements` A page where you can try CFG interactively is available at the section entitled :ref:`playground`. (It uses the :ref:`JavaScript implementation of the CFG API `.) Reference implementations are available for :ref:`Python `, :ref:`the JVM ` (using Kotlin), :ref:`.NET `, :ref:`Go `, :ref:`Rust `, :ref:`D `, :ref:`JavaScript `, :ref:`Ruby `, :ref:`Elixir `, :ref:`Nim ` and :ref:`Dart ` and are licenced using the `3-clause BSD licence `_. There are minimal examples of programs/projects that use CFG `here `_. A Simple Example ---------------- The simplest scenario is, of course, "Hello, world". Let's look at a very simple configuration file :file:`simple.cfg` where a message is configured: .. code-block:: cfg-body :caption: simple.cfg # The configured message (this is a comment) message: 'Hello, world!' A Python program to read this configuration would be: .. code-block:: python from config import Config cfg = Config('simple.cfg') print(cfg['message']) # will print 'Hello, world!' A configuration is, at the top level, a list of key-value pairs. Each value, as we'll see later, can be a list or a key-value mapping, and these can be nested without any arbitrary limits. Nested Values ------------- With the following configuration .. code-block:: cfg-body :caption: langs.cfg nested: { hello: { en: 'Hello' fr: 'Bonjour' de: 'Hallo' es: 'Hola' } goodbye: { en: 'Goodbye' fr: 'Au revoir' de: 'Auf Wiedersehen' es: 'Adiós' } } You can access the nested values in a single step. Again, using Python, we have: .. code-block:: python from config import Config cfg = Config('langs.cfg') print(cfg['nested.hello.es']) # will print 'Hola' print(cfg['nested.goodbye.fr']) # will print 'Au revoir' A Larger Example ---------------- A larger example of a CFG configuration is below. It shows a few more features of the format. .. code-block:: cfg # You can have comments anywhere in a configuration. { # You can have standard JSON-like key-value mapping. "writer": "Oscar Fingal O'Flahertie Wills Wilde", # But also use single-quotes for keys and values. 'a dimension': 'length: 5"', # You can use identifiers for the keys. string_value: 'a string value', integer_value: 3, float_value = 2.71828, # you can use = instead of : as a key-value separator boolean_value: true, # these values are just like in JSON opposite_boolean_value: false, null_value: null list_value: [ 123, 4.5 # note the absence of a comma - a newline acts as a separator, too. [ 1, 'A', 2, 'b', # note the trailing comma - doesn't cause errors ] ] # a comma isn't needed here. nested_mapping: { integer_as_hex: 0x123 float_value: .14159, # note the trailing comma - doesn't cause errors } # no comma needed here either. # You can use escape sequences ... snowman_escaped: '\u2603' # or not, and use e.g. utf-8 encoding. snowman_unescaped: '☃' # You can refer to code points outside the Basic Multilingual Plane face_with_tears_of_joy: '\U0001F602' unescaped_face_with_tears_of_joy: '😂' # Include sub-configurations. logging: @'logging.cfg', # Refer to other values in this configuration. refer_1: ${string_value}, # -> 'a string value' refer_2: ${list_value[1]}, # -> 4.5 refer_3: ${nested_mapping.float_value}, # -> 0.14159 # Special values are implementation-dependent. On Python, for example: s_val_1: `sys:stderr`, # -> module attribute sys.stderr s_val_2: `$LANG|en_GB.UTF-8` # -> environment var with default s_val_3: `2019-03-28T23:27:04.314159` # -> date/time value # Expressions. # N.B. backslash immediately followed by newline is seen as a continuation: pi_approx: ${integer_value} + \ ${nested_mapping.float_value} # -> 3.14159 sept_et_demi: ${integer_value} + \ ${list_value[1]} # -> 7.5 } .. comment We can't mark the toctree as :hidden:, as that seems not to actually build the tree. So we just mark the tree as hidden with a CSS class. .. cssclass:: hidden .. toctree:: :maxdepth: 5 intro features playground api simple_grammar full_grammar glossary Next Steps ---------- If you are interested in knowing more, you might want to look at the :ref:`history`, the :ref:`features`, :ref:`simple-grammar` or the :ref:`api`.