What are the rules of the yaml duration numerical format? - yaml

I just discovered what, for lack of a better word, I'm calling yaml's duration numerical format.
Take the following yaml
value_1: 1:00:00
value_2: 01:00:00
My expectation would be that if this were to be converted to json it would be written as
{
"value_1": "1:00:00",
"value_2": "01:00:00"
}
To my surprise though it is actually converted to
{
"value_1": 3600,
"value_2": "01:00:00"
}
I observed this using both pyyaml and an online yaml to json converter
I've done a quick search through the yaml spec and wasn't seeing this laid out as a supported numerical format, at least not in the terms I'd think to look for it. My speculation is that it is being interpreted as hh:mm:ss and converted into a count of seconds.
Is this part of the yaml specification or an extension within popular yaml implementations? If it is part of the specification what is the exact format supported?

I reached out to the folks over at pyyaml and they were able to point me towards the right place in the yaml spec. The format is called sexagesimal and has been removed from Yaml v1.2 however it looks like yaml v1.1 and prior are still pretty dominant. Taken from the v1.1 spec:
Using “:” allows expressing integers in base 60, which is convenient for time and angle values.
The regex defining it is
[-+]?[1-9][0-9_]*(:[0-5]?[0-9])+
or for floats [-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]*

Related

What is the essential difference between Document and Collectiction in YAML syntax?

Warning: This question is a more philosophical question than practical, but I find it well as to be asked and answered in practical contexts (forums like StackOverflow here, instead of the SoftwareEngineering stack-exchange website), due to the native development in the actual use de-facto of YAML and the way the way it's specification has evolved and features have been added to it over time. Let's ask:
As opposed to formats/languages/protocols such as JSON, the YAML format allows you (according to this link, that seems pretty official, or at least accurate and reliable source to understand the YAML specification) to embed multiple 'Documents' within one file/stream, using the three-dashes marking ("---").
If so, it's hard to ignore the fact that the concept/model/idea of 'Document' in YAML, is no longer an external definition, or "meta"-directive that helps the human/parser to organize multiple/distincted documents along each other (similar to the way file-systems defining the concept of "file" to organize different files, but each file in itself - does not necessarily recognize that it's a file, or that it's being part of a file system that wraps it, by definition, AFAIK.
However, when YAML allows for a multi-Document YAML files, that gather collections of Documents in a single YAML file (and perhaps in a way that is similar/analogous to HTTP Pipelining approach of HTTP protocol), the concept/model/idea/goal of Document receives a new, wider definition/character de-facto, as a part of the YAML grammar and it's produces, and not just of the YAML specification as an assistive concept or format description that helps to describe the specification.
If so, being a Document part of the language itself, what is the added value of this data-structure, compared to the existing, familiar and well-used good old data-structure of Collection (array of items)?
I'm asking it, because I've seen in this link (here) some snippet (in the second example), which describes a YAML sequence that is actually a collection of logs. For some reason, the author of the example, chose to prefer to present each log as a separate "Document" (separated with three-dashes), gathered together in the same YAML sequence/file, instead of writing a file that has a "Collection" of logs represented with the data-type of array. Why did he choose to do this? Is his choice fit, correct, ideal?
I can speculate that the added value of the distinction between a Document and a Collection become relevant when using more advanced features of the YAML grammar, such as Anchors, Tags, References. I guess every Document provide a guarantee that all these identifiers will be a unique set, and there is no collision or duplicates among them. Am I right? And if so, is this the only advantage, or maybe there are any more justifications for the existence of these two pretty-similar data structures?
My best for now, is to see Document as a "meta"-Collection, that is more strict, and lack of high-level logic, or as two different layers of collection schemes. Is it correct, accurate way of view?
And even if I am right, why in the above example (of the logs document from the link), when there's no use and not imply or expected to use duplications or collisions or even identifiers/anchors or compound structures at all - the author is still choosing to represent the collection's items as separate documents? Is this just not so successful selection of an example? Or maybe I'm missing something, and this is a redundancy in the specification, or an evolving syntactic-sugar due to practical needs?
Because the example was written on a website that looks serious with official information written by professionals who dealt with the essence of the language and its definition, theory and philosophy behind (as opposed to practical uses in the wild), and also in light of other provided examples I have seen in it and the added value of them being meticulous, I prefer not to assume that the example is just simply imperfect/meticulous/fit, and that there may be a good reason to choose to write it this way over another, in the specific case exampled.
First, let's look at the technical difference between the list of documents in a YAML stream and a YAML sequence (which is a collection of ordered items). For this, I'll discuss YAML tags, which are an advanced feature so I'll provide a quick overview:
YAML nodes can have tags, such as !!str (the official tag for string values) or !dice (a local tag that can be interpreted by your application but is unknown to others). This applies to all nodes: Scalars, mappings and sequences. Nodes that do not have such a tag set in the source will be assigned the non-specific tag ?, except for quoted scalars which get ! instead. These non-specific tags are later resolved to specific tags, thereby defining to which kind of data structure the node will be deserialized into.
YAML implementations in scripting languages, such as PyYAML, usually only implement resolution by looking at the node's value. For example, a scalar node containing true will become a boolean value, 42 will become an integer, and droggeljug will become a string.
YAML implementations for languages with static types, however, do this differently. For example, assume you deserialize your YAML into a Java class
public class Config {
String name;
int count;
}
Assume the YAML is
name: 42
count: five
The 42 will become a String despite the fact that it looks like a number. Likewise, five will generate an error because it is not a number; it won't be deserialized into a string. This means that not the content of the node defines how it will be deserialized, but the path to the node.
What does this have to do with documents? Well, the YAML spec says:
Resolving the tag of a node must only depend on the following three parameters: (1) the non-specific tag of the node, (2) the path leading from the root to the node and (3) the content (and hence the kind) of the node.)
So, the technical difference is: If you put your data into a single document with a collection at the top, the YAML processor is allowed to take into account the position of the data in the top-level collection when resolving a tag. However, when you put your data in different documents, the YAML processor must not depend on the position of the document in the YAML stream for resolving the tag.
What does this mean in practice? It means that YAML documents are structurally disjoint from one another. Whether a YAML document is valid or not must not depend on any preceeding or succeeding documents. Consequentially, even when deserialization runs into a semantic problem (such as with the five above) in one document, a following document may still be deserialized successfully.
The goal of this design is to be able to concatenate arbitrary YAML documents together without altering their semantics: A middleware component may, without understanding the semantics of the YAML documents, collect multiple streams together or split up a single stream. As long as they are syntactically correct, stream splitting and merging are sound operations that do not invalidate a YAML document even if another document is structurally invalid.
This design primary focuses on sending and receiving data over networks. Of course, nowadays, YAML is primarily used as configuration language. This is why this feature is seldom used and of rather little importance.
Edit: (Reply to comment)
What about end-cases like a string-tagged Document starts with a folded-string, making even its following "---" and "..." just a characters of the global string?
That is not the case, see rules l-bare-document and c-forbidden. A line containing un-indented ... not followed by non-whitespace will always end a document if one is open.
Moreover, ... doesn't do anything if no document is open. This ensures that a stream merger can always append ... to a document to ensure that the current document is closed, but no additional one is created.
--- has widely been adopted as separator between YAML documents (and, perhaps more prominently, between YAML front matter and content in tools like Jekyll) where ... would have been more appropriate, particularly in Jekyll. This gives the false impression that --- should be used by tooling to separate documents, when in reality ... is the syntactic element designed for that use-case.

Alias overwrite flagged as bad indentation of a mapping entry

I have an anchor as follows:
helm-install
docker-flags: &my_docker_flags
- "--network host"
- "--env KUBECONFIG=/tmp/admin.conf"
- "--env HOME=${env.HOME}"
- "--volume ${env.KUBECONFIG}:/tmp/admin.conf:ro"
- "--volume ${env.PWD}:${env.PWD}"
- "--volume ${env.HOME}/.helm:${env.HOME}/.helm"
- "--volume
${var.docker_config_basepath}:${var.docker_config_basepath}"
later I want to do:
docker-flags:
<<: *my_docker_flags
- "--env K8_NAMESPACE=${env.K8_NAMESPACE}"
But, the last line is flagged as bad indentation of a mapping entry YAML
The YAML merge key <<, defined here, is a feature defined for outdated YAML 1.1. It has never been part of the spec and thus its implementation is optional. Lots of YAML implementations implemented it and it remains a feature even while they get updated for YAML 1.2, which doesn't define this feature.
As a „key“, it is not a special syntax feature. Instead, much like the scalar true, it gets interpreted as something special because of its content. Supporting implementations will treat it according to the linked specification when it occurs as key in a mapping.
However, a sequence like the one you are showing is a different data structure: It contains a sequence of items. There is no place to put a merge key here, so you cannot use this feature in a sequence.
Generally, YAML is not a data processing language. << was and is an exception to that, there are no other processing features – neither for merging sequences, nor for different operations you would expect from a data processing language, like e.g. concatenation of strings.
For this reason, lots of tools that heavily use YAML, such as Ansible or Helm, include some kind of template processing for their YAML input files. While far from perfect, templating is currently the most versatile way to do data processing in a YAML file.
If the tool that reads your YAML doesn't provide you with a templating engine, your only option is to pre-process the YAML file manually, for example using a simple templating engine like mustache. Whether that is feasible depends of course on the context.

Why yaml is popular? Is there anything else that does better. [duplicate]

What are the differences between YAML and JSON, specifically considering the following things?
Performance (encode/decode time)
Memory consumption
Expression clarity
Library availability, ease of use (I prefer C)
I was planning to use one of these two in our embedded system to store configure files.
Related:
Should I use YAML or JSON to store my Perl data?
Technically YAML is a superset of JSON. This means that, in theory at least, a YAML parser can understand JSON, but not necessarily the other way around.
See the official specs, in the section entitled "YAML: Relation to JSON".
In general, there are certain things I like about YAML that are not available in JSON.
As #jdupont pointed out, YAML is visually easier to look at. In fact the YAML homepage is itself valid YAML, yet it is easy for a human to read.
YAML has the ability to reference other items within a YAML file using "anchors." Thus it can handle relational information as one might find in a MySQL database.
YAML is more robust about embedding other serialization formats such as JSON or XML within a YAML file.
In practice neither of these last two points will likely matter for things that you or I do, but in the long term, I think YAML will be a more robust and viable data serialization format.
Right now, AJAX and other web technologies tend to use JSON. YAML is currently being used more for offline data processes. For example, it is included by default in the C-based OpenCV computer vision package, whereas JSON is not.
You will find C libraries for both JSON and YAML. YAML's libraries tend to be newer, but I have had no trouble with them in the past. See for example Yaml-cpp.
Differences:
YAML, depending on how you use it, can be more readable than JSON
JSON is often faster and is probably still interoperable with more systems
It's possible to write a "good enough" JSON parser very quickly
Duplicate keys, which are potentially valid JSON, are definitely invalid YAML.
YAML has a ton of features, including comments and relational anchors. YAML syntax is accordingly quite complex, and can be hard to understand.
It is possible to write recursive structures in yaml: {a: &b [*b]}, which will loop infinitely in some converters. Even with circular detection, a "yaml bomb" is still possible (see xml bomb).
Because there are no references, it is impossible to serialize complex structures with object references in JSON. YAML serialization can therefore be more efficient.
In some coding environments, the use of YAML can allow an attacker to execute arbitrary code.
Observations:
Python programmers are generally big fans of YAML, because of the use of indentation, rather than bracketed syntax, to indicate levels.
Many programmers consider the attachment of "meaning" to indentation a poor choice.
If the data format will be leaving an application's environment, parsed within a UI, or sent in a messaging layer, JSON might be a better choice.
YAML can be used, directly, for complex tasks like grammar definitions, and is often a better choice than inventing a new language.
Bypassing esoteric theory
This answers the title, not the details as most just read the title from a search result on google like me so I felt it was necessary to explain from a web developer perspective.
YAML uses space indentation, which is familiar territory for Python developers.
JavaScript developers love JSON because it is a subset of JavaScript and can be directly interpreted and written inside JavaScript, along with using a shorthand way to declare JSON, requiring no double quotes in keys when using typical variable names without spaces.
There are a plethora of parsers that work very well in all languages for both YAML and JSON.
YAML's space format can be much easier to look at in many cases because the formatting requires a more human-readable approach.
YAML's form while being more compact and easier to look at can be deceptively difficult to hand edit if you don't have space formatting visible in your editor. Tabs are not spaces so that further confuses if you don't have an editor to interpret your keystrokes into spaces.
JSON is much faster to serialize and deserialize because of significantly less features than YAML to check for, which enables smaller and lighter code to process JSON.
A common misconception is that YAML needs less punctuation and is more compact than JSON but this is completely false. Whitespace is invisible so it seems like there are less characters, but if you count the actual whitespace which is necessary to be there for YAML to be interpreted properly along with proper indentation, you will find YAML actually requires more characters than JSON. JSON doesn't use whitespace to represent hierarchy or grouping and can be easily flattened with unnecessary whitespace removed for more compact transport.
The Elephant in the room: The Internet itself
JavaScript so clearly dominates the web by a huge margin and JavaScript developers prefer using JSON as the data format overwhelmingly along with popular web APIs so it becomes difficult to argue using YAML over JSON when doing web programming in the general sense as you will likely be outvoted in a team environment. In fact, the majority of web programmers aren't even aware YAML exists, let alone consider using it.
If you are doing any web programming, JSON is the default way to go because no translation step is needed when working with JavaScript so then you must come up with a better argument to use YAML over JSON in that case.
This question is 6 years old, but strangely, none of the answers really addresses all four points (speed, memory, expressiveness, portability).
Speed
Obviously this is implementation-dependent, but because JSON is so widely used, and so easy to implement, it has tended to receive greater native support, and hence speed. Considering that YAML does everything that JSON does, plus a truckload more, it's likely that of any comparable implementations of both, the JSON one will be quicker.
However, given that a YAML file can be slightly smaller than its JSON counterpart (due to fewer " and , characters), it's possible that a highly optimised YAML parser might be quicker in exceptional circumstances.
Memory
Basically the same argument applies. It's hard to see why a YAML parser would ever be more memory efficient than a JSON parser, if they're representing the same data structure.
Expressiveness
As noted by others, Python programmers tend towards preferring YAML, JavaScript programmers towards JSON. I'll make these observations:
It's easy to memorise the entire syntax of JSON, and hence be very confident about understanding the meaning of any JSON file. YAML is not truly understandable by any human. The number of subtleties and edge cases is extreme.
Because few parsers implement the entire spec, it's even harder to be certain about the meaning of a given expression in a given context.
The lack of comments in JSON is, in practice, a real pain.
Portability
It's hard to imagine a modern language without a JSON library. It's also hard to imagine a JSON parser implementing anything less than the full spec. YAML has widespread support, but is less ubiquitous than JSON, and each parser implements a different subset. Hence YAML files are less interoperable than you might think.
Summary
JSON is the winner for performance (if relevant) and interoperability. YAML is better for human-maintained files. HJSON is a decent compromise although with much reduced portability. JSON5 is a more reasonable compromise, with well-defined syntax.
GIT and YAML
The other answers are good. Read those first. But I'll add one other reason to use YAML sometimes: git.
Increasingly, many programming projects use git repositories for distribution and archival. And, while a git repo's history can equally store JSON and YAML files, the "diff" method used for tracking and displaying changes to a file is line-oriented. Since YAML is forced to be line-oriented, any small changes in a YAML file are easier to see by a human.
It is true, of course, that JSON files can be "made pretty" by sorting the strings/keys and adding indentation. But this is not the default and I'm lazy.
Personally, I generally use JSON for system-to-system interaction. I often use YAML for config files, static files, and tracked files. (I also generally avoid adding YAML relational anchors. Life is too short to hunt down loops.)
Also, if speed and space are really a concern, I don't use either. You might want to look at BSON.
I find YAML to be easier on the eyes: less parenthesis, "" etc. Although there is the annoyance of tabs in YAML... but one gets the hang of it.
In terms of performance/resources, I wouldn't expect big differences between the two.
Futhermore, we are talking about configuration files and so I wouldn't expect a high frequency of encode/decode activity, no?
Technically YAML offers a lot more than JSON (YAML v1.2 is a superset of JSON):
comments
anchors and inheritance - example of 3 identical items:
item1: &anchor_name
name: Test
title: Test title
item2: *anchor_name
item3:
<<: *anchor_name
# You may add extra stuff.
...
Most of the time people will not use those extra features and the main difference is that YAML uses indentation whilst JSON uses brackets. This makes YAML more concise and readable (for the trained eye).
Which one to choose?
YAML extra features and concise notation makes it a good choice for configuration files (non-user provided files).
JSON limited features, wide support, and faster parsing makes it a great choice for interoperability and user provided data.
If you don't need any features which YAML has and JSON doesn't, I would prefer JSON because it is very simple and is widely supported (has a lot of libraries in many languages). YAML is more complex and has less support. I don't think the parsing speed or memory use will be very much different, and maybe not a big part of your program's performance.
Benchmark results
Below are the results of a benchmark to compare YAML vs JSON loading times, on Python and Perl
JSON is much faster, at the expense of some readability, and features such as comments
Test method
100 sequential runs on a fast machine, average number of seconds
The dataset was a 3.44MB JSON file, containing movie data scraped from Wikipedia
https://raw.githubusercontent.com/prust/wikipedia-movie-data/master/movies.json
Linked to from: https://github.com/jdorfman/awesome-json-datasets
Results
Python 3.8.3 timeit
JSON: 0.108
YAML CLoader: 3.684
YAML: 29.763
Perl 5.26.2 Benchmark::cmpthese
JSON XS: 0.107
YAML XS: 0.574
YAML Syck: 1.050
Perl 5.26.2 Dumbbench (Brian D Foy, excludes outliers)
JSON XS: 0.102
YAML XS: 0.514
YAML Syck: 1.027
From: Arnaud Lauret Book “The Design of Web APIs.” :
The JSON data format
JSON is a text data format based on how the JavaScript programming language describes data but is, despite its name, completely language-independent (see https://www.json.org/). Using JSON, you can describe objects containing unordered name/value pairs and also arrays or lists containing ordered values, as shown in this figure.
An object is delimited by curly braces ({}). A name is a quoted string ("name") and is sep- arated from its value by a colon (:). A value can be a string like "value", a number like 1.23, a Boolean (true or false), the null value null, an object, or an array. An array is delimited by brackets ([]), and its values are separated by commas (,).
The JSON format is easily parsed using any programming language. It is also relatively easy to read and write. It is widely adopted for many uses such as databases, configura- tion files, and, of course, APIs.
YAML
YAML (YAML Ain’t Markup Language) is a human-friendly, data serialization format. Like JSON, YAML (http://yaml.org) is a key/value data format. The figure shows a comparison of the two.
Note the following points:
There are no double quotes (" ") around property names and values in YAML.
JSON’s structural curly braces ({}) and commas (,) are replaced by newlines and
indentation in YAML.
Array brackets ([]) and commas (,) are replaced by dashes (-) and newlines in
YAML.
Unlike JSON, YAML allows comments beginning with a hash mark (#).
It is relatively easy to convert one of those formats into the other. Be forewarned though, you will lose comments when converting a YAML document to JSON.
Since this question now features prominently when searching for YAML and JSON, it's worth noting one rarely-cited difference between the two: license. JSON purports to have a license which JSON users must adhere to (including the legally-ambiguous "shall be used for Good, not Evil"). YAML carries no such license claim, and that might be an important difference (to your lawyer, if not to you).
Sometimes you don't have to decide for one over the other.
In Go, for example, you can have both at the same time:
type Person struct {
Name string `json:"name" yaml:"name"`
Age int `json:"age" yaml:"age"`
}
I find both YAML and JSON to be very effective. The only two things that really dictate when one is used over the other for me is one, what the language is used most popularly with. For example, if I'm using Java, Javascript, I'll use JSON. For Java, I'll use their own objects, which are pretty much JSON but lacking in some features, and convert it to JSON if I need to or make it in JSON in the first place. I do that because that's a common thing in Java and makes it easier for other Java developers to modify my code. The second thing is whether I'm using it for the program to remember attributes, or if the program is receiving instructions in the form of a config file, in this case I'll use YAML, because it's very easily human read, has nice looking syntax, and is very easy to modify, even if you have no idea how YAML works. Then, the program will read it and convert it to JSON, or whatever is preferred for that language.
In the end, it honestly doesn't matter. Both JSON and YAML are easily read by any experienced programmer.
If you are concerned about better parsing speed then storing the data in JSON is the option. I had to parse the data from a location where the file was subject to modification from other users and hence I used YAML as it provides better readability compared to JSON.
And you can also add comments in the YAML file which can't be done in a JSON file.
JSON encodes six data types: Objects (mappings), Arrays, Strings Numbers, Booleans and Null. It is extremely easy for a machine to parse and provides very little flexibility. The specification is about a page and a half.
YAML allows the encoding of arbitrary Python data and other crazy crap (which leads to vulnerabilities when decoding it). It is hard to parse because it offers so much flexibility. The specification for YAML was 86 pages, the last time I checked. YAML syntax is obviously influenced by Python, but maybe they should have been a little more influenced by the Python philosophy on a few points: e.g. “there should be one—and preferably only one—obvious way to do it” and “simple is better than complex.”
The main benefit of YAML over JSON is that it’s easier for humans to read and edit, which makes it a natural choice for configuration files.
These days, I’m leaning towards TOML for configuration files. It’s not as pretty or as flexible as YAML, but it’s easier both for machines and humans to parse. The syntax is (almost) a superset of INI syntax, but it parses out to JSON-like data structures, adding only one additional type: the date type.

Is there a standard format for describing a flat file?

Is there a standard or open format which can be used to describe the formating of a flat file. My company integrates many different customer file formats. With an XML file it's easy to get or create an XSD to describe the XML file format. I'm looking for something similar to describe a flat file format (fixed width, delimited etc). Stylus Studio uses a proprietary .conv format to do this. That .conv format can be used at runtime to transform an arbitrary flat file to an XML file. I was just wondering if there was any more open or standards based method for doing the same thing.
I'm looking for one method of describing a variety of flat file formats whether they are fixed width or delimited, so CSV is not an answer to this question.
XFlat:
http://www.infoloom.com/gcaconfs/WEB/philadelphia99/lyons.HTM#N29
http://www.unidex.com/overview.htm
For complex cases (e.g. log files) you may consider a lexical parser.
About selecting existing flat file formats: There is the Comma-separated values (CSV) format. Or, more generally, DSV. But these are not "fixed-width", since there's a delimiter character (such as a comma) that separates individual cells. Note that though CSV is standardized, not everybody adheres to the standard. Also, CSV may be to simple for your purposes, since it doesn't allow a rich document structure.
In that respect, the standardized and only slightly more complex (but thus more useful) formats JSON and YAML are a better choice. Both are supported out of the box by plenty of languages.
Your best bet is to have a look at all languages listed as non-binary in this overview and then determine which works best for you.
About describing flat file formats: This could be very easy or difficult, depending on the format. Though in most cases easier solutions exist, one way that will work in general is to view the file format as a formal grammar, and write a lexer/parser for it. But I admit, that's quite† heavy machinery.
If you're lucky, a couple of advanced regular expressions may do the trick. Most formats will not lend themselves for that however.‡ If you plan on writing a lexer/parser yourself, I can advise PLY (Python Lex-Yacc). But many other solutions exists, in many different languages, a lot of them more convenient than the old-school Lex & Yacc. For more, see What parser generator do you recommend?
  †: Yes, that may be an understatement.
  ‡: Even properly describing the email address format is not trivial.
COBOL (whether you like it or not) has a standard format for describing fixed-width record formats in files.
Other file formats, however, are somewhat simpler to describe. A CSV file, for example, is just a list of strings. Often the first row of a CSV file is the column names -- that's the description.
There are examples of using JSON to formulate metadata for text files. This can be applied to JSON files, CSV files and fixed-format files.
Look at http://www.projectzero.org/sMash/1.1.x/docs/zero.devguide.doc/zero.resource/declaration.html
This is IBM's sMash (Project Zero) using JSON to encode metadata. You can easily apply this to flat files.
At the end of the day, you will probably have to define your own file standard that caters specifically to your storage needs. What I suggest is using xml, YAML or JSON as your internal container for all of the file types you receive. On top of this, you will have to implement some extra validation logic to maintain meta-data such as the column sizes of the fixed width files (for importing from and exporting to fixed width). Alternatively, you can store or link a set of metadata to each file you convert to the internal format.
There may be a standard out there, but it's too hard to create 'one size fits all' solutions for these problems. There are entity relationship management tools out there (Talend, others) that make creating these mappings easier, but you will still need to spend a lot of time maintaining file format definitions and rules.
As for enforcing column width, xml might be the best solution as you can describe the formats using xml schemas (with the length restriction). For YAML or JSON, you may have to write your own logic for this, although I'm sure someone else has come up with a solution.
See XML vs comma delimited text files for further reference.
I don't know if there is any standard or open format to describe a flat file format. But one industry has done this: the banking industry. Financial institutions are indeed communicating using standardized message over a dedicated network called SWIFT. SWIFT messages were originally positional (before SWIFTML, the XMLified version). I don't know if it's a good suggestion as it's kinda obscure but maybe you could look at the SWIFT Formatting Guide, it may gives you some ideas.
Having that said, check out Flatworm, an humble flat file parser. I've used it to parse positional and/or CSV file and liked its XML descriptor format. It may be a better suggestion than SWIFT :)
CSV
CSV is a delimited data format that has fields/columns separated by the comma character and records/rows separated by newlines. Fields that contain a special character (comma, newline, or double quote), must be enclosed in double quotes. However, if a line contains a single entry which is the empty string, it may be enclosed in double quotes. If a field's value contains a double quote character it is escaped by placing another double quote character next to it. The CSV file format does not require a specific character encoding, byte order, or line terminator format.
The CSV entry on wikipedia allowed me to find a comparison of data serialization formats that is pretty much what you asked for.
The only similar thing I know of is Hachoir, which can currently parse 70 file formats:
http://bitbucket.org/haypo/hachoir/wiki/Home
I'm not sure if it really counts as a declarative language, since it's plugin parser based, but it seems to work, and is extensible, which may meet your needs just fine.
As an aside, there are interesting standardised, extensible flat-file FORMATS, such as IFF (Interchange File Format).

Most non-confrontational delimiter for my text files?

I am saving all my notes in a log file. Each line is a note, suffixed by tags, and prefixed by a date and time marker, which currently looks like this: [12.20.09:22.22] ([date:time].
I am planning to have this a long-living format. Notes will be logged willy-nilly with this format 20-30 times a day for years to come. I foresee numerous kinds of parsing for analytics, filtering, searching ...
I am worried about the [ ]s though. Could they possibly trip some parsing code (someone else's if not mine)? What would be the most non-confrontational marker?
If you end up going with your own format, can I recommend ISO 8601 for your date and time format.
In summary, the basic format is:
yyyy-mm-dd hh:mm:ss
You can extend this with timezone and microsecond info if you wish. Timezone is recommended or assume UTC.
With the date/time in this format there's no confusion over which is the month and the day. And it has the bonus of sorting using a basic string sort.
I'd consider using either XML or JSON as the format for the file.
In particular your date/time marker is ambiguous. Is it mm/dd/yy or dd/mm/yy? Or even yy/mm/dd? And in what timezone is the date and time?
Both XML and JSON define a way to have dates that are culture and timezone independent, and (best of all) there's masses of tooling available for both formats.
XML datetime format is defined here: for example, 2000-01-12T12:13:14Z.
JSON datetime format is defined as the number of seconds since Jan 1, 1970, so it's a bit uglier: { currentDate: "#1163531522089#" }
If you want everything to last in a long-lived format, then the metadata needs to be as explicit as possible. If it's intended to be long-lived, then many others will need to read it, as easily as possible.
I agree with Jeremy McGee: XML is an excellent choice. Even if no other data lives, then having it be in the format:
<note>
<datetime>
<year>
2009
</year>
<month>
12
</month>
. . .
</datetime>
<message>
Foo bar baz quox
</message>
<note>
cannot be misunderstood.
This depends on your data. However, if you escape them with a special character of some sort, (i.e. \]) and code accordingly to look at the previous character when finding a "[" or "]", you should have no problem.
Also, if you're open to a new format, I'm a fan of JSON as it's light weight and very useful.
Using '[]' as the markers would be ok provided that you allow the DSL the ability to escape the characters. This is typical of operations on text which need parsing.
As an example check out the typical regular expression syntax which enables '/' as the seperator, whilst letting the user specify an escape character such as '\'. You may get some more ideas from the likes of such Unix tools as; awk, sed and grep
I would tend to think a standardized format is the way to go, with JSON being my personal choice because of it's simplicity. Not only does that help to avoid parsing issues since others have already though about it, you are also given a lot more tools to work with over the life of the project.

Resources