Carrot From 10,000 Meters

1 - What's Carrot?

It is a markup language.

Carrot is not bound to the web, or any other medium. Carrot's native output format is a datastructure (if these words make you teary-eyed, welcome home; if you don't understand them, I promise you won't have to fiddle with it). Carrot is not owned by anyone or encumbered by anything.

Carrot is designed to be survivable and adaptable. Carrot will be around for a long time. Carrot will change and grow.

2 - Carrot Looks Like This

;;; for mr. steves's 4th period english (sucks)
[[document title;'My Summer Vacation' date;2019-08-22
           author;'Ramona Cartwright']]

  This year's vacation was a lot of fun, and we did a bunch of
  stuff.
    
[[section title;'Grandma's House'
    Our first stop was Grandma's. It's always cool to visit her
    because she used to work at [link uri;http://google.com
    Google], and she tells the best stories.
    
    I love Grandma!
]]

We may as well start at the beginning.

;;; for mr. steves's 4th period english (sucks)
[[document title;'My Summer Vacation' date;2019-08-22
           author;'Ramona Cartwright']]
    
This year's vacation was a lot of fun, and we did a bunch of

The first line of our sample doc is a comment. Comments start with three semicolons and run to end-of-line. There are no multiline comments.

;;; for mr. steves's 4th period english (sucks)
[[document title;'My Summer Vacation' date;2019-08-22
           author;'Ramona Cartwright']]

This year's vacation was a lot of fun, and we did a bunch of

The highlighted portion here is the document trigger. All Carrot documents must begin with a document trigger.

It contains metadata about the document. This can include simple things like document titles (seen above) and more complex things like instructions to the Carrot compiler (which we'll see later).

;;; for mr. steves's 4th period english (sucks)
[[document title;'My Summer Vacation' date;2019-08-22
           author;'Ramona Cartwright']]

This year's vacation was a lot of fun, and we did a bunch of

The document trigger is bounded by two square brackets. Left brackets for open; right brackets for close. The opening brackets must be the first characters on a new line, and the closing brackets must be the last characters on a line.

[[document title;'My Summer Vacation' date;2019-08-22
           author;'Ramona Cartwright']]
     ...
[[section title;'Grandma's House'
  Our first stop was Grandma's. It's always cool to visit her
     ...
  I love Grandma!
]]

Notice that the chunk of text labelled section shares some formatting with the document trigger.

This is because they are both triggers. Where HTML/XML have one type of markup (the tag), Carrot has three distinct forms: triggers, tags, and verbatim chunks. Each has a different job to do in the document, but all share common markup characters and formatting.

3 - Triggers

The job of triggers is to mark logical blocks of content within the document.

The document trigger contains information about the document. A section trigger groups paragraphs of text into sections or subsections. Triggers provide structure to the document.

3.1 - Names

[[document title;'My Summer Vacation' date;2019-08-22
           author;'Ramona Cartwright']]
     ...
[[section title;'Grandma's House'
  Our first stop was Grandma's. It's always cool to visit her
     ...
  I love Grandma!
]]

A trigger's name always immediately follows its opening brackets (no spaces allowed). The name simply says what kind of trigger it is.

3.2 - Attributes

[[document title;'My Summer Vacation' date;2019-08-22
           author;'Ramona Cartwright']]
     ...
[[section title;'Grandma's House'
  Our first stop was Grandma's. It's always cool to visit her
     ...
  I love Grandma!
]]

Following the trigger's name are its attributes. A trigger can have many attributes, or one, or none. Each trigger has its own set of attributes. That is to say, not all triggers accept all attributes.

Attributes are key-value pairs, with a semicolon separating the key and value. Attributes are separated from each other by whitespace.

[[document title;'My Summer Vacation' date;2019-08-22
           author;'Ramona Cartwright']]
     ...
[[section title;'Grandma's House'
  Our first stop was Grandma's. It's always cool to visit her
     ...
  I love Grandma!
]]

Attribute keys never contain spaces.

[[document title;'My Summer Vacation' date;2019-08-22
           author;'Ramona Cartwright']]
     ...
[[section title;'Grandma's House'
  Our first stop was Grandma's. It's always cool to visit her
     ...
  I love Grandma!
]]

Attribute values may contain whitespace, but if so, they must be bounded by single-quotes.

[[section title;'Grandma's House'
  Our first stop was Grandma's. It's always cool to visit her
     ...
  I love Grandma!
]]

Unlike most languages, Carrot allows the quote character to occur inside quotes, so long as it is within a word. (It's possible to have a quote at the end of a word, or even standing alone, but we'll cover that later.)

3.3 - Content

[[document title;'My Summer Vacation' date;2019-08-22
           author;'Ramona Cartwright']]

This year's vacation was a lot of fun, and we did a bunch of
stuff.

[[section title;'Grandma's House'
  Our first stop was Grandma's. It's always cool to visit her
  because she used to work at [link uri;http://google.com    
  Google], and she tells the best stories.                   

  I love Grandma!
]]

The highlighted text is the content of the section trigger. Not all triggers have content — the document trigger doesn't — but most of them do.

Content may be simple paragraphs of text, as it is here, or it may be more highly structured, as in a trigger which generates a list of some sort.

3.4 - Formatting Details

[[document title;'My Summer Vacation' date;2019-08-22
           author;'Ramona Cartwright']]
    ...
[[section title;'Grandma's House'
  Our first stop was Grandma's. It's always cool to visit her
    ...
  I love Grandma!
]]

Closing brackets do have to be the last thing on a line, but they don't have to be on the same line as the content of the trigger. They can be separated from the content by any amount of whitespace.

[[section title;'Grandma's House'
  Our first stop was Grandma's. It's always cool to visit her
  because she used to work at [link uri;http://google.com    
  Google], and she tells the best stories.                   
  
  I love Grandma!
]]

Like most programming and/or markup languages, indention is not neccessary, but it does look nice and provide important visual cues.

[[section title;'Grandma's House'
  Our first stop was Grandma's. It's always cool to visit her
  ...

There is no markup which separates attributes from content, or attributes from trigger names, or trigger names from content; all have distinct forms and the compiler recognizes them.

4 - Tags

The job of tags is to handle markup which is inline of text content..

Our first stop was Grandma's. It's always cool to visit her
because she used to work at [link uri;http://google.com
Google], and she tells the best stories.

The highlighted text above is a tag. Tags have two immediately noticable differences from triggers:

  1. They are bounded by pairs of single left/right square brackets
  2. They can occur anywhere on a line

Nearly everything else about them is the same.

because she used to work at [link uri;http://google.com
Google], and she tells the best stories.

They have names, which must be adjacent to their opening bracket.

because she used to work at [link uri;http://google.com
Google], and she tells the best stories.

They can have attributes (one, or many, or none), which look and behave exactly the same as trigger attributes.

because she used to work at [link uri;http://google.com
Google], and she tells the best stories.

They can (and usually will) have textual content, which is somehow modified or used by the tag.

because she used to work at [link uri;http://google.com
[[list type;unordered
  -- Google and        ;;; no no no
  -- Baidu and       
  -- Moto]] ], and she tells the best stories.

Finally, triggers can contain tags, but tags can never contain triggers (or verbatim chunks).

5 - Verbatim Chunks

The job of verbatim chunks is to contain text which should not be transformed.

[[section title;'Carrot Looks Like This'

[[[code
 ;;; for mr. steves's 4th period english (sucks)
 [[document title;'My Summer Vacation' date;2019-08-22
            author;'Ramona Cartwright']]
     
 This year's vacation was a lot of fun, and we did a bunch of
]]]

We may as well start at the beginning.

No processing will be done on the highlighted text above. It will all simply be stored for later presentation. All whitespace will be preserved.

[[[code
 ;;; for mr. steves's 4th period english (sucks)
 [[document title;'My Summer Vacation' date;2019-08-22
            author;'Ramona Cartwright']]
     
 This year's vacation was a lot of fun, and we did a bunch of
]]]

Verbatim chunks open with treble left square brackets, and (like triggers) they must begin on a new line.

Verbatim chunks close with treble right square brackets, and these (unlike triggers) must be the only thing on that line. Not even whitespace is allowable. This is to enable text which would normally be interpreted as a verbatim chunk to be unambiguously included in verbatim chunks.

Verbatim chunks can be contained inside triggers, but, self-evidently, neither triggers or tags can exist in a meaningful way inside a verbatim chunk.

6 - And A Peek At All The Rest

6.1 - Entities

HTML uses entities to include "unusual" characters in documents. Carrot does too, but they have two forms.

Hello.
[H][e][l][l][o][.]

The first form is actually a generalized escape, like the Unix convention of preceeding a character with a backslash. Any single character between a pair of square brackets is equivalent to that character. Therefore, post-processing, the above lines of text are equivalent.

title;'The Dog Is The Boys[']'

You may have already figured out that this is how you get a singlequote at the beginning or end of a quoted attribute value.

S[e'][c,][o"][n~]d[->]f[o/]rm entities
Séçöñd→førm entities

Any pair of characters bounded by square brackets will be looked up and replaced with a single character which they have been mapped to. This is directly analagous to HTML entities.

You may be wondering if entities are a general-purpose macro system, in the style of the C preprocessor. I believe the answer is (and should be) "No."

You may be exceptionally troublesome, and wondering if entities are resolved inside verbatim chunks. I believe the answer is (and should be) "Yes."

6.2 - Compact Forms

[[section title;Foo
[[s t;Foo

[[list type;ordered
[[l t;o

If you were asking why a language so concerned with saving typing had such long element and attribute names, you can take it easy. All elements and attribute names can be aliased to abbreviated forms. Please note that the above examples are abstract, and for illustrative purposes only.

6.3 - Internationalization

"Well, then," you say, "what about your carefully chosen markup characters? They're all unshifted on a US keyboard, but there are other keyboards, you ignorant cultural imperialist!"

;;; altered markup
[[docinfo markup;<>="*]]

<<section title="Faux HTML"

Now my markup looks like weird HTML.>>

Carrot's language definition isn't hardcoded. It is possible to redefine almost everything, including the very characters used to delineate markup. The only caveat is that the document trigger must always use the standard markup characters.

Additionally, the aliasing mechanism described in the previous section lets all the names in the system have equivalents in the author's native language (again, excepting those in the document trigger).

In short: Carrot's is fully localizable. It will be easy to type no matter where you are.

6.4 - Customization and Extension

The Carrot system will be customizable in the usual manner, with per-system and per-user option configurations.

Users and system admins can also define local aliases and entities, write whole new markup element handlers, or rewrite existing ones to better suit their needs. Carrot's design does not presume to foresee everything.

It is, in fact, hoped that Carrot will attract an active community of users and contributors, and that a CPAN-like repository of contributed modules will be available for everyone to use.

With or without a CPAN-alike, there will be a way to safely write documents using local modifications without worrying about other people having those modifications in their Carrot installs. A scheme called "document export" is being developed, which will check documents for nonstandard markups and include processing instructions for them inside the exported document itself, as checksummed, compressed data. It's pretty swank.

7 - Conclusion

You should now know what Carrot is, some of the problems it was designed to solve, and the basics of its structure and rules. You've also had a peek at some specific features which are less basic, but there's much more to see.

Portions of this document are forward-looking, but nothing described herein is vaporware. Almost all features and designs have had their implementation problems "cracked", and will be real software relatively shortly. (The one lingering unknown is how to create pluggable output modules, but there is much work to be done between the present day and that problem needing to be solved.)

Carrot is coming, and sooner rather than later :)