├── static
├── .nojekyll
└── img
│ ├── favicon.ico
│ ├── old
│ ├── favicon.ico
│ └── logo.svg
│ ├── gura-thumbnail.png
│ ├── logos
│ ├── gura-200.png
│ ├── gura-500.png
│ └── gura-thumbnail.png
│ ├── differences
│ ├── gura.png
│ ├── json.png
│ ├── toml.png
│ └── yaml.png
│ ├── features
│ ├── simple.png
│ ├── friendly.png
│ └── robustness.png
│ └── logos-usage
│ ├── blog.png
│ ├── development.png
│ └── IDE-extension.png
├── docs
├── Developers
│ ├── _category_.yml
│ ├── introduction.md
│ ├── availability.md
│ ├── parsing.md
│ ├── abnf.md
│ └── tokenization.md
├── conventions.md
├── gura.md
├── changelog.md
└── spec.md
├── versions.json
├── .vscode
└── settings.json
├── CHANGELOG.md
├── src
├── theme
│ └── CodeSnippet
│ │ ├── styles.module.css
│ │ └── index.js
├── components
│ ├── HomepageFeatures.module.css
│ ├── ResourcesUsage
│ │ ├── ResourcesUsage.module.css
│ │ └── ResourcesUsage.tsx
│ ├── ResourceList
│ │ ├── ResourceList.module.css
│ │ └── ResourceList.tsx
│ ├── HomepageFeatures.tsx
│ ├── FeaturesReview
│ │ └── FeaturesReview.tsx
│ └── Differences
│ │ └── Differences.tsx
├── pages
│ ├── index.module.css
│ ├── resources.tsx
│ └── index.tsx
├── prism_themes
│ ├── monokai
│ │ └── index.js
│ └── github
│ │ └── index.js
└── css
│ └── custom.scss
├── babel.config.js
├── versioned_sidebars
└── version-1.0.0-sidebars.json
├── tsconfig.json
├── .gitignore
├── sidebars.js
├── versioned_docs
└── version-1.0.0
│ ├── conventions.md
│ ├── gura.md
│ ├── abnf.md
│ └── spec.md
├── LICENSE
├── package.json
├── docusaurus.config.js
└── README.md
/static/.nojekyll:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/Developers/_category_.yml:
--------------------------------------------------------------------------------
1 | position: 5
--------------------------------------------------------------------------------
/versions.json:
--------------------------------------------------------------------------------
1 | [
2 | "1.0.0"
3 | ]
4 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "git.ignoreLimitWarning": true
3 | }
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 0.1.0 / 2013-03-17
2 |
3 | * First release.
4 |
--------------------------------------------------------------------------------
/src/theme/CodeSnippet/styles.module.css:
--------------------------------------------------------------------------------
1 | .codeSnippet {
2 | font-size: 10pt;
3 | }
--------------------------------------------------------------------------------
/static/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/favicon.ico
--------------------------------------------------------------------------------
/static/img/old/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/old/favicon.ico
--------------------------------------------------------------------------------
/static/img/gura-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/gura-thumbnail.png
--------------------------------------------------------------------------------
/static/img/logos/gura-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/logos/gura-200.png
--------------------------------------------------------------------------------
/static/img/logos/gura-500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/logos/gura-500.png
--------------------------------------------------------------------------------
/static/img/differences/gura.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/differences/gura.png
--------------------------------------------------------------------------------
/static/img/differences/json.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/differences/json.png
--------------------------------------------------------------------------------
/static/img/differences/toml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/differences/toml.png
--------------------------------------------------------------------------------
/static/img/differences/yaml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/differences/yaml.png
--------------------------------------------------------------------------------
/static/img/features/simple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/features/simple.png
--------------------------------------------------------------------------------
/static/img/logos-usage/blog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/logos-usage/blog.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
3 | };
4 |
--------------------------------------------------------------------------------
/static/img/features/friendly.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/features/friendly.png
--------------------------------------------------------------------------------
/static/img/features/robustness.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/features/robustness.png
--------------------------------------------------------------------------------
/static/img/logos/gura-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/logos/gura-thumbnail.png
--------------------------------------------------------------------------------
/static/img/logos-usage/development.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/logos-usage/development.png
--------------------------------------------------------------------------------
/static/img/logos-usage/IDE-extension.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gura-conf/gura/HEAD/static/img/logos-usage/IDE-extension.png
--------------------------------------------------------------------------------
/versioned_sidebars/version-1.0.0-sidebars.json:
--------------------------------------------------------------------------------
1 | {
2 | "version-1.0.0/guraSidebar": [
3 | {
4 | "type": "autogenerated",
5 | "dirName": "."
6 | }
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/src/components/HomepageFeatures.module.css:
--------------------------------------------------------------------------------
1 | /* stylelint-disable docusaurus/copyright-header */
2 |
3 | .features {
4 | display: flex;
5 | align-items: center;
6 | padding: 2rem 0;
7 | width: 100%;
8 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@tsconfig/docusaurus/tsconfig.json",
3 | "include": [
4 | "src/"
5 | ],
6 | "compilerOptions": {
7 | "jsx": "react",
8 | "moduleResolution": "node"
9 | }
10 | }
--------------------------------------------------------------------------------
/src/components/ResourcesUsage/ResourcesUsage.module.css:
--------------------------------------------------------------------------------
1 | /* stylelint-disable docusaurus/copyright-header */
2 |
3 | .usage-img {
4 | border-radius: 5px;
5 | }
6 |
7 | @media screen and (max-width: 966px) {
8 | .usage-img {
9 | margin-top: 10%;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/components/ResourceList/ResourceList.module.css:
--------------------------------------------------------------------------------
1 | .logo-img {
2 | height: 200px;
3 | width: 200px;
4 | }
5 |
6 | @media screen and (max-width: 966px) {
7 | .logo-img {
8 | float: left;
9 | }
10 |
11 | .download-buttons-div {
12 | display: inline;
13 | vertical-align: text-bottom;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | /node_modules
3 |
4 | # Production
5 | /build
6 |
7 | # Generated files
8 | .docusaurus
9 | .cache-loader
10 |
11 | # Misc
12 | .DS_Store
13 | .env.local
14 | .env.development.local
15 | .env.test.local
16 | .env.production.local
17 |
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
--------------------------------------------------------------------------------
/sidebars.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creating a sidebar enables you to:
3 | - create an ordered group of docs
4 | - render a sidebar for each doc of that group
5 | - provide next/previous navigation
6 |
7 | The sidebars can be generated from the filesystem, or explicitly defined here.
8 |
9 | Create as many sidebars as you want.
10 | */
11 |
12 | module.exports = {
13 | // By default, Docusaurus generates a sidebar from the docs folder structure
14 | guraSidebar: [{type: 'autogenerated', dirName: '.'}],
15 | };
16 |
--------------------------------------------------------------------------------
/src/pages/index.module.css:
--------------------------------------------------------------------------------
1 | /* stylelint-disable docusaurus/copyright-header */
2 |
3 | /**
4 | * CSS files with the .module.css suffix will be treated as CSS modules
5 | * and scoped locally.
6 | */
7 |
8 | .mainBanner {
9 | padding: 4rem 0;
10 | /* text-align: center; */
11 | position: relative;
12 | overflow: hidden;
13 | }
14 |
15 | @media screen and (max-width: 966px) {
16 | .mainBanner {
17 | padding: 2rem;
18 | }
19 | }
20 |
21 | .buttons {
22 | display: flex;
23 | align-items: left;
24 | justify-content: left;
25 | }
26 |
--------------------------------------------------------------------------------
/versioned_docs/version-1.0.0/conventions.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 3
3 | ---
4 |
5 | # Conventions
6 |
7 |
8 | ## Filename Extension
9 |
10 | Gura files should use the extension `.ura`.
11 |
12 |
13 | ## File naming convention
14 |
15 | As with keys, file names should have short, all-lowercase names and underscores can be used if it improves readability.
16 |
17 |
18 | ## MIME Type
19 |
20 | When transferring Gura files over the internet, the appropriate MIME type is `application/gura`.
21 |
22 |
23 | ## ABNF Grammar
24 |
25 | A formal description of Gura's syntax is available in the [ABNF section][abnf].
26 |
27 |
28 | ## License
29 |
30 | Gura is distributed under the terms of the MIT license.
31 |
32 |
33 | [abnf]: abnf.md
--------------------------------------------------------------------------------
/docs/conventions.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 4
3 | description: 'Gura conventions and license'
4 | keywords: ['File name extension', 'Conventions', 'MIME', 'ABNF', 'License']
5 | ---
6 |
7 | # Conventions
8 |
9 |
10 | ## Filename extension
11 |
12 | Gura files should use the extension `.ura`.
13 |
14 |
15 | ## File naming convention
16 |
17 | As with keys, file names should have short, all-lowercase names and underscores can be used if it improves readability.
18 |
19 |
20 | ## MIME type
21 |
22 | When transferring Gura files over the internet, the appropriate MIME type is `application/gura`.
23 |
24 |
25 | ## ABNF grammar
26 |
27 | A formal description of Gura's syntax is available in the [ABNF section][abnf].
28 |
29 |
30 | ## License
31 |
32 | Gura is distributed under the terms of the MIT license.
33 |
34 |
35 | [abnf]: Developers/abnf.md
36 |
--------------------------------------------------------------------------------
/versioned_docs/version-1.0.0/gura.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 1
3 | ---
4 |
5 |
6 | # Gura
7 |
8 | Gura configuration file.
9 |
10 | By Jware solutions.
11 |
12 |
13 |
14 |
15 | ## Objectives
16 |
17 | Gura aims to be a minimal configuration file format that's easy to read due to its similarity with YAML. The key of the language is that there is one and only one way to do things. That feature make it ease to learn, parse, implement and understand.
18 |
19 |
20 | ## Standard errors
21 |
22 | The Gura specifications define the semantic errors that should be thrown in certain situations to define implementation-agnostic behavior so that you can receive the same type of error regardless of the programming language from which you are using Gura.
23 |
24 | Each type of error will be mentioned in the respective sections.
25 |
--------------------------------------------------------------------------------
/src/prism_themes/monokai/index.js:
--------------------------------------------------------------------------------
1 | // Converted automatically using ./tools/themeFromVsCode
2 | var theme = {
3 | "plain": {
4 | "color": "#f8f8f2",
5 | "backgroundColor": "#272822"
6 | },
7 | "styles": [{
8 | "types": ["comment"],
9 | "style": {
10 | "color": "rgb(136, 132, 111)"
11 | }
12 | }, {
13 | "types": ["string", "changed"],
14 | "style": {
15 | "color": "rgb(230, 219, 116)"
16 | }
17 | }, {
18 | "types": ["punctuation", "tag", "deleted"],
19 | "style": {
20 | "color": "rgb(249, 38, 114)"
21 | }
22 | }, {
23 | "types": ["number", "builtin"],
24 | "style": {
25 | "color": "rgb(174, 129, 255)"
26 | }
27 | }, {
28 | "types": ["variable"],
29 | "style": {
30 | "color": "rgb(248, 248, 242)"
31 | }
32 | }, {
33 | "types": ["function", "attr-name", "inserted"],
34 | "style": {
35 | "color": "rgb(166, 226, 46)"
36 | }
37 | }]
38 | };
39 | module.exports = theme;
40 |
--------------------------------------------------------------------------------
/docs/gura.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 1
3 | description: 'Gura documentation introduction'
4 | keywords: ['Gura', 'Config lang', 'Gura documentation']
5 | ---
6 |
7 |
8 | # Gura
9 |
10 | Gura configuration language. By [JWare solutions][jware-organization].
11 |
12 |
13 |
14 |
15 | ## Objectives
16 |
17 | Gura aims to be a minimal configuration file format that's easy to read due to its similarity with YAML. The key of the language is that there is one and only one way to do things. That feature make it ease to learn, parse, implement and understand.
18 |
19 |
20 | ## Standard errors
21 |
22 | The Gura specifications define the semantic errors that should be thrown in certain situations to define implementation-agnostic behavior so that you can receive the same type of error regardless of the programming language from which you are using Gura.
23 |
24 | Each type of error will be mentioned in the respective sections.
25 |
26 |
27 | [jware-organization]: https://github.com/jware-solutions/
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 JWare Solutions
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/docs/Developers/introduction.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Introduction
3 | sidebar_position: 1
4 | ---
5 |
6 | # Developers section
7 |
8 | The following section is intended for those developers who want to implement Gura, if you are implementing a parser, a serialization/deserialization tool, a content generator in Gura format, or any other project that uses this language, this section is for you!
9 |
10 | If you are looking for the language specifications to use in your projects, you can check the [official specifications][specs] or use an [existing implementation][implementations].
11 |
12 | This section will detail the basic structure that your future implementation should cover, such as the data types, errors that should be thrown in certain situations, conventions, etc. Some resources that may be useful are also provided.
13 |
14 | If you are a designer and you are looking for official resources for your designs, you can check the [Resources section][resources] where the official logos are available for free usage.
15 |
16 |
17 | [specs]: /docs/gura
18 | [implementations]: https://github.com/gura-conf/gura#library-implementations
19 | [resources]: /resources
20 |
--------------------------------------------------------------------------------
/src/pages/resources.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Layout from "@theme/Layout";
3 | import { ResourcesUsage } from '../components/ResourcesUsage/ResourcesUsage'
4 | import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
5 | import styles from "./index.module.css";
6 | import { ResourceList } from '../components/ResourceList/ResourceList'
7 |
8 |
9 | export default function ResourcesPage() {
10 | const { siteConfig } = useDocusaurusContext();
11 | const pageTitle = `${siteConfig.title} Official branding`
12 |
13 | return (
14 |
21 | If you are developing your own tool for Gura management, be it a parser, an IDE extension or just want to mention the language, you are free to use our official logos.
22 | {example.description}{pageTitle}
20 |
41 | {tokens.map((line, i) => (
42 |
49 | )}
50 |
53 |
{example.title}
56 |
{props.description}
51 |47 | Gura is a file format for configuration files. Gura is as readable as YAML and simple as TOML. Its syntax is clear and powerful, yet familiar for YAML/TOML users. 48 |
49 |144 | Gura was born from the need to have a configuration language that is human readable without falling into the unnecessary complexity of popular formats such as YAML. 145 |
146 | 148 | Read more in the full specs! 149 | 150 |23 | YAML offered a readable alternative to JSON or INI for a configuration file. While TOML was great for basic files because of its simplicity, YAML provided a readable solution when the complexity of the file grew. However, as the NOYAML manifesto argues, we should stop supporting that format. The reason? YAML is unnecessarily complex. We highlight main issues with YAML that Gura tries to solve. 24 | 25 |
44 | It's easy, JSON is and will be the fastest serialization language available. Gura is not meant for fast processing and/or machine-to-machine communication. When a readable, simple, and maintainable language is needed Gura becomes an excellent alternative. 45 |
46 | > 47 | ), 48 | }, 49 | { 50 | title: 'Differences with TOML', 51 | imageUrl: 'img/differences/toml.png', 52 | description: ( 53 | <> 54 |55 | The idea of Gura is not to replace TOML but to complement it when the complexity of the project warrants it. The use of TOML for files such as cargo.toml in the Rust programming language is an excellent example of matching the complexity of the language to that of the domain. However, when the level of nesting increases, TOML is very cumbersome since you must resort to repeating all the parent levels (using Dotted keys) every time you want to define a nested value. 56 | 57 | Furthermore, even TOML falls in some cases into the same complexity as YAML, with features such as: 58 | 59 |
74 | Gura combines the readability of YAML and a reduced version of its syntax with the (even more simplified) simplicity of TOML. It also brings in some features and characteristics exclusive to this language: 75 | 76 |
{description}
111 |
2 |
3 | # Gura
4 |
5 | [](https://app.netlify.com/sites/gura/deploys)
6 |
7 | Gura is a file format for *configuration files*. Gura is as **flexible as YAML** and **simple and readable like TOML**. Its syntax is clear and powerful, yet familiar for YAML/TOML users:
8 |
9 | > This repository contains the source code of the Gura specification.
10 | > You can find the released versions at https://gura.netlify.app/.
11 |
12 | ```yaml
13 | # This is a comment in a Gura configuration file.
14 | # Define a variable named `title` with string value "Gura Example"
15 | title: "Gura Example"
16 |
17 | # Define an object with fields `username` and `age`
18 | # with string and integer values, respectively
19 | # Indentation is used to indicate nesting
20 | person:
21 | username: "Stephen"
22 | age: 20
23 |
24 | # Define a list of values
25 | # Line breaks are OK when inside arrays
26 | hosts: [
27 | "alpha",
28 | "omega"
29 | ]
30 |
31 | # Variables can be defined and referenced to avoid repetition
32 | $foreground: "#FFAH84"
33 | color_scheme:
34 | editor: $foreground
35 | ui: $foreground
36 |
37 | ```
38 | The file extension for Gura is `ura`. We recommend the filename `config.ura` for main configuration files.
39 |
40 | To learn more about Gura, you can read the [Official Gura Documentation][specs].
41 |
42 | Currently, Gura has, among many others, a [Python implementation][gura-python-parser] you can install with `pip install gura` and start using today.
43 |
44 | ```python
45 | import gura
46 |
47 | gura_string = """
48 | title: "Gura Example"
49 |
50 | person:
51 | username: "Stephen"
52 | age: 20
53 |
54 | hosts: [
55 | "alpha",
56 | "omega"
57 | ]
58 | """
59 |
60 | # Transforms in dictionary
61 | parsed_gura = gura.loads(gura_string)
62 |
63 | # Access a specific field
64 | print(f"Title -> {parsed_gura['title']}")
65 |
66 | # Access object data
67 | person = parsed_gura['person']
68 | print(f"My username is {person['username']}")
69 |
70 | # Iterate over structure
71 | for host in parsed_gura['hosts']:
72 | print(f'Host -> {host}')
73 | ```
74 |
75 | [Javascript/Typescript][gura-js-parser] parser is also available! Check the [complete implementation list](#library-implementations) to see available libraries. Other programming languages implementations are being currently developed and will be available shortly.
76 |
77 |
78 | ## Index
79 |
80 | - [Implementations](#library-implementations)
81 | - [IDE support](#ide-support)
82 | - [Contributing](#contributing)
83 | - [Acknowledgements](#acknowledgements)
84 | - [Rationale](#rationale)
85 | - [Licence](#licence)
86 |
87 |
88 | ## Library implementations
89 |
90 | Below is the list of implementations available for Gura. If you have an implementation of your own that you want to make known simply create a new issue and it will be added here.
91 |
92 | - Dart: [gura-dart-parser][gura-dart-parser]
93 | - Javascript/Typescript: [gura-js-parser (official)][gura-js-parser]
94 | - Python: [gura-python-parser (official)][gura-python-parser]
95 | - Rust: [gura-rs-parser (official)][gura-rs-parser]
96 | - V: [vgura (official)][vgura]
97 |
98 |
99 | ## IDE support
100 |
101 | Below is the list of IDEs plugins available for Gura. If you have developed a plugin or IDE integration that you want to make known simply create a new issue and it will be added here.
102 |
103 | - VS Code: [Gura Syntax Highlighting][vs-code-plugin]
104 |
105 |
106 | ## Contributing
107 |
108 | All help is more than welcome. You can:
109 |
110 | - Join to our [community in Discord][discord-server]!
111 | - Write an RFC via our [GitHub Discussions][discussions] if you feel there is a bug in Gura or a missing feature.
112 | - Contribute to some of the implementations, or write your own in the programming language of your choice! In the latter case don't forget to make an issue letting us know that your implementation is available so we can add it to the [Implementations](#implementations) list.
113 |
114 | If you want to contribute with this website: it is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
115 |
116 | ### Installation
117 |
118 | ```console
119 | yarn install
120 | ```
121 |
122 | ### Local Development
123 |
124 | ```console
125 | yarn start
126 | ```
127 |
128 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
129 |
130 | ### Build
131 |
132 | ```console
133 | yarn build
134 | ```
135 |
136 | This command generates static content into the `build` directory and can be served using any static contents hosting service.
137 |
138 |
139 | ## Rationale
140 |
141 | Gura was born from the need to have a configuration language that is human readable without falling into the unnecessary complexity of popular formats such as YAML. The following is an overview of the issues with such formats, which motivated the creation of this new configuration language.
142 |
143 |
144 | ### Differences with YAML
145 |
146 | YAML offered a readable alternative to JSON or INI for a configuration file. While TOML was great for basic files because of its simplicity, YAML provided a readable solution when the complexity of the file grew. However, as [the NOYAML manifesto][blog] argues, we should stop supporting that format. The reason? [YAML is unnecessarily complex][reddit-post]. We highlight main issues with YAML that Gura tries to solve.
147 |
148 | - Multiple different ways to define a list and the elements inside it
149 | - 4 (!) ways to define a boolean
150 | - Boolean automatically inferred from strings ([workarounds][boolean-workaround])
151 | - Unnecessary unquoted strings that lead to float type inference problems
152 | - Serious security issues. [Safe YAML][safe-yaml] attempts to address those, but only those.
153 | - [Increadibly long YAML specs][yaml-specs] for what is supposed to be a simple configuration language?
154 | - Special data types such as *Date* or *Datetime* are defined in the spec, but the definition of their semantics is relegated to each specific implementation.
155 |
156 | All the previous points lead to a difficult implementation in any programming language, it is enough to see the repositories of the different languages to realize that carrying out a YAML parser is a complicated task.
157 |
158 |
159 | ### Differences with TOML
160 |
161 | The idea of Gura is not to replace TOML, but to complement it when the complexity of the project warrants it. The use of TOML for files such as `cargo.toml` in the Rust programming language is an excellent example of matching the complexity of the language to that of the domain. However, when the level of nesting increases, TOML is very cumbersome since you must resort to repeating all the parent levels (using [Dotted keys][dotted-keys]) every time you want to define a nested value.
162 |
163 | Furthermore, even TOML falls in some cases into the same complexity as YAML, with features such as:
164 |
165 | - Multiple ways to specify keys
166 | - Empty keys
167 | - Special data types
168 |
169 |
170 | ### Differences with JSON
171 |
172 | JSON is and will be the fastest serialization language available. Gura is not meant for fast processing and/or machine-to-machine communication. When a readable, simple and maintainable language is needed Gura becomes an excellent alternative.
173 |
174 |
175 | ### Gura
176 |
177 | Gura combines the readability of YAML and a reduced version of its syntax with the (even more simplified) simplicity of TOML. It also brings in some features and characteristics exclusive to this language:
178 |
179 | - 📦 Variables: Gura allows you to define variables of any type, even using environment variables, both as a flat value and as values inside a string. So you can compact and reuse the values you require.
180 | - 📑 Imports: Gura defines a way to import different Gura files within the same file in order to modularize the configuration.
181 | - 🚫 Standard errors: Gura defines the *semantic* errors that should be thrown in certain situations. This way you get an implementation-agnostic definition and the developer can get the same type of error regardless of the programming language he/she is using.
182 | - 🥧 Gura is short and simple to learn and use, since it follows the `only one way to do it` Python maxim.
183 | - 🌈 Writing a parser or wrapper for Gura in a new language should be a short and simple as well.
184 |
185 |
186 | Gura does not seek to replace the behavior that any programming language already offers in a much flexible and robust way. Therefore, it is limited to explicit static definitions that make it easier to understand both the language and the configuration files.
187 |
188 | Gura **will always be focused on simplicity**. Therefore, we are reluctant to support more complex structures. If you are looking for a way to execute code like loops, conditions, functions and so on in a config file, we recommend [Dhall][dhall].
189 |
190 |
191 | ## Acknowledgements
192 |
193 | I want to give my sincere thanks to [Facundo Quiroga][quiroga] and [Ulises Jeremias Cornejo Fandos][cornejo-fandos] for their guidance and valuable opinions during the design and implementation of Gura.
194 |
195 |
196 | ## License
197 |
198 | Gura is distributed under the terms of the MIT license.
199 |
200 |
201 | [blog]: https://noyaml.com/
202 | [specs]: https://gura.netlify.app/docs/gura
203 | [boolean-workaround]: https://stackoverflow.com/questions/53648244/specifying-the-string-value-yes-in-a-yaml-property
204 | [safe-yaml]: https://pyyaml.docsforge.com/master/api/yaml/safe_load/
205 | [yaml-specs]: https://yaml.org/spec/1.2/spec.html
206 | [reddit-post]: https://www.reddit.com/r/programming/comments/iqwbek/stop_adding_support_for_yaml_in_your_products/
207 | [dotted-keys]: https://toml.io/en/v1.0.0#table
208 | [dhall]: https://dhall-lang.org/#
209 | [gura-dart-parser]: https://github.com/zajrik/gura-dart-parser
210 | [gura-js-parser]: https://github.com/gura-conf/gura-js-parser
211 | [gura-python-parser]: https://github.com/gura-conf/gura-python-parser
212 | [gura-rs-parser]: https://github.com/gura-conf/gura-rs-parser
213 | [vgura]: https://github.com/gura-conf/vgura
214 | [discussions]: https://github.com/gura-conf/gura/discussions/categories/ideas-rfc
215 | [quiroga]: https://github.com/facundoq
216 | [cornejo-fandos]: https://github.com/ulises-jeremias
217 | [discord-server]: https://discord.gg/Qs5AXPQpKd
218 | [vs-code-plugin]: https://marketplace.visualstudio.com/items?itemName=zajrik.gura-syntax-highlight
219 |
--------------------------------------------------------------------------------
/versioned_docs/version-1.0.0/spec.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 2
3 | ---
4 |
5 | # Specs
6 |
7 | * Gura is case-sensitive.
8 | * A Gura file must be a valid UTF-8 encoded Unicode document.
9 | * Whitespace means tab (U+0009) or space (U+0020).
10 | * Newline means LF (U+000A) or CRLF (U+000D U+000A).
11 |
12 |
13 | ## Comment
14 |
15 | A hash symbol marks the rest of the line as a comment, except when inside a
16 | string.
17 |
18 | ```yaml
19 | # This is a full-line comment
20 | key: "value" # This is a comment at the end of a line
21 | another: "# This is not a comment"
22 | ```
23 |
24 | Control characters other than tab (U+0000 to U+0008, U+000A to U+001F, U+007F) are not permitted in comments.
25 |
26 |
27 | ## Key/Value Pair
28 |
29 | The primary building block of a Gura document is the key/value pair.
30 |
31 | Keys are on the left of the colon and values are on the right. Whitespace is ignored around key names and values. The key, colon, and value must be on the same line (though some values can be broken over multiple lines).
32 |
33 | ```yaml
34 | key: "value"
35 | ```
36 |
37 | Values must have one of the following types.
38 |
39 | - [Null](#null)
40 | - [String](#string)
41 | - [Integer](#integer)
42 | - [Float](#float)
43 | - [Boolean](#boolean)
44 | - [Object](#object)
45 | - [Array](#array)
46 |
47 | Unspecified values are invalid.
48 |
49 | ```yaml
50 | key: # INVALID
51 | ```
52 |
53 | There must be a newline (or EOF) after a key/value pair.
54 |
55 | ```
56 | first: "Carlitos" last: "Gardel" # INVALID
57 | ```
58 |
59 |
60 | ## Keys
61 |
62 | In Gura there is only one way to define keys. A key may only contain ASCII letters and underscores (`A-Za-z0-9_`). Dashes are not allowed to keep a simple and consistent key naming convention. Note that keys are allowed to be composed of only ASCII digits, e.g. `1234`, but are always interpreted as strings.
63 |
64 | ```yaml
65 | key: "value"
66 | some_key: "value"
67 | some-key: "value" # INVALID
68 | 1234: "value"
69 | ```
70 |
71 | A key must be non-empty.
72 |
73 | ```yaml
74 | : "no key name" # INVALID
75 | ```
76 |
77 | Defining a key multiple times is invalid and must raise a `DuplicatedKeyError` error.
78 |
79 | ```yaml
80 | # DO NOT DO THIS
81 | name: "Carlos"
82 | name: "Anibal"
83 | ```
84 |
85 |
86 | ## Null
87 |
88 | The absence of a value can be represented by the `null` value:
89 |
90 | ```yaml
91 | none_value: null
92 | ```
93 |
94 |
95 | ## String
96 |
97 | There are four ways to express strings: basic, multi-line basic, literal, and multi-line literal. All strings must contain only valid UTF-8 characters.
98 |
99 | Unlike YAML, unquoted strings are not allowed.
100 |
101 | **Basic strings** are surrounded by quotation marks (`"`). Any Unicode character may be used except those that must be escaped: quotation mark, backslash, and the control characters other than tab (U+0000 to U+0008, U+000A to U+001F, U+007F).
102 |
103 | ```yaml
104 | str: "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
105 | ```
106 |
107 | For convenience, some popular characters have a compact escape sequence.
108 |
109 | ```
110 | \b - backspace (U+0008)
111 | \t - tab (U+0009)
112 | \n - linefeed (U+000A)
113 | \f - form feed (U+000C)
114 | \r - carriage return (U+000D)
115 | \" - quote (U+0022)
116 | \\ - backslash (U+005C)
117 | \$ - dollar sign (variables) (U+0024)
118 | \uXXXX - unicode (U+XXXX)
119 | \UXXXXXXXX - unicode (U+XXXXXXXX)
120 | ```
121 |
122 | Any Unicode character may be escaped with the `\uXXXX` or `\UXXXXXXXX` forms. The escape codes must be valid Unicode [scalar values](https://unicode.org/glossary/#unicode_scalar_value).
123 |
124 | All other escape sequences not listed above will be interpreted as literal.
125 |
126 | Sometimes you need to express passages of text (e.g. translation files) or would like to break up a very long string into multiple lines. Gura makes this easy.
127 |
128 | **Multi-line basic strings** are surrounded by three quotation marks on each side and allow newlines. A newline immediately following the opening delimiter will be trimmed. All other whitespace and newline characters remain intact.
129 |
130 | ```yaml
131 | str1: """
132 | Roses are red
133 | Violets are blue"""
134 | ```
135 |
136 | Gura parsers should feel free to normalize newline to whatever makes sense for their platform.
137 |
138 | ```yaml
139 | # On a Unix system, the above multi-line string will most likely be the same as:
140 | str2: "Roses are red\nViolets are blue"
141 |
142 | # On a Windows system, it will most likely be equivalent to:
143 | str3: "Roses are red\r\nViolets are blue"
144 | ```
145 |
146 | For writing long strings without introducing extraneous whitespace, use a "line ending backslash". When the last non-whitespace character on a line is an unescaped `\`, it will be trimmed along with all whitespace (including newlines) up to the next non-whitespace character or closing delimiter. All of the escape sequences that are valid for basic strings are also valid for multi-line basic strings.
147 |
148 | ```yaml
149 | # The following strings are byte-for-byte equivalent:
150 | str1: "The quick brown fox jumps over the lazy dog."
151 |
152 | str2: """
153 | The quick brown \
154 |
155 |
156 | fox jumps over \
157 | the lazy dog."""
158 |
159 | str3: """\
160 | The quick brown \
161 | fox jumps over \
162 | the lazy dog.\
163 | """
164 | ```
165 |
166 | Any Unicode character may be used except those that must be escaped: backslash and the control characters other than tab, line feed, and carriage return (U+0000 to U+0008, U+000B, U+000C, U+000E to U+001F, U+007F).
167 |
168 | You can write a quotation mark, or two adjacent quotation marks, anywhere inside a multi-line basic string. They can also be written just inside the delimiters.
169 |
170 | ```yaml
171 | str4: """Here are two quotation marks: "". Simple enough."""
172 | # str5: """Here are three quotation marks: """.""" # INVALID
173 | str5: """Here are three quotation marks: ""\"."""
174 | str6: """Here are fifteen quotation marks: ""\"""\"""\"""\"""\"."""
175 | ```
176 |
177 | Unlike TOML, it is invalid to use three quotation marks inside a multi-line string:
178 |
179 | ```yaml
180 | # "This," she said, "is just a pointless statement."
181 | str7: """"This," she said, "is just a pointless statement."""" # INVALID
182 | ```
183 |
184 | If you're a frequent specifier of Windows paths or regular expressions, then having to escape backslashes quickly becomes tedious and error-prone. To help, Gura supports literal strings which do not allow escaping at all.
185 |
186 | **Literal strings** are surrounded by single quotes. Like basic strings, they must appear on a single line:
187 |
188 | ```yaml
189 | # What you see is what you get.
190 | winpath: 'C:\Users\nodejs\templates'
191 | winpath2: '\\ServerX\admin$\system32\'
192 | quoted: 'John "Dog lover" Wick'
193 | regex: '<\i\c*\s*>'
194 | ```
195 |
196 | Since there is no escaping, there is no way to write a single quote inside a literal string enclosed by single quotes. Luckily, Gura supports a multi-line version of literal strings that solves this problem.
197 |
198 | **Multi-line literal strings** are surrounded by three single quotes on each side and allow newlines. Like literal strings, there is no escaping whatsoever. A newline immediately following the opening delimiter will be trimmed. All other content between the delimiters is interpreted as-is without modification.
199 |
200 | ```yaml
201 | regex2: '''I [dw]on't need \d{2} apples'''
202 | lines: '''
203 | The first newline is
204 | trimmed in raw strings.
205 | All other whitespace
206 | is preserved.
207 | '''
208 | ```
209 |
210 | You can write 1 or 2 single quotes anywhere within a multi-line literal string, but sequences of three or more single quotes are not permitted.
211 |
212 | ```yaml
213 | quot15: '''Here are fifteen quotation marks: """""""""""""""'''
214 |
215 | # apos15: '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID
216 | apos15: "Here are fifteen apostrophes: '''''''''''''''"
217 |
218 | # 'That,' she said, 'is still pointless.'
219 | str: ''''That,' she said, 'is still pointless.''''
220 | ```
221 |
222 | Control characters other than tab are not permitted in a literal string. Thus, for binary data, it is recommended that you use Base64 or another suitable ASCII or UTF-8 encoding. The handling of that encoding will be application-specific.
223 |
224 |
225 | ## Integer
226 |
227 | Integers are whole numbers. Positive numbers may be prefixed with a plus sign. Negative numbers are prefixed with a minus sign.
228 |
229 | ```yaml
230 | int1: +99
231 | int2: 42
232 | int3: 0
233 | int4: -17
234 | ```
235 |
236 | For large numbers, you may use underscores between digits to enhance readability. Each underscore must be surrounded by at least one digit on each side.
237 |
238 | ```yaml
239 | int5: 1_000
240 | int6: 5_349_221
241 | int7: 53_49_221 # Indian number system grouping
242 | ```
243 |
244 | Leading zeros are not allowed. Integer values `-0` and `+0` are valid and identical to an unprefixed zero. Non-negative integer values may also be expressed in hexadecimal, octal, or binary. In these formats, leading `+` is not allowed and leading zeros are allowed (after the prefix). Hex values are case-insensitive. Underscores are allowed between digits (but not between the prefix and the value).
245 |
246 | ```yaml
247 | # Hexadecimal with prefix `0x`
248 | hex1: 0xDEADBEEF
249 | hex2: 0xdeadbeef
250 | hex3: 0xdead_beef
251 |
252 | # Octal with prefix `0o`
253 | oct1: 0o01234567
254 | oct2: 0o755 # useful for Unix file permissions
255 |
256 | # Binary with prefix `0b`
257 | bin1: 0b11010110
258 | ```
259 |
260 | Arbitrary 64-bit signed integers (from −2^63 to 2^63−1) should be accepted and handled losslessly. If an integer cannot be represented losslessly, an error must be thrown.
261 |
262 |
263 | ## Float
264 |
265 | Floats should be implemented as IEEE 754 binary64 values.
266 |
267 | A float consists of an integer part (which follows the same rules as decimal integer values) followed by a fractional part and/or an exponent part. If both a fractional part and exponent part are present, the fractional part must precede the exponent part.
268 |
269 | ```yaml
270 | # Fractional
271 | flt1: +1.0
272 | flt2: 3.1415
273 | flt3: -0.01
274 |
275 | # Exponent
276 | flt4: 5e+22
277 | flt5: 1e06
278 | flt6: -2E-2
279 |
280 | # Both
281 | flt7: 6.626e-34
282 | ```
283 |
284 | A fractional part is a decimal point followed by one or more digits.
285 |
286 | An exponent part is an E (upper or lower case) followed by an integer part (which follows the same rules as decimal integer values but may include leading zeros).
287 |
288 | The decimal point, if used, must be surrounded by at least one digit on each side.
289 |
290 | ```yaml
291 | # INVALID FLOATS
292 | invalid_float_1: .7
293 | invalid_float_2: 7.
294 | invalid_float_3: 3.e+20
295 | ```
296 |
297 | Similar to integers, you may use underscores to enhance readability.
298 |
299 | ```yaml
300 | flt8: 224_617.445_991_228
301 | ```
302 |
303 | Float values `-0.0` and `+0.0` are valid and should map according to IEEE 754.
304 |
305 | Special float values can also be expressed. They are always lowercase.
306 |
307 | ```yaml
308 | # Infinity
309 | sf1: inf # Positive infinity
310 | sf2: +inf # Positive infinity
311 | sf3: -inf # Negative infinity
312 |
313 | # Not a number
314 | sf4: nan # Actual sNaN/qNaN encoding is implementation-specific
315 | sf5: +nan # Same as `nan`
316 | sf6: -nan # Valid, actual encoding is implementation-specific
317 | ```
318 |
319 |
320 | ## Boolean
321 |
322 | Booleans are just the tokens you're used to. Always lowercase.
323 |
324 | ```yaml
325 | bool1: true
326 | bool2: false
327 | ```
328 |
329 |
330 | ## Object
331 |
332 | Like YAML, objects have a header (key), a colon and underneath each of their attributes, which must begin in an indented block. This indentation must be respected throughout the entire Gura file and each indentation level must be represented by 4 (four) spaces (U+0020). Unlike YAML, tabs (U+0009) are not allowed to define indentation blocks in order to standardize language formatting and provide users with a convenient way to maintain documents.
333 |
334 |
335 | ```yaml
336 | services:
337 | nginx:
338 | host: "127.0.0.1"
339 | port: 80
340 |
341 | apache:
342 | virtual_host: "10.10.10.4"
343 | port: 81
344 | ```
345 |
346 | The equivalent JSON would be:
347 |
348 | ```json
349 | {
350 | "services": {
351 | "nginx": {
352 | "host": "127.0.0.1",
353 | "port": 80
354 | },
355 | "apache": {
356 | "virtual_host": "10.10.10.4",
357 | "port": 81
358 | }
359 | }
360 | }
361 | ```
362 |
363 | **Some considerations about the indentation**
364 |
365 | A space (U+0020) or a tab (U+0009) can be used on useless lines like comments o empty lines (lines composed of whitespaces and new lines) but only. In case a tab is found as an indentation character, an `InvalidIndentationError` must be raised.
366 |
367 | Also, as mentioned previously, the indentation levels must be divisible by 4, otherwise an `InvalidIndentationError` error must be raised:
368 |
369 | ```yaml
370 | # INVALID as second level has block of 8 spaces as indentation
371 | services:
372 | nginx:
373 | host: "127.0.0.1"
374 | port: 80
375 |
376 | # INVALID as 2 spaces are used as indentation block
377 | user:
378 | name: "Gura"
379 | ```
380 |
381 | Finally, as empty values are not allowed, the following case considers any value below `name` as an internal block. As the indentation length between parent and child blocks is the same an `InvalidIndentationError` exception will be thrown:
382 |
383 | ```yaml
384 | user:
385 | name: # INVALID
386 | surname: "Troilo"
387 | ```
388 |
389 | **Empty objects**
390 |
391 | While the idea is that the configuration of a system is valid, complete, and static information, there may be situations where the information is empty. Assume the following case in JSON:
392 |
393 | ```json
394 | {
395 | "empty_object": {}
396 | }
397 | ```
398 |
399 | To maintain compatibility with existing languages with support for empty objects such as JSON or YAML, Gura provides the `empty` keyword to cover these scenarios. The above example could be represented in Gura as follows:
400 |
401 | ```yaml
402 | empty_object: empty
403 | ```
404 |
405 | In this way, an explicit and clear syntax is provided to cover these rare cases, without losing the portability of the configuration to and from other languages.
406 |
407 |
408 | ## Array
409 |
410 | Arrays are square brackets with values inside. Whitespace is ignored. Elements are separated by commas. Arrays can contain values of the same data types as allowed in key/value pairs. Values of different types may be mixed.
411 |
412 | ```yaml
413 | integers: [ 1, 2, 3 ]
414 | colors: [ "red", "yellow", "green" ]
415 | nested_arrays_of_ints: [ [ 1, 2 ], [3, 4, 5] ]
416 | nested_mixed_array: [ [ 1, 2 ], ["a", "b", "c"] ]
417 |
418 | # Mixed-type arrays are allowed
419 | numbers: [ 0.1, 0.2, 0.5, 1, 2, 5 ]
420 | tango_singers: [
421 | user1:
422 | name: "Carlos"
423 | surname: "Gardel"
424 | year_of_birth: 1890,
425 |
426 | user2:
427 | name: "Aníbal"
428 | surname: "Troilo"
429 | year_of_birth: 1914
430 | ]
431 | ```
432 |
433 | Arrays can span multiple lines. A terminating comma (also called a trailing comma) is permitted after the last value of the array. Any number of newlines and comments may precede values, commas, and the closing bracket. Indentation between array values and commas is treated as whitespace and ignored.
434 |
435 | ```yaml
436 | integers2: [
437 | 1, 2, 3
438 | ]
439 |
440 | integers3: [
441 | 1,
442 | 2, # This is ok
443 | ]
444 | ```
445 |
446 | Since the comma is the only valid element separator for an array, it is recommended to add a line between elements that are objects or multiple key/values to improve legibility:
447 |
448 | ```yaml
449 | # It is valid but a little hard to read
450 | singers: [
451 | name: "Andrea"
452 | surname: "Bocelli"
453 | gender: "Opera",
454 | name: "Jimi"
455 | surname: "Hendrix"
456 | gender: "Rock"
457 | ]
458 |
459 | # Much better!
460 | singers: [
461 | name: "Andrea"
462 | surname: "Bocelli"
463 | gender: "Opera",
464 |
465 | name: "Jimi"
466 | surname: "Hendrix"
467 | gender: "Rock"
468 | ]
469 | ```
470 |
471 |
472 | ## Variables
473 |
474 | You can define variables. They start with a `$` sign, a name and a colon. A variable name has to respect the same regex as keys and only strings, numbers or other variable are allowed as values. If any of another kind of value type is used a parsing error must be raised.
475 |
476 | ```yaml
477 | $my_string_var: "127.0.0.1"
478 | $my_integer_var: 8080
479 |
480 | nginx:
481 | host: $my_string_var
482 | port: $my_integer_var
483 |
484 | $invalid_var: null # INVALID null is not allowed as variable value
485 | $invalid_var2: true # INVALID booleans are not allowed as variable value
486 | $invalid_var3: [ 1, 2, 3 ] # INVALID complex types such as arrays or objects are not allowed as variable value
487 | ```
488 |
489 | Variables can not be used as key.
490 |
491 | ```yaml
492 | $hostkey: "host"
493 | nginx:
494 | $hostkey : 4 # INVALID
495 | ```
496 |
497 | Variables must be specified before they are used, in source code order. Redefining variables must raise a `DuplicatedVariableError` error, even when defined in different files (see [imports](#imports)).
498 |
499 | Variables can be used in *Basic strings* and *Multi-line basic strings*:
500 |
501 | ```yaml
502 | $name: "Gura"
503 | key: "$name is cool"
504 | key_2: """Config languages using variables:
505 | - $name"""
506 | ```
507 |
508 | Environment variables can be accessed using `$` sign too.
509 |
510 | ```yaml
511 | service:
512 | postgres:
513 | environment:
514 | user: $DB_USER
515 | password: $DB_PASS
516 |
517 | # You can store its value in a variable too
518 | $my_path: $PATH
519 |
520 | # You can replace environment variables like normal ones. After all, environment variables are normal variables defined before parsing.
521 | $PATH: "Another value"
522 | ```
523 |
524 | When a variable is used Gura looks for the definition in the current file and the imported ones. If it is not defined, checks for available environment variables, if it is not, it must raise a `VariableNotDefinedError` error.
525 |
526 | To use `$` in string just use literal or escape them:
527 |
528 |
529 | ```yaml
530 | basic: "I won \$500 dollars!"
531 | basic_multiline: """I won \$500 dollars!"""
532 | literal: 'I won $500 dollars!'
533 | literal_multiline: '''I won $500 dollars!'''
534 | ```
535 |
536 |
537 | ## Imports
538 |
539 | You can import one or more Gura files using an `import` statement. The effect of importing a file is the same as replacing the import by the file's contents. Therefore, all the keys and variables defined on them will be available in the file which is importing.
540 |
541 | Imports must occur at the beginning of the file and there must be no blanks in front of the `import` statement. Must be only one whitespace between the `import` and file name. The file name must be between single quotation marks (") and there won't be special character escaping. Importing a non-existing file must raise a `FileNotFoundError` error.
542 |
543 | ```yaml
544 | import "another_file.ura" # Good
545 | import "another_file.ura" # INVALID: there are blanks before import
546 | import "another_file.ura" # INVALID: there are more than one whitespace between import and file name
547 |
548 | some_key: "Some value"
549 |
550 | import "another_file.ura" # INVALID: is not at the beginning of the file
551 | ```
552 |
553 |
554 |
555 | A file can only be imported once. Re-importing a file must raise a `DuplicatedImportError` error.
556 |
557 |
558 | **one.ura**:
559 |
560 | ```yaml
561 | life: 42
562 | ```
563 |
564 | **two.ura**:
565 |
566 | ```yaml
567 | import "one.ura"
568 |
569 | $my_var: "My var value"
570 | ```
571 |
572 | **three.ura**:
573 |
574 | ```yaml
575 | $name: "Elisa"
576 | ```
577 |
578 | **main.ura**:
579 |
580 | ```yaml
581 | import "two.ura"
582 | import "/absolute/path/to/three.ura" # You can use absolute path too
583 |
584 | # life, $my_var and $name are available here
585 | my_name: $name
586 |
587 | # life: "some value" # This WILL NOT work as it is defined in one.ura which is included in two.ura
588 | ```
589 |
590 | You can use variables inside import sentences!
591 |
592 | ```yaml
593 | $common_path: "/extremely/long/path/to/some/useful/directory"
594 |
595 | import "$common_path/one.ura"
596 | import "$common_path/two.ura"
597 | ```
598 |
--------------------------------------------------------------------------------
/docs/spec.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 3
3 | description: 'Gura configuration language specifications'
4 | keywords: ['Gura specs']
5 | ---
6 |
7 | # Specs
8 |
9 | * Gura is case-sensitive.
10 | * A Gura file must be a valid UTF-8 encoded Unicode document.
11 | * Whitespace means tab (U+0009) or space (U+0020).
12 | * Newline means LF (U+000A) or CRLF (U+000D U+000A).
13 |
14 |
15 | ## Comment
16 |
17 | A hash symbol (U+0023) marks the rest of the line as a comment, except when inside a string.
18 |
19 | ```yaml
20 | # This is a full-line comment
21 | key: "value" # This is a comment at the end of a line
22 | another: "# This is not a comment"
23 | ```
24 |
25 | Control characters other than tab (U+0000 to U+0008, U+000A to U+001F, U+007F) are not permitted in comments.
26 |
27 |
28 | ## Key/Value Pair
29 |
30 | The primary building block of a Gura document is the key/value pair.
31 |
32 | Keys are on the left of the colon and values are on the right. Whitespace is ignored around key names and values. The key, colon, and value must be on the same line (though some values can be broken over multiple lines).
33 |
34 | ```yaml
35 | key: "value"
36 | ```
37 |
38 | Values must have one of the following types.
39 |
40 | - [Null](#null)
41 | - [String](#string)
42 | - [Integer](#integer)
43 | - [Float](#float)
44 | - [Boolean](#boolean)
45 | - [Object](#object)
46 | - [Array](#array)
47 |
48 | Unspecified values are invalid.
49 |
50 | ```yaml
51 | key: # INVALID
52 | ```
53 |
54 | There must be a newline (or EOF) after a key/value pair.
55 |
56 | ```
57 | first: "Carlitos" last: "Gardel" # INVALID
58 | ```
59 |
60 |
61 | ## Keys
62 |
63 | In Gura there is only one way to define keys. A key may only contain ASCII letters and underscores (`A-Za-z0-9_`). Dashes are not allowed to keep a simple and consistent key naming convention. Note that keys are allowed to be composed of only ASCII digits, e.g. `1234`, but are always interpreted as strings.
64 |
65 | ```yaml
66 | key: "value"
67 | some_key: "value"
68 | some-key: "value" # INVALID
69 | 1234: "value"
70 | ```
71 |
72 | A key must be non-empty.
73 |
74 | ```yaml
75 | : "no key name" # INVALID
76 | ```
77 |
78 | Defining a key multiple times is invalid and must raise a `DuplicatedKeyError` error.
79 |
80 | ```yaml
81 | # DO NOT DO THIS
82 | name: "Carlos"
83 | name: "Anibal"
84 | ```
85 |
86 | **Literal keys**
87 |
88 | Gura was created with simplicity, maintainability, and **portability** in mind. In a production environment, you will likely have to work with different tools that handle different configuration languages. To make Gura compatible with other configuration schemes, *Literal Keys* are provided, these are defined between grave accents `` ` `` (U+0060 GRAVE ACCENT) and can contain any valid UTF-8 character.
89 |
90 | If the `` ` `` character is required within a Literal Key, it must be escaped. Any character from the list in the [String section](#string) can be escaped inside Literal Keys too. If any other character that has not been previously mentioned is escaped, `InvalidEscapedCharacterError` must be raised, exactly as if it were a string.
91 |
92 | ```yaml
93 | `a/literal.key!`: "Some value"
94 | `Escaped\`char\tWithTabs`: true
95 | `\invalid`: false # INVALID: \i is not a valid escape sentence
96 | ```
97 |
98 | :::caution
99 |
100 | The purpose of the Literal Keys is solely to provide compatibility with other configuration languages. **It is recommended to avoid them unless strictly necessary**, in order to maintain a clean and standardized configuration.
101 |
102 | :::
103 |
104 |
105 | ## Null
106 |
107 | The absence of a value can be represented by the `null` value:
108 |
109 | ```yaml
110 | none_value: null
111 | ```
112 |
113 |
114 | ## String
115 |
116 | There are four ways to express strings: basic, multi-line basic, literal, and multi-line literal. All strings must contain only valid UTF-8 characters.
117 |
118 | Unlike YAML, unquoted strings are not allowed.
119 |
120 | **Basic strings** are surrounded by quotation marks (`"`). Any Unicode character may be used except those that must be escaped: quotation mark, backslash, and the control characters other than tab (U+0000 to U+0008, U+000A to U+001F, U+007F).
121 |
122 | ```yaml
123 | str: "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
124 | ```
125 |
126 | For convenience, some popular characters have a compact escape sequence.
127 |
128 | ```
129 | \b - backspace (U+0008)
130 | \t - tab (U+0009)
131 | \n - linefeed (U+000A)
132 | \f - form feed (U+000C)
133 | \r - carriage return (U+000D)
134 | \" - quote (U+0022)
135 | \\ - backslash (U+005C)
136 | \$ - dollar sign (variables) (U+0024)
137 | \uXXXX - unicode (U+XXXX)
138 | \UXXXXXXXX - unicode (U+XXXXXXXX)
139 | ```
140 |
141 | Any Unicode character may be escaped with the `\uXXXX` or `\UXXXXXXXX` forms. The escape codes must be valid Unicode [scalar values](https://unicode.org/glossary/#unicode_scalar_value).
142 |
143 | All other escape sequences not listed above are not valid and must raise `InvalidEscapedCharacterError`.
144 |
145 | Sometimes you need to express passages of text (e.g. translation files) or would like to break up a very long string into multiple lines. Gura makes this easy.
146 |
147 | **Multi-line basic strings** are surrounded by three quotation marks on each side and allow newlines. A newline immediately following the opening delimiter will be trimmed. All other whitespace and newline characters remain intact.
148 |
149 | ```yaml
150 | str1: """
151 | Roses are red
152 | Violets are blue"""
153 | ```
154 |
155 | Gura parsers should feel free to normalize newline to whatever makes sense for their platform.
156 |
157 | ```yaml
158 | # On a Unix system, the above multi-line string will most likely be the same as:
159 | str2: "Roses are red\nViolets are blue"
160 |
161 | # On a Windows system, it will most likely be equivalent to:
162 | str3: "Roses are red\r\nViolets are blue"
163 | ```
164 |
165 | For writing long strings without introducing extraneous whitespace, use a "line ending backslash". When the last non-whitespace character on a line is an unescaped `\`, it will be trimmed along with all whitespace (including newlines) up to the next non-whitespace character or closing delimiter. All of the escape sequences that are valid for basic strings are also valid for multi-line basic strings.
166 |
167 | ```yaml
168 | # The following strings are byte-for-byte equivalent:
169 | str1: "The quick brown fox jumps over the lazy dog."
170 |
171 | str2: """
172 | The quick brown \
173 |
174 |
175 | fox jumps over \
176 | the lazy dog."""
177 |
178 | str3: """\
179 | The quick brown \
180 | fox jumps over \
181 | the lazy dog.\
182 | """
183 | ```
184 |
185 | Any Unicode character may be used except those that must be escaped: backslash and the control characters other than tab, line feed, and carriage return (U+0000 to U+0008, U+000B, U+000C, U+000E to U+001F, U+007F).
186 |
187 | You can write a quotation mark, or two adjacent quotation marks, anywhere inside a multi-line basic string. They can also be written just inside the delimiters.
188 |
189 | ```yaml
190 | str4: """Here are two quotation marks: "". Simple enough."""
191 | # str5: """Here are three quotation marks: """.""" # INVALID
192 | str5: """Here are three quotation marks: ""\"."""
193 | str6: """Here are fifteen quotation marks: ""\"""\"""\"""\"""\"."""
194 | ```
195 |
196 | Unlike TOML, it is invalid to use three quotation marks inside a multi-line string:
197 |
198 | ```yaml
199 | # "This," she said, "is just a pointless statement."
200 | str7: """"This," she said, "is just a pointless statement."""" # INVALID
201 | ```
202 |
203 | If you're a frequent specifier of Windows paths or regular expressions, then having to escape backslashes quickly becomes tedious and error-prone. To help, Gura supports literal strings which do not allow escaping at all.
204 |
205 | **Literal strings** are surrounded by single quotes. Like basic strings, they must appear on a single line:
206 |
207 | ```yaml
208 | # What you see is what you get.
209 | winpath: 'C:\Users\nodejs\templates'
210 | winpath2: '\\ServerX\admin$\system32\'
211 | quoted: 'John "Dog lover" Wick'
212 | regex: '<\i\c*\s*>'
213 | ```
214 |
215 | Since there is no escaping, there is no way to write a single quote inside a literal string enclosed by single quotes. Luckily, Gura supports a multi-line version of literal strings that solves this problem.
216 |
217 | **Multi-line literal strings** are surrounded by three single quotes on each side and allow newlines. Like literal strings, there is no escaping whatsoever. A newline immediately following the opening delimiter will be trimmed. All other content between the delimiters is interpreted as-is without modification.
218 |
219 | ```yaml
220 | regex2: '''I [dw]on't need \d{2} apples'''
221 | lines: '''
222 | The first newline is
223 | trimmed in raw strings.
224 | All other whitespace
225 | is preserved.
226 | '''
227 | ```
228 |
229 | You can write 1 or 2 single quotes anywhere within a multi-line literal string, but sequences of three or more single quotes are not permitted.
230 |
231 | ```yaml
232 | quot15: '''Here are fifteen quotation marks: """""""""""""""'''
233 |
234 | # apos15: '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID
235 | apos15: "Here are fifteen apostrophes: '''''''''''''''"
236 |
237 | # 'That,' she said, 'is still pointless.'
238 | str: ''''That,' she said, 'is still pointless.''''
239 | ```
240 |
241 | Control characters other than tab are not permitted in a literal string. Thus, for binary data, it is recommended that you use Base64 or another suitable ASCII or UTF-8 encoding. The handling of that encoding will be application-specific.
242 |
243 |
244 | ## Integer
245 |
246 | Integers are whole numbers. Positive numbers may be prefixed with a plus sign. Negative numbers are prefixed with a minus sign.
247 |
248 | ```yaml
249 | int1: +99
250 | int2: 42
251 | int3: 0
252 | int4: -17
253 | ```
254 |
255 | For large numbers, you may use underscores between digits to enhance readability. Each underscore must be surrounded by at least one digit on each side.
256 |
257 | ```yaml
258 | int5: 1_000
259 | int6: 5_349_221
260 | int7: 53_49_221 # Indian number system grouping
261 | ```
262 |
263 | Leading zeros are not allowed. Integer values `-0` and `+0` are valid and identical to an unprefixed zero. Non-negative integer values may also be expressed in hexadecimal, octal, or binary. In these formats, leading `+` is not allowed and leading zeros are allowed (after the prefix). Hex values are case-insensitive. Underscores are allowed between digits (but not between the prefix and the value).
264 |
265 | ```yaml
266 | # Hexadecimal with prefix `0x`
267 | hex1: 0xDEADBEEF
268 | hex2: 0xdeadbeef
269 | hex3: 0xdead_beef
270 |
271 | # Octal with prefix `0o`
272 | oct1: 0o01234567
273 | oct2: 0o755 # useful for Unix file permissions
274 |
275 | # Binary with prefix `0b`
276 | bin1: 0b11010110
277 | ```
278 |
279 | Arbitrary 64-bit signed integers (from −2^63 to 2^63−1) should be accepted and handled losslessly. If an integer cannot be represented losslessly, an error must be thrown.
280 |
281 |
282 | ## Float
283 |
284 | Floats should be implemented as IEEE 754 binary64 values.
285 |
286 | A float consists of an integer part (which follows the same rules as decimal integer values) followed by a fractional part and/or an exponent part. If both a fractional part and exponent part are present, the fractional part must precede the exponent part.
287 |
288 | ```yaml
289 | # Fractional
290 | flt1: +1.0
291 | flt2: 3.1415
292 | flt3: -0.01
293 |
294 | # Exponent
295 | flt4: 5e+22
296 | flt5: 1e06
297 | flt6: -2E-2
298 |
299 | # Both
300 | flt7: 6.626e-34
301 | ```
302 |
303 | A fractional part is a decimal point followed by one or more digits.
304 |
305 | An exponent part is an E (upper or lower case) followed by an integer part (which follows the same rules as decimal integer values but may include leading zeros).
306 |
307 | The decimal point, if used, must be surrounded by at least one digit on each side.
308 |
309 | ```yaml
310 | # INVALID FLOATS
311 | invalid_float_1: .7
312 | invalid_float_2: 7.
313 | invalid_float_3: 3.e+20
314 | ```
315 |
316 | Similar to integers, you may use underscores to enhance readability.
317 |
318 | ```yaml
319 | flt8: 224_617.445_991_228
320 | ```
321 |
322 | Float values `-0.0` and `+0.0` are valid and should map according to IEEE 754.
323 |
324 | Special float values can also be expressed. They are always lowercase.
325 |
326 | ```yaml
327 | # Infinity
328 | sf1: inf # Positive infinity
329 | sf2: +inf # Positive infinity
330 | sf3: -inf # Negative infinity
331 |
332 | # Not a number
333 | sf4: nan # Actual sNaN/qNaN encoding is implementation-specific
334 | sf5: +nan # Same as `nan`
335 | sf6: -nan # Valid, actual encoding is implementation-specific
336 | ```
337 |
338 |
339 | ## Boolean
340 |
341 | Booleans are just the tokens you're used to. Always lowercase.
342 |
343 | ```yaml
344 | bool1: true
345 | bool2: false
346 | ```
347 |
348 |
349 | ## Object
350 |
351 | Like YAML, objects have a header (key), a colon and underneath each of their attributes, which must begin in an indented block. This indentation must be respected throughout the entire Gura file and each indentation level must be represented by 4 (four) spaces (U+0020). Unlike YAML, tabs (U+0009) are not allowed to define indentation blocks in order to standardize language formatting and provide users with a convenient way to maintain documents.
352 |
353 |
354 | ```yaml
355 | services:
356 | nginx:
357 | host: "127.0.0.1"
358 | port: 80
359 |
360 | apache:
361 | virtual_host: "10.10.10.4"
362 | port: 81
363 | ```
364 |
365 | The equivalent JSON would be:
366 |
367 | ```json
368 | {
369 | "services": {
370 | "nginx": {
371 | "host": "127.0.0.1",
372 | "port": 80
373 | },
374 | "apache": {
375 | "virtual_host": "10.10.10.4",
376 | "port": 81
377 | }
378 | }
379 | }
380 | ```
381 |
382 | **Some considerations about the indentation**
383 |
384 | A space (U+0020) or a tab (U+0009) can be used on useless lines like comments o empty lines (lines composed of whitespaces and new lines) but only. In case a tab is found as an indentation character, an `InvalidIndentationError` must be raised.
385 |
386 | Also, as mentioned previously, the indentation levels must be divisible by 4, otherwise an `InvalidIndentationError` error must be raised:
387 |
388 | ```yaml
389 | # INVALID as second level has block of 8 spaces as indentation
390 | services:
391 | nginx:
392 | host: "127.0.0.1"
393 | port: 80
394 |
395 | # INVALID as 2 spaces are used as indentation block
396 | user:
397 | name: "Gura"
398 | ```
399 |
400 | Finally, as empty values are not allowed, the following case considers any value below `name` as an internal block. As the indentation length between parent and child blocks is the same an `InvalidIndentationError` exception will be thrown:
401 |
402 | ```yaml
403 | user:
404 | name: # INVALID
405 | surname: "Troilo"
406 | ```
407 |
408 | **Empty objects**
409 |
410 | While the idea is that the configuration of a system is valid, complete, and static information, there may be situations where the information is empty. Assume the following case in JSON:
411 |
412 | ```json
413 | {
414 | "empty_object": {}
415 | }
416 | ```
417 |
418 | To maintain compatibility with existing languages with support for empty objects such as JSON or YAML, Gura provides the `empty` keyword to cover these scenarios. The above example could be represented in Gura as follows:
419 |
420 | ```yaml
421 | empty_object: empty
422 | ```
423 |
424 | In this way, an explicit and clear syntax is provided to cover these rare cases, without losing the portability of the configuration to and from other languages.
425 |
426 |
427 | ## Array
428 |
429 | Arrays are square brackets with values inside. Whitespace is ignored. Elements are separated by commas. Arrays can contain values of the same data types as allowed in key/value pairs. Values of different types may be mixed.
430 |
431 | ```yaml
432 | integers: [ 1, 2, 3 ]
433 | colors: [ "red", "yellow", "green" ]
434 | nested_arrays_of_ints: [ [ 1, 2 ], [3, 4, 5] ]
435 | nested_mixed_array: [ [ 1, 2 ], ["a", "b", "c"] ]
436 |
437 | # Mixed-type arrays are allowed
438 | numbers: [ 0.1, 0.2, 0.5, 1, 2, 5 ]
439 | tango_singers: [
440 | user1:
441 | name: "Carlos"
442 | surname: "Gardel"
443 | year_of_birth: 1890,
444 |
445 | user2:
446 | name: "Aníbal"
447 | surname: "Troilo"
448 | year_of_birth: 1914
449 | ]
450 | ```
451 |
452 | Arrays can span multiple lines. A terminating comma (also called a trailing comma) is permitted after the last value of the array. Any number of newlines and comments may precede values, commas, and the closing bracket. Indentation between array values and commas is treated as whitespace and ignored.
453 |
454 | ```yaml
455 | integers2: [
456 | 1, 2, 3
457 | ]
458 |
459 | integers3: [
460 | 1,
461 | 2, # This is ok
462 | ]
463 | ```
464 |
465 | Since the comma is the only valid element separator for an array, it is recommended to add a line between elements that are objects or multiple key/values to improve legibility:
466 |
467 | ```yaml
468 | # It is valid but a little hard to read
469 | singers: [
470 | name: "Andrea"
471 | surname: "Bocelli"
472 | gender: "Opera",
473 | name: "Jimi"
474 | surname: "Hendrix"
475 | gender: "Rock"
476 | ]
477 |
478 | # Much better!
479 | singers: [
480 | name: "Andrea"
481 | surname: "Bocelli"
482 | gender: "Opera",
483 |
484 | name: "Jimi"
485 | surname: "Hendrix"
486 | gender: "Rock"
487 | ]
488 | ```
489 |
490 |
491 | ## Variables
492 |
493 | You can define variables. They start with a `$` sign, a name and a colon. A variable name has to respect the same regex as keys, and only basic types (null, strings, booleans, numbers, and `empty`) or another variable are allowed as values. If another value type is used, a parsing error must be raised.
494 |
495 | ```yaml
496 | $my_string_var: "127.0.0.1"
497 | $my_integer_var: 8080
498 | $my_bool_var: true
499 |
500 | nginx:
501 | host: $my_string_var
502 | port: $my_integer_var
503 | ignore_warning: $my_bool_var
504 |
505 | $invalid_var: [ 1, 2, 3 ] # INVALID complex types such as arrays or objects are not allowed as variable value
506 |
507 | # INVALID complex types such as arrays or objects are not allowed as variable value
508 | $invalid_var_2: service:
509 | name: "Service name"
510 | ```
511 |
512 | Variables can not be used as key.
513 |
514 | ```yaml
515 | $hostkey: "host"
516 | nginx:
517 | $hostkey : 4 # INVALID
518 | ```
519 |
520 | Variables must be specified before they are used, in source code order. Redefining variables must raise a `DuplicatedVariableError` error, even when defined in different files (see [imports](#imports)).
521 |
522 | Variables can be used in *Basic strings* and *Multi-line basic strings*:
523 |
524 | ```yaml
525 | $name: "Gura"
526 | key: "$name is cool"
527 | key_2: """Config languages using variables:
528 | - $name"""
529 | ```
530 |
531 | **Environment variables** can be accessed using `$` sign too.
532 |
533 | ```yaml
534 | service:
535 | postgres:
536 | environment:
537 | user: $DB_USER
538 | password: $DB_PASS
539 |
540 | # You can store its value in a variable too
541 | $my_path: $PATH
542 |
543 | # You can replace environment variables like normal ones. After all, environment variables are normal variables defined before parsing.
544 | $PATH: "Another value"
545 | ```
546 |
547 | When a variable is used Gura looks for the definition in the current file and the imported ones. If it is not defined, checks for available environment variables, if it is not defined either, it must raise a `VariableNotDefinedError` error.
548 |
549 | To avoid security issues accessing environments variables in sensitive systems, each implementation must provide an ENV vars disabling mechanism. If they are disabled, only local variables will be considered, if not found the `VariableNotDefinedError` exception will be thrown.
550 |
551 | To use `$` in string just use literal or escape them:
552 |
553 |
554 | ```yaml
555 | basic: "I won \$500 dollars!"
556 | basic_multiline: """I won \$500 dollars!"""
557 | literal: 'I won $500 dollars!'
558 | literal_multiline: '''I won $500 dollars!'''
559 | ```
560 |
561 |
562 | ## Imports
563 |
564 | You can import one or more Gura files using an `import` statement. The effect of importing a file is the same as replacing the import by the file's contents. Therefore, all the keys and variables defined on them will be available in the file which is importing.
565 |
566 | Imports must occur at the beginning of the file and there must be no blanks in front of the `import` statement. Must be only one whitespace between the `import` and file name. The file name must be between single quotation marks (") and there won't be special character escaping. Importing a non-existing file must raise a `FileNotFoundError` error.
567 |
568 | ```yaml
569 | import "another_file.ura" # Good
570 | import "another_file.ura" # INVALID: there are blanks before import
571 | import "another_file.ura" # INVALID: there are more than one whitespace between import and file name
572 |
573 | some_key: "Some value"
574 |
575 | import "another_file.ura" # INVALID: is not at the beginning of the file
576 | ```
577 |
578 | A file can only be imported once. Re-importing a file must raise a `DuplicatedImportError` error.
579 |
580 |
581 | **one.ura**:
582 |
583 | ```yaml
584 | life: 42
585 | ```
586 |
587 | **two.ura**:
588 |
589 | ```yaml
590 | import "one.ura"
591 |
592 | $my_var: "My var value"
593 | ```
594 |
595 | **three.ura**:
596 |
597 | ```yaml
598 | $name: "Elisa"
599 | ```
600 |
601 | **main.ura**:
602 |
603 | ```yaml
604 | import "two.ura"
605 | import "/absolute/path/to/three.ura" # You can use absolute path too
606 |
607 | # life, $my_var and $name are available here
608 | my_name: $name
609 |
610 | # life: "some value" # This WILL NOT work as it is defined in one.ura which is included in two.ura
611 | ```
612 |
613 | You can use variables inside import sentences!
614 |
615 | ```yaml
616 | $common_path: "/extremely/long/path/to/some/useful/directory"
617 |
618 | import "$common_path/one.ura"
619 | import "$common_path/two.ura"
620 | ```
621 |
622 | To avoid errors in environments without filesystem access, prevent security problems in sensitive environments, or whatever the reason, each implementation must provide an import disabling mechanism. This flag must be part of the process of parsing a text string in Gura format to a structure useful for the implementation (e.g. a dictionary in Python, an object in Javascript, a HashMap in Java and Rust, etc).
623 |
624 | In case the user sets this flag to `true` it should not be possible to import Gura files into one, and any `import` statement encountered should throw `ImportDisabledError`.
625 |
626 | This gives more control to the users to use Gura in the most efficient way for their requirements.
627 |
--------------------------------------------------------------------------------