@@ -1,17 +1,698 @@
11+++
2−title = "Udon"
3−weight = 8
2+title = "Sail and Udon"
3+weight = 7
44template = "doc.html"
55+++
6+
7+Sail is Hoon markup that’s used to render a web page with XML. But what makes it special is that you can run arbitrary Hoon code within such a web page without using a separate markup language.
8+
9+Udon is a way to write content for the web. It's a minimalist markup language for creating and rendering text documents, with a Markdown-inspired syntax. It's integrated with our Hoon programming language, allowing it to be used as standalone prose in its own file or embedded inside a Hoon source file, in which case it will be parsed into a tree of HTML nodes using Sail.
10+
11+This document will be divided into two main sections: the Sail guide and the Udon guide. The Udon guide has two sub-sections that each walk you through a practical example. Also, you're encouraged to read the Getting Started section below, which applies to both Udon and Sail.
12+
613## Table of Contents
714
8−- #### [Udon: A Guide](#guide)
15+- #### [Sail: A Guide](#sail)
16+
17+- #### [Udon: A Guide](#udon)
18+
19+- #### [Udon: A Simple Blog](#blog)
20+
21+- #### [Udon: A Static Site](#static)
22+
23+## Getting Started
24+
25+Before starting with either Sail or Udon, make sure that your ship is
26+[mounted to Unix](https://urbit.org/docs/using/setup/)
27+
28+To host that output, your ship also has a web-server, called
29+[Eyre](https://urbit.org/docs/using/web/), that can be found at
30+`http://localhost:8080/` if it’s your first ship that’s running on the a
31+machine, `http://localhost:8081/` if it’s the second ship on that same machine,
32+and so on. In the startup messages, a ship will tell you which HTTP port it's
33+using.
34+
35+The `/web` directory of the `%home` desk is served by default. You can change
36+which desk you're serving by using the command `|serve` in the Dojo. If you
37+have already created and mounted a desk named `%sandbox`, for example, you can
38+switch to serving it with this command:
39+
40+```
41+|serve %sandbox
42+```
43+
44+The first time you serve a desk, `/web` will be included as default. After that,
45+you will need to explicitly append `/web` to the desk you're switching to --
46+otherwise, you'll need to write `http://localhost:8080/web` every time you
47+navigate to your web-server. Newly served desks not automatically having `/web`
48+as their root directory is a bug.
49+
50+To switch back to your `%home` desk and set `/web` as your root directory, run:
51+
52+```
53+|serve %/web
54+```
55+
56+We'll be serving the `%home` desk for the examples in this tutorial.
57+
58+### Rendering
59+
60+That server has access to source files located in `/<your-urbit>/home/web` and
61+any sub-folders thereof. For the purposes of this tutorial, we will only be
62+using files that are located in the `/<your-urbit>/home/web/pages` path.
63+
64+There is an important distinction between these two paths. According to
65+`/ren/urb.hoon`, any file inside of `/web` or any of its sub-directories
66+is put through a tree of renderers specified at `/ren/urb/tree.hoon`
67+-- _except_ for files inside of `/web/pages`. All of the files in `/web` and
68+its non-`/pages` children directories have various operations on files, such as
69+wrapping your Sail the `html`, `head`, and `body` nodes. This rendering tool,
70+called simply **Tree**, also adds certain formatting polish, such as a sidebar
71+that lists sibling files in the same directory.
72+
73+The `/web/pages` sub-directory is a unique case with its own rendering rules.
74+The Tree is not used when rendering files in this path. The existence of no tag
75+is inferred, and no special formatting is applied. Such simplicity is ideal for
76+introducing the basics of Sail. Any source file located in `/web/pages` must
77+produce a complete HTML node with "head" and "body" nodes as children.
78+
79+Understanding the details of the rendering pipeline is not necessary to complete
80+this tutorial. But, if you are curious, you might find it illuminating to
81+explore the contents of the `/ren` directory.
82+
83+So, if a Sail source file named `sailtest.hoon` is saved in your `/web/pages`
84+folder on your only running urbit process, you can view that source rendered
85+into a web-page at `localhost:8080/pages/sailtest/`.
86+
87+## <a name="sail"></a>Sail: A Guide
88+
89+It’s easy to see how Sail can directly translate to HTML:
90+
91+### Sail code
92+
93+```
94+;html
95+ ;head
96+ ;title: My first webpage
97+ ==
98+ ;body
99+ ;h1: Welcome!
100+ ; Hello, world!
101+ ; We're on the web.
102+ ;div;
103+ ;script@"http://unsafely.tracking.you/cookiemonster.js";
104+ ==
105+==
106+```
107+
108+### HTML code
109+
110+```
111+<html>
112+ <head>
113+ <title>My first webpage</title>
114+ </head>
115+ <body>
116+ <h1>Welcome!</h1>
117+ Hello, world!
118+ We’re on the web.
119+ <div></div>
120+ <script src="http://unsafely.tracking.you/cookiemonster.js"></script>
121+ </body>
122+</html>
123+```
124+
125+Save the above Sail code in `/home/web/pages/firstsail.hoon`, and the above
126+HTML code in `/home/web/pages/firsth.html`. Access the resulting pages by
127+navigating to `http://localhost:8080/pages/firstsail` and
128+`http://localhost:8080/pages/firsth.html`, respectively, in your browser. The
129+resulting pages should be identical!
130+
131+It shouldn't be hard to see the similarities here. So let's go into more
132+detail about what the differences are.
133+
134+### Tags and Closing
135+
136+In Sail, tag heads are written with the tag name prepended by `;`. Unlike in
137+HTML, there are different ways on closing tags, depending on the needs of the
138+tag. One of the nice things about Hoon is that you don’t have to be constantly
139+closing expressions; Sail inherits this convenience.
140+
141+#### Empty
142+
143+Empty tags are closed with a `;` following the tag. Example:
144+
145+```
146+;div;
147+```
148+
149+Equals:
150+
151+```
152+<div></div>
153+```
154+
155+#### Filled
156+
157+Filled tags are closed via line-break. To fill text inside, add `:` after the
158+tag name, then insert your plain text following a space. Example:
159+
160+```
161+;h1: The title
162+```
163+
164+Equals:
165+
166+```
167+<h1>The title</h1>
168+```
169+
170+#### Nested
171+
172+To nest tags, simply create a new line. Nested tags need to be closed
173+with `==`, because they expect a list of sub-tags. If we nest a line of plain
174+text with no tag, a `<p>` is prepended.
175+
176+Sail, like Hoon, is white-space sensitive. Unlike in Hoon, however, two spaces
177+(called a "gap") is not necessarily equivalent to a line-break in Sail.
178+
179+```
180+;body
181+ ;h1: Blog title
182+ This is some good content.
183+==
184+```
185+
186+Equals:
187+
188+```
189+<body>
190+ <h1>Blog title</h1>
191+ <p>This is some good content.</p>
192+</body>
193+```
194+
195+
196+Conversely, if we want to write a string with no tag at all, then we can prepend
197+those untagged lines with `;`.
198+
199+```
200+;body
201+ ;h1: Welcome!
202+ ; Hello, world!
203+ ; We’re on the web.
204+==
205+```
206+
207+Equals:
208+
209+```
210+<body>
211+ <h1>Welcome!</h1>
212+ Hello, world!
213+ We’re on the web.
214+</body>
215+```
216+
217+
218+#### Attributes
219+
220+Attributes are key-value pairs that go into an HTML node.
221+
222+Adding attributes is simple: just add the desired attribute between parentheses,
223+right after the tag name without a space. We separate different attributes of
224+the same node by using `,`.
225+
226+Attributes can be used in two forms: flat, which uses one line; and tall, which
227+uses multiple lines, when a single line would not be practical. Flat forms and
228+flat forms are two syntaxes of semantically equivalent expressions.
229+
230+
231+#### Generic
232+
233+The code below produces a “Submit” button on the page.
234+
235+Wide-form Sail:
236+
237+```
238+;input(type "submit", value "Submit");
239+```
240+
241+Tall-form Sail:
242+
243+```
244+;input
245+ =type "submit"
246+ =value "Submit";
247+==
248+```
249+
250+Equals:
251+
252+```
253+<input type="submit" value="Submit">`
254+```
255+
256+#### IDs
257+
258+```
259+;nav#header: Menu
260+```
261+
262+Equals:
263+
264+```
265+<nav id="header">Menu</nav>
266+```
267+
268+Add `#` after tag name to add an ID.
269+
270+#### Classes
271+
272+`;h1.text-blue: Title` equals `<h1 class="text-blue">Title</h1>`
273+
274+Add `.` after tag name to add a class. However, if you want a class name that
275+contains a space, you will need to use use the syntax of a generic attribute:
276+
277+`;div(class "logo inverse");` equals `<div class="logo inverse"></div>`
278+
279+
280+#### Image
281+
282+`;img@"example.png";`
283+
284+Equals
285+
286+`<img src="example.png"/>`
287+
288+Add `@` after the tag name to link your source.
289+
290+To add attributes to the image, like size specifications, add the
291+desired attribute after the `"` of the image name and before the final `;` of
292+the `img` tag.
293+
294+For example:
295+
296+`;img@"https://urbit.org/example.png"(width "100%");`
297+
298+#### Linking
299+
300+`;a/"urbit.org": A link to Urbit.org`
301+
302+Equals
303+
304+`<a href="urbit.org">A link to Urbit.org</a>`
305+
306+Add `/` after tag name to start an href.
307+
308+### Hoon in Sail
309+
310+Our first example is useful to understand how Sail syntax translates to HTML
311+syntax, but Sail finds its usefulness in the fact that it can be used seamlessly
312+with Hoon code.
313+
314+One place where Sail diverges from HTML is that it supports string
315+interpolation. In Sail, the contents of all tags are a string type called `tape`
316+unless otherwise designated. Tapes are delineated by the double quotes `""`.
317+That’s important, because tapes can be interpolated with Hoon expressions,
318+provided that those expressions produce something a tape as well. Interpolation
319+is done by wrapping the code to be inserted in `{}`. In your Dojo prompt, try
320+the command below (without the `>`):
321+
322+```
323+> "I am a l{(mul 3 11)}t Urbit user."
324+! exit
325+```
326+
327+Oh no! That command produced a nest-fail error, which indicates that there was
328+a problem related to Hoon type-system. We used the proper `{}` syntax for
329+interpolation, and we used the proper function-call syntax inside of it. So
330+what happened?
331+
332+Trying the `mul` function on its own will help answer this question. Try the
333+following command in your Dojo:
334+
335+```
336+> (mul 3 11)
337+33
338+```
339+
340+This should work, producing `33`, an atom. That’s our problem. The
341+interpolation expression expects a tape, but our first command tried to
342+interpolate with something that results in an atom. Try this now:
343+
344+```
345+> <(mul 3 11)>
346+"33"
347+```
348+
349+We get a similar result, but we know that it’s a tape because it’s wrapped in
350+`""`. Bingo! With this knowledge, let’s perform a successful interpolation:
351+
352+```
353+> "I am a l{<(mul 3 11)>}t Urbit user."
354+"I am a l33t Urbit user."
355+```
356+
357+Great!
358+
359+### The Subject
360+
361+The default subject of a Sail file is different from the subject that
362+expressions in the Dojo or a Hoon generator are evaluated against.
363+
364+To see this difference, first save the code below to a file at
365+`home/web/pages/sub.hoon` and view the rendering at
366+`http://localhost:8080/pages/sub`.
367+
368+```
369+;html
370+ ;head;
371+ ;body
372+ {<.>}
373+ ==
374+==
375+```
376+
377+Then enter the following command in the Dojo:
378+
379+```
380+> .
381+```
382+
383+You'll notice that the Sail subject is like a stripped-down version of the Dojo
384+subject. Its final line should match the Dojo subject.
385+
386+Now swap the code below into your Sail file.
387+
388+```
389+/= gas /$ fuel:html
390+;html
391+ ;head;
392+ ;body
393+ {<.>}
394+ ==
395+==
396+```
9397
10−- #### [A Simple Udon Blog](#blog)
398+You'll find that the resulting Sail subject is much larger. If you look closely,
399+you'll see that there's some new similarities with the Dojo subject, such as
400+containing the name of your ship. There's also some new differences, since
401+`fuel:html` contains things that are specifically useful for performing
402+web-related operations.
403+
404+### A More Interesting Example
405+
406+Now let’s apply knowledge of string interpolation and the Sail subject in a Sail
407+source file. The following code produces more interesting things than the
408+example we saw before.
409+
410+```
411+/= gas /$ fuel:html
412+=/ show-list &
413+=+ wid=(met 3 p.bem.gas)
414+=/ what-kind
415+?: (lte wid 1) "galaxy"
416+?: =(2 wid) "star"
417+?: (lte wid 4) "planet"
418+?: (lte wid 8) "moon"
419+ "comet"
420+;html
421+ ;head
422+ ;meta(charset "utf-8");
423+ ;title: A more advanced page
424+ ==
425+ ;body
426+ ;h1: This is the Title
427+ ; This is a
428+ ;a/"http://urbit.org": link to Urbit.org.
429+ ;span: Check it out!
430+ ;+ ?: show-list
431+ ;ol
432+ ;li(style "color: green"): We're doing interesting stuff now.
433+ ;li: We're pretty-printing this sum with Hoon: {<(add 50 50)>}.
434+ ;li: The code above is shorthand for {(scow %ud (add 50 50))}.
435+ ;li: I am {(trip '~lodleb-ritrul')}.
436+ ;li: Actually, my name is {<p.bem.gas>}. I'm a {what-kind}.
437+ ==
438+ ;div: My name is {<p.bem.gas>}. I'm a {what-kind}.
439+ ==
440+==
441+```
442+
443+Save the above Sail code in to `home/web/pages/secondsail.hoon` and access the
444+resulting page by navigating to `http://localhost:8080/pages/secondsail` in
445+your browser.
446+
447+There are some interesting things here. Let’s go through this code piece by
448+piece.
449+
450+```
451+/= gas /$ fuel:html
452+```
453+
454+Later in this code we want produce the name of the ship is hosting it, something
455+that looks like ~lodleb-ritrul. In a generator, we could produce our ship name
456+by writing `our` -- try it in the Dojo. But remember that Sail is rendered
457+against its own subject, `our` is not part of the default subject. To augment
458+our subject with the information that we need, we use `/= gas /$ fuel:html`.
459+
460+The above expression uses two Ford runes, `/=` and `/$`, to add the relevant
461+information to the current subject. We can pull the ship’s name out of this
462+augmented subject later. It's important to note that these runes are not part of
463+Hoon. They are part of Ford, our build system.
464+
465+`/$` is used to get data from the environment, and `/=` adds that data to
466+subject in the face `gas`. The
467+[Ford user manual](https://urbit.org/docs/arvo/internals/ford/runes/) has
468+details on these and other Ford runes, but understanding these runes isn’t
469+necessary for the purposes of this tutorial.
470+
471+`fuel:html` gets extra data from your ship’s Eyre module, which handles all
472+things HTTP, and sticks it in the subject when Eyre renders a page. This
473+includes the name of the ship, which is what we look for in the next line, but
474+it includes much more.
475+
476+`p.bem.gas` is an expression that looks for `p` within `bem` within `gas`, the
477+face that we stored the above `fuel:html` expression in. That wing happens to
478+resolve to the name of the ship that is hosting the web-server. If we wanted to
479+access the current desk, we would use the wing expression `q.bem.gas`.
480+
481+You can take a look at what you can access by typing `fuel:html` in the Dojo,
482+and then explore it by modifying your wing expression in your Sail file
483+accordingly.
484+
485+```
486+=/ show-list &
487+```
488+
489+The above line of code stores a variable used later for a conditional. `&` means
490+`true`, meaning that any evaluation of `show-list` will be true until changed in
491+the source code.
492+
493+```
494+=+ wid=(met 3 p.bem.gas)
495+=/ what-kind
496+ ?: (lte wid 1) "galaxy"
497+ ?: =(2 wid) "star"
498+ ?: (lte wid 4) "planet"
499+ ?: (lte wid 8) "moon"
500+ "comet"
501+```
502+
503+This code chunk is a series of conditionals that checks the host ship’s name to
504+see what its value is.
505+
506+The first line, `=+ wid=(met 3 p.bem.gas)`, combines a new noun with the
507+subject and gives it the face `wid`. This noun is produced by the the
508+standard-library function [`met`](/docs/reference/library/2c), which measures the number of
509+[blocks](/docs/reference/library/1c/) of size `a` within `b`. Blocks are units that have a
510+bitwidth of `2^a`. So, in this case, it measures how many bytes (blocks of size
511+3 are bitwidths of 8; `2^3 = 8`) are fully contained in your ship's address.
512+
513+Galaxies contain zero to one 3-blocks; stars contain two 3-blocks; planets
514+contain three to four 3-blocks; moons contain five to eight 3-blocks; comets
515+contain nine to sixteen 3-blocks. Each test uses `lte`, the
516+less-than-or-equal-to function, to determine if `wid` is of a given size. The
517+result of this series of tests is added to the subject and given the face
518+`what-kind`.
519+
520+Ship names are simply another representation of atoms, and ship
521+categories are different ranges of possible atomic values. Because of this, we
522+perform less-than tests to see what kind of ship is running the web-server.
523+
524+```
525+;html
526+ ;head
527+ ;meta(charset "utf-8");
528+ ;title: A more advanced page
529+ ==
530+```
531+
532+Sail proper begins here. These four lines are four nodes. The `;html` node
533+indicates that the contained code should be rendered as HTML; this tag is closed
534+on the final line. The `;head` node contains metadata, and is closed three lines
535+later. The `;meta` node sets the character set to UTF-8, and the `;title` node
536+sets the title of the page that shows up in the browser tab.
537+
538+```
539+ ;body
540+ ;h1: This is the Title
541+ ; This is a
542+ ;a/"http://urbit.org": link to Urbit.org.
543+ ;span: Check it out!
544+```
11545
12−- #### [A Static Site](#static)
546+The first line here opens, of course, the body node. The second line creates
547+header text.
13548
14−## A Guide
549+The third, fourth, and fifth lines of code here construct a single line with an
550+inline link.
551+`; This is a` begins the rendered line with plain text.
552+
553+`;a/"http://urbit.org": link to Urbit.org.` continues that same rendered line,
554+and creates hyperlinked text out of `link to Urbit.org.`
555+
556+`;span: Check it out!` continues that same rendered line further. `;span:`
557+has the same use as `<span>` in HTML, and by following it with just a `:` and no
558+attributes, it continues the line without formatting. Following `;span:` with
559+**two** spaces causes there to be single space following the produced `<span>`
560+element, because one of those spaces is syntactically necessary.
561+
562+In the following lines, we beginning to use some Hoon expressions again.
563+
564+```
565+ ;+ ?: show-list
566+ ;ol
567+```
568+
569+In the top line in the chunk above, we use the `;+` Sail rune, which
570+resolves an expression to a single node. That expression, in this case, is
571+`?:`, which tests the truth value of `show-list`, which we assigned the value
572+`&` (meaning “true”) at the beginning of the program. It’s closed by the `==` on
573+the last line.
574+
575+Thus, this program resolves to the first child of `show-list`, the node `;ol`.
576+That node creates an ordered list, and the items contained within that node.
577+
578+```
579+ ;li(style "color: green"): We're doing more interesting stuff now.
580+```
581+
582+The line above is the only element of this list that does not use
583+Hoon proper. The line renders as green, as interpreted by the browser,
584+because of the Sail attribute.
585+
586+The next items in the list use `{}`. Recall that these braces, pronounced “lob”
587+and “rob” in Hoon-speak, allow for the interpolation of code within a string.
588+
589+```
590+ ;li: We're pretty-printing this sum with Hoon: {<(add 50 50)>}.
591+```
592+
593+The line above is interpolated with Hoon code that produces the sum of 50 plus
594+50, which is wrapped in `<>` to put the product in double quotes to make it a
595+tape, like the rest of the line.
596+
597+
598+```
599+ ;li: The code above is shorthand for {(scow %ud (add 50 50))}.
600+```
601+
602+The `{(scow %ud (add 50 50)}` on this line is just a different way
603+writing the `{<(add 50 50)>}` expression. `scow` is a Hoon function that turns a
604+noun into a `tape`, Hoon’s string type. `%ud` tells `scow` that its argument
605+should be displayed in the form of an unsigned decimal.
606+
607+
608+```
609+ ;li: I am {(trip '~lodleb-ritrul')}.
610+```
611+
612+`trip` is a function that takes a `cord` and produces a `tape`. A piece of
613+data of the cord type is one big atom formed from adjacent unicode bytes and
614+delineated by `''`. Remember that all text rendered in Sail is treated as a
615+tape. So, by converting `~lodleb-ritrul` to a tape, it can be included in the
616+tape that we are trying to insert it into without getting a type error.
617+
618+```
619+ ;li: Actually, my name is {<p.bem.gas>}. I'm a {what-kind}.
620+ ==
621+```
622+
623+The line above has interpolated code that uses a wing expression to access the
624+name of the host ship, and then accesses the face `what-kind` contains a string
625+describing what type of ship it is. We declared `gas` on the very first line so
626+that we could add that sort of information to the subject that our Sail is
627+rendered against. The wing expression `p.bem.gas` looks for `p` within `bem`
628+within `gas`, which happens to be where the name of the ship is located.
629+
630+Note that `{what-kind}` does not have a `<>` wrapper. Why do you think this is?
631+
632+```
633+ ;div; My name is {<p.bem.gas>}. I'm a {ship}.
634+ ==
635+==
636+```
637+
638+The `;div;` node above is only rendered, as an alternative to the above list,
639+if `show-list` is evaluated as true. This means it won’t be shown with your
640+default code. To show this line, change the `&` on line 2 to `|` (“false”).
641+
642+### Sail Runes
643+
644+In the previous example, we used a few special runes that aren’t used in typical
645+Hoon code. But there are others that are worth learning about at this point.
646+
647+`;+` is an expression that resolves to a single node. We saw this on line 20
648+in our Sail example above: `;+ ?: show-list` resolves to the node `;ol` and
649+all of that node’s children.
650+
651+`;*` is an expression that resolves to a list of nodes. If we want to render
652+multiple nodes side-by-side, and not just the children of a single node, this
653+is the expression that we use.
654+
655+`;=` turns a tuple of nodes into a list of nodes.
656+
657+
658+To see how these runes work, let’s take a chunk of our previous code starting at
659+line 20 and modify it a bit:
660+
661+```
662+ ;* ?: show-list
663+ ;=
664+ ;li: I am {(trip '~lodleb-ritrul')}.
665+ ;li: Actually, my name is {<p.bem.gas>}.
666+ ==
667+ ;=
668+ ;div: My name is {<p.bem.gas>}. I'm a {what-kind}.
669+ ;div: No list here!
670+ ==
671+ ==
672+```
673+
674+We changed the conditional branches so that each contains two Sail nodes,
675+side-by-side -- notice that the `;ol` is absent from the first branch.
676+
677+We begin with the `;*` rune, which resolves to a list of nodes, instead of the
678+`;+` rune, which only resolves to a single node.
679+
680+But that’s not enough on its own. `;*` needs to resolve to a list, and a few
681+Sail nodes aren’t lists until they are explicitly made into lists. Until we wrap
682+those nodes in `;=`, the nodes treated as mere tuples. All branches must be
683+valid lists for the `;* ?: show-list` expression to resolve.
684+
685+### Further Reading
686+
687+You should now have foundational knowledge for making web pages with Sail. There
688+is, of course, more to learn.
689+
690+The [Ford manual](https://urbit.org/docs/arvo/internals/ford/runes/)
691+can show you how to access various ship resources for user in your pages. To
692+learn more about how the renderer works, take a look at the
693+`/home/ren/urb.hoon` file inside your urbit.
694+
695+## <a name="udon"></a>Udon: A Guide
15696
16697Udon is a way to write content for the web. It's a minimalist
17698markup language for creating and rendering text documents, with a
@@ -34,36 +715,7 @@ Markdown: some syntax errors will prevent the file from being parsed at all.
34715We provide a few simple examples [here](#examples) of how to publish
35716Udon files using our web interface.
36717
37−### Getting Started
38−
39−Before starting, make sure that your urbit is
40−[mounted to Unix](https://urbit.org/docs/using/setup/)
41−
42−To host Udon and other kinds of files, your ship also has a
43−web-server, called [Eyre](https://urbit.org/docs/using/web/), that can be found
44−at `http://localhost:8080/` if it’s your first ship that’s running on the
45−machine, `http://localhost:8081/` if it’s the second ship on that same machine,
46−and so on. If you can't find your ship on one of these for some reason, try the
47−next one. When a ship starts, it will print a message like
48−`http: live (insecure, public) on 8081` to let you know what port it's using.
49−
50−That server has access to source files located in `/<your-urbit>/home/web` and
51−any sub-folders thereof (except for `/home/web/pages`, which has special
52−rendering rules.) Your ship's `%home` desk is served by default. You can
53−[change](https://urbit.org/docs/using/web/) which desk you're serving, however.
54−
55−Everything in the `/<your-urbit>/home/web/` directory, with the exception of
56−`/home/web/pages`, knows how to interpret and files of `.udon` type. So, to
57−experiment with UM, create a `.udon` file in that path, and then try to access it
58−at `http://localhost:8080/<yourfile>` in your browser -- no `.udon` required in
59−the URL. It's a good idea to copy-paste the following examples into your file to
60−see how the code works.
61−
62−Make sure that you have proper syntax throughout, and check often that it
63−renders properly as you add more code. If you have parser-breaking syntax, then
64−the default renderer won't tell you much.
65−
66−## Syntax
718+## Udon Syntax
67719
68720### Front Matter
69721
@@ -129,7 +781,7 @@ through `<h6>`. The header for this section is `### Headers`.
129781
130782##### Header (h5)
131783```
132−###### Produces:
784+**Produces:**
133785
134786#### Header (h4)
135787
@@ -150,7 +802,7 @@ element.
150802To get their *attention*, you need that _je ne sais quoi_.
151803```
152804
153−###### Produces:
805+**Produces:**
154806
155807To get their **attention**, you need that _je ne sais quoi_.
156808
@@ -170,7 +822,7 @@ This second line is separated by two newlines, so it's a separate paragraph.
170822This line looks like a distinct paragraph, but...
171823It's only separated by a single newline, so it's included in the same paragraph.
172824```
173−###### Produces:
825+**Produces:**
174826
175827
176828Here's the first line.
@@ -192,7 +844,7 @@ I wonder how long each line
192844will be if I put backslashes\
193845at the ends of the lines.
194846```
195−###### Produces:
847+**Produces:**
196848
197849I wonder how long each line
198850will be if I put backslashes\
@@ -210,7 +862,7 @@ Here is some *bold* text.
210862Here is some \*not bold* text.
211863```
212864
213−###### Produces:
865+**Produces:**
214866
215867Here is some **bold** text.
216868Here is some \*not bold* text.
@@ -318,7 +970,7 @@ destination.
318970[I'm an inline-style link](https://www.urbit.org/docs/reference/shell)
319971```
320972
321−###### Produces:
973+**Produces:**
322974
323975[I'm an inline-style link](https://www.urbit.org/docs/reference/shell)
324976
@@ -332,7 +984,7 @@ the all of the URL that the destination has in common with the origin page.
332984[I'm a reference-style link](../shell)
333985```
334986
335−###### Produces:
987+**Produces:**
336988
337989[I'm a reference-style link](../shell)
338990
@@ -349,7 +1001,7 @@ so we need to use some [Sail](#sail). If there are two or more anchors with
3491001the same `id` on the page, you will arrive at the earliest instance of the the
3501002anchor.
3511003
352−###### Example:
1004+**Example:**
3531005
3541006```
3551007Check out this [section](#the-destination) that we want to jump to.
@@ -361,7 +1013,7 @@ It was the best of times, it was the worst of times...
3611013## Here we are!
3621014```
3631015
364−###### Produces
1016+**Produces:**
3651017
3661018Check out this [section](#the-destination) that we want to jump to.
3671019
@@ -381,7 +1033,7 @@ opening and closing quotes -- that is, `“` and `”`.
3811033"Yes," he said. "That is the way with him."
3821034```
3831035
384−###### Produces:
1036+**Produces:**
3851037
3861038"Yes," he said. "That is the way with him."
3871039
@@ -399,7 +1051,7 @@ bug.
3991051\
4001052```
4011053
402−##### Inline Code Literal
1054+#### Inline Code Literal
4031055
4041056Enclosing some text in
4051057```
@@ -417,7 +1069,7 @@ throughout this guide to `format text` to distinguish code from prose.
4171069```
4181070`*[a 2 b c] -> *[*[a b] *[a c]]` is like lisp's `apply`.
4191071```
420−###### Produces:
1072+**Produces:**
4211073
4221074`*[a 2 b c] -> *[*[a b] *[a c]]` is like lisp's `apply`.
4231075
@@ -431,13 +1083,13 @@ Hoon.
4311083The ++add arm is used to sum two numbers.
4321084```
4331085
434−###### Produces:
1086+**Produces:**
4351087
4361088The ++add arm is used to sum two numbers.
4371089
4381090#### Block Code Literal
4391091
440−By enclosing a block of text in ``` on their own lines
1092+By enclosing a block of text in a tick on their own lines
4411093before and after the contained text, the text will be treated as a code block.
4421094
4431095Most of our examples so far have used.
@@ -456,7 +1108,7 @@ Most of our examples so far have used.
4561108 ```
4571109```
4581110
459−###### Produces:
1111+**Produces:**
4601112
4611113```
4621114(def Y (fn [f]
@@ -494,7 +1146,7 @@ Three or more hyphens, such as `---`, on their own line produce an `<hr>`
4941146element, the 'horizontal rule'. This is rendered as a horizontal line the
4951147width of its containing paragraph.
4961148
497−###### Example:
1149+**Example:**
4981150
4991151```
5001152Above the line
@@ -504,7 +1156,7 @@ Below the line
5041156And below this line, too
5051157```
5061158
507−###### Produces:
1159+**Produces:**
5081160
5091161
5101162Above the line
@@ -537,7 +1189,7 @@ Quote break.
5371189 He is pale and thin, he wears a thin and ragged linen shirt.
5381190```
5391191
540−###### Produces:
1192+**Produces:**
5411193
5421194> As Gregor Samsa awoke one morning from uneasy dreams
5431195 he found himself transformed in his bed into a **monstrous** vermin.
@@ -556,7 +1208,7 @@ normally in Udon, newlines are treated as spaces and do not create a
5561208new line of text. If you want to embed text where newlines are retained, then
5571209indent the text in question with **eight spaces**.
5581210
559−###### Example:
1211+**Example:**
5601212
5611213```
5621214 A shape with lion body and the head of a man,
@@ -564,7 +1216,7 @@ indent the text in question with **eight spaces**.
5641216 Is moving its slow thighs, while all about it
5651217 Reel shadows of the indignant desert birds.
5661218```
567−###### Produces:
1219+**Produces:**
5681220
5691221 A shape with lion body and the head of a man,
5701222 A gaze blank and pitiless as the sun,
@@ -607,7 +1259,7 @@ Produces:
6071259</p>
6081260
6091261
610−## A Simple Udon Blog
1262+## <a name="blog"></a>A Simple Udon Blog
6111263
6121264Publishing using Udon is really easy. It uses the file extension `.udon`. Here we'll create a very simple blog and publish our first posts.
6131265
@@ -748,7 +1400,7 @@ Use `;join` to keep up with comments as they get posted:
7481400
7491401That's it! Easy.
7501402
751−## A Static Site
1403+## <a name="static"></a>A Static Site
7521404
7531405Hosting a static tree of content is easy. Let's put together a really
7541406simple site for an imaginary Urbit meetup group.