@@ -1,1242 +0,0 @@
2−title = "Sail and Udon"
5−aliases = ["docs/using/sail-and-udon/"]
8−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.
10−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.
12−This document will be divided into two main sections: the Sail guide and the Udon guide. Also, you should read the Getting Started section below, which applies to both Udon and Sail.
16−- [Getting Started](#getting-started)
18−- [Sail: A Guide](#sail)
20−- [Udon: A Guide](#udon)
22−## Getting Started {#getting-started}
24−Before starting with either Sail or Udon, make sure that your ship is
25−[mounted to Unix](@/using/install.md).
27−To host that output, your ship also has a web-server that can be found at
28−`http://localhost/` (default port 80) if it's your first ship that's running on the
29−machine, `http://localhost:8081/` if it's the second ship on that same machine,
30−and so on. In the startup messages, a ship will tell you which HTTP port it's
33−Udon and Sail files are often run as independent files (`.udon` and `.hoon`
34−respectively), but for the purpose of this guide, we will run them out of the
35−`frontpage.hoon` file located in the `/gen` directory. The default content of
36−`frontpage.hoon` is Sail code.
38−To use `frontpage.hoon`, we use a `|serve` command like this one in your ship's
42−|serve /test %home /gen/frontpage/hoon
45−This command has three arguments:
46−- The first is the URL we want to bind our site to. We chose `/test`, so the URL
47−we will find our site at is `http://localhost/test`.
48−- The second is the desk we want to serve. We will be serving from `%home` in
50−- The third is the file that we want to serve. In this tutorial, we will be
51−using `/gen/frontpage/hoon`, which refers to `/gen/frontpage.hoon`.
53−Run the command `|serve /test %home /gen/frontpage/hoon`. Now navigate to
54−`http://localhost/test` (or `http://localhost:8081/test` if your ship is on that port) in your
55−browser, and you should see the rendered Sail.
57−**Note:** Important to remember that every time you edit a file in your ship's
58−pier (Unix directory), including `frontpage.hoon`, you need to run `|commit %home`
59−to copy those changes to Urbit.
61−## <a name="sail"></a>Sail: A Guide
63−It's easy to see how Sail can directly translate to HTML:
70− ;title: My first webpage
77− ;script@"http://unsafely.tracking.you/cookiemonster.js";
87− <title>My first webpage</title>
94− <script src="http://unsafely.tracking.you/cookiemonster.js"></script>
99−You can test above Sail code by placing it
100−under `^- manx` in your `frontpage.hoon` file, and then running `|commit %home`
101−in the Dojo. If you've already run the `|serve` command code from the first
102−section, the new content should appear at `http://localhost/test`.
104−It shouldn't be hard to see the similarities between Sail and HTML. So let's go
105−into more detail about what the differences are.
109−In Sail, tag heads are written with the tag name prepended by `;`. Unlike in
110−HTML, there are different ways on closing tags, depending on the needs of the
111−tag. One of the nice things about Hoon is that you don't have to be constantly
112−closing expressions; Sail inherits this convenience.
116−Empty tags are closed with a `;` following the tag. Example:
130−Filled tags are closed via line-break. To fill text inside, add `:` after the
131−tag name, then insert your plain text following a space. Example:
145−To nest tags, simply create a new line. Nested tags need to be closed
146−with `==`, because they expect a list of sub-tags. If we nest a line of plain
147−text with no tag, a `<p>` is prepended.
149−Sail, like Hoon, is white-space sensitive. Unlike in Hoon, however, two spaces
150−(called a `gap`) is not necessarily equivalent to a line-break in Sail.
155− This is some good content.
164− <p>This is some good content.</p>
168−Conversely, if we want to write a string with no tag at all, then we can prepend
169−those untagged lines with `;`.
191−Attributes are key-value pairs that go into an HTML node.
193−Adding attributes is simple: just add the desired attribute between parentheses,
194−right after the tag name without a space. We separate different attributes of
195−the same node by using `,`.
197−Attributes can be used in two forms: wide, which uses one line; and tall, which
198−uses multiple lines, when a single line would not be practical. Wide forms and
199−tall forms are two syntaxes of semantically equivalent expressions.
203−The code below produces a "Submit" button on the page.
208−;input(type "submit", value "Submit");
223−<input type="submit" value="Submit">
235−<nav id="header">Menu</nav>
238−Add `#` after tag name to add an ID.
242−`;h1.text-blue: Title`
246−`<h1 class="text-blue">Title</h1>`
248−Add `.` after tag name to add a class. However, if you want a class list that
249−contains a space, you will need to use use the syntax of a generic attribute:
251−`;div(class "logo inverse");`
255−`<div class="logo inverse"></div>`
259−`;img@"example.png";`
263−`<img src="example.png" />`
265−Add `@` after the tag name to link your source.
267−To add attributes to the image, like size specifications, add the
268−desired attribute after the closing `"` of the image name and before the final
269−`;` of the `img` tag.
273−`;img@"https://urbit.org/example.png"(width "100%");`
277−`;a/"urbit.org": A link to Urbit.org`
281−`<a href="urbit.org">A link to Urbit.org</a>`
283−Add `/` after tag name to start an href.
285−To add attributes to the link, like target specifications, add the
286−desired attribute after the closing `"` of the link url and before the `:` of
291−`;a/"urbit.org"(target "_blank"): A link to Urbit.org`
295−Our first example is useful to understand how Sail syntax translates to HTML
296−syntax, but Sail finds its usefulness in the fact that it can be used seamlessly
299−One place where Sail diverges from HTML is that it supports string
300−interpolation. In Sail, the contents of all tags are a string type called `tape`
301−unless otherwise designated. Tapes are delineated by the double quotes `""`.
302−That's important, because tapes can be interpolated with Hoon expressions,
303−provided that those expressions produce something a tape as well. Interpolation
304−is done by wrapping the code to be inserted in `{}`. In your Dojo prompt, try
305−the command below (without the `>`):
308−> "I am a l{(mul 3 11)}t Urbit user."
312−Oh no! That command produced a nest-fail error, which indicates that there was
313−a problem related to Hoon type-system. We used the proper `{}` syntax for
314−interpolation, and we used the proper function-call syntax inside of it. So
317−Trying the `mul` function on its own will help answer this question. Try the
318−following command in your Dojo:
325−This should work, producing `33`, an atom. That's our problem. The
326−interpolation expression expects a tape, but our first command tried to
327−interpolate with something that results in an atom. Try this now:
334−We get a similar result, but we know that it's a tape because it's wrapped in
335−`""`. Bingo! With this knowledge, let's perform a successful interpolation:
338−> "I am a l{<(mul 3 11)>}t Urbit user."
339−"I am a l33t Urbit user."
346−The default subject of a Sail file is different from the subject that
347−expressions in the Dojo or a Hoon generator are evaluated against.
349−To see this difference, first save the code below to a file at
350−`home/web/pages/sub.hoon` and view the rendering at
351−`http://localhost:8080/pages/sub`.
362−Then enter the following command in the Dojo:
368−You'll notice that the Sail subject is like a stripped-down version of the Dojo
369−subject. Its final line should match the Dojo subject.
371−Now swap the code below into your Sail file.
383−You'll find that the resulting Sail subject is much larger. If you look closely,
384−you'll see that there's some new similarities with the Dojo subject, such as
385−containing the name of your ship. There's also some new differences, since
386−`fuel:html` contains things that are specifically useful for performing
387−web-related operations.
389−### A More Interesting Example
391−Now let's apply knowledge of string interpolation and the Sail subject in a Sail
392−source file. The following code produces more interesting things than the
393−example we saw before.
398−=+ wid=(met 3 p.bem.gas)
400−?: (lte wid 1) "galaxy"
402−?: (lte wid 4) "planet"
403−?: (lte wid 8) "moon"
407− ;meta(charset "utf-8");
408− ;title: A more advanced page
411− ;h1: This is the Title
413− ;a/"http://urbit.org": link to Urbit.org.
414− ;span: Check it out!
417− ;li(style "color: green"): We're doing interesting stuff now.
418− ;li: We're pretty-printing this sum with Hoon: {<(add 50 50)>}.
419− ;li: The code above is shorthand for {(scow %ud (add 50 50))}.
420− ;li: I am {(trip '~lodleb-ritrul')}.
421− ;li: Actually, my name is {<p.bem.gas>}. I'm a {what-kind}.
423− ;div: My name is {<p.bem.gas>}. I'm a {what-kind}.
428−Save the above Sail code in to `home/web/pages/secondsail.hoon` and access the
429−resulting page by navigating to `http://localhost:8080/pages/secondsail` in
432−There are some interesting things here. Let's go through this code piece by
439−Later in this code we want to produce the name of the ship which is hosting it,
440−something that looks like ~lodleb-ritrul. In a generator, we could produce our ship
441−name by writing `our` -- try it in the Dojo. But remember that Sail is rendered
442−against its own subject, `our` is not part of the default subject. To augment
443−our subject with the information that we need, we use `/= gas /$ fuel:html`.
445−The above expression uses two Ford runes, `/=` and `/$`, to add the relevant
446−information to the current subject. We can pull the ship's name out of this
447−augmented subject later. It's important to note that these runes are not part of
448−Hoon. They are part of Ford, our build system.
450−`/$` is used to get data from the environment, and `/=` adds that data to
451−subject in the face `gas`. The
452−[Ford user manual](https://urbit.org/docs/arvo/internals/ford/runes/) has
453−details on these and other Ford runes, but understanding these runes isn't
454−necessary for the purposes of this tutorial.
456−`fuel:html` gets extra data from your ship's Eyre module, which handles all
457−things HTTP, and sticks it in the subject when Eyre renders a page. This
458−includes the name of the ship, which is what we look for in the next line, but
459−it includes much more.
461−`p.bem.gas` is an expression that looks for `p` within `bem` within `gas`, the
462−face that we stored the above `fuel:html` expression in. That wing happens to
463−resolve to the name of the ship that is hosting the web-server. If we wanted to
464−access the current desk, we would use the wing expression `q.bem.gas`.
466−You can take a look at what you can access by typing `fuel:html` in the Dojo,
467−and then explore it by modifying your wing expression in your Sail file
474−The above line of code stores a variable used later for a conditional. `&` means
475−`true`, meaning that any evaluation of `show-list` will be true until changed in
479−=+ wid=(met 3 p.bem.gas)
481− ?: (lte wid 1) "galaxy"
483− ?: (lte wid 4) "planet"
484− ?: (lte wid 8) "moon"
488−This code chunk is a series of conditionals that checks the host ship's name to
489−see what its value is.
491−The first line, `=+ wid=(met 3 p.bem.gas)`, combines a new noun with the
492−subject and gives it the face `wid`. This noun is produced by the the
493−standard-library function [`met`](/docs/reference/library/2c), which measures the number of
494−[blocks](/docs/reference/library/1c/) of size `a` within `b`. Blocks are units that have a
495−bitwidth of `2^a`. So, in this case, it measures how many bytes (blocks of size
496−3 are bitwidths of 8; `2^3 = 8`) are fully contained in your ship's address.
498−Galaxies contain zero to one 3-blocks; stars contain two 3-blocks; planets
499−contain three to four 3-blocks; moons contain five to eight 3-blocks; comets
500−contain nine to sixteen 3-blocks. Each test uses `lte`, the
501−less-than-or-equal-to function, to determine if `wid` is of a given size. The
502−result of this series of tests is added to the subject and given the face
505−Ship names are simply another representation of atoms, and ship
506−categories are different ranges of possible atomic values. Because of this, we
507−perform less-than tests to see what kind of ship is running the web-server.
512− ;meta(charset "utf-8");
513− ;title: A more advanced page
517−Sail proper begins here. These four lines are four nodes. The `;html` node
518−indicates that the contained code should be rendered as HTML; this tag is closed
519−on the final line. The `;head` node contains metadata, and is closed three lines
520−later. The `;meta` node sets the character set to UTF-8, and the `;title` node
521−sets the title of the page that shows up in the browser tab.
525− ;h1: This is the Title
527− ;a/"http://urbit.org": link to Urbit.org.
528− ;span: Check it out!
531−The first line here opens, of course, the body node. The second line creates
534−The third, fourth, and fifth lines of code here construct a single line with an
536−`; This is a` begins the rendered line with plain text.
538−`;a/"http://urbit.org": link to Urbit.org.` continues that same rendered line,
539−and creates hyperlinked text out of `link to Urbit.org.`
541−`;span: Check it out!` continues that same rendered line further. `;span:`
542−has the same use as `<span>` in HTML, and by following it with just a `:` and no
543−attributes, it continues the line without formatting. Following `;span:` with
544−**two** spaces causes there to be single space following the produced `<span>`
545−element, because one of those spaces is syntactically necessary.
547−In the following lines, we begin to use some Hoon expressions again.
554−In the top line in the chunk above, we use the `;+` Sail rune, which
555−resolves an expression to a single node. That expression, in this case, is
556−`?:`, which tests the truth value of `show-list`, which we assigned the value
557−`&` (meaning `true`) at the beginning of the program. It's closed by the `==` on
560−Thus, this program resolves to the first child of `show-list`, the node `;ol`.
561−That node creates an ordered list, and the items contained within that node.
564− ;li(style "color: green"): We're doing more interesting stuff now.
567−The line above is the only element of this list that does not use
568−Hoon proper. The line renders as green, as interpreted by the browser,
569−because of the Sail attribute.
571−The next items in the list use `{}`. Recall that these braces, pronounced "lob"
572−and "rob" in Hoon-speak, allow for the interpolation of code within a string.
575− ;li: We're pretty-printing this sum with Hoon: {<(add 50 50)>}.
578−The line above is interpolated with Hoon code that produces the sum of 50 plus
579−50, which is wrapped in `<>` to put the product in double quotes to make it a
580−tape, like the rest of the line.
583− ;li: The code above is shorthand for {(scow %ud (add 50 50))}.
586−The `{(scow %ud (add 50 50)}` on this line is just a different way
587−writing the `{<(add 50 50)>}` expression. `scow` is a Hoon function that turns a
588−noun into a `tape`, Hoon's string type. `%ud` tells `scow` that its argument
589−should be displayed in the form of an unsigned decimal.
592− ;li: I am {(trip '~lodleb-ritrul')}.
595−`trip` is a function that takes a `cord` and produces a `tape`. A piece of
596−data of the cord type is one big atom formed from adjacent unicode bytes and
597−delineated by `''`. Remember that all text rendered in Sail is treated as a
598−tape. So, by converting `~lodleb-ritrul` to a tape, it can be included in the
599−tape that we are trying to insert it into without getting a type error.
602− ;li: Actually, my name is {<p.bem.gas>}. I'm a {what-kind}.
606−The line above has interpolated code that uses a wing expression to access the
607−name of the host ship, and then accesses the face `what-kind` that contains a
608−string describing what type of ship it is. We declared `gas` on the very first
609−line so that we could add that sort of information to the subject that our Sail
610−is rendered against. The wing expression `p.bem.gas` looks for `p` within `bem`
611−within `gas`, which happens to be where the name of the ship is located.
613−Note that `{what-kind}` does not have a `<>` wrapper. Why do you think this is?
616− ;div; My name is {<p.bem.gas>}. I'm a {ship}.
621−The `;div;` node above is only rendered, as an alternative to the above list,
622−if `show-list` is evaluated as `true`. This means it won't be shown with your
623−default code. To show this line, change the `&` on line 2 to `|` (`false`).
627−In the previous example, we used a few special runes that aren't used in typical
628−Hoon code. But there are others that are worth learning about at this point.
630−`;+` is an expression that resolves to a single node. We saw this on line 20
631−in our Sail example above: `;+ ?: show-list` resolves to the node `;ol` and
632−all of that node's children.
634−`;*` is an expression that resolves to a list of nodes. If we want to render
635−multiple nodes side-by-side, and not just the children of a single node, this
636−is the expression that we use.
638−`;=` turns a tuple of nodes into a list of nodes.
640−To see how these runes work, let's take a chunk of our previous code starting at
641−line 20 and modify it a bit:
646− ;li: I am {(trip '~lodleb-ritrul')}.
647− ;li: Actually, my name is {<p.bem.gas>}.
650− ;div: My name is {<p.bem.gas>}. I'm a {what-kind}.
656−We changed the conditional branches so that each contains two Sail nodes,
657−side-by-side -- notice that the `;ol` is absent from the first branch.
659−We begin with the `;*` rune, which resolves to a list of nodes, instead of the
660−`;+` rune, which only resolves to a single node.
662−But that's not enough on its own. `;*` needs to resolve to a list, and a few
663−Sail nodes aren't lists until they are explicitly made into lists. Until we wrap
664−those nodes in `;=`, the nodes treated as mere tuples. All branches must be
665−valid lists for the `;* ?: show-list` expression to resolve.
669−You should now have foundational knowledge for making web pages with Sail. There
670−is, of course, more to learn.
672−The [Ford manual](https://urbit.org/docs/arvo/internals/ford/runes/)
673−can show you how to access various ship resources for use in your pages. To
674−learn more about how the renderer works, take a look at the
675−`/home/ren/urb.hoon` file inside your pier.
677−## Udon: A Guide {#udon}
679−Udon is a way to write content for the web. It's a minimalist
680−markup language for creating and rendering text documents, with a
681−Markdown-inspired syntax. It's integrated with our Hoon programming language,
682−allowing it to be used as standalone prose in its own file or embedded inside a
683−Hoon source file, in which case it will be parsed into a tree of HTML nodes
684−using Hoon's XML-templating syntax, Sail.
686−There are quite a few similarities between Udon and the
687−CommonMark standard, but there are enough differences that you shouldn't rely on
688−existing knowledge of the latter. Udon generally supports only one
689−syntax for each type of HTML node it emits. Udon is also stricter than
690−Markdown: some syntax errors will prevent the file from being parsed at all.
694−Udon files use the `.udon` file extension, but for this entry-level guide, we
695−will use the `frontpage.hoon` method that we are already familiar with.
697−To test out Udon, put a `;>` under the `^- manx` in your `frontpage.hoon` file,
698−and then put all your Udon code under that `;>`. Then run `|commit %home`
699−in the Dojo. If you've already run the `|serve` command code from the first
700−section, the new content should appear at `http://localhost/test`.
706−> Note: The Front Matter section only applies to .udon files, and not the
707−frontpage.hoon testing method.
709−The first thing on a `.udon` file is a chunk of code called the front matter. It
710−contains metadata about your page, such as date, title, and position relative
713−As an example, let's look at the front matter of this very page:
716−:- :~ navhome/'/docs/'
723−What's going on here?
725−`:-`, the Hoon rune for creating a cell, creates a cell composed of
726−the `:~` Hoon rune for creating a list, and `;>`, which is a Sail rune
729−`:~` creates a list out of the three elements: `navhome/'/docs/'`, which
730−indicates that navigating "home" will bring you to the urbit.org/docs section
731−of the website; `sort/'28'`, which assigns it the 28th position of the
732−immediate section that contains it, the one you see in the sidebar;
733−and `title/'Udon'`, which gives the page its title. The `==` digraph
736−`;>` is a Sail rune that creates a node that contains everything that follows
737−it, telling the parser that this text should be interpreted as Udon.
738−It's not technically front matter, but you'll always find it following the
739−front matter, since all Udon must come after this rune.
741−The categories listed in the example above -- `navhome`, `sort`, and `title` --
742−make sense to Eyre by default, but any arbitrary category can be used. The code
743−below is valid front matter.
746−:- :~ date/~2018.9.12
747− author/~lodleb-ritrul
752−Note that `~2018.9.12`, `~lodleb-ritrul`, and `'rad'` are all of of atom
753−types: `@da`(date), `@p` (ship name), and `@t` (cord), respectively. Only atom
754−types work here. Having `music/"rad"` would prevent the source file from
759−Headers in Udon begin the line with one or more `#` characters,
760−followed by a single space. After that space comes the actual text to be
761−displayed. The number of leading `#` characters corresponds to the resulting HTML
762−header-size element: `#` yields an `<h1>`, `##` yields an `<h2>`, and so on,
763−through `<h6>`. The header for this section is `### Headers`.
781−Enclosing text with `_` will cause that text to appear italicized, using an `<i>`
784−Enclosing text with `*` will cause that text to appear bolded, using a `<b>`
790−To get their *attention*, you need that _je ne sais quoi_.
795−To get their **attention**, you need that _je ne sais quoi_.
799−A blank line is interpreted as a line break, creating a distinct
800−paragraph. However, a newline on its own is merely interpreted as a space on
806−Here's the first line.
808−This second line is separated by two newlines, so it's a separate paragraph.
810−This line looks like a distinct paragraph, but ...
811−It's only separated by a single newline, so it's included in the same paragraph.
816−Here's the first line.
818−This second line is separated by two newlines, so it's a separate paragraph.
820−This line looks like a distinct paragraph, but ...
821−It's only separated by a single newline, so it's included in the same paragraph.
823−#### Backslash Line Break
825−A backslash at the end of a line inserts a line break (`<br>`)
826−after that line. This contrasts with the normal Udon behavior of
827−converting newlines to spaces.
832−I wonder how long each line
833−will be if I put backslashes\
834−at the ends of the lines.
839−I wonder how long each line
840−will be if I put backslashes\
841−at the ends of the lines.
845−A backslash directly _before_ a word (with no spaces) will be interpreted
846−as an escape character, causing it to be rendered raw.
851−Here is some *bold* text.
852−Here is some \*not bold\* text.
857−Here is some **bold** text.
858−Here is some \*not bold\* text.
862−A line beginning with a `-` followed by a space is interpreted as an
863−element of an **unordered list** (`<ul>`). Each line in an unordered list is
864−prepended with a bullet point.
866−A line beginning with a `+` followed by a space is interpreted as an element
867−of an **ordered list** (`<ol>`). Each line in an ordered list is prepended with
868−a number corresponding to its position in that list.
870−New list elements are delineated by newlines beginning with list symbols of
871−the appropriate type (`-` or `+`).
873−Just as with non-list text, text on a bare newline will appear on the line before,
874−separated by a space. A `\\` is used to create a line-break that isn't the list
875−itself and isn't a list. Both of these kinds of newlines must be indented by two
876−spaces, or else the page will not parse.
878−Indentation is also used for creating nested sub-lists. Sub-lists of one kind
879−can be used with parent lists of the other kind. Sub-lists can't be nested
880−directly after either kind of aforementioned newline that isn't a list element;
881−only lines that are themselves list elements can nest sub-lists.
883−A newline after a blank line is interpreted as a new paragraph in normal text.
884−Between two list elements, however, a blank line is semantically equivalent to
885−a bare newline. To separate two lists with blank space, create a blank line
886−followed by a `\\` on its own line.
896− Make sure that you get enough for the barbecue
898− + Ask the baker what's fresh
899− + Buy the second-freshest batch
903−+ First, separate eggs into a bowl
904−+ Then, add a splash of cream
905− - If you don't have cream, you can use milk, but cream is preferred
906− + If you don't have milk or cream, melt an eighth of a stick of butter on
908− + Scramble the eggs in the bowl
909− + Pour the eggs onto the skillet before the butter browns
912−+ Scramble eggs and put them into skillet
926− Make sure that you get enough for the barbecue
928− 1. Ask the baker what's fresh
929− 1. Buy the second-freshest batch
933−1. First, separate eggs into a bowl
934−1. Then, add a splash of cream
935− - If you don't have cream, you can use milk, but cream is preferred
936− 1. If you don't have milk or cream, melt an eighth of a stick of butter on
938− 1. Scramble the eggs in the bowl
939− 1. Pour the eggs onto the skillet before the butter browns
942−1. Scramble eggs and put them into skillet
950−There are two ways to create links, but both contain the text be hyperlinked
951−in `[]` followed by the destination in `()`.
953−The first type is an inline-style link, which simply uses the full URL as its
959−[I'm an inline-style link](https://urbit.org/operations/#using-the-shell)
964−[I'm an inline-style link](https://urbit.org/operations/#using-the-shell)
966−The second type is a reference-style link, which uses a relative path, based on
967−the current page's location. Instead of the full url, we use `..` to fill in
968−all of the URL that the destination has in common with the origin page.
973−[I'm a reference-style link](../shell)
978−[I'm a reference-style link](../shell)
980−If this page is located at `https://www.urbit.org/docs/reference/`, then these two
981−examples should have the same destination.
985−A link to a section of the same page is in the style of
986−`[text to be linked](#the-destination)`.
988−The destination for the anchor link is designated with the HTML element `id`,
989−so we need to use some [Sail](#sail). If there are two or more anchors with
990−the same `id` on the page, you will arrive at the earliest instance of the the
993−Note that each HTML element `id` should be unique and not be used more than once.
998−Check out this [section](#here-we-are) that we want to jump to.
1000−Four score and seven years ago ...
1002−It was the best of times, it was the worst of times ...
1009−Check out this [section](#here-we-are) that we want to jump to.
1011−Four score and seven years ago ...
1013−It was the best of times, it was the worst of times ...
1019−Text enclosed in double quotes (`"`) will be rendered with
1020−opening and closing quotes -- that is, `"` and `"`.
1024−"Yes," he said. "That is the way with him."
1029−"Yes," he said. "That is the way with him."
1033−There are two ways to show the literal text of code without running it: inline
1034−and block. Both highlight the contained text in another color.
1036−Note that the backslash, due to its role as the escape character, can only be
1037−displayed in a code block literal and not as inline code literal. This is a
1044−#### Inline Code Literal
1046−Enclosing some text in `` ` `` characters will cause it to be displayed as code,
1047−inside a `<code>` HTML element with monospace font and highlighted with a
1048−different background color.
1050−Using `` ` `` is useful when you want to designate only part of a line as code.
1051−Since this page is written in Udon, we've been using this operation
1052−throughout this guide to _format text_ to distinguish `code` from prose.
1057−`*[a 2 b c] -> *[*[a b] *[a c]]` is like lisp's `apply`.
1062−`*[a 2 b c] -> *[*[a b] *[a c]]` is like lisp's `apply`.
1064−Also, using the `++` prefix before a word will cause the word to be rendered as
1065−code with the `++` displayed, since that's the standard notation for an arm in
1071−The ++add arm is used to sum two numbers.
1076−The `++add` arm is used to sum two numbers.
1078−#### Block Code Literal
1080−By enclosing a block of text in a tick on their own lines
1081−before and after the contained text, the text will be treated as a code block.
1083−Most of our examples so far have used.
1109−Hoon has several syntactic forms for literals (numbers, strings, dates, etc.)
1110−that can be used in Udon as well. Udon detects such code, and so these
1111−forms will automatically appear inside a `<code>` element like inline code.
1129−Three or more hyphens, such as `---`, on their own line produce an `<hr>`
1130−element, the "horizontal rule". This is rendered as a horizontal line the
1131−width of its containing paragraph.
1140−And below this line, too
1153−And below this line, too
1157−A section of text with the first line beginning with `>` and a space,
1158−and each successive newline indented by two spaces, yields a
1159−`<blockquote>` HTML element. This block quote can itself contain more Udon,
1160−including more block quotes to render nested levels of quotation.
1162−Blank newlines do not end the block quote, but a blank newline followed by an
1163−unindented line of text _will_ end the quote.
1168−> As Gregor Samsa awoke one morning from uneasy dreams, he
1169− found himself transformed in his bed into a *monstrous* vermin.
1175− He is pale and thin, he wears a thin and ragged linen shirt.
1180−> As Gregor Samsa awoke one morning from uneasy dreams
1181− he found himself transformed in his bed into a **monstrous** vermin.
1187−> He is pale and thin, he wears a thin and ragged linen shirt.
1191−A poem is a section of text with meaningful newlines. Recall that,
1192−normally in Udon, newlines are treated as spaces and do not create a
1193−new line of text. If you want to embed text where newlines are retained, then
1194−indent the text in question with **eight spaces**.
1199− A shape with lion body and the head of a man,
1200− A gaze blank and pitiless as the sun,
1201− Is moving its slow thighs, while all about it
1202− Reel shadows of the indignant desert birds.
1207− A shape with lion body and the head of a man,
1208− A gaze blank and pitiless as the sun,
1209− Is moving its slow thighs, while all about it
1210− Reel shadows of the indignant desert birds.
1214−It's possible to use Udon as an HTML templating language akin to
1215−PHP, ERB, JSP, or Handlebars templates. This facility derives
1216−in part from the support for embedding Hoon code inside the markup.
1218−Sail is a domain-specific language within Hoon for creating XML nodes,
1219−including HTML. It can be used directly within Udon to provide
1220−scripting capability with Hoon and also to provide more precise control over the
1221−resulting HTML. The [Sail guide](#sail) is a good place to learn the
1229− ;strong: Don't panic!
1231− ;small: [reactive publishing intensifies]
1239− <strong>Don't panic!</strong>
1241− <small>[reactive publishing intensifies]</small>