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