Jekyll2019-02-14T13:53:58+01:00/Tim BrandesA personal collection of essays and technical programming guides. I co-run my software company Zinkler & Brandes and coach young soccer goalkeepers in Hannover, Germany.Amateurs demand – Professionals require.2019-02-14T13:37:00+01:002019-02-14T13:37:00+01:00/essay/2019/02/14/amateurs-demand-professionals-require<p>Sometimes it’s me who demands, sometimes it’s a client or a contractor. We demand a new feature to be shipped on a specific date, a contract to be written in a certain way or a family member to perform a task for us. I’ve picked up the saying “amateurs demand – professionals require” some years ago and I often refer to it when I encounter a personal or business confrontation. Demanding instantly introduces hierachy, like the king who demands of his subordinates or the principal of his agent.</p>
<p>Requiring on the other hand is an invitation to listen and understand the underlying needs. It’s the first step to build a partnership, to help each other achieve a goal – rather than builing a wall that seperates us from each other. Demanding only touches the <em>what</em> and sometimes the <em>how</em>. But even in total disagreement, requiring invites to a mutual discussion about the <em>why</em> and helps finding a peaceful solution.</p>Sometimes it’s me who demands, sometimes it’s a client or a contractor. We demand a new feature to be shipped on a specific date, a contract to be written in a certain way or a family member to perform a task for us. I’ve picked up the saying “amateurs demand – professionals require” some years ago and I often refer to it when I encounter a personal or business confrontation. Demanding instantly introduces hierachy, like the king who demands of his subordinates or the principal of his agent.Debugging missing remote clients in Uchiwa with Sensu, RabbitMQ and Redis2015-11-25T10:20:00+01:002015-11-25T10:20:00+01:00/guide/2015/11/25/debugging-missing-remote-clients-in-uchiwa-with-sensu-rabbitmq-and-redis<h2 id="the-10-hours-bug-hunt-because-of-a-missing-comma-aka-understand-the-system-to-debug-your-configuration">The 10 hours bug hunt because of a missing comma aka understand the system to debug your configuration</h2>
<p>It all happend once my sensu-server was all set up and functioning well. The local sensu-client shows up in a dashboard and I moved on to configure the first remote client. So I’ve closely followed (in retrospect multiple times) the documentation on how to install and configure the sensu-client. I’ve self-signed the SSL certificates on the sensu-server, distributed the client.key and client.pem files to the server and even managed to install the client directly with the <a href="https://github.com/sensu/sensu-chef">sensu-chef Cookbook</a>. Then, I restarted the client and looked at the Uchiwa Dashboard on the server: nothing except my local client. I’ve restarted all services on the server like api, server, uchiwa in case I had miss-interpreted how Sensu works and which philosophy it follows. Unfurtunately to the effect of: nothing. The remote just wouldn’t show up. So searching the Internet began and with it some suggestions which log files to consult for help.</p>
<blockquote>
<a href="/assets/2015-11-sensu.png"><img src="/assets/2015-11-sensu.png" /></a>
</blockquote>
<h3 id="make-sure-ssl-is-setup-correctly">Make sure SSL is setup correctly</h3>
<p>Since all my remote clients should talk to the sensu master server via SSL, I wanted to make sure this SSL connection with self-signed certs would work as I intented. It did not, instead, I was getting TLS handshake failures all over the RabbitMQ logs. By the way, each sensu-client has a config hash that specifies how it talks to RabbitMQ on the sensu master server. The remote client will talk directly to RabbitMQ, so this is probably a good first place to look for failures when a remote client doesn’t show up in Uchiwa. On the client, I was checking the sensu-client logs unter <em>/var/log/sensu/sensu-client.log</em>. It said something like <em>reconnecting to transport</em> and just hang there. The RabbitMQ logs on the server under <em>/var/log/rabbitmq/rabbit@sensu.log</em> displayed the TLS error.</p>
<p>And this is how it looked like on the remote client</p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="p">{</span><span class="s2">"timestamp"</span><span class="ss">:"2015-11-23T11:17:04.318751+0100"</span><span class="p">,</span><span class="s2">"level"</span><span class="ss">:"warn"</span><span class="p">,</span><span class="s2">"message"</span><span class="ss">:"loading config file"</span><span class="p">,</span><span class="s2">"file"</span><span class="ss">:"/etc/sensu/config.json"</span><span class="p">}</span>
<span class="p">{</span><span class="s2">"timestamp"</span><span class="ss">:"2015-11-23T11:17:04.318847+0100"</span><span class="p">,</span><span class="s2">"level"</span><span class="ss">:"warn"</span><span class="p">,</span><span class="s2">"message"</span><span class="ss">:"loading config files from directory"</span><span class="p">,</span><span class="s2">"directory"</span><span class="ss">:"/etc/sensu/conf.d"</span><span class="p">}</span>
<span class="p">{</span><span class="s2">"timestamp"</span><span class="ss">:"2015-11-23T11:17:04.321103+0100"</span><span class="p">,</span><span class="s2">"level"</span><span class="ss">:"warn"</span><span class="p">,</span><span class="s2">"message"</span><span class="ss">:"loading extension files from directory"</span><span class="p">,</span><span class="s2">"directory"</span><span class="ss">:"/etc/sensu/extensions"</span><span class="p">}</span>
<span class="p">{</span><span class="s2">"timestamp"</span><span class="ss">:"2015-11-23T11:17:04.407738+0100"</span><span class="p">,</span><span class="s2">"level"</span><span class="ss">:"warn"</span><span class="p">,</span><span class="s2">"message"</span><span class="ss">:"reconnecting to transport"</span><span class="p">}</span>
<span class="p">{</span><span class="s2">"timestamp"</span><span class="ss">:"2015-11-23T11:22:14.426687+0100"</span><span class="p">,</span><span class="s2">"level"</span><span class="ss">:"error"</span><span class="p">,</span><span class="s2">"message"</span><span class="ss">:"[amqp] Detected TCP connection failure"</span><span class="p">}</span></code></pre></figure>
<p>Here is the RabbitMQ Server log</p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="o">=</span><span class="no">INFO</span> <span class="no">REPORT</span><span class="o">====</span> <span class="mi">23</span><span class="o">-</span><span class="no">Nov</span><span class="o">-</span><span class="mi">2015</span><span class="o">::</span><span class="mi">11</span><span class="p">:</span><span class="mi">22</span><span class="p">:</span><span class="mi">33</span> <span class="o">===</span>
<span class="n">accepting</span> <span class="no">AMQP</span> <span class="n">connection</span> <span class="o"><</span><span class="mf">0.248</span><span class="o">.</span><span class="mi">0</span><span class="o">></span> <span class="p">(</span><span class="no">SENSU_REMOTE_CLIENT_IP</span><span class="p">:</span><span class="mi">33954</span> <span class="o">-></span> <span class="no">SENSU_SERVER_IP</span><span class="p">:</span><span class="mi">5671</span><span class="p">)</span>
<span class="o">=</span><span class="no">ERROR</span> <span class="no">REPORT</span><span class="o">====</span> <span class="mi">23</span><span class="o">-</span><span class="no">Nov</span><span class="o">-</span><span class="mi">2015</span><span class="o">::</span><span class="mi">11</span><span class="p">:</span><span class="mi">22</span><span class="p">:</span><span class="mi">33</span> <span class="o">===</span>
<span class="no">Error</span> <span class="n">on</span> <span class="no">AMQP</span> <span class="n">connection</span> <span class="o"><</span><span class="mf">0.244</span><span class="o">.</span><span class="mi">0</span><span class="o">></span><span class="p">:</span>
<span class="p">{</span><span class="n">ssl_upgrade_error</span><span class="p">,{</span><span class="n">tls_alert</span><span class="p">,</span><span class="s2">"record overflow"</span><span class="p">}}</span></code></pre></figure>
<p>So instead of cheating by telling RabbitMQ to not validate my certs, I’ve set them up from scratch again. This time it worked. So it was probably a mistake on my side where I falsly copied some files or forgot a step. It looked like this now:</p>
<p>Sensu remote client log</p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="p">{</span><span class="s2">"timestamp"</span><span class="ss">:"2015-11-23T13:47:09.656492+0100"</span><span class="p">,</span><span class="s2">"level"</span><span class="ss">:"info"</span><span class="p">,</span><span class="s2">"message"</span><span class="ss">:"reconnected to transport"</span><span class="p">}</span>
<span class="p">{</span><span class="s2">"timestamp"</span><span class="ss">:"2015-11-23T13:47:10.657438+0100"</span><span class="p">,</span><span class="s2">"level"</span><span class="ss">:"debug"</span><span class="p">,</span><span class="s2">"message"</span><span class="ss">:"scheduling keepalives"</span><span class="p">}</span>
<span class="p">{</span><span class="s2">"timestamp"</span><span class="ss">:"2015-11-23T13:47:10.657671+0100"</span><span class="p">,</span><span class="s2">"level"</span><span class="ss">:"debug"</span><span class="p">,</span><span class="s2">"message"</span><span class="ss">:"publishing keepalive"</span><span class="p">,</span><span class="s2">"payload"</span><span class="p">:{</span><span class="s2">"name"</span><span class="ss">:"errbit"</span><span class="p">,</span><span class="s2">"address"</span><span class="ss">:"localhost"</span><span class="p">,</span><span class="s2">"subscriptions"</span><span class="p">:[</span><span class="s2">"ALL"</span><span class="p">],</span><span class="s2">"version"</span><span class="ss">:"0.20.6"</span><span class="p">,</span><span class="s2">"timestamp"</span><span class="p">:</span><span class="mi">1448282830</span><span class="p">}}</span>
<span class="p">{</span><span class="s2">"timestamp"</span><span class="ss">:"2015-11-23T13:47:10.658116+0100"</span><span class="p">,</span><span class="s2">"level"</span><span class="ss">:"debug"</span><span class="p">,</span><span class="s2">"message"</span><span class="ss">:"subscribing to client subscriptions"</span><span class="p">}</span>
<span class="p">{</span><span class="s2">"timestamp"</span><span class="ss">:"2015-11-23T13:47:10.658210+0100"</span><span class="p">,</span><span class="s2">"level"</span><span class="ss">:"debug"</span><span class="p">,</span><span class="s2">"message"</span><span class="ss">:"subscribing to a subscription"</span><span class="p">,</span><span class="s2">"subscription"</span><span class="ss">:"ALL"</span><span class="p">}</span>
<span class="p">{</span><span class="s2">"timestamp"</span><span class="ss">:"2015-11-23T13:47:10.658602+0100"</span><span class="p">,</span><span class="s2">"level"</span><span class="ss">:"debug"</span><span class="p">,</span><span class="s2">"message"</span><span class="ss">:"scheduling standalone checks"</span><span class="p">}</span>
<span class="p">{</span><span class="s2">"timestamp"</span><span class="ss">:"2015-11-23T13:47:30.658960+0100"</span><span class="p">,</span><span class="s2">"level"</span><span class="ss">:"debug"</span><span class="p">,</span><span class="s2">"message"</span><span class="ss">:"publishing keepalive"</span><span class="p">,</span><span class="s2">"payload"</span><span class="p">:{</span><span class="s2">"name"</span><span class="ss">:"errbit"</span><span class="p">,</span><span class="s2">"address"</span><span class="ss">:"localhost"</span><span class="p">,</span><span class="s2">"subscriptions"</span><span class="p">:[</span><span class="s2">"ALL"</span><span class="p">],</span><span class="s2">"version"</span><span class="ss">:"0.20.6"</span><span class="p">,</span><span class="s2">"timestamp"</span><span class="p">:</span><span class="mi">1448282850</span><span class="p">}}</span></code></pre></figure>
<p>RabbitMQ Server log</p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="o">=</span><span class="no">INFO</span> <span class="no">REPORT</span><span class="o">====</span> <span class="mi">23</span><span class="o">-</span><span class="no">Nov</span><span class="o">-</span><span class="mi">2015</span><span class="o">::</span><span class="mi">13</span><span class="p">:</span><span class="mi">47</span><span class="p">:</span><span class="mi">08</span> <span class="o">===</span>
<span class="n">accepting</span> <span class="no">AMQP</span> <span class="n">connection</span> <span class="o"><</span><span class="mf">0.301</span><span class="o">.</span><span class="mi">0</span><span class="o">></span> <span class="p">(</span><span class="no">SENSU_REMOTE_CLIENT_IP</span><span class="p">:</span><span class="mi">34272</span> <span class="o">-></span> <span class="no">SENSU_MASTER_SERVER_IP</span><span class="p">:</span><span class="mi">5671</span><span class="p">)</span></code></pre></figure>
<h2 id="however-the-sensu-remote-client-was-still-not-visible-in-uchiwa">However, the sensu remote client was still not visible in Uchiwa</h2>
<p>So this is where things seemed so strange to me that after I’ve spent another 4 hours looking for clues on what was wrong with my setup, I’ve decided to check in to the #sensu IRC channel. <em>rob_</em> was kind and pointed me towards redis and run “redis-cli keys ‘*’” on the sensu server to check if redis was saving anything for that client. It did not, the name of name remote sensu client wasn’t in that list. Since a remote client talks to the Sensu API which again talks to Redis-Server (thank you <em>warmfusion</em> for helping get the connections right on IRC), something was probably wrong on the transport between the remote client and the sensu server. But this was OK, however, still no remote client in sensu. I’ve decided to head over to the sensu master server again. Then, in the sensu-server log it hit me:</p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="p">{</span><span class="s2">"timestamp"</span><span class="ss">:"2015-11-23T17:30:42.501290+0100"</span><span class="p">,</span><span class="s2">"level"</span><span class="ss">:"warn"</span><span class="p">,</span><span class="s2">"message"</span><span class="ss">:"config file must be valid json"</span><span class="p">,</span><span class="s2">"file"</span><span class="ss">:"/etc/sensu/config.json"</span><span class="p">,</span><span class="s2">"error"</span><span class="ss">:"parse error: after key and value, inside map, I expect ',' or '}'</span><span class="se">\n</span><span class="ss"> , </span><span class="se">\"</span><span class="ss">vhost</span><span class="se">\"</span><span class="ss">: </span><span class="se">\"</span><span class="ss">/sensu</span><span class="se">\"</span><span class="ss"> </span><span class="se">\"</span><span class="ss">ssl</span><span class="se">\"</span><span class="ss">: { </span><span class="se">\"</span><span class="ss">cert_chain_file</span><span class="se">\"\n</span><span class="ss"> (right here) ------^</span><span class="se">\n</span><span class="ss">"</span><span class="p">}</span></code></pre></figure>
<p>Checking the <em>/etc/sensu/config.json</em>, I’ve added the missing comma, restarted the server via <em>service sensu-server restart</em> and everything was well and good. Still, I can’t believe why the system didn’t warn me about it, I’ve used the restarting service command a dozen times at least that day. So my takeaway from this is: if anything seems strange, check ALL the log files from sensu, redis, rabbitmq and the sensu-client first and don’t from hypothesis about was might be wrong when the fault isn’t isolated well enough.</p>
<p>The resulting diagramm shows not only the interplay of the sensu master server and the sensu remote clients but also the integration of configuration management (chef/puppet) and how to use the sensu community plugins in a DRY-way. I’ll might follow up with another post on that topic soon.</p>The 10 hours bug hunt because of a missing comma aka understand the system to debug your configurationOptimize BibDesk, Multimarkdown and Scrivener for a nice scientific bibliography and citation workflow2014-04-08T08:00:00+02:002014-04-08T08:00:00+02:00/guide/2014/04/08/optimize-bibdesk-multimarkdown-and-scrivener-for-a-nice-scientific-bibliography-and-citation-workflow<p>To me, writing academic papers directly in LaTeX feels like I develop a software program. I have a hard time bringing my ideas to understandable sentences when I see so many brackets and backslashes. Multimarkdown (MMD) is a good combination of both worlds, content can be written without much syntactical noise and there is still structure. With the help of Scrivener, the workflow and organization of the MMD files becomes comfortable. Writing academic content, there is actually no excuse not to use a bibliography tool. Personally, I like BibDesk. It is open source, has a clean user interface and just enough options to categorize the material without being to overloaded. However, BibDesk was designed to work well with LaTeX. I tweaked BibDesk to fit into the MMD workflow.</p>
<h2 id="scientific-multimarkdown-citations-to-latex">Scientific Multimarkdown citations to LaTeX</h2>
<p>The <a href="http://fletcher.github.io/peg-multimarkdown/mmd-manual.pdf">official MMD documentation</a> by Fletcher Penny is a good source for the conversion rules and possibilities of MMD cite keys to LaTeX citation rules. I’ll show the application his examples here. Since I mostly write within the psychological rules, the final output after the LaTeX conversion is according to the “apacite” LaTeX package (see my <a href="http://timbrandes.com/blog/2012/02/28/howto-write-your-thesis-in-latex-using-scrivener-2-multimarkdown-3-and-bibdesk/">previous Scrivener article</a> for further information). Here is how I want the input and output to convert to:</p>
<blockquote>
<p>[#webster_2002a] —> (Webster 2002)</p>
</blockquote>
<blockquote>
<p>[p. 49][#webster_2002a] —> (Webster, 2002, p. 46)</p>
</blockquote>
<blockquote>
<p>[take a look at\]\[][#webster_2002a] —> (take a look at Webster, 2002)</p>
</blockquote>
<blockquote>
<p>[take a look at\]\[p. 49][#webster_2002a] —> (take a look at Webster, 2002, p. 46)</p>
</blockquote>
<blockquote>
<p>[#webster_2002a, smith_1999a] —> (Webster, 2002; Smith 1999)</p>
</blockquote>
<p>By adding a semicolon to before a closing bracket, we can create an inline citation:</p>
<blockquote>
<p>[p. 49][#webster_2002a;] —> Webster (2002, p. 46)</p>
</blockquote>
<h2 id="auto-generate-bibdesk-cite-keys">Auto-generate BibDesk cite keys</h2>
<p>Every time you add a new publication to your BibDesk collection, you are prompted to fill in the cite key yourself. While this is usually a quick thing, it often leads to inconsistencies with the naming. Did you know BibDesk can auto-generate that key based on attributes you fill in, like author and year?
Enter <em>Preferences > Cite Key > and Check ‘Autogenerate the cite key when enough fields are supplied’</em>. I have clicked on advanced and set the <em>Preset Format</em> to <em>Custom</em> and I use this Format String: <em>%a2_%Y%u1</em>. Furthermore I checked the option <em>Generate lowercase cite keys</em>. My cite keys will have the first to authors, an underscore followed by the year and an indicator from a-z. A publication from McCracken and Maxwell from 2004 would result in a cite key like:</p>
<blockquote>
<p>mccrackenmaxwell_2004a</p>
</blockquote>
<blockquote>
<p><a href="/assets/2014-04-bibdesk3.jpg"><img src="/assets/2014-04-bibdesk3_p.jpg" /></a></p>
</blockquote>
<h2 id="copy-mmd-cite-keys-directly-from-bibdesk-to-scrivener">Copy MMD cite keys directly from BibDesk to Scrivener</h2>
<p>Now each and every time you cite something in your Scrivener, ie. MMD file, you would have to look up the corresponding cite key in BibDesk, open a square bracket, add a hash symbol and the type in the key. This demotivates me from citing a lot, which must be improved. I’d like to use <em>Alt+CMD+C</em> to copy the MMD cite key and just paste it into my MMD file with <em>CMD+V</em>. The output should look like this:</p>
<blockquote>
<p>[#mccrackenmaxwell_2004a]</p>
</blockquote>
<p>BibDesk has a neat feature called Templates. Here is how we will be able to <em>Alt+CMD+C</em> the cite key in MMD format:</p>
<ol>
<li>Define a custom template</li>
<li>Add this template to BibDesk</li>
<li>Create the <em>Alt+CMD+C</em> shortcut</li>
</ol>
<h3 id="1-define-a-custom-template">1. Define a custom template</h3>
<p>Open your finder, click <em>Shift+CMD+G</em> (in Menu: <em>Go > Go to Folder</em>) and go there:</p>
<blockquote>
<p>~/Library/Application Support/BibDesk/Templates</p>
</blockquote>
<p>Add a new file there, you can name it “mmdCiteKey.txt” and enter this content:</p>
<blockquote>
<p>[#<$publications.citeKey.@componentsJoinedByComma/>]</p>
</blockquote>
<h3 id="2-add-this-template-to-bibdesk">2. Add this template to BibDesk</h3>
<p>In BibDesk, go to <em>Preferences > Templates</em>. Click the small <em>+</em> Button on the bottom right and double click the red words to add a new file. Choose your new “mmdCiteKey.txt”. Your result should look like this:</p>
<blockquote>
<p><a href="/assets/2014-04-bibdesk2.jpg"><img src="/assets/2014-04-bibdesk2_p.jpg" /></a></p>
</blockquote>
<h3 id="3-create-the-altcmdc-shortcut">3. Create the <em>Alt+CMD+C</em> shortcut</h3>
<p>By now, from within BibDesk, you can just go to <em>Edit > Copy As > Template > mmdCiteKey</em> or you right click an article and choose <em>Copy Using Template > mmdCiteKey</em>. If this is fine for you and you use your mouse more often than you use your keyboard, go with the right click option. Everyone else who wants to be really fast, follow me one more step. Go to you Mac System Preferences (click the Apple on the top left and then Preferences). Go to <em>Keyboard > Shortcuts</em> and pick <em>App Shortcuts</em> on the bottom left of the list. Click the <em>+</em> button and find the BibDesk application. For the menu title enter</p>
<blockquote>
<p><em>Edit->Copy As->Template->mmdCiteKey</em></p>
</blockquote>
<p>and for the Keyboard Shortcut press <em>ALT+CMD+C</em>.</p>
<blockquote>
<p><a href="/assets/2014-04-bibdesk1.jpg"><img src="/assets/2014-04-bibdesk1_p.jpg" /></a></p>
</blockquote>
<p>Now go to BibDesk, click on an article and press <em>ALT+CMD+C</em>. Paste it anywhere with CMD+V and enjoy your output:</p>
<blockquote>
<p>[#mccrackenmaxwell_2004a].</p>
</blockquote>
<h3 id="bonus-tip-1">Bonus Tip 1</h3>
<p>You can even select multiple authors, it will automatically insert all of them like:</p>
<blockquote>
<p>[#mccrackenmaxwell_2004a, smith_1999a]</p>
</blockquote>
<h3 id="bonus-tip-2">Bonus Tip 2</h3>
<p>I’ve built multiple templates for all kind of purposes: inline citations, append, prepend, everything that improves your workflow is worth it. Just go the folder with the templates and create new files.</p>
<blockquote>
<p><a href="/assets/2014-04-bibdesk4.jpg"><img src="/assets/2014-04-bibdesk4_p.jpg" /></a></p>
</blockquote>
<p>Here is how my new custom templates look like:</p>
<blockquote>
<p>mmdCiteKey_append.txt:
<br />
[S. ][#<$publications.citeKey.@componentsJoinedByComma/>]</p>
</blockquote>
<blockquote>
<p>mmdCiteKey_inline_append.txt:
<br />
[S. ][#<$publications.citeKey.@componentsJoinedByComma/>;]</p>
</blockquote>
<blockquote>
<p>mmdCiteKey_prepend.txt:
<br />
[vgl.][][#<$publications.citeKey.@componentsJoinedByComma/>]</p>
</blockquote>
<blockquote>
<p>mmdCiteKey.txt:
<br />
[#<$publications.citeKey.@componentsJoinedByComma/>]</p>
</blockquote>To me, writing academic papers directly in LaTeX feels like I develop a software program. I have a hard time bringing my ideas to understandable sentences when I see so many brackets and backslashes. Multimarkdown (MMD) is a good combination of both worlds, content can be written without much syntactical noise and there is still structure. With the help of Scrivener, the workflow and organization of the MMD files becomes comfortable. Writing academic content, there is actually no excuse not to use a bibliography tool. Personally, I like BibDesk. It is open source, has a clean user interface and just enough options to categorize the material without being to overloaded. However, BibDesk was designed to work well with LaTeX. I tweaked BibDesk to fit into the MMD workflow.How to write your Thesis in LaTeX with Scrivener 2, MultiMarkdown 3 and BibDesk2012-02-28T23:50:00+01:002012-02-28T23:50:00+01:00/guide/2012/02/28/howto-write-your-thesis-in-latex-using-scrivener-2-multimarkdown-3-and-bibdesk<h2 id="the-pros-and-cons-of-latex">The pros and cons of LaTeX</h2>
<p>When you are dealing with rather large chunks of text that should become a thesis, a manual or whatnot, having to deal with MS Word or Pages might not be the best experience. During the writing process, I often find myself dealing with all kinds of formatting related tasks. Not only does this distract me from writing good content, it also leaves me with just one long document. Keeping track of all the chapters and their relations to each other can be a real pain when you have more than a couple of thousand words. At this point, <a href="http://www.literatureandlatte.com/scrivener.php">Scrivener</a> comes in as a great writing tool. Basically, Scrivener lets you organize your chapters and sub-texts in a tree-like project drawer. <a href="http://www.jasonshafer.net/?p=177">Jason Shafer</a> has a good post about the <em>why</em>.</p>
<p>Writing LaTeX directly can be like writing source code and for most people it might not be the optimal environment for creating texts. For <em>outputting</em> and <em>typesetting</em> however, LaTeX is super cool. Not only will you have sugar-sweet PDF, you can manage and change your whole citation and bibliohraphy style literally with one command. So, before we look into the relationship between Scrivener and LaTeX, let’s first check the requirements for an academic writing workflow.</p>
<p>Here is how the end result should look like:</p>
<blockquote>
<a href="/assets/2012-02-thesis08.jpg"><img src="/assets/2012-02-thesis08_p.jpg" /></a>
<a href="/assets/2012-02-thesis09.jpg"><img src="/assets/2012-02-thesis09_p.jpg" /></a>
<a href="/assets/2012-02-thesis10.jpg"><img src="/assets/2012-02-thesis10_p.jpg" /></a>
</blockquote>
<p>All files used here can be <a href="https://github.com/tibra/ScrivenerToLaTeX">found on GitHub</a>.</p>
<h2 id="citations">Citations</h2>
<p><em>Don’t Repeat Yourself</em> (DRY) is a common practice among programmers. The basic idea is that having duplicated information about the same thing will mess things up at some point. When writing a thesis, you might have experienced this with citations. In a Word document, you would do something like this:</p>
<blockquote>
Mayer & Moreno (2002) argue that computer-based learning environments can help improving student understanding.
</blockquote>
<p>Then in your bibliography index you add</p>
<blockquote>
Mayer, R. E. & Moreno, R. (2002). Aids to computer-based multimedia learning. Learning and Instruction (12), 107-119.
</blockquote>
<p>At some point you decide to throw out that top sentence. But in your bibliography index you will still find the entry for Mayer and Moreno. And what will happen when you decide to change your citation style from APA to Harvard or something else? There is no technical relationship between the two and you will have to fix everything by search and replace or by hand.</p>
<h3 id="introducing-bibdesk-and-citekeys">Introducing BibDesk and Citekeys</h3>
<p><a href="http://bibdesk.sourceforge.net/">BibDesk</a> is an open-source bibliography manager for the Mac. It has a clean and simple interface. Every book, article or website that is important for your thesis, you put into BibDesk with a new entry and a unique <em>citekey</em>. My citekeys look like this:</p>
<blockquote>
Mayer_2002
<br />
Jonassen_2004b
</blockquote>
<blockquote>
<a href="/assets/2012-02-thesis01.jpg" class="lightbox"><img src="/assets/2012-02-thesis01_p.jpg" /></a>
</blockquote>
<h3 id="using-citekeys-in-scrivener">Using citekeys in Scrivener</h3>
<p>In Scrivener we can write in <a href="http://fletcherpenney.net/multimarkdown/">MultiMarkdown (MMD)</a> to link our citations to an unqiue entry in our BibDesk <em>*.bib</em> file.</p>
<blockquote>
[#Mayer_2002;] argue that computer-based learning environments can help improving student understanding.
</blockquote>
<p>This will later be formatted nicely to match a certain style like APA, Harvard & co. You can use your citekey as shown above by putting it into square brackets after a hash symbol like <em>[#mycitekey]</em>. If you use an inline citation, in the current version 3.2 of MMD, you have to put a semicolon behind your key inside the brackets like <em>[#mycitekey;]</em>. Here are some more examples:</p>
<blockquote>
Computer-based learning environments can help improving student understanding[#Mayer_2002].
[P. 108][#Mayer_2002;] notes: "Computer-based multimedia learning environments — consisting of pictures (such as animation) and words (such as narration) — offer a potentially powerful venue for improving student understanding."
"Computer-based multimedia learning environments — consisting of pictures (such as animation) and words (such as narration) — offer a potentially powerful venue for improving student understanding"[P. 108][#Mayer_2002].
</blockquote>
<p><em>Update, 08.04.2014:</em> I’ve written a <a href="http://timbrandes.com/blog/2014/04/08/optimize-bibdesk-multimarkdown-and-scrivener-for-a-nice-scientific-bibliography-and-citation-workflow/">follow up article on multimarkdown citations and optimizing the BibDesk workflow</a>.</p>
<p>For more information about MMD 3 and citations, see <a href="http://fletcher.github.com/peg-multimarkdown/">the parapraph about Citations in the MMD Guide</a>.</p>
<p><em>Please note that you’ll have to install MMD 3 *and* its support files. By default, Scrivener 2.2 will use MMD 2 which won’t support the above syntax. It took me four hours to discover that. Basically, you will have to download and install MultiMarkdown-Support-Mac-….pkg.zip into your users ~/Library/Application Support/MultiMarkdown/ directory.</em> Thanks to Neil Ernst who explains <a href="http://neilernst.net/2011/07/27/writing-complex-latex-documents-with-scrivener-2-1-and-multimarkdown-3/">in more detail in his blog post</a>.</p>
<h2 id="organize-your-document-in-scrivener">Organize your document in Scrivener</h2>
<p>Putting your document together in Scrivener is very straightforward. Begin with a new blank project. I like organizing my chapters with folders as first level headers in which I put second and third level chapters.</p>
<p>Here is a sample that shows my structure for a sample document:</p>
<blockquote>
<a href="/assets/2012-02-thesis02.jpg" class="lightbox"><img src="/assets/2012-02-thesis02_p.jpg" /></a>
</blockquote>
<h3 id="integrate-bibdesk">Integrate BibDesk</h3>
<p>In Scrivener settings (<em>Scrivener->Settings->General Tab</em>) under “Bibliography Manager” pick the BibDesk Application to tell Scrivener what to open when you hit your bibliography shortcut CMD+Y within Scrivener.</p>
<h3 id="use-citations">Use Citations</h3>
<p>Now let’s go and make a reference to a citekey. I added the article to BibDesk and gave it the citekey “Mayer_2002”. Now in Scrivener I simply embed it into my text like the following. Make sure to save your BibDesk file (best place is the same directory as your Scrivener file).</p>
<blockquote>
To achieve this, [#Mayer_2002;] mentions it would be necessary to have uniform grammar, pronunciation and more common words.
</blockquote>
<blockquote>
<a href="/assets/2012-02-thesis03.jpg" class="lightbox"><img src="/assets/2012-02-thesis03_p.jpg" /></a>
<a href="/assets/2012-02-thesis04.jpg" class="lightbox"><img src="/assets/2012-02-thesis04_p.jpg" /></a>
</blockquote>
<h2 id="compile-the-multimarkdown-into-latex">Compile the MultiMarkdown into LaTeX</h2>
<p>At the moment, all we have is a Scrivener file with some MMD flavoured syntax. To generate a PDF from a LaTeX file we first have to generate a LaTeX file. This process is called <em>compiling</em>. In Scrivener, head over to <em>File->Compile…</em> (ALT+CMD+E). Change “Compile For: Print” at the bottom to “Compile For: MultiMarkdown -> LaTeX”. Under Formatting, check the “Title” checkboxes for every level if you want all to be part of your document (see second screenshot). Now comes the part every Scrivener to LaTeX tutorial I found was outdated. Before Scrivener 2, the Meta-Data settings were in some settings menu, now they are in the Compile window under “Meta-Data”. Meta-Data is important because it will include commands into the LaTeX file that gets saved. Scrivener will only output the plain text (in a structured way for LaTeX) but not any specific information about your thesis like your citation style or title page. Add the following Meta-Data key-value pairs as shown in the third screenshot like this:</p>
<p><em>Note: make sure you have the exact order and spelling! latex-input has to be at the very bottom!</em></p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="no">Key</span> <span class="no">Value</span>
<span class="no">Base</span> <span class="no">Header</span> <span class="no">Level</span> <span class="mi">2</span>
<span class="no">BibTeX</span> <span class="n">literature</span><span class="p">.</span><span class="nf">bib</span> <span class="p">(</span><span class="n">or</span> <span class="n">what</span> <span class="n">your</span> <span class="n">files</span> <span class="nb">name</span> <span class="n">is</span><span class="p">)</span>
<span class="n">latex</span> <span class="n">footer</span> <span class="n">my</span><span class="o">-</span><span class="n">thesis</span><span class="o">-</span><span class="n">footer</span>
<span class="no">Bibliostyle</span> <span class="n">apacite</span> <span class="p">(</span><span class="n">or</span> <span class="n">plain</span> <span class="n">or</span> <span class="n">harvard</span> <span class="n">or</span> <span class="n">sth</span><span class="p">.</span> <span class="nf">else</span><span class="p">)</span>
<span class="no">Author</span> <span class="no">Tim</span> <span class="no">Brandes</span>
<span class="no">Quotes</span> <span class="n">language</span> <span class="n">german</span> <span class="p">(</span><span class="n">or</span> <span class="n">something</span> <span class="k">else</span><span class="p">)</span>
<span class="n">latex</span> <span class="n">input</span> <span class="n">my</span><span class="o">-</span><span class="n">thesis</span><span class="o">-</span><span class="n">input</span></code></pre></figure>
<p>So here is the explanation for the values. Base Header Level will tell LaTeX how you want your folder-file structure from Scrivener to be translated into chapters. Play around with 1, 2 and 3 and compare results. BibTeX (note spelling) references your literature.bib (or your naming of it) file. latex footer is a file called my-thesis-footer.tex we create and put into the same directory. This file includes everything that is at the very bottom of your latex document like your bibliography index. Bibliostyle can also be managed later in the my-thesis-input.tex file but we do it here for convenience. For more options, see <a href="http://amath.colorado.edu/documentation/LaTeX/reference/faq/bibstyles.pdf">this bibstyles.pdf file</a>. Author and Quotes language should be clear and latex-input will be the document that we will create in a minute called my-thesis-input.tex which will include our <a href="http://www.artofproblemsolving.com/Wiki/index.php/LaTeX:Layout">LaTeX-Preamble</a>.</p>
<blockquote>
<a href="/assets/2012-02-thesis05.jpg" class="lightbox"><img src="/assets/2012-02-thesis05_p.jpg" /></a>
<a href="/assets/2012-02-thesis07.jpg" class="lightbox"><img src="/assets/2012-02-thesis07_p.jpg" /></a>
<a href="/assets/2012-02-thesis06.jpg" class="lightbox"><img src="/assets/2012-02-thesis06_p.jpg" /></a>
</blockquote>
<p>Now press “Compile” and save the document into your thesis directory where your .bib file is.</p>
<h3 id="my-thesis-input-and-my-thesis-footer">my-thesis-input and my-thesis-footer</h3>
<p>Before we generate the PDF we have to make two new files that we reference as our input (which is really more a header but the header meta-data seems to be broken) and footer file. Here is <a href="https://gist.github.com/1935325">the input (preamble) file</a> and here is <a href="https://gist.github.com/1935333">the footer file</a>. Drop those two files into your directory where your Scrivener file is.</p>
<h2 id="make-the-pdf">Make the PDF</h2>
<p>Now it is only the PDF that is left to be generated from our LaTeX file. Make sure you have installed the <a href="http://www.tug.org/mactex/2011/">MacTeX-Bundle</a> or similar. Iuse TextMate’s LaTeX Bundle to typeset my PDF files. Open the thesis.tex file in TexShop or TextMate and click “Set LaTeX” once, then click “Set BibTex” and click “Set LaTeX” twice more. Without any errors messages, you should now find eight more files next to your thesis.tex file. One of them is a pdf that should look like this:</p>
<blockquote>
<a href="/assets/2012-02-thesis08.jpg" class="lightbox"><img src="/assets/2012-02-thesis08_p.jpg" /></a>
<a href="/assets/2012-02-thesis09.jpg" class="lightbox"><img src="/assets/2012-02-thesis09_p.jpg" /></a>
<a href="/assets/2012-02-thesis10.jpg" class="lightbox"><img src="/assets/2012-02-thesis10_p.jpg" /></a>
</blockquote>
<p>Of course, everytime you have a change in your text, all you have to do is compile from Scrivener and typeset the LaTeX in TextMate or TeXShop into your PDF. The whole setup process described here is basically just a one time thing.</p>
<h2 id="resources">Resources</h2>
<p>The project with all documents used and generated can be <a href="https://github.com/tibra/ScrivenerToLaTeX">found on GitHub</a>.</p>
<p><a href="http://www.aidanfindlater.com/citations-with-scrivener-multimarkdown-bibdesk-and-texshop">Citations with Scrivener, MultiMarkDown, BibDesk, and TeXShop</a>
<a href="http://neilernst.net/2011/07/27/writing-complex-latex-documents-with-scrivener-2-1-and-multimarkdown-3/">Writing Complex Latex Documents with Scrivener 2.1 and MultiMarkDown 3</a></p>
<p>Great series of screencasts:
<a href="http://www.macosxscreencasts.com/general/scrivener-tutorial-1-setup-mmd-und-latex/">Scrivener Tutorial 1: Setup, MMD And LaTeX</a>
<a href="http://www.macosxscreencasts.com/?s=scrivener&x=0&y=0">…and more of them</a></p>
<p>Follow up blog post on Multimarkdown citations:
<a href="http://timbrandes.com/blog/2014/04/08/optimize-bibdesk-multimarkdown-and-scrivener-for-a-nice-scientific-bibliography-and-citation-workflow/">Optimize BibDesk, Multimarkdown and Scrivener for a nice scientific bibliography and citation workflow</a></p>
<p><em>Enjoy writing your papers!</em></p>The pros and cons of LaTeXMaking the RVM web site responsive with CSS3 media queries2011-06-21T01:38:00+02:002011-06-21T01:38:00+02:00/guide/2011/06/21/making-the-rvm-web-site-responsive-with-css3-media-queries<p>So, you might have heard of this shiny new book by <a href="http://ethanmarcotte.com/">Ethan Marcotte</a> called <a href="http://www.abookapart.com/products/responsive-web-design">Responsive Web Design</a>. The basic idea is to make one web site and let it respond differently to the screen size of the user. We use three ingredients to do so</p>
<ul>
<li>A Flexible Grid</li>
<li>Flexible Images</li>
<li>CSS3 Media Queries</li>
</ul>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="ss">tibra: </span><span class="k">if</span> <span class="n">you</span> <span class="n">have</span> <span class="n">more</span> <span class="n">than</span> <span class="mi">1200</span> <span class="n">pixel</span> <span class="n">width</span>
<span class="ss">tibra: </span><span class="n">make</span> <span class="n">it</span> <span class="n">smaller</span> <span class="n">than</span> <span class="mi">768</span>
<span class="ss">tibra: </span><span class="n">and</span> <span class="n">watch</span> <span class="n">the</span> <span class="n">header</span> <span class="n">boxes</span>
<span class="ss">wayneeseguin: </span><span class="n">ok</span>
<span class="ss">wayneeseguin: </span><span class="n">holy</span> <span class="n">shit</span> <span class="n">how</span> <span class="n">did</span> <span class="n">you</span> <span class="k">do</span> <span class="n">that</span> <span class="o">!</span>
<span class="ss">wayneeseguin: </span><span class="n">totally</span> <span class="n">fucking</span> <span class="n">awesome</span></code></pre></figure>
<h1 id="a-flexible-grid">A Flexible Grid</h1>
<p>The idea behind a flexible grid is to consequently use percentages and em’s in favor of fixed pixels. The <a href="https://rvm.beginrescueend.com">RVM web site</a> already had the main content area as a percentage sized width. However, the header area still uses fixed width boxes of 220px.</p>
<blockquote>
<a href="/assets/2011-06-rvmsite.jpg" class="lightbox"><img src="/assets/2011-06-rvmsite_p.jpg" /></a>
<a href="/assets/2011-06-rvmsite2.jpg" class="lightbox"><img src="/assets/2011-06-rvmsite2_p.jpg" /></a>
</blockquote>
<p>Mixing pixels and percentages leads to some ugliness when resizing the browser window and making it shorter. But is this <em>really</em> a problem for coders? How often do we use a documentary site on a small screen or with a very small browser window? I think the problem lies on the other side of the universe: high resolution screens.</p>
<blockquote>
<a href="/assets/2011-06-rvmsite3.jpg" class="lightbox"><img src="/assets/2011-06-rvmsite3_p.jpg" /></a>
<a href="/assets/2011-06-rvmsite4.jpg" class="lightbox"><img src="/assets/2011-06-rvmsite4_p.jpg" /></a>
</blockquote>
<p>As you can see, there is the documentation index on the bottom of the site. The content area takes up all the space and stretches its text far too wide. When I did this design about a year ago, I didn’t consider this usability/readability issue. Now let’s go and see how a flexible grid can help us with the header and those boxes on top.</p>
<p>Except for the wider sponsors box, all boxes inherit the same basic style from a compass mixin:</p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="vi">@mixin</span> <span class="n">default</span><span class="o">-</span><span class="n">box</span>
<span class="ss">float: </span><span class="n">left</span>
<span class="ss">width: </span><span class="mi">18</span><span class="o">%</span>
<span class="n">margin</span><span class="o">-</span><span class="ss">right: </span><span class="mf">0.7</span><span class="o">%</span></code></pre></figure>
<p>And then we simply use it on a selector, here the recommend and irc boxes:</p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="c1">#recommend, #irc</span>
<span class="vi">@include</span> <span class="n">default</span><span class="o">-</span><span class="n">box</span></code></pre></figure>
<p>So, that’s just floating divs with a width and a margin that is a percentage value. Pretty easy and works as expected.</p>
<blockquote>
<a href="/assets/2011-06-rvmsite5.jpg" class="lightbox"><img src="/assets/2011-06-rvmsite5_p.jpg" /></a>
</blockquote>
<h1 id="flexible-images">Flexible Images</h1>
<p>We have four images in the head area and our “w00t! RVM! TENNNGH! RUBYYYYYYYYYY! CRUNCH“ image that’s greeting us welcome. Our best friend with flexible images is <em>max-width: 100%</em>. This attribute makes sure images adapt to their parents container size even if they are bigger. We let the browser resize the images dynamically and hope for some smooth rendering (good browsers will give you that). Here is how the logo is styled:</p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="c1">#logo</span>
<span class="n">text</span><span class="o">-</span><span class="ss">align: </span><span class="n">center</span>
<span class="n">img</span>
<span class="n">max</span><span class="o">-</span><span class="ss">width: </span><span class="mi">100</span><span class="o">%</span>
<span class="n">max</span><span class="o">-</span><span class="ss">height: </span><span class="mi">170</span><span class="n">px</span></code></pre></figure>
<p>And the haml view looks like this</p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="c1">#logo</span>
<span class="o">%</span><span class="n">a</span><span class="p">{</span> <span class="ss">:href</span> <span class="o">=></span> <span class="s2">"/"</span> <span class="p">}</span>
<span class="o">%</span><span class="n">img</span><span class="p">{</span> <span class="ss">:src</span> <span class="o">=></span> <span class="s2">"/images/logo.png"</span><span class="p">,</span> <span class="ss">:alt</span> <span class="o">=></span> <span class="s2">"RVM Logo"</span><span class="p">}</span></code></pre></figure>
<p>I have added the <em>max-height: 170px</em> after some testing with resizing the browser window. If you don’t specify any <em>max-height</em> the logo will become bigger and bigger until it hits the original file size. I left the logo.png untouched and gave it some height constraints instead.
The “w00t! RVM!…“-image looks just as simple as this:</p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="c1">#content</span>
<span class="n">img</span>
<span class="n">max</span><span class="o">-</span><span class="ss">width: </span><span class="mi">100</span><span class="o">%</span></code></pre></figure>
<p>And here is the result on big and small browser windows:</p>
<blockquote>
<a href="/assets/2011-06-rvmsite6.jpg" class="lightbox"><img src="/assets/2011-06-rvmsite6_p.jpg" /></a>
<a href="/assets/2011-06-rvmsite7.jpg" class="lightbox"><img src="/assets/2011-06-rvmsite7_p.jpg" /></a>
</blockquote>
<h1 id="css3-media-queries">CSS3 Media Queries</h1>
<p>While this is all well and good so far, the real power becomes visible when we introduce CSS3 Media Queries.
The last screenshot already has some media queries in use (see the long text from before in those boxes on top? No? Me neither :)).</p>
<p>But don’t you find that there is still too much whitespace in the content area? Wouldn’t it be great if we could simply move the big <em>Documentation Index</em> from the bottom of the page to the right and float it <em>next to</em> the content area? This way, widescreen users could really benefit from their screen size and scrolling down would only be necessary if we were on a smaller screen. You might have guessed it already: Media Queries - that’s what they’re here for.</p>
<blockquote>
<a href="/assets/2011-06-rvmsite8.jpg" class="lightbox"><img src="/assets/2011-06-rvmsite8_p.jpg" /></a>
</blockquote>
<h2 id="how-do-we-include-media-queries">How do we include Media Queries?</h2>
<p>Media Queries allow us to change the style depending on the users screen size. We simply include them into our normal stylesheet like this:</p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="vi">@media</span> <span class="n">screen</span> <span class="n">and</span> <span class="p">(</span><span class="n">max</span><span class="o">-</span><span class="ss">width: </span><span class="mi">768</span><span class="n">px</span><span class="p">)</span>
<span class="sr">//</span> <span class="n">changes</span> <span class="k">for</span> <span class="n">everything</span> <span class="n">smaller</span> <span class="n">than</span> <span class="mi">768</span><span class="n">px</span>
<span class="vi">@media</span> <span class="n">screen</span> <span class="n">and</span> <span class="p">(</span><span class="n">min</span><span class="o">-</span><span class="ss">width: </span><span class="mi">1200</span><span class="n">px</span><span class="p">)</span>
<span class="sr">//</span> <span class="n">changes</span> <span class="k">for</span> <span class="n">wide</span><span class="o">-</span><span class="n">screen</span> <span class="n">users</span></code></pre></figure>
<h2 id="let-it-float-baby">Let it float, baby</h2>
<p>Now, this code is all it takes to make it happen:</p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="vi">@media</span> <span class="n">screen</span> <span class="n">and</span> <span class="p">(</span><span class="n">min</span><span class="o">-</span><span class="ss">width: </span><span class="mi">1200</span><span class="n">px</span><span class="p">)</span>
<span class="c1">#content</span>
<span class="ss">width: </span><span class="mi">50</span><span class="o">%</span>
<span class="ss">float: </span><span class="n">left</span>
<span class="n">margin</span><span class="o">-</span><span class="ss">bottom: </span><span class="mi">1</span><span class="o">%</span>
<span class="c1">#docindex</span>
<span class="ss">width: </span><span class="mi">44</span><span class="o">%</span>
<span class="ss">float: </span><span class="n">right</span>
<span class="n">a</span><span class="p">.</span><span class="nf">docindex</span>
<span class="ss">display: </span><span class="n">none</span></code></pre></figure>
<p>And as a little bonus, we hide the link to the <em>Documentation Index</em> at the top of the content area.</p>
<blockquote>
<a href="/assets/2011-06-rvmsite10.jpg" class="lightbox"><img src="/assets/2011-06-rvmsite10_p.jpg" /></a>
<a href="/assets/2011-06-rvmsite9.jpg" class="lightbox"><img src="/assets/2011-06-rvmsite9_p.jpg" /></a>
</blockquote>
<h1 id="see-it-live">See it live</h1>
<p>Wayne has already <a href="https://rvm.beginrescueend.com">deployed the new version</a>, be sure to check it out! I hope you find this useful and you are encouraged to make some responsive designs yourself. I believe it’s the future. If you can imagine a way to make this better, find the <a href="https://github.com/wayneeseguin/rvm-site">RVM website on Github</a> and start hacking!</p>So, you might have heard of this shiny new book by Ethan Marcotte called Responsive Web Design. The basic idea is to make one web site and let it respond differently to the screen size of the user. We use three ingredients to do so