Eno is an [[LGPLv3]] licensed data and configuration language written in [[3. Reference/Software/Programming Languages/C|C]].
- [Website](https://eno-lang.org/)
- [CodeBerg](https://codeberg.org/simonrepp/libeno/) (official C implementation)
- [Documentation](https://eno-lang.org/guide/)
- [Playground](https://eno-lang.org/playground/)
- AlternativeTo
> Eno is a data language for all people, not just developers. Its simple syntax and versatile nature welcomes a wide audience, both in regards to cultural background as well as technical ability. Unlike traditional developer- and machine-centric data languages, its type-agnostic design embraces our human superpower - our effortless understanding of context - and thereby makes it one of the easiest data languages to grasp and author content in.
# Notability
Looks like [[Markdown]] got teleported in the same pod with Ruby.
May be useful when developing [[Storymode - Ideas]] or for other plain text configuration such as [[FUSE FS DB]].
This is really good, but there are obvious design deficiencies. As simple as it is, these might be overlooked for their poor handling of edge cases, but it does make me uncomfortable, and seems that these decisions were just quick patches rather than thoughtfully addressed - which may indicate other issues in the language.
## Implementations
- [[3. Reference/Software/Programming Languages/C|C]] - https://codeberg.org/simonrepp/libeno/ (official, beta quality?)
- [[Ruby]] - https://eno-lang.org/ruby/ / https://codeberg.org/simonrepp/enolib-rb
- [[Python]] - https://eno-lang.org/python/ / https://codeberg.org/simonrepp/enolib-py
- [[Rust]] - https://codeberg.org/simonrepp/enolib-rs (not crated)
- [[Javascript]] - https://codeberg.org/simonrepp/enolib-js
# Philosophy
# OS Support
## Editor/Highlighting Support
- Prism.js - https://codeberg.org/simonrepp/prism-eno
- [[Ace]] - https://codeberg.org/simonrepp/ace-eno
# Features
# Example
```toml
> comment (not output)
key a: string
key b:
- list item a
- list item b
key c:
nested key a = value
nested key b = value
# section
another key: value
## nested section
yet another key: value
-- heredoc
foo
-- heredoc
```
Generates this structure:
![[Screenshot from 2023-10-25 09-31-27.png]]
# Syntax
- All excess whitespace is ignored except in the heredoc syntax which is preserved exactly as written
## Value
The only value types are `null` or string.
## Dictionaries
Called "*fields*". They use the common YAML-like syntax:
```yaml
key: value
```
A dictionary key has a "type" which determines what it can contain. They cannot be heterogeneous. The first item determines the type. The type can be `null`, a string, a nested dictionary, or a list.
## Nested Dictionaries
Called "*fieldsets*". They use the common INI-like syntax:
```toml
child 1 = value
child 2 = value
```
Unfortunately, dictionaries cannot be nested more than this. Nested dictionaries are **required** to belong to a dictionary key, they cannot be directly below a section in the hierarchy.
## Lists
They're just Markdown lists:
```markdown
- a list item
- a second list item
- oh no, now there are three of them
```
Lists are **required** to belong to a dictionary key, they cannot be directly below a section in the hierarchy.
## Multiline Values
### Heredoc
Called "*multiline fields*". This heredoc syntax is super gross, if I am honest, and my least favorite part of the language.
```eno
-- field name
first line
second line
-- field name
```
I much prefer the style of [[NestedText]]'s `>` or even simple indented lines like [[YAML]].
### Line Continuation
It seems that in addition to the heredoc syntax, it is possible to have multiline values by indicating them individually.
To join the strings with a single space (called "*spaced line continuation*"), begin the next line with a backslash:
```
\ leading whitespace is ignored
\ this line will be separated by 1 space
```
To ignore all whitespace (such as for long commands and URLs - called "*direct line continuation*"), begin the next line with a pipe:
```eno
| this
| will
| become
| a
| single
| word
```
## Enums
Called "*empties*" for some ungodly reason. They are just barewords.
```eno
enable_flag!
SOME_DATA_ANNOTATION
```
## Sections
Sections are just like Markdown and avoid the weirdness of TOML's dotted sections and the problems with nesting in YAML more than a one layer.
```markdown
# section
## nested section
### double nested section
#### etc
```
## References
Called "*copies*". Similar to [[Storymode - Ideas]], any section name can be referenced later. The syntax that Eno uses is similar to Ruby's subclassing:
```eno
# child section < parent section
```
Children appear to be copy on write style.
To append to sections from parents in the children instead of overwriting them (called "*deep copies*"), use two angle brackets `<<`:
```eno
# child section << parent section
```
## Comments
Eno uses the Markdown quote `>` for comments, and they are ignored:
```markdown
> this is a comment
```
If a comment is attached to any field, then it is attached to it in the output (how?):
```
> this is an attached comment
field: value
```
## Escaping
In the event that a line would become ambiguous due to characters that should be interpreted as strings rather than Eno syntax, they must be wrapped in backticks:
```eno
`-0`: negative zero
`https://example.com`: website
```
To escape leading backticks, use two and then a space:
```eno
`` `mother i crave violence` ``: true
```
If the key needs to be any amount of empty space, then this edge case is handled with regular double quotes instead, which is... not ideal.
```eno
" ": two spaces
```
# Tips
# References