-
Notifications
You must be signed in to change notification settings - Fork 5
/
index.html
611 lines (487 loc) · 21.8 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
<!DOCTYPE html>
<html en="en">
<head>
<title>Archie Markup Language (ArchieML)</title>
<meta charset='utf-8'>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
<meta name="description" content="ArchieML is a text format optimized for human writability. It was designed for users unfamiliar with existing serialization formats, and defines a forgiving, incremental parser that does not throw syntax errors.">
<meta name="twitter:card" content="summary">
<meta name="twitter:url" content="https://archieml.org/">
<meta name="twitter:title" content="Archie Markup Language (ArchieML)">
<meta name="twitter:description" content="ArchieML is a text format optimized for human writability, with a syntax designed to be as simple as possible.">
<meta name="twitter:image" content="https://archieml.org/assets/twittercard.png">
<meta name="og:image" content="https://archieml.org/assets/facebookshare.png">
<meta name="og:site_name" content="ArchieML.org">
<meta name="og:url" content="https://archieml.org/">
<link rel="canonical" href="https://archieml.org/" />
<link href="poole.css" media="all" rel="stylesheet" />
<link href="hyde.css" media="all" rel="stylesheet" />
<link href="archieml.css" media="all" rel="stylesheet" />
<script type="text/javascript" src="https://typeface.nytimes.com/zam5nzz.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
<script src="archieml.js"></script>
</head>
<body>
<div class="sidebar">
<div class="container sidebar-sticky">
<div class="sidebar-about">
<div><img style="margin:0 auto; display: block;" src="/assets/archieml-tri.png" width="200"></div>
<h1>ArchieML</h1>
<p class="lead">ArchieML is a structured text format optimized for human writability.</p>
</div>
<ul class="sidebar-nav">
<li class="sidebar-nav-item sidebar-nav-hash"><a href="#resources">Resources</a></li>
<li class="sidebar-nav-item sidebar-nav-hash"><a href="#demo">Demo</a></li>
<li class="sidebar-nav-item sidebar-nav-hash"><a href="#usage">Usage</a></li>
<li class="sidebar-nav-item"><a href="/sandbox.html">Sandbox</a></li>
<li class="sidebar-nav-item"><a href="/spec/1.0/CR-20151015.html">Spec</a></li>
</ul>
<p class="rear">Structured text,<br>for an unstructured world.</p>
</div>
</div>
<div class="content container">
<h2>What is Archie Markup Language?</h2>
<p>
ArchieML (or "AML") was created at The New York Times to make it easier to write and edit structured text on deadline that could be rendered in web pages, or more specifically, rendered in interactive graphics.
</p>
<p>One of the main goals was to make it easy to tag text as data, without having type a lot of special characters. Another goal was to allow the document to contain lots of notes and draft text that would not be read into the data. And finally, because we make extensive use of Google Documents's concurrent-editing features — while working on a graphic, we can have several reporters, editors and developers all pouring information into a single document — we wanted to have a format that could survive being edited by users who may never have seen ArchieML or any other markup language at all before.
</p>
<hr>
<h3 id="why-not">Why not YAML? Or JSON?</h3>
<p>ArchieML differs from other popular formats like <a href="https://yaml.org/">YAML</a> and <a href="https://json.org/">JSON</a> in several areas that we've found are key to making it easy to use:</p>
<ul>
<li>
<p>
<strong>Whitespace is not significant to the document structure</strong>
<br>
In YAML, lines must be indented precisely and variably; the wrong number of spaces to the left of a key invalidates the document, and tabs can't be used. AML ignores all whitespace not within a value. We believe this makes it easier for non-programmers to use, and is essential for use in environments with non-monospaced fonts, like in Google Documents.
</p>
</li>
<li>
<p>
<strong>Unstructured text is ignored; there is no such thing as a parsing error</strong>
<br>
AML was designed so that writers could work in a freeform environment. They should be able to add entire paragraphs as scratch work that do not appear in the output. JSON and YAML have strict schemas that forbid text deviating from a pattern. AML doesn't assume text follows any pattern. If it finds text that looks like data, it treats it as data. Otherwise, it moves on.
</p>
</li>
<li>
<p>
<strong>The notation makes sense to non-programmers</strong>
<br>
Lists of values are noted with bullet points / asterisks, not hyphens or quoted strings that must be separated with commas. An overriding goal was to have a intuitive format that could be passed to a non-technical user — a reporter, an assigning editor or a copy editor — to edit, and to have the format be clear enough that they could make changes without breaking the parsing of the document. If we were using another format, we'd have to explain indentation rules in YAML, or how to match curly braces or properly escape quotation marks in JSON, and so forth.
</p>
</li>
</ul>
<hr>
<h3 id="practice">How Does It Work in Practice?</h3>
<p>For a very simple example, here's a screenshot of the Google Doc that powers a <a href="https://www.nytimes.com/interactive/2015/01/31/sports/football/common-ploys-of-patriots-and-seahawks.html">recent graphic about the trick plays</a> used by the New England Patriots and Seattle Seahawks:</p>
<div class="example-image"><img src="assets/example-football.png"></div>
<p>To generate the graphic, we load the ArchieML data from the document using the <a href="https://www.npmjs.com/package/archieml ">archieml-js npm module</a>, then pass it to an underscore template to render the final markup server-side. This lets the journalists who are focusing on the text and content concentrate on getting the copy in shape independently of the developers working on the graphic.</p>
<p>While this is a very simple example, with only a few bits of text and data and one comment at the end that is ignored, when we're covering a breaking news story, we can have a half-dozen people all contributing to a Google Doc at the same time as we gather all the information we need for a graphic and turn it into the final copy blocks that make their way into the finished piece.</p>
<h2 id="resources">Resources</h2>
<p>Parsers and tools in (hopefully) your language of choice.</p>
<ul>
<li>
<strong>JavaScript</strong> Both parsers can be used client-side in the browser, or using Asynchronous Module Definitions (AMD) such as RequireJS, and have test coverage.
<ul>
<li>
<strong><a href="https://github.com/newsdev/archieml-js">archieml-js</a></strong>
<ul>
<li><a href="https://www.npmjs.com/package/archieml">Node Package Manager (npm)</a></li>
</ul>
</li>
<li>
<strong><a href="https://github.com/dundalek/archieml-peg">archieml-peg</a></strong> (by <a href="https://dundalek.com/">Jakub Dundalek</a>)
</li>
<li>
<strong><a href="https://github.com/newsdev/archieml-loader">archieml-loader</a></strong> is a Webpack loader for ArchieML files.
</li>
<li>
<strong><a href="https://github.com/achavez/grunt-archieml">grunt-archieml</a></strong> (by <a href="https://twitter.com/adchavez">Andrew Chavez</a>)
</li>
<li>
<strong><a href="https://github.com/dallasmorningnews/gulp-archieml">gulp-archieml</a></strong> (by <a href="https://twitter.com/adchavez">Andrew Chavez</a> / The Dallas Morning News)
</li>
</ul>
</li>
<li>
<strong>Ruby</strong>
<ul>
<li>
<strong><a href="https://github.com/newsdev/archieml-ruby">archieml-ruby</a></strong> is a Ruby parser for ArchieML. It is available through the RubyGems package manager, and has test coverage.
<ul>
<li><a href="https://rubygems.org/gems/archieml">RubyGems</a></li>
</ul>
</li>
<li>
<strong><a href="https://github.com/BBC-News-Labs/stream-cms">stream-cms</a></strong> is an elasticsearch backed archieml-to-json manager (by <a href="https://twitter.com/jacqui">Jacqui Maher</a> / BBC News Labs)
</li>
</ul>
</li>
<li>
<strong>R</strong>
<ul>
<li>
<strong><a href="https://github.com/noamross/rchie">rchie</a></strong> (by <a href="https://twitter.com/noamross">Noam Ross</a>)
</li>
</ul>
</li>
<li>
<strong>.NET/C#</strong>
<ul>
<li>
<strong><a href="https://github.com/partlyhuman/archieml-net">archieml-net</a></strong> (by <a href="https://twitter.com/partlyhuman">Roger Braunstein</a> / Partlyhuman)
</li>
</ul>
</li>
<li>
<strong>PHP</strong>
<ul>
<li>
<strong><a href="https://github.com/4d47/php-archieml">php-archieml</a></strong> (by <a href="https://twitter.com/4d47">Mathieu Gagnon</a>)
</li>
</ul>
</li>
<li>
<strong>Python</strong>
<ul>
<li>
<strong><a href="https://github.com/brainkim/archieml-python">archieml-python</a></strong> (by <a href="https://twitter.com/bravebriankim">Brian Kim</a>)
<ul>
<li><a href="https://pypi.python.org/pypi/archieml">pip</a></li>
</ul>
</li>
<li>
<strong><a href="https://github.com/kevinschaul/archieml-python">archieml-python</a></strong> (by <a href="https://twitter.com/kevinschaul">Kevin Schaul</a>)
</li>
</ul>
</li>
<li>
<strong>Scala</strong>
<ul>
<li>
<strong><a href="https://github.com/maciej/sarchieml">SArchieML</a></strong> (by <a href="https://twitter.com/maciejb">Maciej Biłas</a>)
</li>
</ul>
</li>
<li>
<strong>HTML</strong>
<ul>
<li>
<strong><a href="https://github.com/pilgreen/archieml-element">archieml-element</a></strong> is a Polymer 1.0 component for parsing ArchieML content (by <a href="https://twitter.com/jaypilgreen">Jay Pilgreen</a>)
</li>
</ul>
</li>
<li>
<strong>Clojure</strong>
<ul>
<li>
<strong><a href="https://github.com/mihi-tr/archieclj">archieclj</a></strong> (by <a href="https://twitter.com/mihi_tr">Michael Bauer</a>)
<ul>
<li><a href="https://clojars.org/archieclj">Clojars</a></li>
</ul>
</li>
</ul>
</li>
<li>
<strong id="google-docs-plugins">Google Docs Plugins</strong> tools for connecting to Google Drive and parsing documents as ArchieML
<ul>
<li>
<strong><a href="https://github.com/Quartz/aml-gdoc-server">aml-gdoc-server</a></strong> (by <a href="https://twitter.com/YAN0">David Yanofsky</a> / Quartz)
<ul>
<li><a href="https://www.npmjs.com/package/aml-gdoc-server">Node Package Manager (npm)</a></li>
</ul>
</li>
<li>
<strong><a href="https://github.com/NewsappAJC/grunt-google-archieml">grunt-google-archieml</a></strong> (by <a href="https://twitter.com/ashlynstill">Ashlyn Still</a> / The Atlanta Journal-Constitution)
<ul>
<li><a href="https://www.npmjs.com/package/grunt-google-archieml">Node Package Manager (npm)</a></li>
</ul>
</li>
<li>
<strong><a href="https://github.com/fusioneng/interactive-template">Fusion Interactive Template</a></strong> (by <a href="https://twitter.com/kit__cross">Kit Cross</a> / Fusion)
</li>
<li>
<strong><a href="https://github.com/stuartathompson/node-archieml-boilerplate">node-archieml-boilerplate</a></strong> (by <a href="https://twitter.com/stuartathompson">Stuart Thompson</a> / The Wall Street Journal)
</li>
<li>
<strong><a href="https://github.com/bradoyler/googledoc-to-json">googledoc-to-json</a></strong> (by <a href="https://twitter.com/bradoyler">Brad Oyler</a>)
<ul>
<li><a href="https://www.npmjs.com/package/googledoc-to-json">Node Package Manager (npm)</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="google-docs">Integrating with Google Documents</h3>
<p>At The New York Times, we normally write ArchieML in Google Documents. Both parsers include quick-start examples for how to download text from Google Docs and run it through the parser. They also include some formatting steps we take, such as converting links to HTML tags.<br />
Examples:
</p>
<ul>
<li><a href="https://github.com/newsdev/archieml-js/tree/master#using-with-google-documents">JavaScript example</a></li>
<li><a href="https://github.com/newsdev/archieml-ruby/tree/master#using-with-google-documents">Ruby example</a></li>
</ul>
<p>For more fully-fledged integrations with Google Docs, use one of the <a href="#google-docs-plugins">plugins above</a>.</p>
<hr>
<h2 id="demo">Introductory Demo</h2>
<p>Click on any ArchieML textarea to try it out yourself, and see how changes affect the output.</p>
<p>Or try out ArchieML in the <a href="/sandbox.html">Sandbox</a>.</p>
<h3>Keys and values</h3>
<p>Strings can be stored as part of key/value pairs, defined whenever a line in ArchieML begins with a token followed by a colon. Keys can contain any unicode character, with the exception of whitespace / invisible characters, and a handful of characters that are used within ArchieML (<code>{ } [ ] : . +</code>). The rest of the string is the value.</p>
<aml>
key: This is a value
☃: Unicode Snowman for you and you and you!
</aml>
<p>Whitespace surrounding keys and values is ignored. Indent as you like. Keys are case sensitive.</p>
<aml>
1: value
2:value
3 : value
4: value
5: value
a: lowercase a
A: uppercase A
</aml>
<p>Lines that don't look like keys or other special commands are ignored:</p>
<aml>
This is a key:
key: value
It's a nice key!
</aml>
<h3>Nested key structure</h3>
<p>Use dot-notation to create nested objects.</p>
<aml>
colors.red: #f00
colors.green: #0f0
colors.blue: #00f
</aml>
<p>You can also use "object" blocks to namespace a group of keys.</p>
<aml>
{colors}
red: #f00
green: #0f0
blue: #00f
{}
{numbers}
one: 1
ten: 10
one-hundred: 100
{}
key: value
</aml>
<p>Dot notation can be used in object blocks as well:</p>
<aml>
{colors.reds}
crimson: #dc143c
darkred: #8b0000
{}
{colors.blues}
cornflowerblue: #6495ed
darkblue: #00008b
{}
</aml>
<p>You can close an object by beginning a line with <code>{}</code>. ArchieML is parsed one line at a time, so you can also close an object by opening a new one.</p>
<aml>
{colors}
red: #f00
green: #0f0
blue: #00f
{numbers}
one: 1
ten: 10
one-hundred: 100
{}
key: value
</aml>
<h3>Nested object blocks</h3>
<p>Object blocks with names prepened with a period nest inside of open objects instead of ending them. Beginning a line with <code>{}</code> closes a nested object and returns to the parent.</p>
<aml>
{colors}
red: #f00
green: #0f0
blue: #00f
{.numbers}
one: 1
ten: 10
one-hundred: 100
{}
nestedKey: nestedValue
{months}
january: 0
february: 1
</aml>
<h3>Arrays of objects</h3>
<p>Groups of keys can be placed inside an array by giving the array a name within brackets. The name of the array can be any valid key, and can use dot-notation. You can optionally end an array with an empty set of brackets, or by beginning a new array.</p>
<aml>
[scope.array]
[]
</aml>
<p>All keys inside the array are inserted into a single object within the array. The parser remembers the first key it found, and whenever it encounters it again, a new object is started.</p>
<aml>
[arrayName]
Jeremy spoke with her on Friday, follow-up scheduled for next week
name: Amanda
age: 26
# Contact: 434-555-1234
name: Tessa
age: 30
[]
</aml>
<h3>Arrays of strings</h3>
<p>You can also create "simple" or "flat" arrays of strings. If an asterisk is encountered first within an array, that array will become a simple array, and key/value pairs within it will be ignored. If a key/value pairs is encountered first, then asterisk lines will be ignored.</p>
<aml>
[days]
* Sunday
note: holiday!
* Monday
* Tuesday
Whitespace is still fine around the '*'
* Wednesday
* Thursday
Friday!
* Friday
* Saturday
[]
</aml>
<h3 id="nested-arrays">Nested arrays</h3>
<p>Array elements can contain arrays of their own. To begin an array while inside an array element, prepend its name with a period.</p>
<aml>
[array]
[.subarray]
[.subsubarray]
key: value
</aml>
<p>Much like nested object blocks, nested arrays must be "closed" with empty brackets in order to move up to the parent level.</p>
<aml>
[days]
name: Monday
[.tasks]
* Clean dishes
* Pick up room
[]
name: Tuesday
[.tasks]
* Buy milk
[]
</aml>
<h3 id="freeform-arrays">Freeform arrays</h3>
<p>Freeforms are a third type of array that was created to have better <strong>control over presentation</strong> from within ArchieML.</p>
<p>Unlike regular arrays, which group lines into objects whose values have no order, <strong>freeforms preserve the order of each of its lines</strong>. Clients that use ArchieML's output can then use that order to render the values, allowing you to vary the presentation for each array item.</p>
<aml>
[+books]
kicker: Books you should read
score: ★★★★★!!!
title: Wuthering Heights
author: Emily Brontë
title: Middlemarch
author: George Eliot
score: ★★★★☆
[]
</aml>
<p><strong>Each line becomes its own object</strong>, with a <strong>type</strong> and <strong>value</strong>. ArchieML splits these two words into separate objects to make it easier to deal with different type of information; rendering logic can always be based on the content of the <strong>type</strong> attribute.</p>
<p>Freeforms also allow you to type unstructured lines of text, which are included as items in the array with a type of <strong>text</strong>. Note that this means that comments do not work within freeforms.</p>
<aml>
[+text]
I can type words here...
And separate them into different paragraphs without tags.
[]
</aml>
<p>Having full control over order is useful when arrays need to be <strong>mixed with other types of data</strong>. For example, showing a list of events interspersed with general artwork.</p>
<aml>
[+events]
header: My Birthday
date: August 20th, 1990
{.image}
src: https://example.com/photo.png
alt: Family Photo
{}
header: High School Graduation
date: June 4th, 2008
[]
</aml>
<h3>Multi-line values</h3>
<p>Values automatically end when a newline is encountered. But all subsequent text is read into a buffer that can be added to that key. Anchor the end of a multi-line value by following the value with a line beginning with ":end". All whitespace within the block is preserved.</p>
<p>Try removing the last line to see how it changes the output:</p>
<aml>
key: value
More value
Even more value
:end
</aml>
<h4>Works within object and simple arrays</h4>
<aml>
[arrays.complex]
key: value
more value
:end
[arrays.simple]
* value
more value
:end
</aml>
<h4>Escape characters</h4>
<p>You can place any text inside of a multi-line value. If one of your lines would be interpreted by the parser as a key or some other special command, you may have to escape that line by adding a backslack to the beginning of it. The backslash won't be included in the value.</p>
<p>Try removing the backslashes from the following lines:</p>
<aml>
key: value
\:end
:end
</aml>
<aml>
key: value
\more: value
:end
</aml>
<aml>
key: value
[escaping * is not necessary if we're not inside an array, but will still be removed]
\* value
:end
</aml>
<aml>
key: value
\:ignore
\:skip
\:endskip
:end
</aml>
<h3>Block comments</h3>
<p>Wrap text between lines that begin with ":skip" and ":endskip" to ignore blocks of text.</p>
<aml>
:skip
this: text
will: be
ignored
:endskip
</aml>
<p>There is also a safety mechanism of sorts built in. When the parser encounters a line beginning with ":ignore" (even if it's within a :skip block), parsing immediately stops, and the rest of the document is ignored.</p>
<aml>
key: value
:ignore
[array]
* Blah
[]
other-key: other value
</aml>
<hr>
<h2 id="usage">Usage</h2>
<p>If you use JavaScript or Ruby, we hope you'll try one of the <a href="#resources">existing ArchieML parsers</a>.</p>
<p>If you want to make a parser yourself (or want the technical details on the format), the full specification is online <a href="/spec/1.0/">here</a>.</p>
<p>Questions or concerns? The Github repository for this site is available at <a href="https://github.com/newsdev/archieml.org">newsdev/archieml.org</a>, and you can use its <a href="https://github.com/newsdev/archieml.org/issues">Issues</a> page to submit questions or bugs on the spec itself.</p>
<hr>
<p style="font-size:.8em;opacity:0.5;">Created by <a href="https://twitter.com/moriogawa">Michael Strickland</a>, <a href="https://twitter.com/archietse">Archie Tse</a>, <a href="https://twitter.com/mericson">Matthew Ericson</a> and <a href="https://github.com/giratikanon">Tom Giratikanon</a> / <a href="https://github.com/newsdev">The New York Times</a></p>
<p style="font-size:.8em;opacity:0.5;">Copyright (c) 2015 The New York Times Company</p>
</div>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-60337978-1', 'auto');
ga('send', 'pageview');
</script>
<script src="/assets/sandbox.js"></script>
</body>
</html>