1<!doctype html> 2<html lang="en"> 3 4 <head> 5 <meta charset="utf-8"> 6 7 <title>DCDW: Pyparsing</title> 8 9 <meta name="description" content=""> 10 <meta name="author" content="Travis Hoppe"> 11 12 <meta name="apple-mobile-web-app-capable" content="yes" /> 13 <meta name="apple-mobile-web-app-status-bar-style" 14 content="black-translucent" /> 15 16 <meta name="viewport" content="width=device-width, 17 initial-scale=1.0, 18 maximum-scale=1.0, 19 user-scalable=no"> 20 21 <link rel="stylesheet" href="reveal.js/css/reveal.css"> 22 <link rel="stylesheet" href="reveal.js/css/theme/simple.css" id="theme"> 23 24 <!-- For syntax highlighting --> 25 <link rel="stylesheet" href="reveal.js/lib/css/zenburn.css"> 26 27 <!-- For LaTeX formating highlighting --> 28 <link rel="stylesheet" href="md2reveal/css/latex_style.css"> 29 30 <!--[if lt IE 9]> 31
31<script src="reveal.js/lib/js/html5shiv.js"></script>
31 32 <![endif]--> 33 </head> 34 35 <body> 36 37 <div class="reveal"><div class="slides"> 38 <section class="vertical-stack"> 39<section class="vertical-slide" data-background-transition="none"> 40<link rel="stylesheet" href="reveal.js/css/theme/beige.css" id="theme"> 41<br> 42<p> 43<h1>PYPARSING</h1><h3><em>helping data get its sexy back</em></h3></p> 44<br> 45<p> 46<strong><a href="http://thoppe.github.io/">Travis Hoppe</a></strong><br><em><a href="http://www.meetup.com/Data-Wranglers-DC/">DC Data Wranglers</a></em> / <a href="https://github.com/thoppe/DCDW_pres_feb_2014">(deck source)</a></p> 47</section> 48</section><section class="vertical-stack"> 49<section class="vertical-slide" data-background-transition="none"> 50<p> 51<h2>What is parsing?</h2></p> 52<br> 53<p> 54<em>syntactic analysis of symbols</em><br><em>according to a formal grammar</em></p> 55<br> 56<br> 57<p> 58Analyzing a log file<br>Extracting data from a webpage<br>Sanitizing input from untrusted sources</p> 59</section><section class="vertical-slide" data-background-transition="none"> 60<p> 61<h2>don't do it!</h2></p> 62<br> 63<p> 64Write the <strong>grammar</strong> not the <strong>parser</strong>!</p> 65<br> 66<p> 67It's easier to construct/maintain<br>a mini-language. Really!</p> 68<br> 69<p> 70Traditional utilities: regex, lex, yacc.</p> 71</section><section class="vertical-slide" data-background-transition="none"> 72<p> 73<h2>Example problems</h2></p> 74<br> 75<p> 76<h3>Easy:</h3>Addresses, phone numbers, quoted strings</p> 77<br> 78<p> 79<h3>Hard:</h3>HTML, recursive descent parsers<br>(mathematical expressions, pdf's, meta-font, LISP)</p> 80</section> 81</section><section class="vertical-stack"> 82<section class="vertical-slide" data-background-transition="none"> 83<p> 84<h2>Lifecycle of code</h2></p> 85<br> 86<ul><li>Time to code</li> 87<li>Time to run</li> 88<li>Time to maintain</li></ul> 89<br> 90<br> 91<p> 92<em>Which is more important?</em></p> 93</section><section class="vertical-slide" data-background-transition="none"> 94<p> 95This is not NLP (natural language processing)<br>This is a <strong>context-free</strong> grammar.<div class="fragment"><br></p> 96<br> 97<p> 98<h3>One morning I shot an elephant in my pajamas.</h3></div><div class="fragment"><h3>How he got into my pajamas I'll never know.</h3><em>(sometimes context matters!)</em><br></div></p> 99</section><section class="vertical-slide" data-background-transition="none"> 100<p> 101<h1>Backus-Naur Form</h1></p> 102<br> 103<p> 104"<em>... a notation for a context-free grammar, used to describe the syntax of languages used in computing, such as computer programming languages, document formats, instruction sets and communication protocols</em>" - Wikipedia</p> 105<br> 106<pre><code class=python><postal-address> ::= <name-part> <street-address> <zip-part> 107<name-part> ::= <personal-part> <last-name> <opt-suffix-part> <EOL> 108 | <personal-part> <name-part> 109<personal-part> ::= <first-name> | <initial> "." 110<street-address> ::= <house-num> <street-name> <opt-apt-num> <EOL> 111<zip-part> ::= <town-name> "," <state-code> <ZIP-code> <EOL></code></pre> 112</section> 113</section><section class="vertical-stack"> 114<section class="vertical-slide" data-background-transition="none"> 115<p> 116<h2>Why not regex?</h2><em><a href="http://www.codinghorror.com/blog/2008/06/regular-expressions-now-you-have-two-problems.html">Now you have two problems</a></em></p> 117<br> 118<p> 119"<em>Regular expressions are like a particularly spicy hot sauce, to be used in moderation and with restraint only when appropriate. If you drench your plate in hot sauce, you're going to be very, very sorry later.</em>" - Jeff Atwood</p> 120</section><section class="vertical-slide" data-background-transition="none"> 121<p> 122Validating a phone number (<em>reasonable regex</em>)</p> 123<pre><code class=python>"^\(*\d{3}\)*( |-)*\d{3}( |-)*\d{4}$"</code></pre> 124<br> 125<p> 126Validating RFC822 email addresses (<em>have fun!</em>)</p> 127<pre><code>(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?
127:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>
127(?:(?:\r\n)?[ \t])*)(?:,\s*(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*))*)?;\s*) 128</code></pre> 129</section> 130</section><section class="vertical-stack"> 131<section class="vertical-slide" data-background-transition="none"> 132<p> 133<h1>Pyparsing</h1>A free, pure python drop-in <a href="http://pyparsing.wikispaces.com/">parsing module</a>. Allows you to write/maintain the grammar, <em>abstracted</em> from the parser.</p> 134<a href=http://shop.oreilly.com/product/9780596514235.do><img class="" src="images/book.jpg" height="300px"></a> 135<p> 136Examples in this talk adapted from the <a href="http://shop.oreilly.com/product/9780596514235.do">book</a>.</p> 137</section> 138</section><section class="vertical-stack"> 139<section class="vertical-slide" data-background-transition="none"> 140<p> 141<h3><a href="code/hello_world.py">hello_world.py</a></h3>Build the grammar iteratively, bottom up</p> 142<pre><code class=python>from pyparsing import * 143s = "Hello World!" 144word = Word(alphas) 145grammar = word 146print grammar.parseString(s) 147# Only grabs "Hello"</code></pre> 148<p> 149<div class="fragment"></p> 150<pre><code class=python>word_list = OneOrMore(word) 151grammar = word_list 152# Now we get a list ["Hello", "World"]</code></pre> 153<p> 154</div><div class="fragment"></p> 155<pre><code class=python>end_punc = oneOf(". ! ?") 156grammar = word_list + end_punc 157# Grabs the end symbol ["Hello", "World", "!"]</code></pre> 158<p> 159</div><div class="fragment"></p> 160<pre><code class=python>grammar = Group(word_list) + end_punc.suppress() 161# Group and suppress [["Hello", "World"]]</code></pre> 162<p> 163</div></p> 164</section><section class="vertical-slide" data-background-transition="none"> 165<p> 166<h3><a href="code/hello_world.py">hello_world.py</a></h3></p> 167<br> 168<p> 169Like OOP, each mini-grammar can be reused</p> 170<pre><code class=python>s2 = "Hello sir, how are you today?" 171phrase = Group(word_list) + (Literal(",") | end_punc).suppress() 172grammar = OneOrMore(phrase) 173print grammar.parseString(s2)</code></pre> 174<p> 175<div class="fragment"></p> 176<pre><code class=python># [['Hello', 'sir'], ['how', 'are', 'you', 'today']]</code></pre> 177<p> 178</div></p> 179</section> 180</section><section class="vertical-stack"> 181<section class="vertical-slide" data-background-transition="none"> 182<p> 183<h3><a href="code/records.py">records.py</a></h3>Take the raw data with missing values</p> 184<pre><code class=python>sue 185Travis Hoppe 31 186Marky Mark 42 187 188James earl JONES 189Rudolfo Alphonzo Raffaelo Pierre di Valentina D'Antonguolla 31</code></pre> 190<p> 191<div class="fragment">
191and transform it into a nicely type-casted JSON</p> 192<pre><code class=python>[{ "age": null, "name": "Sue"}, 193 { "age": 31, "name": "Travis Hoppe"}, 194 { "age": 42, "name": "Marky Mark"}, 195 { "age": null, "name": "James Earl Jones"}, 196 { "age": 31, "name": "Rudolfo Alphonzo Raffaelo Pierre Di Valentina D'Antonguolla" }]</code></pre> 197<p> 198</div></p> 199</section><section class="vertical-slide" data-background-transition="none"> 200<p> 201<h3><a href="code/records.py">records.py</a></h3>The data guides the grammar</p> 202<pre><code class=python>sue 203Travis Hoppe 31 204Marky Mark 42 205 206James earl JONES 207Rudolfo Alphonzo Raffaelo Pierre di Valentina D'Antonguolla 31</code></pre> 208<p> 209and self-documents the process for maintenance</p> 210<pre><code class=python>ParserElement.setDefaultWhitespaceChars(' \t') 211 212name = Word(alphas + "'") 213full_name = Group(OneOrMore(name))("name") 214age = Word(nums)("age") 215EOL = LineEnd().suppress() 216 217record = full_name + Optional(age) + EOL 218record_list = OneOrMore(record | EOL)</code></pre> 219</section><section class="vertical-slide" data-background-transition="none"> 220<p> 221<h3><a href="code/records.py">records.py</a></h3>Our first attempt gives</p> 222<pre><code class=python>print record_list.parseString(data)
223# [['sue'], ['Travis', 'Hoppe'], '31', ['Marky', 'Mark'], '42', ['James', 'earl', 'JONES'], ['Rudolfo', 'Alphonzo', 'Raffaelo', 'Pierre', 'di', 'Valentina', "D'Antonguolla"], '31']</code></pre> 224<br> 225<p> 226Format the results</p> 227<pre><code class=python>def clean_record(tokens): 228 name = ' '.join(tokens["name"]).title() 229 if "age" in tokens: 230 age = int(tokens["age"]) 231 else: 232 age = None 233 return {'name':name, 'age':age} 234 235record.setParseAction(clean_record)</code></pre> 236</section><section class="vertical-slide" data-background-transition="none"> 237<p> 238<h3><a href="code/records.py">records.py</a></h3>Proper type casting, string formatting, and a dictionary!</p> 239<pre><code class=python>sol = record_list.parseString(data) 240print sol 241# [{'age': None, 'name': 'Sue'}, {'age': 31, 'name': 'Travis Hoppe'}, {'age': 42, 'name': 'Marky Mark'}, {'age': None, 'name': 'James Earl Jones'}, {'age': 31, 'name': "Rudolfo Alphonzo Raffaelo Pierre Di Valentina D'Antonguolla"}]</code></pre> 242<br> 243<p> 244Pretty-print the results in JSON</p> 245<pre><code class=python>import json 246js = json.dumps(sol.asList(),indent=2) 247print js 248 249# [{"age": null, "name": "Sue"}, 250# { "age": 31, "name": "Travis Hoppe"}, 251# { "age": 42, "name": "Marky Mark"}, 252# { "age": null, "name": "James Earl Jones"}, 253# { "age": 31, "name": "Rudolfo Alphonzo Raffaelo Pierre Di Valentina D'Antonguolla" }]</code></pre> 254</section> 255</section><section class="vertical-stack"> 256<section class="vertical-slide" data-background-transition="none"> 257<p> 258<h3><a href="code/recursive.py">recursive.py</a></h3></p> 259<pre><code class=python>raw ='''(defun factorial (x) 260(if (zerop x) 1 261(* x (factorial (- x 1)))))'''</code></pre> 262<p> 263<div class="fragment"></p> 264<pre><code class=python>from pyparsing import * 265alpha = Word(alphas) 266operation = oneOf("+ * - /") 267number = Word(nums) 268argument = alpha | number | operation</code></pre> 269<p> 270</div><div class="fragment">The expression is a recursive grammar!</p> 271<pre><code class=python>expr = Forward() 272LP,RP = map(Suppress, "()") 273expr << (argument | Group(LP + ZeroOrMore(expr) + RP)) 274 275print expr.parseString(raw) 276# [['defun', 'factorial', ['x'], ['if', ['zerop', 'x'], '1', ['*', 'x', ['factorial', ['-', 'x', '1']]]]]]</code></pre> 277<p> 278</div></p> 279</section> 280</section><section class="vertical-stack"> 281<section class="vertical-slide" data-background-transition="none"> 282<p> 283<h3><a href="code/postfix_calc.py">postfix_calc.py</a></h3>Evaluate the string as a mathematical expression</p> 284<pre><code class=python>s = "((((3 4 +) 9 *) (8 9 +) *) 1050 -) 2 ^)"</code></pre> 285<p> 286<div class="fragment"></p> 287<pre><code class=python>from pyparsing import * 288expr = Forward() 289number = Word(nums)("value") 290operation = oneOf("+ * ^ -") 291LP, RP = Literal("(").suppress(), Literal(")").suppress() 292nest = (LP + expr + RP) 293expr << Group( (number | nest) 294 + (number | nest) 295 + operation) 296 297print expr.parseString(s) 298#[[[[[['3', '4', '+'], '9', '*'], ['8', '9', '+'], '*'], '1050', '-'], '2', '^']]</code></pre> 299<p> 300</div></p> 301</section><section class="vertical-slide" data-background-transition="none"> 302<p> 303<h3><a href="code/postfix_calc.py">postfix_calc.py</a></h3>Convert numbers into integers</p> 304<pre><code class=python>number.setParseAction(lambda x:int(x["value"]))</code></pre> 305<br> 306<p> 307Apply a function depending on the symbol</p> 308<pre><code class=python>actions = {"+":lambda x,y:x+y, 309 "*":lambda x,y:x*y, 310 "-":lambda x,y:x-y, 311 "^":lambda x,y:x**y} 312 313def apply(tokens): 314 a,b,op = tokens[0] 315 val = actions[op](a,b) 316 print "Evaluating {} {} {} = {}".format(a,op,b,val) 317 return val 318 319expr.setParseAction(apply)</code></pre> 320</section><section class="vertical-slide" data-background-transition="none"> 321<p> 322<h3><a href="code/postfix_calc.py">postfix_calc.py</a></h3></p> 323<pre><code class=python>s = "((((3 4 +) 9 *) (8 9 +) *) 1050 -) 2 ^)"</code></pre> 324<br> 325<p> 326Parse results, remove from last group</p> 327<pre><code class=python>result = expr.parseString(s)[0] 328print "Final value:", result</code></pre> 329<br> 330<p> 331Print statements help debug (use <a href="http://docs.python.org/2/l
331ibrary/logging.html">logging</a>!)</p> 332<pre><code class=python>Evaluating 3 + 4 = 7 333Evaluating 7 * 9 = 63 334Evaluating 8 + 9 = 17 335Evaluating 63 * 17 = 1071 336Evaluating 1071 - 1050 = 21 337Evaluating 21 ^ 2 = 441 338Final value: 441</code></pre> 339</section><section class="vertical-slide" data-background-transition="none"> 340<p> 341<h3><a href="code/postfix_calc.py">postfix_calc.py</a></h3></p> 342<br> 343<p> 344Extending the functionality is easy!</p> 345<br> 346<pre><code class=python>actions["%"] = lambda a,b: a%b 347actions["choose"] = scipy.misc.comb</code></pre> 348<br> 349<br> 350<p> 351With a little work, we could make use of unary operators,<br>arbitrary length inputs, and floats!</p> 352</section> 353</section><section class="vertical-stack"> 354<section class="vertical-slide" data-background-transition="none"> 355<p> 356<h3>Why pyparsing?</h3>Grammar specification is a natural-looking part of the python<br>Class/function names are easier than specialized typography<br>Easy-to-read and familiar in style<br>Processing <em>during</em> parsing<br>Whitespace is <em>optional</em><div class="fragment"><br><h3>Why not?</h3>Slow for complex grammars (memoization helps)<br>Specialized libraries may be better (xml, html)<br><em>Sometimes</em> overkill (<code>str.split</code>?)<br></div></p> 357</section> 358</section><section class="vertical-stack"> 359<section class="vertical-slide" data-background-transition="none"> 360<p> 361<h1>Thanks, you.</h1></p> 362</section><section class="vertical-slide" data-background-transition="none"> 363<p> 364<div display='inline' align='left'><h2>How were these slides made?</h2></div></p> 365<br> 366<p> 367<div display='inline' align='left'><h3>Math Rendering: <svg class="latexSVG" height="100%" version="1.2" viewBox="0 0 25.00225 9.15575" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 368 <defs> 369 <g> 370 <symbol id="equation_WLNOJ_2" overflow="visible"> 371 <path d="M 5.796875 -2.578125 L 5.546875 -2.578125 C 5.4375 -1.5625 5.296875 -0.3125 3.546875 -0.3125 L 2.734375 -0.3125 C 2.265625 -0.3125 2.25 -0.375 2.25 -0.703125 L 2.25 -6.015625 C 2.25 -6.359375 2.25 -6.5 3.1875 -6.5 L 3.515625 -6.5 L 3.515625 -6.8125 C 3.15625 -6.78125 2.25 -6.78125 1.84375 -6.78125 C 1.453125 -6.78125 0.671875 -6.78125 0.328125 -6.8125 L 0.328125 -6.5 L 0.5625 -6.5 C 1.328125 -6.5 1.359375 -6.390625 1.359375 -6.03125 L 1.359375 -0.78125 C 1.359375 -0.421875 1.328125 -0.3125 0.5625 -0.3125 L 0.328125 -0.3125 L 0.328125 0 L 5.515625 0 Z M 5.796875 -2.578125 " style="stroke:none;"/> 372 </symbol> 373 <symbol id="equation_WLNOJ_1" overflow="visible"> 374 <path d="M 6.640625 -6.75 L 0.546875 -6.75 L 0.359375 -4.5 L 0.609375 -4.5 C 0.75 -6.109375 0.890625 -6.4375 2.40625 -6.4375 C 2.578125 -6.4375 2.84375 -6.4375 2.9375 -6.421875 C 3.15625 -6.375 3.15625 -6.265625 3.15625 -6.046875 L 3.15625 -0.78125 C 3.15625 -0.453125 3.15625 -0.3125 2.109375 -0.3125 L 1.703125 -0.3125 L 1.703125 0 C 2.109375 -0.03125 3.125 -0.03125 3.59375 -0.03125 C 4.046875 -0.03125 5.078125 -0.03125 5.484375 0 L 5.484375 -0.3125 L 5.078125 -0.3125 C 4.03125 -0.3125 4.03125 -0.453125 4.03125 -0.78125 L 4.03125 -6.046875 C 4.03125 -6.234375 4.03125 -6.375 4.21875 -6.421875 C 4.328125 -6.4375 4.59375 -6.4375 4.78125 -6.4375 C 6.296875 -6.4375 6.4375 -6.109375 6.578125 -4.5 L 6.828125 -4.5 Z M 6.640625 -6.75 " style="stroke:none;"/> 375 </symbol> 376 <symbol id="equation_WLNOJ_4" overflow="visible"> 377 <path d="M 1.359375 -0.78125 C 1.359375 -0.421875 1.328125 -0.3125 0.5625 -0.3125 L 0.328125 -0.3125 L 0.328125 0 L 6.078125 0 L 6.5 -2.578125 L 6.25 -2.578125 C 6 -1.03125 5.765625 -0.3125 4.0625 -0.3125 L 2.734375 -0.3125 C 2.265625 -0.3125 2.25 -0.375 2.25 -0.703125 L 2.25 -3.375 L 3.140625 -3.375 C 4.109375 -3.375 4.21875 -3.046875 4.21875 -2.203125 L 4.46875 -2.203125 L 4.46875 -4.84375 L 4.21875 -4.84375 C 4.21875 -3.984375 4.109375 -3.671875 3.140625 -3.671875 L 2.25 -3.671875 L 2.25 -6.078125 C 2.25 -6.40625 2.265625 -6.46875 2.734375 -6.46875 L 4.015625 -6.46875 C 5.546875 -6.46875 5.8125 -5.921875 5.96875 -4.53125 L 6.21875 -4.53125 L 5.9375 -6.78125 L 0.328125 -6.78125 L 0.328125 -6.46875 L 0.5625 -6.46875 C 1.328125 -6.46875 1.359375
377-6.359375 1.359375 -6 Z M 1.359375 -0.78125 " style="stroke:none;"/> 378 </symbol> 379 <symbol id="equation_WLNOJ_3" overflow="visible"> 380 <path d="M 4 -3.84375 L 5.375 -5.859375 C 5.59375 -6.171875 5.9375 -6.484375 6.8125 -6.5 L 6.8125 -6.8125 C 6.4375 -6.796875 5.96875 -6.78125 5.71875 -6.78125 C 5.3125 -6.78125 4.828125 -6.78125 4.4375 -6.8125 L 4.4375 -6.5 C 4.828125 -6.484375 5.046875 -6.265625 5.046875 -6.046875 C 5.046875 -5.9375 5.03125 -5.921875 4.96875 -5.8125 L 3.828125 -4.125 L 2.546875 -6.046875 C 2.515625 -6.078125 2.46875 -6.15625 2.46875 -6.203125 C 2.46875 -6.3125 2.6875 -6.484375 3.125 -6.5 L 3.125 -6.8125 C 2.765625 -6.78125 2.046875 -6.78125 1.671875 -6.78125 C 1.359375 -6.78125 0.734375 -6.78125 0.375 -6.8125 L 0.375 -6.5 L 0.5625 -6.5 C 1.109375 -6.5 1.296875 -6.4375 1.484375 -6.15625 L 3.3125 -3.375 L 1.6875 -0.96875 C 1.546875 -0.765625 1.25 -0.3125 0.234375 -0.3125 L 0.234375 0 C 0.59375 -0.015625 1.015625 -0.03125 1.34375 -0.03125 C 1.71875 -0.03125 2.265625 -0.03125 2.625 0 L 2.625 -0.3125 C 2.15625 -0.3125 2 -0.59375 2 -0.765625 C 2 -0.859375 2.03125 -0.890625 2.09375 -1 L 3.515625 -3.09375 L 5.078125 -0.71875 C 5.109375 -0.671875 5.140625 -0.640625 5.140625 -0.609375 C 5.140625 -0.484375 4.921875 -0.3125 4.484375 -0.3125 L 4.484375 0 C 4.828125 -0.03125 5.5625 -0.03125 5.9375 -0.03125 C 6.359375 -0.03125 6.8125 -0.015625 7.234375 0 L 7.234375 -0.3125 L 7.046875 -0.3125 C 6.53125 -0.3125 6.3125 -0.359375 6.109375 -0.671875 Z M 4 -3.84375 " style="stroke:none;"/> 381 </symbol> 382 <symbol id="equation_WLNOJ_0" overflow="visible"> 383 <path d="M 3.125 -4.8125 C 3.09375 -4.921875 3.0625 -4.96875 2.9375 -4.96875 C 2.796875 -4.96875 2.78125 -4.921875 2.734375 -4.8125 L 1.125 -0.734375 C 1.0625 -0.5625 0.9375 -0.25 0.3125 -0.25 L 0.3125 0 C 0.546875 -0.015625 0.796875 -0.03125 1.03125 -0.03125 C 1.3125 -0.03125 1.828125 0 1.875 0 L 1.875 -0.25 C 1.5625 -0.25 1.359375 -0.390625 1.359375 -0.578125 C 1.359375 -0.640625 1.375 -0.65625 1.40625 -0.71875 L 1.734375 -1.578125 L 3.71875 -1.578125 L 4.125 -0.5625 C 4.125 -0.53125 4.15625 -0.484375 4.15625 -0.453125 C 4.15625 -0.25 3.78125 -0.25 3.59375 -0.25 L 3.59375 0 C 3.9375 -0.015625 4.390625 -0.03125 4.625 -0.03125 C 4.953125 -0.03125 5.484375 0 5.546875 0 L 5.546875 -0.25 L 5.421875 -0.25 C 4.953125 -0.25 4.90625 -0.328125 4.828125 -0.515625 Z M 2.71875 -4.09375 L 3.609375 -1.828125 L 1.828125 -1.828125 Z M 2.71875 -4.09375 " style="stroke:none;"/> 384 </symbol> 385 </g> 386 </defs> 387 <g id="surface1"> 388 <g> 389 <use x="-0.328125" xlink:href="#equation_WLNOJ_2" y="7.01075"/> 390 </g> 391 <g>
392 <use x="2.311875" xlink:href="#equation_WLNOJ_0" y="4.96875"/> 393 </g> 394 <g> 395 <use x="6.698875" xlink:href="#equation_WLNOJ_1" y="7.01075"/> 396 </g> 397 <g> 398 <use x="12.232875" xlink:href="#equation_WLNOJ_4" y="9.15575"/> 399 </g> 400 <g> 401 <use x="17.767875" xlink:href="#equation_WLNOJ_3" y="7.01075"/> 402 </g> 403 </g> 404</svg></h3></div><div display='inline' align='left'><h3>JavaScript : <a href="http://hakim.se/projects/reveal-js">reveal.js</a></h3></div><div display='inline' align='left'><h3>Markdown : <a href="http://daringfireball.net/">Daring Fireball</a></h3></div></p> 405<br> 406<hr> 407<br> 408<p> 409<div display='inline' align='left'><h3>Markdown to HTML: <a href="https://github.com/thoppe/md2reveal">md2reveal.py</a></h3></div><div display='inline' align='left'><em> (uses pyparsing to write a talk about pyparsing)</em></div></p> 410</section><section class="vertical-slide" data-background-transition="none"> 411<p> 412<h2>How does it work?</h2></p> 413<br> 414<p> 415A <strong>text-based</strong> human-readable markup.<br>SVG equations <svg class="latexSVG" height="100%" version="1.2" viewBox="0 0 37.61575 8.848375" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 416 <defs> 417 <g> 418 <symbol id="equation_YBWFB_5" overflow="visible"> 419 <path d="M 1.859375 -2.296875 C 2.15625 -2.296875 2.890625 -2.328125 3.390625 -2.53125 C 4.09375 -2.828125 4.140625 -3.421875 4.140625 -3.5625 C 4.140625 -4 3.765625 -4.40625 3.078125 -4.40625 C 1.96875 -4.40625 0.453125 -3.4375 0.453125 -1.6875 C 0.453125 -0.671875 1.046875 0.109375 2.03125 0.109375 C 3.453125 0.109375 4.28125 -0.953125 4.28125 -1.0625 C 4.28125 -1.125 4.234375 -1.203125 4.171875 -1.203125 C 4.109375 -1.203125 4.09375 -1.171875 4.03125 -1.09375 C 3.25 -0.109375 2.15625 -0.109375 2.046875 -0.109375 C 1.265625 -0.109375 1.171875 -0.953125 1.171875 -1.265625 C 1.171875 -1.390625 1.1875 -1.6875 1.328125 -2.296875 Z M 1.390625 -2.515625 C 1.78125 -4.03125 2.8125 -4.1875 3.078125 -4.1875 C 3.53125 -4.1875 3.8125 -3.890625 3.8125 -3.5625 C 3.8125 -2.515625 2.21875 -2.515625 1.796875 -2.515625 Z M 1.390625 -2.515625 " style="stroke:none;"/> 420 </symbol> 421 <symbol id="equation_YBWFB_0" overflow="visible"> 422 <path d="M 2.265625 -4.359375 C 2.265625 -4.46875 2.171875 -4.625 1.984375 -4.625 C 1.796875 -4.625 1.59375 -4.4375 1.59375 -4.234375 C 1.59375 -4.125 1.671875 -3.96875 1.875 -3.96875 C 2.0625 -3.96875 2.265625 -4.171875 2.265625 -4.359375 Z M 0.84375 -0.8125 C 0.8125 -0.71875 0.78125 -0.640625 0.78125 -0.515625 C 0.78125 -0.1875 1.046875 0.0625 1.4375 0.0625 C 2.125 0.0625 2.4375 -0.890625 2.4375 -1 C 2.4375 -1.09375 2.34375 -1.09375 2.328125 -1.09375 C 2.234375 -1.09375 2.21875 -1.046875 2.1875 -0.96875 C 2.03125 -0.40625 1.734375 -0.125 1.453125 -0.125 C 1.3125 -0.125 1.28125 -0.21875 1.28125 -0.375 C 1.28125 -0.53125 1.328125 -0.65625 1.390625 -0.8125 C 1.46875 -1 1.546875 -1.1875 1.609375 -1.375 C 1.671875 -1.546875 1.9375 -2.171875 1.953125 -2.265625 C 1.984375 -2.328125 2 -2.40625 2 -2.484375 C 2 -2.8125 1.71875 -3.078125 1.34375 -3.078125 C 0.640625 -3.078125 0.328125 -2.125 0.328125 -2 C 0.328125 -1.921875 0.421875 -1.921875 0.453125 -1.921875 C 0.546875 -1.921875 0.546875 -1.953125 0.578125 -2.03125 C 0.75 -2.625 1.0625 -2.875 1.3125 -2.875 C 1.421875 -2.875 1.484375 -2.828125 1.484375 -2.640625 C 1.484375 -2.46875 1.453125 -2.375 1.28125 -1.9375 Z M 0.84375 -0.8125 " style="stroke:none;"/> 423 </symbol> 424 <symbol id="equation_YBWFB_1" overflow="visible"> 425 <path d="M 2.171875 -2.53125 L 3 -2.53125 C 2.890625 -2.109375 2.734375 -1.484375 2.734375 -0.921875 C 2.734375 -0.640625 2.78125 -0.453125 2.8125 -0.3125 C 2.921875 0.046875 3.015625 0.0625 3.125 0.0625 C 3.296875 0.0625 3.453125 -0.078125 3.453125 -0.25 C 3.453125 -0.296875 3.4375 -0.328125 3.40625 -0.390625 C 3.265625 -0.65625 3.140625 -1.046875 3.140625 -1.625 C 3.140625 -1.75 3.140625 -2.03125 3.234375 -2.53125 L 4.109375 -2.53125 C 4.234375 -2.53125 4.296875 -2.53125 4.375 -2.578125 C 4.46875 -2.65625 4.484375 -2.765625 4.484375 -2.796875 C 4.484375 -3 4.3125 -3 4.1875 -3 L 1.5625 -3 C 1.28125 -3 1.078125 -2.9375 0.765625 -2.640625 C 0.578125 -2.484375 0.3125 -2.109375 0.3125 -2.046875 C 0.3125 -1.96875 0.40625 -1.96875 0.4375 -1.96875 C 0.515625 -1.96875 0.515625 -1.984375 0.5625 -2.046875 C 0.90625 -2.53125 1.34375 -2.53125 1.5 -2.53125 L 1.921875 -2.53125 C 1.703125 -1.765625 1.328125 -0.9375 1.125 -0.515625 C 1.078125 -0.4375 1.015625 -0.28125 0.984375 -0.265625 C 0.984375 -0.234375 0.96875 -0.203125 0.96875 -0.15625 C 0.96875 -0.046875 1.046875 0.0625 1.21875 0.0625 C 1.484375 0.0625 1.5625 -0.25 1.734375 -0.875 Z M 2.171875 -2.53125 " style="stroke:none;"/> 426 </symbol> 427 <symbol id="equation_YBWFB_3" overflow="visible"> 428 <path d="M 6.84375 -3.265625 C 7 -3.265625 7.1875 -3.265625 7.1875 -3.453125 C 7.1875 -3.65625 7 -3.65625 6.859375
428-3.65625 L 0.890625 -3.65625 C 0.75 -3.65625 0.5625 -3.65625 0.5625 -3.453125 C 0.5625 -3.265625 0.75 -3.265625 0.890625 -3.265625 Z M 6.859375 -1.328125 C 7 -1.328125 7.1875 -1.328125 7.1875 -1.53125 C 7.1875 -1.71875 7 -1.71875 6.84375 -1.71875 L 0.890625 -1.71875 C 0.75 -1.71875 0.5625 -1.71875 0.5625 -1.53125 C 0.5625 -1.328125 0.75 -1.328125 0.890625 -1.328125 Z M 6.859375 -1.328125 " style="stroke:none;"/> 429 </symbol> 430 <symbol id="equation_YBWFB_2" overflow="visible"> 431 <path d="M 2.9375 -6.375 C 2.9375 -6.625 2.9375 -6.640625 2.703125 -6.640625 C 2.078125 -6 1.203125 -6 0.890625 -6 L 0.890625 -5.6875 C 1.09375 -5.6875 1.671875 -5.6875 2.1875 -5.953125 L 2.1875 -0.78125 C 2.1875 -0.421875 2.15625 -0.3125 1.265625 -0.3125 L 0.953125 -0.3125 L 0.953125 0 C 1.296875 -0.03125 2.15625 -0.03125 2.5625 -0.03125 C 2.953125 -0.03125 3.828125 -0.03125 4.171875 0 L 4.171875 -0.3125 L 3.859375 -0.3125 C 2.953125 -0.3125 2.9375 -0.421875 2.9375 -0.78125 Z M 2.9375 -6.375 " style="stroke:none;"/> 432 </symbol> 433 <symbol id="equation_YBWFB_4" overflow="visible"> 434 <path d="M 6.5625 -2.296875 C 6.734375 -2.296875 6.921875 -2.296875 6.921875 -2.5 C 6.921875 -2.6875 6.734375 -2.6875 6.5625 -2.6875 L 1.171875 -2.6875 C 1 -2.6875 0.828125 -2.6875 0.828125 -2.5 C 0.828125 -2.296875 1 -2.296875 1.171875 -2.296875 Z M 6.5625 -2.296875 " style="stroke:none;"/> 435 </symbol> 436 </g> 437 </defs> 438 <g id="surface1"> 439 <g> 440 <use x="-0.453125" xlink:href="#equation_YBWFB_5" y="8.739"/> 441 </g> 442 <g> 443 <use x="4.185875" xlink:href="#equation_YBWFB_0" y="4.625"/> 444 <use x="7.004685" xlink:href="#equation_YBWFB_1" y="4.625"/> 445 </g> 446 <g> 447 <use x="15.178875" xlink:href="#equation_YBWFB_3" y="8.739"/> 448 </g> 449 <g> 450 <use x="25.694875" xlink:href="#equation_YBWFB_4" y="8.739"/> 451 </g> 452 <g> 453 <use x="33.443875" xlink:href="#equation_YBWFB_2" y="8.739"/> 454 </g> 455 </g> 456</svg>, and <a href="http://thoppe.github.io/">links</a>!<br>The code for <em>this particular slide</em> looks like this:</p> 457<br> 458<pre><code class=python>## How does it work? 459 460A *text-based* human-readable markup. 461Equation rendering is simple $e^{i \pi} = -1$. 462and [links](http://thoppe.github.io/)! 463The code for this _particular slide_ looks like this:</code></pre> 464</section> 465</section> 466 </div></div> 467 468
468<script src="reveal.js/lib/js/head.min.js"></script>
468 469
469<script src="reveal.js/js/reveal.js"></script>
469 470 471
471<script> 472 // Full list of configuration options available here: 473 // https://github.com/hakimel/reveal.js#configuration 474 Reveal.initialize({ 475 overview: true, height: 900, keyboard: true, touch: true, hideAddressBar: true, rollingLinks: false, mouseWheel: false, controls: true, width: 1200, viewDistance: 3, rtl: false, progress: true, fragments: true, autoSlide: 0, autoSlideStoppable: true, backgroundtransition: "default", transitionSpeed: "default", center: true, embedded: true, transition: "default", maxScale: 1.2, minScale: 0.2, previewLinks: false, margin: 0.05, loop: false, history: true, 476 477 theme: Reveal.getQueryHash().theme, 478 // available themes are in reveal.js/css/theme 479 480 // Optional libraries used to extend on reveal.js 481 dependencies: [ { src: 'reveal.js/lib/js/classList.js', condition: function() { 482 return !document.body.classList; } }, 483 484{ src: 'reveal.js/plugin/markdown/showdown.js', condition: function() { 485 return !!document.querySelector( '[data-markdown]' ); } }, 486 487{ src: 'reveal.js/plugin/markdown/markdown.js', condition: function() { 488 return !!document.querySelector( '[data-markdown]' ); } }, 489 490{ src: 'reveal.js/plugin/highlight/highlight.js', async: true, callback: 491 function() { hljs.initHighlightingOnLoad(); } }, 492 493{ src: 'reveal.js/plugin/zoom-js/zoom.js', async: true, condition: 494 function() { return !!document.body.classList; } }, 495 ] 496 497 }); 498 </script>
498 499 500 </body> 501</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.