You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pollen/doc/first-tutorial.html

13 lines
62 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/><title>5&nbsp;First tutorial</title><link rel="stylesheet" type="text/css" href="scribble.css" title="default"/><link rel="stylesheet" type="text/css" href="racket.css" title="default"/><link rel="stylesheet" type="text/css" href="manual-style.css" title="default"/><link rel="stylesheet" type="text/css" href="manual-racket.css" title="default"/><script type="text/javascript" src="scribble-common.js"></script><script type="text/javascript" src="manual-racket.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--></head><body id="scribble-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist tocviewlisttopspace"><div class="tocviewtitle"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,&quot;tocview_0&quot;);">&#9660;</a></td><td></td><td><a href="index.html" class="tocviewlink" data-pltdoc="x">Pollen:<span class="mywbr"> &nbsp;</span> the book is a program</a></td></tr></table></div><div class="tocviewsublisttop" style="display: block;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right">1&nbsp;</td><td><a href="Installation.html" class="tocviewlink" data-pltdoc="x">Installation</a></td></tr><tr><td align="right">2&nbsp;</td><td><a href="quick-tour.html" class="tocviewlink" data-pltdoc="x">Quick tour</a></td></tr><tr><td align="right">3&nbsp;</td><td><a href="Backstory.html" class="tocviewlink" data-pltdoc="x">Backstory</a></td></tr><tr><td align="right">4&nbsp;</td><td><a href="big-picture.html" class="tocviewlink" data-pltdoc="x">The big picture</a></td></tr><tr><td align="right">5&nbsp;</td><td><a href="first-tutorial.html" class="tocviewselflink" data-pltdoc="x">First tutorial</a></td></tr><tr><td align="right">6&nbsp;</td><td><a href="second-tutorial.html" class="tocviewlink" data-pltdoc="x">Second tutorial</a></td></tr><tr><td align="right">7&nbsp;</td><td><a href="raco-pollen.html" class="tocviewlink" data-pltdoc="x">Using <span class="stt">raco pollen</span></a></td></tr><tr><td align="right">8&nbsp;</td><td><a href="File_formats.html" class="tocviewlink" data-pltdoc="x">File formats</a></td></tr><tr><td align="right">9&nbsp;</td><td><a href="reader.html" class="tocviewlink" data-pltdoc="x">&#9674; command overview</a></td></tr><tr><td align="right">10&nbsp;</td><td><a href="Module_reference.html" class="tocviewlink" data-pltdoc="x">Module reference</a></td></tr><tr><td align="right">11&nbsp;</td><td><a href="Acknowledgments.html" class="tocviewlink" data-pltdoc="x">Acknowledgments</a></td></tr><tr><td align="right">12&nbsp;</td><td><a href="License___source_code.html" class="tocviewlink" data-pltdoc="x">License &amp; source code</a></td></tr><tr><td align="right"></td><td><a href="doc-index.html" class="tocviewlink" data-pltdoc="x">Index</a></td></tr></table></div></div><div class="tocviewlist"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,&quot;tocview_1&quot;);">&#9658;</a></td><td>5&nbsp;</td><td><a href="first-tutorial.html" class="tocviewselflink" data-pltdoc="x">First tutorial</a></td></tr></table><div class="tocviewsublistbottom" style="display: none;" id="tocview_1"><table cellspacing="0" cellpadding="0"><tr><td align="right">5.1&nbsp;</td><td><a href="first-tutorial.html#%28part._tutorial-1._.Prerequisites%29" class="tocviewlink" data-pltdoc="x">Prerequisites</a></td></tr><tr><td align="right">5.2&nbsp;</td><td><a href="first-tutorial.html#%28part._.The_relationship_of_.Racket___.Pollen%29" class="tocviewlink" data-pltdoc="x">The relationship of Racket &amp; Pollen</a></td></tr><tr><td align="right">5.3&nbsp;</td><td><a href="first-tutorial.html#%28part._.Starting_a_new_file_in_.Dr.Racket%29" class="tocviewlink" data-pltdoc="x">Starting a new file in Dr<span class="mywbr"> &nbsp;</span>Racket</a></td></tr><tr><td align="right">5.4&nbsp;</td><td><a href="first-tutorial.html#%28part._.Using_the_project_server%29" class="tocviewlink" data-pltdoc="x">Using the project server</a></td></tr><tr><td align="right">5.5&nbsp;</td><td><a href="first-tutorial.html#%28part._.Working_with_the_preprocessor%29" class="tocviewlink" data-pltdoc="x">Working with the preprocessor</a></td></tr><tr><td align="right">5.6&nbsp;</td><td><a href="first-tutorial.html#%28part._.First_tutorial_complete%29" class="tocviewlink" data-pltdoc="x">First tutorial complete</a></td></tr></table></div></div></div><div class="tocsub"><div class="tocsubtitle">On this page:</div><table class="tocsublist" cellspacing="0"><tr><td><span class="tocsublinknumber">5.1<tt>&nbsp;</tt></span><a href="#%28part._tutorial-1._.Prerequisites%29" class="tocsubseclink" data-pltdoc="x">Prerequisites</a></td></tr><tr><td><span class="tocsublinknumber">5.2<tt>&nbsp;</tt></span><a href="#%28part._.The_relationship_of_.Racket___.Pollen%29" class="tocsubseclink" data-pltdoc="x">The relationship of Racket &amp; Pollen</a></td></tr><tr><td><span class="tocsublinknumber">5.3<tt>&nbsp;</tt></span><a href="#%28part._.Starting_a_new_file_in_.Dr.Racket%29" class="tocsubseclink" data-pltdoc="x">Starting a new file in Dr<span class="mywbr"> &nbsp;</span>Racket</a></td></tr><tr><td><span class="tocsublinknumber">5.3.1<tt>&nbsp;</tt></span><a href="#%28part._.Setting_the__lang_line%29" class="tocsubseclink" data-pltdoc="x">Setting the <span class="stt">#lang</span> line</a></td></tr><tr><td><span class="tocsublinknumber">5.3.2<tt>&nbsp;</tt></span><a href="#%28part._.Putting_in_the_text_of_the_poem%29" class="tocsubseclink" data-pltdoc="x">Putting in the text of the poem</a></td></tr><tr><td><span class="tocsublinknumber">5.3.3<tt>&nbsp;</tt></span><a href="#%28part._.Saving___naming_your_source_file%29" class="tocsubseclink" data-pltdoc="x">Saving &amp; naming your source file</a></td></tr><tr><td><span class="tocsublinknumber">5.4<tt>&nbsp;</tt></span><a href="#%28part._.Using_the_project_server%29" class="tocsubseclink" data-pltdoc="x">Using the project server</a></td></tr><tr><td><span class="tocsublinknumber">5.4.1<tt>&nbsp;</tt></span><a href="#%28part._.Starting_the_project_server_with_raco_pollen%29" class="tocsubseclink" data-pltdoc="x">Starting the project server with <span class="stt">raco pollen</span></a></td></tr><tr><td><span class="tocsublinknumber">5.4.2<tt>&nbsp;</tt></span><a href="#%28part._.Using_the_dashboard%29" class="tocsubseclink" data-pltdoc="x">Using the dashboard</a></td></tr><tr><td><span class="tocsublinknumber">5.4.3<tt>&nbsp;</tt></span><a href="#%28part._.Source_files_in_the_dashboard%29" class="tocsubseclink" data-pltdoc="x">Source files in the dashboard</a></td></tr><tr><td><span class="tocsublinknumber">5.5<tt>&nbsp;</tt></span><a href="#%28part._.Working_with_the_preprocessor%29" class="tocsubseclink" data-pltdoc="x">Working with the preprocessor</a></td></tr><tr><td><span class="tocsublinknumber">5.5.1<tt>&nbsp;</tt></span><a href="#%28part._.Setting_up_a_preprocessor_source_file%29" class="tocsubseclink" data-pltdoc="x">Setting up a preprocessor source file</a></td></tr><tr><td><span class="tocsublinknumber">5.5.2<tt>&nbsp;</tt></span><a href="#%28part._.Creating_valid_.H.T.M.L_output%29" class="tocsubseclink" data-pltdoc="x">Creating valid HTML output</a></td></tr><tr><td><span class="tocsublinknumber">5.5.3<tt>&nbsp;</tt></span><a href="#%28part._.Adding_commands%29" class="tocsubseclink" data-pltdoc="x">Adding commands</a></td></tr><tr><td><span class="tocsublinknumber">5.5.4<tt>&nbsp;</tt></span><a href="#%28part._.Racket_basics__if_you_re_not_familiar_%29" class="tocsubseclink" data-pltdoc="x">Racket basics (if you&rsquo;re not familiar)</a></td></tr><tr><td><span class="tocsublinknumber">5.5.5<tt>&nbsp;</tt></span><a href="#%28part._.Defining_variables_with_commands%29" class="tocsubseclink" data-pltdoc="x">Defining variables with commands</a></td></tr><tr><td><span class="tocsublinknumber">5.5.6<tt>&nbsp;</tt></span><a href="#%28part._.Inserting_values_from_variables%29" class="tocsubseclink" data-pltdoc="x">Inserting values from variables</a></td></tr><tr><td><span class="tocsublinknumber">5.5.7<tt>&nbsp;</tt></span><a href="#%28part._.Inserting_variables_within_.C.S.S%29" class="tocsubseclink" data-pltdoc="x">Inserting variables within CSS</a></td></tr><tr><td><span class="tocsublinknumber">5.6<tt>&nbsp;</tt></span><a href="#%28part._.First_tutorial_complete%29" class="tocsubseclink" data-pltdoc="x">First tutorial complete</a></td></tr></table></div></div><div class="maincolumn"><div class="main"><div class="versionbox"><span class="version">6.1.0.5</span></div><div class="navsettop"><span class="navleft"><div class="nosearchform"></div>&nbsp;&nbsp;</span><span class="navright">&nbsp;&nbsp;<a href="big-picture.html" title="backward to &quot;4 The big picture&quot;" data-pltdoc="x">&larr; prev</a>&nbsp;&nbsp;<a href="index.html" title="up to &quot;Pollen: the book is a program&quot;" data-pltdoc="x">up</a>&nbsp;&nbsp;<a href="second-tutorial.html" title="forward to &quot;6 Second tutorial&quot;" data-pltdoc="x">next &rarr;</a></span>&nbsp;</div><h3>5<tt>&nbsp;</tt><a name="(part._first-tutorial)"></a>First tutorial</h3><p>In this tutorial, you&rsquo;ll use Pollen to make a single HTML page with a poem. You&rsquo;ll learn about:</p><ul><li><p>The relationship of Racket &amp; Pollen</p></li><li><p>DrRacket</p></li><li><p>The project server</p></li><li><p>The preprocessor</p></li></ul><p>If you want the shortest possible introduction to Pollen, try the <a href="quick-tour.html" data-pltdoc="x">Quick tour</a>.</p><h4>5.1<tt>&nbsp;</tt><a name="(part._tutorial-1._.Prerequisites)"></a>Prerequisites</h4><p>I&rsquo;m going to assume that you&rsquo;ve already installed Racket and Pollen. If not, do that now.</p><p>I&rsquo;m also going to assume you know the basics of using a command line to run programs and navigate the file system using commands like <span class="stt">cd</span> and <span class="stt">ls</span>. On Mac OS X, your command-line program is called Terminal; on Windows it&rsquo;s the Windows Command Processor.</p><h4>5.2<tt>&nbsp;</tt><a name="(part._.The_relationship_of_.Racket___.Pollen)"></a>The relationship of Racket &amp; Pollen</h4><p>As I mentioned in the <a href="big-picture.html" data-pltdoc="x">The big picture</a>, Pollen is built using Racket, and everything in Pollen ultimately becomes Racket code. If you&rsquo;re comfortable with that idea, you may move along.</p><p>But if not, or if you&rsquo;re just a curious character:</p><p>One of the key features of Racket as a programming language is that it provides tools to create <span style="font-style: italic">other</span> programming languages. These languages might look &amp; behave <a href="http://docs.racket-lang.org/ts-guide/index.html">like Racket</a>. Or they <a href="http://hashcollision.org/brainfudge/">might not</a>. These languages might serve a general purpose, but more often they&rsquo;re specialized for a particular purpose, in which case they&rsquo;re known as <span style="font-style: italic">domain-specific languages</span>, or <span style="font-style: italic">DSLs</span>.</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Racket exploits the fact that under the hood, all programming languages are basically doing the same thing. (CS jocks know this more formally as a side effect of <a href="https://en.wikipedia.org/wiki/Turing_completeness">Turing completeness</a>.) Racket starts with the most general expression of a Turing-complete language &#8212; called <a href="https://en.wikipedia.org/wiki/Lambda_calculus">the lambda calculus</a> &#8212; and lets users build on that. In most programming languages, you can build functions, classes, and modules. But in Racket, you can alter anything about the language.</p></blockquote></blockquote></blockquote><p>If you find this a strange idea, you&rsquo;re not alone. Most programmers &#8212; and until recently, me too &#8212;&#160;have never made or used DSLs. If you have a programming problem to solve, you start with a general-purpose language like Python or Java or Ruby, and go from there. Nothing wrong with that.</p><p>But programming languages contain their own design choices and compromises. Sometimes the problem at hand is best solved by manipulating the language at a deeper level. When you make a DSL, you&rsquo;re still programming in the underlying language, but doing so at a point of higher leverage.</p><p>Pollen is a DSL implemented in Racket. It is a close cousin of <a href="http://docs.racket-lang.org/scribble/index.html" data-pltdoc="x">Scribble: The Racket Documentation Tool</a>, another Racket DSL, which was designed for writing Racket documentation. The key feature of Scribble, and thus also of Pollen, is that it&rsquo;s text-based. Meaning, whereas most languages have source files made of code with text embedded within, Pollen&rsquo;s source files are text with code embedded within.</p><p>Moreover, Pollen is meant to be a small step away from Racket &#8212;&#160;you can think of it as a more convenient notation system for Racket code, similar to how Markdown is a more convenient notation for HTML. But unlike Markdown, which only lets you access a subset of HTML, anything that can be done in Racket can also be done in Pollen.</p><p>As you work more with Pollen, you&rsquo;ll pick up more about how Pollen corresponds to Racket (see <a href="reader.html" data-pltdoc="x">&#9674; command overview</a>) and easily be able to convert commands from one system to the other. In later tutorials, you&rsquo;ll see how larger Pollen projects are made out of both Pollen and Racket source files.</p><p>But in smaller projects, like this one, you can just use Pollen.</p><h4>5.3<tt>&nbsp;</tt><a name="(part._.Starting_a_new_file_in_.Dr.Racket)"></a>Starting a new file in DrRacket</h4><p>DrRacket is the IDE for the Racket programming language, and other languages made with Racket (like Pollen). IDE stands for &ldquo;Integrated Development Environment,&rdquo; which is a fancy phrase for &ldquo;a nice place to edit and run your code.&rdquo; DrRacket is installed as part of the core Racket distribution.</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>If you&rsquo;ve worked with languages like Perl, Python, or Ruby, you may be more familiar with using a general-purpose text editor to edit your code, and then running your program at the command line. You can do that with Racket too. But DrRacket is a considerately designed tool. I recommend it. For these tutorials, I&rsquo;ll assume you&rsquo;re using DrRacket. If you insist on using the command line, I trust you to figure out what you need to do to keep up.</p></blockquote></blockquote></blockquote><p>Launch DrRacket. Start a new file. The code in the file will look like this:</p><blockquote class="SCodeFlow"><p><a href="http://docs.racket-lang.org/guide/Module_Syntax.html#%28part._hash-lang%29" class="RktModLink" data-pltdoc="x"><span class="RktMod">#lang</span></a><span class="hspace">&nbsp;</span><a href="http://docs.racket-lang.org/reference/index.html" class="RktModLink" data-pltdoc="x"><span class="RktSym">racket</span></a></p></blockquote><p>Within the main window, you should also see an <span style="font-style: italic">interactions window</span>, which shows the output of the current file, and starts out looking something like this (details, like the version number, will vary):</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">Welcome to DrRacket, version 6.0.1.6--2013-11-26(-/f) [3m].</span></p></td></tr><tr><td><p><span class="stt">Language: racket; memory limit: 1000 MB.</span></p></td></tr><tr><td><p><span class="stt">&gt; </span></p></td></tr></table></p><p>If you don&rsquo;t see the interactions window, select <span class="ssansserif">View|Show Interactions</span> from the menu.</p><h5>5.3.1<tt>&nbsp;</tt><a name="(part._.Setting_the__lang_line)"></a>Setting the <span class="stt">#lang</span> line</h5><p>The first line of every Racket source file, and every Pollen source file, is called the <span style="font-style: italic"><span class="stt">#lang</span> line</span>. The <span class="stt">#lang</span> line identifies the language used to interpret the rest of the file.</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>For more about the <span class="stt">#lang</span> line, see <a href="http://docs.racket-lang.org/guide/Module_Syntax.html#%28part._hash-lang%29" data-pltdoc="x">The <span class="RktMod">#lang</span> Shorthand</a>.</p></blockquote></blockquote></blockquote><p>When you start a new Pollen source file in DrRacket, you&rsquo;ll need to change the <span class="stt">#lang</span> line to the Pollen language. The simplest way is to change the first line to this:</p><blockquote class="SCodeFlow"><p><a href="http://docs.racket-lang.org/guide/Module_Syntax.html#%28part._hash-lang%29" class="RktModLink" data-pltdoc="x"><span class="RktMod">#lang</span></a><span class="hspace">&nbsp;</span><a href="index.html" class="RktModLink" data-pltdoc="x"><span class="RktSym">pollen</span></a></p></blockquote><p>Now run your file by clicking the <span class="ssansserif">Run</span> button in the upper-right corner, or select <span class="ssansserif">Racket|Run</span> from the menu. You&rsquo;ll get something like:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">Welcome to DrRacket, version 6.0.1.6--2013-11-26(-/f) [3m].</span></p></td></tr><tr><td><p><span class="stt">Language: pollen; memory limit: 1000 MB.</span></p></td></tr><tr><td><p><span class="stt">&gt;</span></p></td></tr></table></p><p>Notice that the language is now reported as <span class="stt">pollen</span>. If you like, change the <span class="stt">#lang</span> line to this:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">#lang pollenxyz</span></p></td></tr></table></blockquote><p>Then click <span class="ssansserif">Run</span> again. DrRacket will print an error:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="RktErr">Module Language: invalid module text
<br/>standard-module-name-resolver: collection not found ...</span></p></td></tr></table></p><p>Why? Because there&rsquo;s no language called <span class="stt">pollenxyz</span>. Switch it back to <span class="stt">pollen</span> and let&rsquo;s move on.</p><h5>5.3.2<tt>&nbsp;</tt><a name="(part._.Putting_in_the_text_of_the_poem)"></a>Putting in the text of the poem</h5><p>Here&rsquo;s a short, bad poem I wrote about CSS.</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">The margin is 42em.</span></p></td></tr><tr><td><p><span class="stt">The border is red.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr></table></p><p>Paste the text of this poem into your DrRacket editing window, below the <span class="stt">#lang</span> line, so it looks like this:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr><tr><td><p><span class="stt">The margin is 42em.</span></p></td></tr><tr><td><p><span class="stt">The border is red.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr></table></blockquote><p><span class="ssansserif">Run</span> the file again. In the interactions window, you&rsquo;ll see:</p><p><span class="RktVal">The margin is 8em.
<br/>The border is blue.
<br/>The padding is 2em.
<br/>The border is too.</span></p><p>This shows you something important: by default, any plain text in a Pollen source file is simply printed as written when you <span class="ssansserif">Run</span> the file (minus the <span class="stt">#lang</span> line, which is just for Racket&rsquo;s benefit). If you like, edit the text of the poem and click <span class="ssansserif">Run</span> again. You&rsquo;ll see the updated text printed in the interactions window.</p><h5>5.3.3<tt>&nbsp;</tt><a name="(part._.Saving___naming_your_source_file)"></a>Saving &amp; naming your source file</h5><p>File naming in Pollen is consequential.</p><p>Ultimately, every Pollen source file in your project will be <span style="font-style: italic">rendered</span> into an output file. Each Pollen source file corresponds to one output file. <span style="font-weight: bold">The name of this output file will be the name of the source file minus the Pollen source extension.</span> So a source file called <span class="stt">file.txt.pp</span> will become <span class="stt">file.txt</span>.</p><p>Thus, to build the name of a source file, we take the name we want for the output file and add the appropriate Pollen file extension. Different Pollen source files use different extensions &#8212; but more about that later. For now, the extension you&rsquo;ll use for your source is <span class="stt">.pp</span>.</p><p>In this case, let&rsquo;s say we want to end up with a file called <span class="stt">poem.html</span>. Therefore, the name of our source file needs to be:</p><p>the output name <span class="stt">poem.html</span> + the source extension <span class="stt">.pp</span> = <span class="stt">poem.html.pp</span></p><p>(If you want to name the file <span class="stt">something-else.html.pp</span>, be my guest. There&rsquo;s no magic associated with the prefix.)</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>You&rsquo;re welcome to change the name of your source files from the desktop. On Mac OS X and Windows, however, the desktop interface often hides file extensions, so check the properties of the file afterward to make sure you got the name you expected.</p></blockquote></blockquote></blockquote><p>In a convenient location (e.g., your home directory or the desktop) create a new directory for your project called <span class="stt">tutorial</span>. In this new directory, save your DrRacket file as <span class="stt">poem.html.pp</span>.</p><blockquote class="Rfilebox"><p class="Rfiletitle"><span class="Rfilename"><span class="stt">"/path/to/tutorial/poem.html.pp"</span></span></p><blockquote class="Rfilecontent"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr><tr><td><p><span class="stt">The margin is 42em.</span></p></td></tr><tr><td><p><span class="stt">The border is red.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr></table></blockquote></blockquote><h4>5.4<tt>&nbsp;</tt><a name="(part._.Using_the_project_server)"></a>Using the project server</h4><p>The project server is a web server built into Pollen. Just as DrRacket lets you run individual files and see if they work as you expect, the project server lets you preview and test your project as a real website. While working on your Pollen project, you may find it convenient to have DrRacket open on half your screen, and on the other half, a web browser pointing at the project server.</p><p><img src="project-server.png" alt="" width="670" height="412"/></p><p>&ldquo;Why can&rsquo;t I just open the HTML files directly in my browser?&rdquo; If you want to keep making web pages the way we did in 1996, go ahead. But that approach has several shortcomings. First, when you open files directly in your browser, you&rsquo;re cruising the local filesystem, and absolute URLs (the kind that start with a <span class="RktInBG"><span class="hspace"></span><span class="RktIn">/</span><span class="hspace"></span></span>) won&rsquo;t work. Second, if you want to test your website on devices other than your own machine &#8212;&#160;well, you can&rsquo;t. Third, you have to render your HTML files in advance, whereas the project server is clever about doing this dynamically.</p><p>So use the project server.</p><p>A note about security. The project server isn&rsquo;t intended for real-world use, but rather as a development tool. That said, once you start the project server, it&rsquo;s an actual web server running on your machine, and it will respond to requests from any computer. If you want to limit traffic to your local network, or certain machines on your local network, it&rsquo;s your job &#8212; not mine &#8212; to configure your firewall or other network security measures accordingly.</p><h5>5.4.1<tt>&nbsp;</tt><a name="(part._.Starting_the_project_server_with_raco_pollen)"></a>Starting the project server with <span class="stt">raco pollen</span></h5><p>Before we start the project server, a word about the <span class="stt">raco pollen</span> command.</p><p>When you installed Racket, Racket installed a utility program called <span class="stt">raco</span>. This name is short for <span style="font-weight: bold">Ra</span>cket <span style="font-weight: bold">co</span>mmand, and <span class="stt">raco</span> acts as a hub for &#8212;&#160;you guessed it &#8212; Racket commands. You used it when you first installed Pollen:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">&gt; raco pkg install pollen</span></p></td></tr></table></p><p>The first argument after <span class="stt">raco</span> is the subcommand. For instance, <span class="stt">raco pkg ...</span> lets you install, update, and remove packages like so:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">&gt; raco pkg update pollen</span></p></td></tr><tr><td><p><span class="stt">&gt; raco pkg remove pollen</span></p></td></tr></table></p><p>Likewise, <span class="stt">raco pollen</span> lets you issue commands relevant to Pollen, like starting the project server. (See <a href="raco-pollen.html" data-pltdoc="x">Using <span class="stt">raco pollen</span></a> for a full description of available commands.)</p><p>Now we&rsquo;ll start the project server. Go to your command line and enter the following:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">&gt; cd /path/to/tutorial</span></p></td></tr><tr><td><p><span class="stt">&gt; raco pollen start</span></p></td></tr></table></p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Windows users, I&rsquo;ll trust you to convert <span class="stt">raco</span> into the appropriate command for your system &#8212; assuming defaults, it&rsquo;s likely to be <span class="stt">"C:\Program Files\Racket\raco"</span> (include the surrounding quotes in the command).</p></blockquote></blockquote></blockquote><p>After a moment, you&rsquo;ll see a startup message like this:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">Welcome to Pollen 0.001 (Racket 6.x.x.x)</span></p></td></tr><tr><td><p><span class="stt">Project root is /path/to/tutorial</span></p></td></tr><tr><td><p><span class="stt">Project server is http://localhost:8080 (Ctrl-C to exit)</span></p></td></tr><tr><td><p><span class="stt">Project dashboard is http://localhost:8080/index.ptree</span></p></td></tr><tr><td><p><span class="stt">Ready to rock</span></p></td></tr></table></p><p><span style="font-style: italic">Project root</span> means the directory that the project server was started in, and which it&rsquo;s treating as its root directory. Any absolute URLs (i.e., those beginning with <span class="RktInBG"><span class="hspace"></span><span class="RktIn">/</span><span class="hspace"></span></span>) will resolve into this directory. So a URL like <span class="stt">/styles.css</span> will impliedly become <span class="stt">/path/to/tutorial/styles.css</span>.</p><p>If you use the bare command <span class="stt">raco pollen start</span>, the project server will start in the current directory. But if you want to start the project server elsewhere, you can add that directory as an argument like this:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">&gt; raco pollen start /some/other/path</span></p></td></tr></table></p><p>The next line of the startup message tells you that the web address of the project server is <span class="stt">http://localhost:8080</span>. This is the address you put into your web browser to test your project. If you&rsquo;re unfamiliar with this style of URL, <span class="stt">localhost</span> refers to your own machine, and <span class="stt">8080</span> is the network port where the project server will respond to browser requests.</p><p>If you want to access the project server from a different machine, you can&rsquo;t use <span class="stt">localhost</span>. But you can use the IP address of the machine running the project server (e.g., <span class="stt">http://192.168.1.10:8080</span>) or any name for that machine available through local DNS (e.g., <span class="stt">http://mb-laptop:8080</span>).</p><p>Though port <span class="stt">8080</span> is the default, you can start the project server on any port you like by adding it as an argument to <span class="stt">raco pollen start</span>:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">&gt; raco pollen start /path/to/tutorial</span></p></td></tr><tr><td><p><span class="stt">&gt; raco pollen start /path/to/tutorial 8088</span></p></td></tr></table></p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>You can also change the default port by altering <span class="RktSym"><a href="World.html#%28def._%28%28lib._pollen%2Fworld..rkt%29._world~3adefault-port%29%29" class="RktValLink" data-pltdoc="x">world:default-port</a></span>, or parameterizing it with <span class="RktSym"><a href="World.html#%28def._%28%28lib._pollen%2Fworld..rkt%29._world~3acurrent-server-port%29%29" class="RktValLink" data-pltdoc="x">world:current-server-port</a></span>.</p></blockquote></blockquote></blockquote><p>Note that when you pass a port argument, you also have to pass a path argument. If you want the project server to start in the current directory, you can use the usual <span class="RktInBG"><span class="hspace"></span><span class="RktIn">.</span><span class="hspace"></span></span> shorthand:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">&gt; cd /path/to/tutorial</span></p></td></tr><tr><td><p><span class="stt">&gt; raco pollen start 8088</span></p></td></tr><tr><td><p><span class="stt"></span><span class="RktErr">/path/to/tutorial/8088 is not a directory</span><span class="stt"></span></p></td></tr><tr><td><p><span class="stt">&gt; raco pollen start . 8088</span></p></td></tr></table></p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>You can run multiple project servers simultaneously. Just start them on different ports so they don&rsquo;t conflict with each other.</p></blockquote></blockquote></blockquote><p>Your terminal window will report status and error messages from the project server as it runs. Use <span class="ssansserif">Ctrl-C</span> to stop the server.</p><h5>5.4.2<tt>&nbsp;</tt><a name="(part._.Using_the_dashboard)"></a>Using the dashboard</h5><p>For each directory in your project, starting at the top, the project server displays a <span style="font-style: italic">dashboard</span> in your web browser. The dashboard gives you an overview of the files in the directory, and links to view them.</p><p>The address of the top-level dashboard is <span class="stt">http://localhost:8080/index.ptree</span>. Other dashboards follow the same pattern (e.g., <span class="stt">http://localhost:8080/path/to/dir/index.ptree</span>.)</p><p>Note that the dashboard is <span style="font-weight: bold">not</span> at <span class="stt">http://localhost:8080/</span> or its equivalent, <span class="stt">http://localhost:8080/index.html</span>. Why? So it doesn&#8217;t interfere with any <span class="stt">index.html</span> that you may want to put in your project.</p><p>Thus, <span class="stt">index.ptree</span>. The <span class="stt">.ptree</span> extension is short for <span style="font-style: italic">pagetree</span>. In Pollen, a pagetree is a hierarchical list of pages. We&rsquo;ll do more with pagetrees in a later tutorial. For now, just be aware that to generate the dashboard, the project server will first look for an actual <span class="stt">index.ptree</span> file in each directory. If it doesn&rsquo;t find one, it will generate a pagetree from a listing of files in the directory.</p><p>Let&rsquo;s look at the root-level dashboard for our project. First, make sure your project server is running:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">&gt; cd /path/to/tutorial</span></p></td></tr><tr><td><p><span class="stt">&gt; raco pollen start</span></p></td></tr></table></p><p>Then, in your web browser, visit <a href="http://localhost:8080/index.ptree"><span class="stt">http://localhost:8080/index.ptree</span></a>.</p><p>You should see something like this:</p><p><img src="dashboard.png" alt="" width="604" height="214"/></p><p>The top line tells us that we&rsquo;re in the root directory of the project. We didn&rsquo;t make an explicit <span class="stt">index.ptree</span> file, so the project server just shows us a directory listing.</p><h5>5.4.3<tt>&nbsp;</tt><a name="(part._.Source_files_in_the_dashboard)"></a>Source files in the dashboard</h5><p>We see the only file, <span class="stt">poem.html.pp</span>. Note that the <span class="stt">.pp</span> extension is grayed out. The dashboard automatically consolidates references to source and output files into a single entry. What this entry says is &ldquo;The directory contains a source file in <span class="stt">.pp</span> format for the output file <span class="stt">poem.html</span>.&rdquo;</p><p>Every source-file entry in the dashboard has three links. The first link is attached to the filename itself, and takes you to a preview of the output file. If the output file doesn&rsquo;t yet exist &#8212;&#160;as is the case here &#8212;&#160;it will be dynamically rendered. (This is true whether you click its name in the dashboard, or link to it from another page.) So click the filename. You&rsquo;ll see in your web browser:</p><blockquote class="SCodeFlow"><p>The margin is 42em. The border is red. The padding is 15em. The border is too.</p></blockquote><p>Granted, this is a boring web page. The main point here is that you&rsquo;re seeing the <span style="font-style: italic">output</span> from your source file, which didn&rsquo;t exist before. Notice that the address bar says <span class="stt">http://localhost:8080/poem.html</span>, not <span class="stt">poem.html.pp</span>. And if you look in your <span class="stt">tutorial</span> directory, you&rsquo;ll see a new file called <span class="stt">poem.html</span>.</p><p>In other words, when you clicked on the filename link in the dashboard, Pollen rendered the output file from your source file and saved it in your project directory. As promised earlier, the name of the output file (<span class="stt">poem.html</span>) is the name of the source file (<span class="stt">poem.html.pp</span>) minus the Pollen extension (<span class="stt">.pp</span>).</p><p>If you go back to the dashboard and click on the filename link again, you&rsquo;ll see the same output file. If the source file hasn&rsquo;t changed, Pollen will just show you the output file that&rsquo;s already been rendered.</p><p>But if you like, open your <span class="stt">poem.html.pp</span> source file in DrRacket, edit the first two lines, and save the file:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr><tr><td><p><span class="stt">The cave is pitch black.</span></p></td></tr><tr><td><p><span class="stt">Look out for the grue.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr></table></blockquote><p>Go back to the dashboard and click on the filename. This time, you&rsquo;ll see:</p><blockquote class="SCodeFlow"><p>The cave is pitch black. Look out for the grue. The padding is 15em. The border is too.</p></blockquote><p>Here, Pollen notices that the source file has changed, so it refreshes the output file. This makes it convenient to work between DrRacket and your web browser, editing source and then reloading to see the changes.</p><p>The other two links in the dashboard are labeled <span class="stt">in</span> and <span class="stt">out</span>.</p><p>The link labeled <span class="stt">in</span> will display the contents of the source file:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr><tr><td><p><span class="stt">The cave is pitch black.</span></p></td></tr><tr><td><p><span class="stt">Look out for the grue.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr></table></blockquote><p>The link labeled <span class="stt">out</span> will display the contents of the output file (just like the &ldquo;view source&rdquo; option in your web browser):</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">The cave is pitch black.</span></p></td></tr><tr><td><p><span class="stt">Look out for the grue.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr></table></blockquote><p>For now, the files are identical except for the <span class="stt">#lang</span> line. But let&rsquo;s change that.</p><h4>5.5<tt>&nbsp;</tt><a name="(part._.Working_with_the_preprocessor)"></a>Working with the preprocessor</h4><p>Pollen can operate in several processing modes. One of these is <span style="font-style: italic">preprocessor</span> mode. A preprocessor is a tool for making systematic, automated changes to a file, often in contemplation of further processing (hence the <span style="font-style: italic">pre-</span>). You can use the Pollen preprocessor this way. Or you can just use it on its own, and leave your files in a finished state.</p><p>That&rsquo;s how we&rsquo;ll&#160;use it in this tutorial. We&rsquo;ll build out our <span class="stt">poem.html.pp</span> source file so that it exits the preprocessor as a legit HTML file.</p><h5>5.5.1<tt>&nbsp;</tt><a name="(part._.Setting_up_a_preprocessor_source_file)"></a>Setting up a preprocessor source file</h5><p><div class="SIntrapara">The file extension of a Pollen source file tells Pollen what kind of processing to apply to it. The &ldquo;<span class="stt">.pp</span>&rdquo; file extension stands for &ldquo;Pollen preprocessor.&rdquo; You can use the preprocessor with any text-based file by:
</div><div class="SIntrapara"><ul><li><p>inserting <span class="stt">#lang pollen</span> as the first line,</p></li><li><p>adding the <span class="stt">.pp</span> file extension,</p></li><li><p>running it through Pollen.</p></li></ul></div></p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>For more about the Pollen processing modes and how to invoke them, see <a href="file-types.html" data-pltdoc="x">File</a>.</p></blockquote></blockquote></blockquote><p>&ldquo;The preprocessor be used with <span style="font-weight: bold">any</span> kind of text-based file?&rdquo; Right. &ldquo;But how?&rdquo; The preprocessor reads the source file, handles any Pollen commands it finds, and lets the rest of the content pass through untouched. To the preprocessor, it&rsquo;s all just text data. It doesn&rsquo;t care whether that text represents HTML, CSS, JavaScript, or even <a href="https://en.wikipedia.org/wiki/TI-BASIC">TI-BASIC</a>.</p><p>Because the preprocessor only deals in text, the Pollen commands you use in the preprocessor also have to produce text. Moreover, Pollen doesn&rsquo;t enforce the semantics of the underlying file &#8212; that&rsquo;s your responsibility. For instance, Pollen won&rsquo;t stop you from doing nonsensical things like this:</p><blockquote class="Rfilebox"><p class="Rfiletitle"><span class="Rfilename"><span class="stt">"bad-poem.html.pp"</span></span></p><blockquote class="Rfilecontent"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr><tr><td><p><span class="stt">The cave is pitch black.</span></p></td></tr><tr><td><p><span class="stt">Look out for the grue.</span></p></td></tr><tr><td><p><span class="stt">&#9674;(insert-mp3-recording-of-scream)</span></p></td></tr></table></blockquote></blockquote><p>Here, the result is not going to be valid HTML, because you can&rsquo;t simply drop binary data in the middle of an HTML file. To paraphrase Mr. Babbage &#8212; garbage in, garbage out.</p><p>I&rsquo;ve encouraged you to mess with the source file, but let&rsquo;s return it to its original state:</p><blockquote class="Rfilebox"><p class="Rfiletitle"><span class="Rfilename"><span class="stt">"/path/to/tutorial/poem.html.pp"</span></span></p><blockquote class="Rfilecontent"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr><tr><td><p><span class="stt">The margin is 42em.</span></p></td></tr><tr><td><p><span class="stt">The border is red.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr></table></blockquote></blockquote><p>This file has <span class="stt">#lang pollen</span> as the first line, and <span class="stt">.pp</span> as the file extension, so it meets the minimum requirements for the preprocessor.</p><h5>5.5.2<tt>&nbsp;</tt><a name="(part._.Creating_valid_.H.T.M.L_output)"></a>Creating valid HTML output</h5><p>Let&rsquo;s update our source so it produces valid HTML. Edit the source as follows:</p><blockquote class="Rfilebox"><p class="Rfiletitle"><span class="Rfilename"><span class="stt">"/path/to/tutorial/poem.html.pp"</span></span></p><blockquote class="Rfilecontent"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt">&lt;!DOCTYPE html&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;html&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;body&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;pre&gt;</span></p></td></tr><tr><td><p><span class="stt">The margin is 42em.</span></p></td></tr><tr><td><p><span class="stt">The border is red.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr><tr><td><p><span class="stt">&lt;/pre&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;/body&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;/html&gt;</span></p></td></tr></table></blockquote></blockquote><p>Return to the project server and view <a href="http://localhost:8080/poem.html">http://localhost:8080/poem.html</a>. Earlier, the output looked like this:</p><blockquote class="SCodeFlow"><p>The margin is 42em. The border is red. The padding is 15em. The border is too.</p></blockquote><p>But now, because of the <span class="stt">&lt;pre&gt;</span> tag, the poem will appear in a monospaced font, and the line breaks will be preserved:</p><blockquote class="SCodeFlow"><p><span class="stt">The margin is 42em.</span><span class="stt">
</span><br/><span class="stt">The border is red.</span><span class="stt">
</span><br/><span class="stt">The padding is 15em.</span><span class="stt">
</span><br/><span class="stt">The border is too.</span></p></blockquote><p>As before, because the source has changed, Pollen refreshes the output file. From the dashboard, you can use the <span class="stt">in</span> and <span class="stt">out</span> links to inspect the source and output.</p><p>This is now a valid HTML page.</p><h5>5.5.3<tt>&nbsp;</tt><a name="(part._.Adding_commands)"></a>Adding commands</h5><p>I mentioned that the preprocessor reads the file and handles any Pollen commands it finds. But our source file doesn&rsquo;t have any commands yet. Let&rsquo;s add some.</p><p>Pollen commands can be embedded in your source file using one of two modes: <span style="font-style: italic">Racket mode</span> or <span style="font-style: italic">text mode</span>. We&rsquo;ll try text mode in a later tutorial. For now, we&rsquo;ll use Racket mode.</p><p>To make a Racket-mode Pollen command, just take any Racket expression and put the lozenge character (<span class="RktInBG"><span class="hspace"></span><span class="RktIn">&#9674;</span><span class="hspace"></span></span>) in front of it. For instance, these are valid Racket expressions:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">(define inner 2)</span></p></td></tr><tr><td><p><span class="stt">(define edge (* inner 4))</span></p></td></tr><tr><td><p><span class="stt">(define color "blue")</span></p></td></tr></table></blockquote><p>And these are the equivalent commands in Pollen:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">&#9674;(define inner 2)</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define edge (* inner 4))</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define color "blue")</span></p></td></tr></table></blockquote><p>How to type a lozenge:
<br/><span style="font-weight: bold">Mac</span>: option + shift + V
<br/><span style="font-weight: bold">Windows</span>: holding down alt, type 9674 on the num pad
<br/><span style="font-weight: bold">Ubuntu</span>: ctrl + shift + U, then 25CA</p><h5>5.5.4<tt>&nbsp;</tt><a name="(part._.Racket_basics__if_you_re_not_familiar_)"></a>Racket basics (if you&rsquo;re not familiar)</h5><p>&ldquo;But how am I supposed to know Racket?&rdquo; You don&rsquo;t. So we&rsquo;ll start now. Here are the five basic rules of Racket:</p><ol><li><p>The core building block of Racket is the <span style="font-style: italic">expression</span>. An expression can be a value (like <span class="RktVal">2</span> or <span class="RktVal">"blue"</span>), a variable (like <span class="stt">edge</span>), or a function call (like <span class="RktPn">(</span><span class="RktSym">*</span><span class="stt"> </span><span class="RktSym">inner</span><span class="stt"> </span><span class="RktVal">4</span><span class="RktPn">)</span>).</p></li><li><p>Every expression is <span style="font-style: italic">evaluated</span> to produce a value.</p></li><li><p>A variable evaluates to whatever value it holds (so <span class="stt">inner</span> would become <span class="RktVal">2</span>). A function call evaluates to its return value (so <span class="RktPn">(</span><span class="RktSym">+</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span> would become <span class="RktVal">2</span>).</p></li><li><p>Function calls go between parentheses. Unlike most languages, the function name comes <span style="font-style: italic">first</span>, followed by its arguments (so it&rsquo;s <span class="RktPn">(</span><span class="RktSym">*</span><span class="stt"> </span><span class="RktSym">inner</span><span class="stt"> </span><span class="RktVal">4</span><span class="RktPn">)</span>, not <span class="RktPn">(</span><span class="RktSym">inner</span><span class="stt"> </span><span class="RktSym">*</span><span class="stt"> </span><span class="RktVal">4</span><span class="RktPn">)</span>). This is called <span style="font-style: italic">prefix notation</span>.</p></li><li><p>Expressions can contain recursively nested expressions. Thus, <span class="RktPn">(</span><span class="RktSym">*</span><span class="stt"> </span><span class="RktSym">inner</span><span class="stt"> </span><span class="RktVal">4</span><span class="RktPn">)</span> could be written <span class="RktPn">(</span><span class="RktSym">*</span><span class="stt"> </span><span class="RktSym">inner</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">+</span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span> or <span class="RktPn">(</span><span class="RktSym">*</span><span class="stt"> </span><span class="RktSym">inner</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">+</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">+</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">+</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span>.</p></li></ol><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Newcomers to Racket often gripe about prefix notation and the parentheses. If you need to get it out of your system, go ahead. Keep in mind, however, that it&rsquo;s not some peculiar affectation, but rather a necessary consequence of rule #1. As you&rsquo;ll come to learn, rule #1 is where the magic happens.</p></blockquote></blockquote></blockquote><p>That should tell you enough to infer what&rsquo;s going on in the Pollen commands above:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">&#9674;(define inner 2)</span></p></td></tr><tr><td><p><span class="stt">&#9674;; create a variable 'inner' that holds the value 2</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define edge (* inner 4))</span></p></td></tr><tr><td><p><span class="stt">&#9674;; create a variable 'edge' that's four times the value of 'inner'</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define color "blue")</span></p></td></tr><tr><td><p><span class="stt">&#9674;; create a variable 'color' that holds the value "blue"</span></p></td></tr></table></blockquote><p>To learn more about Racket syntax, consider a detour through the excellent <a href="http://docs.racket-lang.org/quick/index.html" data-pltdoc="x">Quick: An Introduction to Racket with Pictures</a>.</p><h5>5.5.5<tt>&nbsp;</tt><a name="(part._.Defining_variables_with_commands)"></a>Defining variables with commands</h5><p>Let&rsquo;s use commands to define variables that will hold some values for our page. First, add a <span class="stt">&lt;head&gt;</span> tag to your source file, and three commmands to define three variables:</p><blockquote class="Rfilebox"><p class="Rfiletitle"><span class="Rfilename"><span class="stt">"/path/to/tutorial/poem.html.pp"</span></span></p><blockquote class="Rfilecontent"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt">&lt;!DOCTYPE html&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;html&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;head&gt;</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define inner 2)</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define edge (* inner 4))</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define color "blue")</span></p></td></tr><tr><td><p><span class="stt">&lt;/head&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;body&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;pre&gt;</span></p></td></tr><tr><td><p><span class="stt">The margin is 42em.</span></p></td></tr><tr><td><p><span class="stt">The border is red.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr><tr><td><p><span class="stt">&lt;/pre&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;/body&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;/html&gt;</span></p></td></tr></table></blockquote></blockquote><p>Then look at <a href="http://localhost:8080/poem.html">http://localhost:8080/poem.html</a> again. Does it look the same? Not a trick question &#8212;&#160;it should. If you click the <span class="ssansserif">Out</span> link on the dashboard, you&rsquo;ll see this:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">&lt;!DOCTYPE html&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;html&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;head&gt;</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;</span></p></td></tr><tr><td><p><span class="stt">&lt;/head&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;body&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;pre&gt;</span></p></td></tr><tr><td><p><span class="stt">The margin is 42em.</span></p></td></tr><tr><td><p><span class="stt">The border is red.</span></p></td></tr><tr><td><p><span class="stt">The padding is 15em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr><tr><td><p><span class="stt">&lt;/pre&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;/body&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;/html&gt;</span></p></td></tr></table></blockquote><p>What&rsquo;s happening here? Our <span class="stt">&#9674;(define ...)</span> commands just define variables, so they don&rsquo;t evaluate to any value. Instead, we get blank lines. So far, so good.</p><h5>5.5.6<tt>&nbsp;</tt><a name="(part._.Inserting_values_from_variables)"></a>Inserting values from variables</h5><p>To insert the value of a variable in our file, we use the command <span class="RktInBG"><span class="hspace"></span><span class="RktIn">&#9674;|</span><span class="hspace"></span></span><span style="font-style: italic">variable-name</span><span class="RktInBG"><span class="hspace"></span><span class="RktIn">|</span><span class="hspace"></span></span>. Let&rsquo;s do that now:</p><blockquote class="Rfilebox"><p class="Rfiletitle"><span class="Rfilename"><span class="stt">"/path/to/tutorial/poem.html.pp"</span></span></p><blockquote class="Rfilecontent"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt">&lt;!DOCTYPE html&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;html&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;head&gt;</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define inner 2)</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define edge (* inner 4))</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define color "blue")</span></p></td></tr><tr><td><p><span class="stt">&lt;/head&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;body&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;pre&gt;</span></p></td></tr><tr><td><p><span class="stt">The margin is &#9674;|edge|em.</span></p></td></tr><tr><td><p><span class="stt">The border is &#9674;|color|.</span></p></td></tr><tr><td><p><span class="stt">The padding is &#9674;|inner|em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr><tr><td><p><span class="stt">&lt;/pre&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;/body&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;/html&gt;</span></p></td></tr></table></blockquote></blockquote><p>Here, we&rsquo;re replacing three values in the poem with the variables containing those values &#8212; <span class="stt">&#9674;|edge|</span>, <span class="stt">&#9674;|color|</span>, and <span class="stt">&#9674;|inner|</span>. <a href="http://localhost:8080/poem.html">Reload the file</a> in the project server, and you&rsquo;ll see:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">The margin is 8em.</span></p></td></tr><tr><td><p><span class="stt">The border is blue.</span></p></td></tr><tr><td><p><span class="stt">The padding is 2em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr></table></blockquote><p>Hey, look at that &#8212; the text of the poem changed. Now it even rhymes.</p><p>If you like, in the source file, edit the variable definitions with different values and reload the page in the project server. The page will be rendered afresh with the new values. In particular, if you update <span class="stt">inner</span>, you&rsquo;ll also see <span class="stt">edge</span> change, since its value depends on <span class="stt">inner</span>.</p><h5>5.5.7<tt>&nbsp;</tt><a name="(part._.Inserting_variables_within_.C.S.S)"></a>Inserting variables within CSS</h5><p>Our poem makes claims about the <span class="stt">margin</span>, <span class="stt">border</span>, and <span class="stt">padding</span> of the page that aren&rsquo;t yet true. To fix this, we&rsquo;ll rely on the same basic technique of inserting variables into our HTML file. But instead of putting them in the <span class="stt">&lt;body&gt;</span> of the page, we&rsquo;ll put them in a CSS <span class="stt">&lt;style&gt;</span> tag.</p><p>Update the <span class="stt">&lt;head&gt;</span> section of the page with a new <span class="stt">&lt;style&gt;</span> tag that defines a style for <span class="stt">pre</span> like so, using our variables for the relevant values:</p><blockquote class="Rfilebox"><p class="Rfiletitle"><span class="Rfilename"><span class="stt">"/path/to/tutorial/poem.html.pp"</span></span></p><blockquote class="Rfilecontent"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="stt">#lang pollen</span></p></td></tr><tr><td><p><span class="stt">&lt;!DOCTYPE html&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;html&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;head&gt;</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define inner 2)</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define edge (* inner 4))</span></p></td></tr><tr><td><p><span class="stt">&#9674;(define color "blue")</span></p></td></tr><tr><td><p><span class="stt">&lt;style type="text/css"&gt;</span></p></td></tr><tr><td><p><span class="stt">pre {</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">margin: &#9674;|edge|em;</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">border: &#9674;|inner|em solid &#9674;|color|;</span></p></td></tr><tr><td><p><span class="stt"></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="stt">padding: &#9674;|inner|em;</span></p></td></tr><tr><td><p><span class="stt">}</span></p></td></tr><tr><td><p><span class="stt">&lt;/style&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;/head&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;body&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;pre&gt;</span></p></td></tr><tr><td><p><span class="stt">The margin is &#9674;|edge|em.</span></p></td></tr><tr><td><p><span class="stt">The border is &#9674;|color|.</span></p></td></tr><tr><td><p><span class="stt">The padding is &#9674;|inner|em.</span></p></td></tr><tr><td><p><span class="stt">The border is too.</span></p></td></tr><tr><td><p><span class="stt">&lt;/pre&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;/body&gt;</span></p></td></tr><tr><td><p><span class="stt">&lt;/html&gt;</span></p></td></tr></table></blockquote></blockquote><p>Notice that we&rsquo;re using the same <span class="RktInBG"><span class="hspace"></span><span class="RktIn">&#9674;|</span><span class="hspace"></span></span><span style="font-style: italic">variable-name</span><span class="RktInBG"><span class="hspace"></span><span class="RktIn">|</span><span class="hspace"></span></span> pattern as before to insert the variable values.</p><p>What do we expect to see? We expect that the <span class="stt">padding</span> and <span class="stt">border</span> will be 2em wide, because <span class="stt">inner</span> is 2. We expect the <span class="stt">margin</span> to be 8em, because it&rsquo;s equal to <span class="stt">edge</span>, which is <span class="stt">inner</span> multiplied by 4. And we expect the color of the border to be <span class="RktVal">"blue"</span>, because that&rsquo;s the value of the variable <span class="stt">color</span>.</p><p>And indeed, when you <a href="http://localhost:8080/poem.html">reload the file</a> in the project server, you&rsquo;ll see exactly that:</p><p><img src="result.png" alt="" width="655" height="331"/></p><p>As before, if you edit the values of the variables in the source file and reload in the project server, you&rsquo;ll see both the text and the layout change.</p><h4>5.6<tt>&nbsp;</tt><a name="(part._.First_tutorial_complete)"></a>First tutorial complete</h4><p>This was a sneaky tutorial. The HTML page we made was very simple, but in building it, we covered many important points about how Pollen works.</p><p>Feel free to go back and experiment with what you&rsquo;ve learned. The next tutorial will assume that you&rsquo;re comfortable with all the material here.</p><div class="navsetbottom"><span class="navleft"><div class="nosearchform"></div>&nbsp;&nbsp;</span><span class="navright">&nbsp;&nbsp;<a href="big-picture.html" title="backward to &quot;4 The big picture&quot;" data-pltdoc="x">&larr; prev</a>&nbsp;&nbsp;<a href="index.html" title="up to &quot;Pollen: the book is a program&quot;" data-pltdoc="x">up</a>&nbsp;&nbsp;<a href="second-tutorial.html" title="forward to &quot;6 Second tutorial&quot;" data-pltdoc="x">next &rarr;</a></span>&nbsp;</div></div></div><div id="contextindicator">&nbsp;</div></body></html>