~andrewzah/personal-site

f30a9326dc15e677a349eb0d18dac6ed6e4ae1c5 — Andrew Zah 8 months ago bc35603
bulk update, refactor scss
A content/talks/05-28-2019-wasm-rust-seoul/index.md => content/talks/05-28-2019-wasm-rust-seoul/index.md +322 -0
@@ 0,0 1,322 @@
+++
title = "Web Assembly: What is it? Does it do things? Let's find out!"
slug = "web-assembly-rust-seoul"
date = 2019-05-28
template = "talk.html"

[taxonomies]
tags = ["rust", "webassembly"]
categories = ["talks"]

[extra]
summary = "A talk on what WebAssembly actually is, ways to use it in Rust, and a case study."
keywords = "talk pdf presentation web assembly rust 2019 seoul what is web assembly"
pdflink = "https://s3.amazonaws.com/andrewzah.com/talks/2019-05-28/ZahWebAssemblyRust-05-28-2019.pdf"
+++

```latex
% !TEX program = XeLaTeX
\documentclass[aspectratio=169]{beamer}
\mode<presentation>

\usepackage{tikz}
\usepackage{pgfpages} % notes
\usepackage{graphicx}
\usepackage{color} % for syntax highlighting definitions
\usepackage{fontspec} % for custom firacode setup
\usepackage{listings} % for formatting codeblocks

\usetheme{AnnArbor}
\usecolortheme{spruce}
\usecolortheme{rose}

\setbeamertemplate{navigation symbols}{}
\setbeamertemplate{enumerate items}[default]
\setbeamercolor{item projected}{bg=green!40!black,fg=white}
\setbeamercolor{section in toc}{fg=black}
%\setbeameroption{show notes on second screen}

%% fonts

\setmonofont{Fira Code}[
  Contextuals=Alternate  % Activate the calt feature
]
\usepackage{lstfiracode}

%% code syntax highlighting

\definecolor{lightgray}{rgb}{.9,.9,.9}
\definecolor{darkgray}{rgb}{.4,.4,.4}
\definecolor{purple}{rgb}{0.65, 0.12, 0.82}

\lstdefinelanguage{JavaScript}{
  keywords={break, case, catch, continue, debugger, default, delete, do, else, false, finally, for, function, if, in, instanceof, new, null, return, switch, this, throw, true, try, typeof, var, void, while, with},
  morecomment=[l]{//},
  morecomment=[s]{/*}{*/},
  morestring=[b]',
  morestring=[b]",
  ndkeywords={class, export, boolean, throw, implements, import, this},
  keywordstyle=\color{blue}\ttfamily,
  ndkeywordstyle=\color{darkgray}\ttfamily,
  identifierstyle=\color{black}\ttfamily,
  commentstyle=\color{purple}\ttfamily,
  stringstyle=\color{red}\ttfamily,
  sensitive=true
}

%% behavior modifications

\newenvironment{wideitemize}{\itemize\addtolength{\itemsep}{10pt}}{\enditemize}
\AtBeginSection[]
{
    \begin{frame}
        \frametitle{Journey}
        \tableofcontents[currentsection]
    \end{frame}
}

%% metadata

\title[WASM!]{Web Assembly: What does it do? Does it do things? Let's find out!}
\author[]{Andrew Zah \texttt{<zah@andrewzah.com>}}
\institute[Rust Meetup Seoul]{Rust Meetup Seoul}
\date{May 23, 2019}

%% preamble over

\begin{document}
\maketitle

\section*{Journey}
\begin{frame}
  \tableofcontents
\end{frame}

\section{What is WASM?}
\begin{frame}
  \frametitle{Web Assembly's Definition}
  \begin{block}{from webassembly.org (emphasis mine)}
    WebAssembly (abbreviated Wasm) is a \alert{binary instruction format} for a \alert{stack-based virtual machine}. Wasm is designed as a \alert{portable target} for compilation of high-level languages like C/C++/Rust, enabling \alert{deployment on the web} for client and server applications.
  \end{block}
\end{frame}

\begin{frame}
  \frametitle{What WASM is not}
  \begin{wideitemize}
    \item WASM is not a programming language – though you can write by hand
    \item WASM isn't standalone – it needs a host
    \item WASM is not intended to replace javascript
  \end{wideitemize}
\end{frame}

\begin{frame}
  \frametitle{What is it actually, though?}
  \begin{wideitemize}
    \item WASM's format isn't coupled to any OS or architecture
    \item Very similar to Java's bytecode or C\#'s CLR
    \item Name and definition is a misnomer
    \item It can run \alert{anywhere} you can build a \alert{host}
  \end{wideitemize}
\end{frame}

\begin{frame}
  \frametitle{What is it actually, though? pt. 2}
  \begin{wideitemize}
    \item WASM is \alert{stack-based}, not register-based
    \item WASM 1.0 only had 4 primitives
    \item `i32`, `i64`, `f32`, `f64` 
    \item Unlike other assembly languages, WASM has no `jmp` instruction
  \end{wideitemize}
  \note[item]{Forth is just about the only somewhat-mainline language that is stack-based.}
  \note[item]{RPL also exists but\ldots}
\end{frame}

\begin{frame}
  \frametitle{Memory}
  \begin{columns}
    \begin{column}{0.5\textwidth}
      \begin{wideitemize}
        \item WASM has no \alert{new::()} operator or \alert{heap}
        \item There are no objects or or garbage collection
        \item Instead, WASM has \alert{linear memory}
        \item<2-> Modern programming languages have spoiled us
      \end{wideitemize}
    \end{column}
    \begin{column}{0.5\textwidth}
      \begin{center}
        \only<2-> {
          \begin{tikzpicture}<2->
            \draw [gray] (0,0) rectangle (4,1) node[pos=.5] {unused};
            \draw [teal] (0,1) rectangle (4,2) node[pos=.5] {var3 [80\ldots119]};
            \draw [gray] (0,2) rectangle (4,3) node[pos=.5] {var2 [40\ldots79]};
            \draw [teal] (0,3) rectangle (4,4) node[pos=.5] {var1 [0\ldots39]};
          \end{tikzpicture}
        }
      \end{center}
    \end{column}
  \end{columns}
\end{frame}

\begin{frame}
  \frametitle{Anyone can be a WASM host!}
  
  \begin{alertblock}{The Host needs to:}
    \begin{enumerate}
      \item Load and validate the WASM binary (the file, not the logic)
      \item Expose Exports
      \item Satisfy Imports
      \item Interpret \& Execute Modules
      \item Isolate Modules
    \end{enumerate}
  \end{alertblock}
\end{frame}

\begin{frame}
  \frametitle{Infinity and Beyond}

  \begin{wideitemize}
    \item WebAssembly modules are hotswappable
    \item This means \alert{\em any host} can swap modules at will
    \item PLCs (Programmable Logic Controllers) could adhere to a well-known contract
    \item This would let us program for hardware controllers in \alert{any language}!
  \end{wideitemize}
  
\end{frame}

\begin{frame}
  \frametitle{Security}
  \begin{wideitemize}
    \item WASM can always be converted back to plaintext
    \item Do not put secrets in WASM modules
    \item \alert{Message handoffs} are not always secure!
    \item One can disassemble, modify, recompile, inject a module
    \item Accordingly, \alert{sign} and \alert{encrypt} modules!
  \end{wideitemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Example WASM Syntax}
  \begin{block}{add.wat}
    \begin{lstlisting}[language=Lisp]
(module
  (func $add (param $lhs i32) (param $rhs i32) (result i32)
    (i32.add
        (get_local $lhs)
        (get_local $rhs)
    )
  )
  (export "add" (func $add))
)
    \end{lstlisting}
  \end{block}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Add Example: Rust}
  \begin{block}{main.rs}
    \begin{lstlisting}[language=c++]
#[no_mangle]
pub extern "C" fn add_one(x: i32) -> i32 {
    x + 1
}
    \end{lstlisting}
  \end{block}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Add Example: WASM}
  \begin{block}{main.wasm}
    \begin{lstlisting}[language=Lisp]
(module
  (type $t0 (func (param i32) (result i32)))
  (func $add_one
      (export "add_one") (type $t0) (param $p0 i32) (result i32)
    get_local $p0
    i32.const 1
    i32.add)
  (table $T0 1 1 anyfunc)
  (memory $memory (export "memory") 17))
    \end{lstlisting}
  \end{block}
\end{frame}


\section{How Rust and WASM Intertwine}
\begin{frame}[fragile]
  \frametitle{wasm-pack}
  \begin{block}{main.rs}
    \begin{lstlisting}[language=c++]
#[wasm_bindgen]
extern {
    fn alert(s: &str);
}

#[wasm_bindgen]
pub fn greet() {
    alert("Hello, wasm-game-of-life!");
}
    \end{lstlisting}
  \end{block}
\end{frame}

\begin{frame}[fragile]
  \frametitle{wasm-pack}
  \begin{block}{main.js}
    \begin{lstlisting}[language=javascript]
import * as wasm from "wasm-game-of-life";

wasm.greet();
    \end{lstlisting}
  \end{block}
\end{frame}

\begin{frame}
  \frametitle{wasm-bindgen}
  \begin{wideitemize}
    \item Adds helpers to allow transfer of \alert{complex types}.
  \end{wideitemize}
\end{frame}

\section{A Real, Non-Trivial WASM App}
\begin{frame}
  \frametitle{Korean Apps}
  \begin{wideitemize}
    \item Initially I wrote a cargo crate, \alert{korean-numbers}
    \item I wanted a way to use this logic in a webapp with React
  \end{wideitemize}
\end{frame}

\begin{frame}
  \begin{center}
    {\huge Thank you} \\
    Andrew Zah
  \end{center}
\end{frame}

\section{Appendix}
\begin{frame}[plain]
  \includegraphics[scale=0.34]{webassembly-studio.png}
\end{frame}

\begin{frame}
  \frametitle{Further Reading}
  \begin{itemize}
    \item WASM Homepage \texttt{https://webassembly.org}
    \item WASM Spec \texttt{https://webassembly.github.io/spec/}
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Bibliography}
  \begin{thebibliography}{Dijkstra, 1982}
    \bibitem[Hoffman, 2019]{Hoffman2019}
      K.~Hoffman.
      \newblock{\em Programming WebAssembly with Rust \\
        \small Unified Development for Web, Mobile, and Embedded Applications }
      \newblock{The Pragmatic Programmers, LLC}
      \newblock{ISBN-13: 978-1-68050-636-5}
  \end{thebibliography}
\end{frame}

\end{document}
```

A content/talks/_index.md => content/talks/_index.md +6 -0
@@ 0,0 1,6 @@
+++
title = "Talks"
template = "section.html"
sort_by = "date"
render = true
+++

A sass/_container.scss => sass/_container.scss +158 -0
@@ 0,0 1,158 @@
.container {
  .image-desc {
    font-style: italic;
    color: $headers;
    text-align: center;
    font-size: 15px;
  }

  .page-date {
    font-family: $serif-stack;
    margin-top: -.75rem;
    font-size: 18px;
    display: block;
    color: $light_text;
    font-style: italic;
  }

  hr {
    margin-top: 1rem;
    margin-bottom: 1rem;
  }

  code, ul li code {
    @include wrap-word;

    font-family: $monospace-stack;
    font-size: 14px;
    padding: 2px 4px;
    color: $code_text;
    background-color: $code_background;
    border-radius: 4px;
  }

  pre {
    @include wrap-word;
    padding: 0.5em 1em;
    font-size: 14px;
    background-color: $code_background !important;
    box-shadow: 0 4px 2px hsla(0, 0%, 0%, 0.2);

    span {
      background-color: $code_background !important;
    }
  }

  p {
    @include anchor-colors;
    @include anchor-style;

    margin-bottom: 1rem;
  }

  img.smol-img {
    display: block;
    max-height: 25rem;
    width: auto;
    margin: 0px auto 2rem auto
  }

  p img.full {
    max-width: 100%;
    display: block;
    margin: 0 auto;
    box-shadow: 0 4px 6px 0 hsla(0, 0%, 0%, 0.2);
  }

  p, li, h6 {
    font-family: 'Libre Baskerville', 'Baskerville', serif;
    line-height: 1.5;
  }

  /* Post Headers */
  h1 {
    text-align: left;
    font-weight: bold;
    margin-bottom: 0px;
  }

  h6 {
    text-align: center;
    font-size: 14px;
    color: $med_text;
    margin-top: -1.5rem;
  }

  h1,h2,h3,h4,h5 {
    font-family: $serif-stack;
    font-weight: bold;
    margin-bottom: .5rem;
  }

  table {
    border-spacing: 1;
    border-collapse: collapse;
    background: white;
    border-radius: 10px;
    overflow: hidden;
    width: 100%;
    margin: 1rem auto;
    position: relative;

    * {
      position: relative;
    }

    td, th {
      padding: 6px 8px;
      padding-left: 15px;
    }

    thead tr {
      background-color: $primary;
      color: rgb(248, 248, 248);
      font-weight: bold;
      border-bottom: 1px solid #ccc;
    }

    tbody tr {
      &:nth-child(odd) {
        background-color: $table_lighter;
      }

      &:nth-child(even) {
        background-color: $table_darker;
      }


      &:last-child {
        td {
          border: none;
        }
      }

      &:hover {
        background-color: $table_highlight;
        cursor: pointer;
      }
    }
  }

  blockquote {
    border-left: 4px solid $primary;

    @media (min-width: $mobile-screen) {
      margin-left: 2rem;
    }

    p {
      margin-bottom: 10px;
    }

    ul {
      &:last-child {
        margin-bottom: 2.5rem;
      }
    }
  }
}

M sass/_posts.scss => sass/_posts.scss +6 -167
@@ 43,175 43,14 @@ a.anchorjs-link:hover {
  margin-bottom: 1.25rem;
}

.container {
  .post {
    max-width: 680px;

.container.page {
  max-width: 680px;

  .image-desc {
    font-style: italic;
    color: $headers;
    text-align: center;
    font-size: 15px;
  }

  time {
    font-family: $serif-stack;
    margin-top: -1rem;
    font-size: 18px;
    display: block;
    color: $light_text;
    font-style: italic;
  }

  hr {
    margin-top: 1rem;
    margin-bottom: 1rem;
  }

  code, ul li code {
    @media (max-width: $mobile-screen) {
      @include wrap-word;
    }

    font-family: $monospace-stack;
    font-size: 14px;
    padding: 2px 4px;
    color: $code_text;
    background-color: $code_background;
    border-radius: 4px;
  }

  pre {
    padding: 0.5em 1em;
    font-size: 14px;
    background-color: $code_background !important;
    box-shadow: 0 4px 2px hsla(0, 0%, 0%, 0.2);

    span {
      background-color: $code_background !important;
    }

    @media (max-width: $mobile-screen) {
      @include wrap-word;
    }
  }
  p {
    @include anchor-colors;
    @include anchor-style;
    @include wrap-word;

    margin-bottom: 1rem;
  }

  img.smol-img {
    display: block;
    max-height: 25rem;
    width: auto;
    margin: 0px auto 2rem auto
  }

  p img.full {
    max-width: 100%;
    display: block;
    margin: 0 auto;
    box-shadow: 0 4px 6px 0 hsla(0, 0%, 0%, 0.2);
  }

  p, li, h6 {
    font-family: 'Libre Baskerville', 'Baskerville', serif;
    line-height: 1.5;
  }

  /* Post Headers */
  h1 {
    text-align: left;
    font-weight: bold;
    margin-bottom: 0px;
  }

  h6 {
    text-align: center;
    font-size: 14px;
    color: $med_text;
    margin-top: -1.5rem;
  }

  h1,h2,h3,h4,h5 {
    font-family: $serif-stack;
    font-weight: bold;
    margin-bottom: .5rem;
  }

  h2 {
    border-bottom: 1px solid #ccc;
    padding-bottom: 0.5rem;
    margin-bottom: 1rem;
  }

  table {
    border-spacing: 1;
    border-collapse: collapse;
    background: white;
    border-radius: 10px;
    overflow: hidden;
    width: 100%;
    margin: 1rem auto;
    position: relative;

    * {
      position: relative;
    }

    td, th {
      padding: 6px 8px;
      padding-left: 15px;
    }

    thead tr {
      background-color: $primary;
      color: rgb(248, 248, 248);
      font-weight: bold;
    h2 {
      border-bottom: 1px solid #ccc;
    }

    tbody tr {
      &:nth-child(odd) {
        background-color: $table_lighter;
      }

      &:nth-child(even) {
        background-color: $table_darker;
      }


      &:last-child {
        td {
          border: none;
        }
      }

      &:hover {
        background-color: $table_highlight;
        cursor: pointer;
      }
    }
  }

  blockquote {
    border-left: 4px solid $primary;

    @media (min-width: $mobile-screen) {
      margin-left: 2rem;
    }

    p {
      margin-bottom: 10px;
    }

    ul {
      &:last-child {
        margin-bottom: 2.5rem;
      }
      padding-bottom: 0.5rem;
      margin-bottom: 1rem;
    }
  }
}

A sass/_talks.scss => sass/_talks.scss +3 -0
@@ 0,0 1,3 @@
.container.talks {
  max-width: 845px;
}

A sass/components/_button.scss => sass/components/_button.scss +23 -0
@@ 0,0 1,23 @@
.button.button-primary,
button.button-primary,
input[type="submit"].button-primary,
input[type="reset"].button-primary,
input[type="button"].button-primary {
  color: #FFF;
  background-color: $primary;
  border-color: $primary; }

.button.button-primary:hover,
button.button-primary:hover,
input[type="submit"].button-primary:hover,
input[type="reset"].button-primary:hover,
input[type="button"].button-primary:hover,
.button.button-primary:focus,
button.button-primary:focus,
input[type="submit"].button-primary:focus,
input[type="reset"].button-primary:focus,
input[type="button"].button-primary:focus {
  color: #FFF;
  background-color: $primary-hover;
  border-color: $primary-hover;
}

M sass/components/_random_quote.scss => sass/components/_random_quote.scss +1 -1
@@ 16,7 16,7 @@ div#random-quote {
  }

  #random-quote-citation {
    margin-left: 30px;
    margin-left: 4rem;
    #random-quote-source {
      font-style: italic;
    }

M sass/main.scss => sass/main.scss +4 -2
@@ 2,10 2,9 @@
@import 'vendor/skeleton';
@import 'vendor/lity';

@import '_variables';
@import '_colors';
@import '_mixins';
@import '_variables';
@import '_colors';

/* No need to enable these yet, until I write
 * a post making use of them.


@@ 16,6 15,7 @@

@import 'components/_after_post';
@import 'components/_anchor';
@import 'components/_button';
@import 'components/_codeblocks';
@import 'components/_footer';
@import 'components/_footnote';


@@ 27,7 27,9 @@

@import '_landing';
@import '_misc';
@import '_container';
@import '_posts';
@import '_talks';
@import '_projects';
@import '_section';
@import '_tags';

M sass/vendor/skeleton.scss => sass/vendor/skeleton.scss +0 -8
@@ 206,14 206,6 @@ input[type="button"]:focus {
  color: #333;
  border-color: #888;
  outline: 0; }
.button.button-primary,
button.button-primary,
input[type="submit"].button-primary,
input[type="reset"].button-primary,
input[type="button"].button-primary {
  color: #FFF;
  background-color: #33C3F0;
  border-color: #33C3F0; }
.button.button-primary:hover,
button.button-primary:hover,
input[type="submit"].button-primary:hover,

M templates/categories/single.html => templates/categories/single.html +1 -1
@@ 2,7 2,7 @@

{% block main %}
<article id="taxonomy" class="container post">
    <h2>Posts categorized under {{ term.name }}</h2>
    <h2>Pages categorized under {{ term.name }}</h2>
    {% for page in term.pages %}
      <div class="row">
        <tr>

M templates/landing.html => templates/landing.html +3 -2
@@ 20,8 20,9 @@
      </div>
      <div class="row">
        <h4> Hi, I do stuff with computers. Take a look at my
          <a href="./projects">programming projects</a>, or my
          <a href="./posts">blog</a>.
          <a href="./projects">programming projects</a>, my
          <a href="./posts">blog</a>, or my
          <a href="./talks">talks</a>.
        </h4>
      </div>
    </div>

M templates/macros.html => templates/macros.html +15 -2
@@ 1,8 1,8 @@
{% macro post_link(page) %}
{% macro post_link(page, section) %}
  {% if page.draft %}
  {% else %}
    <h2 class="post-title">
      <a href="/posts/{{page.slug | safe}}/">
      <a href="/{{section.components[0]}}/{{page.slug | safe}}/">
        * {{ page.title }}
      </a>
    </h2>


@@ 112,6 112,7 @@
        <li><a href="/">Home</a></li>
        <li {% if path == 'posts' %}class="active"{% endif %}><a href="/posts/">Posts</a></li>
        <li {% if path == 'proje' %}class="active"{% endif %}><a href="/projects/">Projects</a></li>
        <li {% if path == 'talks' %}class="active"{% endif %}><a href="/talks/">Talks</a></li>
        <li {% if path == 'conta' %}class="active"{% endif %}><a href="/contact/">Contact</a></li>
        <li {% if path == 'quote' %}class="active"{% endif %}><a href="/quotes/">Quotes</a></li>
        <li><a href="/rss.xml">RSS</a></li>


@@ 119,3 120,15 @@
    </div>
  </nav>
{% endmacro render_nav %}

{% macro render_term(term) %}
  <div class="row">
    <tr>
      <td><time datetime="{{ term.date }}">{{ term.date  }}</time></td>
        {% if term.components[0] == "talks" %}
          <td> (talk) </td>
        {% endif %}
      <td><a href="/{{ term.path }}">{{ term.title }}</a></td>
    </tr>
  </div>
{% endmacro render_term %}

M templates/post.html => templates/post.html +1 -1
@@ 17,7 17,7 @@
{% endblock head %}

{% block main %}
  <div itemtype="http://schema.org/Article" class="container page">
  <div itemtype="http://schema.org/Article" class="container post">
    <h1 itemprop="name">{{ page.title }}</h1>
    <time itemprop="datePublished" content="{{ page.date | date(format="%Y-%m-%d")}}" datetime="{{ page.date }}" class="page-date">
        {{ page.date | date(format="%b %d, %Y") }}

M templates/section.html => templates/section.html +2 -2
@@ 5,7 5,7 @@

{% block main %}
  <div class="container section">
    {% set section = get_section(path="posts/_index.md") %}
    {% set section = get_section(path=section.components[0] ~ "/_index.md") %}
    <h2 id="section-title"><a href="{{section.permalink}}">{{ section.title }}</a></h2>

    {% block introduction %}{% endblock introduction %}


@@ 13,7 13,7 @@
    <div class="posts neutral">
        {% for page in section.pages %}
          <div class="section-post page">
            {{ macros::post_link(page=page) }}
            {{ macros::post_link(page=page, section=section) }}
          </div>
        {% endfor %}
    </div>

M templates/tags/single.html => templates/tags/single.html +5 -8
@@ 1,19 1,16 @@
{% extends "base.html" %}

{% import "macros.html" as macros %}
{% block title %} {{ term.name }} | {{ config.title }} {% endblock title %}

{% block main %}
  {% set posts = term.pages | filter(attribute="components.0", value="posts") %}
  {% set talks = term.pages | filter(attribute="components.0", value="talks") %}
  <div id="taxonomy" class="container">
    <h2 class="tag-header"> Posts tagged with {{ term.name | title }}</h2>

    <h1 class="tag-header"> Pages tagged with {{ term.name | title }}</h1>
    <div class="tag-pages">
      {% for page in term.pages %}
        <div class="row">
          <tr>
              <td><time datetime="{{ page.date }}">{{ page.date | date(format="%B %e, %Y") }}</time></td>
              <td><a href="/{{ page.path }}">{{ page.title }}</a></td>
          </tr>
        </div>
        {{ macros::render_term(term=page) }}
      {% endfor %}
    </div>
  </div>

A templates/talk.html => templates/talk.html +73 -0
@@ 0,0 1,73 @@
{% extends "base.html" %}

{% import "macros.html" as macros %}
{% block page %}{{ page }}{% endblock page %}
{% block title %}{{ page.title }} | {{ config.title }}{% endblock title %}
{% block ogtitle %}{{ page.title }} | {{ config.title }}{% endblock ogtitle %}
{% block twittertitle %}{{ page.title }} | {{ config.title }}{% endblock twittertitle %}
{% block summary %}{{ page.extra.summary | safe | striptags }}{% endblock summary %}
{% block ogsummary %}{{ page.extra.summary | safe | striptags }}{% endblock ogsummary %}
{% block keywords %}{{ page.extra.keywords }}{% endblock keywords %}
{% block permalink %}{{ page.permalink }}{% endblock permalink %}

{% block main %}
  <div itemtype="http://schema.org/Article" class="container talks">
    <h1 itemprop="name">{{ page.title }}</h1>
    <time itemprop="datePublished" content="{{ page.date | date(format="%Y-%m-%d")}}" datetime="{{ page.date }}" class="page-date">
        {{ page.date | date(format="%b %d, %Y") }}
        {% if page.extra.updated %} <time itemprop="dateModified" content={{ page.extra.updated }}>(updated on {{ page.extra.updated }})</time> {% endif %}
    </time>
    <div itemtype="PresentationDigitalDocument">
      <a class="button button-primary" href="{{page.extra.pdflink}}">Download PDF</a>
    </div>
    <hr>
    <article itemprop="articleBody">
      <div id="email-me">
        <p>The following is the source code for this PDF.</p>

        <p>Have any observations, criticisms, or corrections? Feel free to <a href="mailto:talks@andrewzah.com">email me</a>. Have a nice day!</p>
      </div>
      {{ page.content | safe }}
    </article>
  </div>
{% endblock main %}

{% block after_main %}
  <div id="after-main" class="container">
    <div id="random-quote">
      <h2> Random quote </h2>
      <blockquote id="random-quote-quote"></blockquote>
      <p id="random-quote-citation">
        <span id="random-quote-author"></span>
        <span id="random-quote-source"></span>
      </p>
    </div>
    <hr>

    <div class="container after-post">
        {% if page.earlier %}
          <div id="previous_post">
            Previous: <i>
              <a class="prev" href="/talks/{{ page.earlier.slug | safe }}">{{ page.earlier.title }}</a>
            </i>
          </div>
        {% endif %}

        {% if page.later %}
          <div id="next_post">
            Next: <i>
              <a class="next" href="/talks/{{ page.later.slug | safe }}">{{ page.later.title }}</a>
            </i>
          </div>
        {% endif %}

        {% if page.taxonomies %}
          {{ macros::render_taxonomies(taxonomies=page.taxonomies) }}
        {% endif %}
    </div>

    <hr>
    </div>

    {% include "_footer.html" %}
    {% endblock after_main %}