[
  {
    "path": ".gitignore",
    "content": "node_modules/\n"
  },
  {
    "path": "README.md",
    "content": "# Slide\n\nThe most simple plain text presentation maker.\n\nThis version is a standalone HTML page of 4K in size that you can edit in place\nand get a working presentation. No other tools needed except for a text editor.\nNo programming knowledge is required, too.\n\nAndroid implementation can be found [here](https://github.com/trikita/slide).\n\n## Tutorial\n\n1. Download `slide.html`.\n   [Open this link](https://raw.githubusercontent.com/trikita/slide-html/master/slide.html)\n   and press <kbd>Ctrl+S</kbd>.\n2. Open the downloaded `slide.html` with a text editor.\n3. Find the line `<pre id=\"slide\">` (should be somewhere around line 36).\n4. Edit the text. This is the contents of your presentation.\n5. After you save the file - open it in your browser and see the results. You\n\t can edit, save and refresh the browser to see how your presentation looks\n\t like.\n\n## Demo\n\nEither open `slide.html` in your browser or [view it online](http://htmlpreview.github.io/?https://github.com/trikita/slide-html/blob/master/slide.html).\n\n## Syntax\n\nSlides are separated with a blank line.\n\nThe font size of each slide is scaled automatically to fit the screen. This is\nsuitable for [Takahashi method](https://en.wikipedia.org/wiki/Takahashi_method).\n\nHeadlines use a larger font size and start with `#` sign.\n\nEmphasized text is written as bold and must be surrounded with asterisks, `*like this*`.\n\nTo print an actual asterist just write it twice, `** like this`.\n\nCode blocks are written with monospace font and must start with at least two spaces.\n\nTo disable the special meaning of newlines, spaces or `#` put a dot at the\nbeginning of the line.\n\n## Styling\n\nAbove the slide contents there is a small style block. You can specify the\ndefault font, foreground and background colors for your slides. You can also\ncustomize header, monospace and emphasized font styles.\n\n## Printing\n\nYou can print your presentation, in this case the slides will be printed as small thumbnails\nso that you could make notes on paper or use it as a story plan for your speech.\n\n## Development\n\nWe really want to keep it minimal, but if you want to customize it or offer a\npull request you can edit files inside the `src` folder. Then you may open\n`src/slide.html` to view your changes, or run `npm run build` to generate the\nstandalone `slide.html` version.\n\n## License\n\nCode is distributed under MIT license, feel free to use it. \n\nMade by [Trikita](http://trikita.co) - feel free to checkout our other works!\n"
  },
  {
    "path": "build.js",
    "content": "var fs = require('fs');\n\nvar uglify = require(\"uglify-js\").minify;\nvar cssmin = require('cssmin');\n\nvar css = fs.readFileSync(\"src/slide.css\", encoding='utf8');\nvar js = fs.readFileSync(\"src/slide.js\", encoding='utf8');\nvar html = fs.readFileSync(\"src/slide.html\", encoding='utf8');\n\nvar inline = html\n  .replace(/<script src=\"slide.js\"><\\/script>/, '<script>'+uglify(js, {fromString: true}).code+'</script>')\n  .replace(/<link .*href=\"slide.css\">/, '<style>'+cssmin(css)+'</style>');\n\nconsole.log(inline);\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"slide\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Plain text presentation maker\",\n  \"scripts\": {\n    \"lint\": \"jshint src/slide.js\",\n    \"build\": \"node build.js > slide.html\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/trikita/slide-html.git\"\n  },\n  \"author\": \"Serge Zaitsev <zaitsev.serge@gmail.com>\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/trikita/slide-html/issues\"\n  },\n  \"homepage\": \"https://github.com/trikita/slide-html#readme\",\n  \"devDependencies\": {\n    \"cssmin\": \"^0.4.3\",\n    \"jshint\": \"^2.9.2\",\n    \"uglify-js\": \"^2.6.2\"\n  }\n}\n"
  },
  {
    "path": "slide.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n    <title>Slide</title>\n    <style>*{margin:0;padding:0;box-sizing:border-box}#slide{display:none}.slide{white-space:nowrap}.slide-content{align-self:center}@media screen{body{position:absolute;top:50%;left:50%}.slide-4x3{width:1024px;height:768px;margin:-384px 0 0 -512px}.slide-16x9{width:1024px;height:576px;margin:-288px 0 0 -512px}.slide-16x10{width:1024px;height:640px;margin:-320px 0 0 -512px}.slide{position:absolute;width:100%;height:100%;display:flex;justify-content:center;overflow:hidden}}@media print{body{transform:none!important}h1{font-size:1.8rem;line-height:1.5;letter-spacing:-.05rem;font-weight:300}.slide-root{width:100%;display:flex;flex-wrap:wrap;align-items:stretch}.slide-content{transform:none!important}.slide{display:flex;justify-content:center;flex:1;padding:.5rem;margin:.5rem .5rem 4rem .5rem;border:1px solid rgba(0,0,0,0.2);visibility:visible!important}}</style>\n    <script>function trimIndent(e){var t=(e.match(INDENT_RE)||[\"\"])[0].length;if(t>0){var n=e.substring(0,t);return e.replace(new RegExp(n,\"g\"),\"\")}}function renderSlide(e,t,n){var i=t.split(\"\\n\"),r=-1,o=document.createElement(\"div\"),d=document.createElement(\"div\"),s=\"\";o.className=\"slide slide-\"+n,d.className=\"slide-content\";for(var l=0;l<i.length;l++){var a=i[l];if(a.startsWith(\"#\"))s=s+\"<h1>\"+a.substring(1)+\"</h1>\";else if(a.startsWith(\"  \")||a.startsWith(\"\t\"))s=s+\"<pre>\"+a.replace(/^(  )|\\t/,\"\")+\"</pre>\";else{a.startsWith(\".\")&&(a=a.substring(1));for(var c=0;c<a.length;c++){var h=a.charAt(c);\"*\"==h?-1==r?(s+=\"<strong>\",r=s.length):(r!=s.length?s+=\"</strong>\":s=s.substring(0,s.length-8)+\"*\",r=-1):s+=h}s+=\"<br/>\"}}d.innerHTML=s,o.appendChild(d),e.appendChild(o),o.style.visibility=\"hidden\"}function render(e){var t=document.createElement(\"div\");t.className=\"slide-root\",document.body.appendChild(t),e=trimIndent(e);for(var n=e.split(/[\\s+]\\n/gm),i=0;i<n.length;i++){var r=n[i].trim();renderSlide(t,r,i)}return t}function resize(){var e=window.innerWidth,t=window.innerHeight,n=document.body.offsetWidth,i=document.body.offsetHeight,r=n/i>e/t?e/n:t/i;document.body.style.transform=\"scale(\"+r+\")\"}function goTo(e){currentSlide=e,window.location.hash=e;for(var t=document.querySelectorAll(\".slide\"),n=0;n<t.length;n++){var i=t[n],r=i.children[0],o=.8*i.offsetWidth/r.offsetWidth,d=.8*i.offsetHeight/r.offsetHeight;r.style.transform=\"scale(\"+Math.min(o,d)+\")\",n==currentSlide?i.style.visibility=\"\":i.style.visibility=\"hidden\"}}function next(){goTo(Math.min(currentSlide+1,document.querySelectorAll(\".slide\").length-1))}function prev(){goTo(Math.max(currentSlide-1,0))}var INDENT_RE=/^(?:( )+|\\t+)/,currentSlide=-1;window.onload=function(){resize(),render(document.getElementById(\"slide\").innerHTML),goTo(window.location.hash.substring(1)||0),window.onclick=next,window.onresize=resize,window.onkeydown=function(e){39==e.keyCode?next():37==e.keyCode&&prev()}};</script>\n    <style media=\"screen\">\n      @import url(https://fonts.googleapis.com/css?family=Lato:400,700&subset=latin,latin-ext);\n      @import url(https://fonts.googleapis.com/css?family=Oswald:400,700);\n      @import url(https://fonts.googleapis.com/css?family=Inconsolata);\n      /* Customize theme: change body, h1, strong, pre or .slide class */\n      body {\n        font-family: 'Lato', sans-serif;\n        background-color: #edd400;\n        color: #453029;\n        line-height: 1.54;\n      }\n      .slide h1 {\n        font-family: 'Oswald', sans-serif;\n        font-weight: 400;\n        font-size: 2.6rem;\n      }\n      .slide pre {\n        font-family: 'Inconsolata';\n        font-size: 0.6rem;\n        line-height: 1.1;\n      }\n      .slide-10 h1 { color: #fff; text-shadow: 1px 1px 3px #453029; }\n      .slide-11 {\n        background: url(\"http://trikita.co/slide/icon.png\"), url(\"http://subtlepatterns2015.subtlepatterns.netdna-cdn.com/patterns/asanoha-400px.png\");\n        background-repeat: no-repeat, repeat;\n        background-size: 35%, auto;\n        background-position: bottom right;\n      }\n      .slide-13 .slide-content {\n        background-image: url(\"http://trikita.co/slide/write_framed.png\"),\n          url(\"http://trikita.co/slide/styles.gif\"),\n          url(\"http://trikita.co/slide/illustrate_framed.png\");\n        background-repeat: no-repeat;\n        background-size: 40%, 40%, 40%;\n        background-position: bottom left, bottom center, bottom right;\n      }\n    </style>\n  </head>\n  <body class=\"slide-16x9\">\n    <pre id=\"slide\">\n      #SLIDE\n      Good speech deserves time it takes\n      Save time for speech\n      Leave presentation to *Slide*\n\n      #Focus on content\n      Learn 5 markup rules\n      to make content look great\n\n      # #1\n      Each paragraph is a slide\n\n      # #2\n      Headers start with #\n\n      # #3\n      Emphasize *words*\n      surrounding them with **asterisks**\n\n      # #4\n      Indent code with 2 spaces\n        /* Day of week: Sakamoto's algorithm */\n        int dow(int y, int m, int d)\n        {\n          static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};\n          y -= m < 3;\n          return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;\n        }\n\n      # #5\n      Lines starting with a dot\n      disable markup such as\n      headlines, code or blank lines\n\n      ↵  = new slide\n      .# = headline\n      ** = emphasize\n      ␣␣ = monospace\n      .. = escape\n\n      # Styling with CSS\n\n      # Selectors\n      ..slide\n      ..slide h1\n      ..slide strong\n      ..slide pre\n      .\n      ..slide-N, where N is slide number\n\n      # Example\n      .\n        .slide-10 h1 {\n          color: #fff;\n          text-shadow: 1px 1px 3px #453029;\n        }\n      .\n\n      # CSS backgrounds\n        .slide-12 {\n          background: url(\"icon.png\"),\n                      url(\"bg.png\");\n          background-repeat: no-repeat, repeat;\n          background-size: 40%, auto;\n          background-position: bottom right;\n        }\n\n\n      # Print mode\n      You can print slide thumbnails\n      to practice your speech\n\n      Slide for Android\n      .\n      .\n      .\n\n      # Links\n      http://trikita.co/slide\n      https://github.com/trikita/slide\n      https://github.com/trikita/slide-html\n      https://play.google.com/store/apps/details?id=trikita.slide\n    </pre>\n  </body>\n</html>\n\n"
  },
  {
    "path": "src/slide.css",
    "content": "* {\n\tmargin: 0;\n\tpadding: 0;\n\tbox-sizing: border-box;\n}\n#slide { display: none; }\n.slide { white-space: nowrap; }\n.slide-content { align-self: center; }\n\n@media screen {\n\t/* Aspect ratio classes for the body tag */\n\tbody { position: absolute; top: 50%; left: 50%; }\n\t.slide-4x3 { width: 1024px; height: 768px; margin: -384px 0 0 -512px; }\n\t.slide-16x9 { width: 1024px; height: 576px; margin: -288px 0 0 -512px; }\n\t.slide-16x10 { width: 1024px; height: 640px; margin: -320px 0 0 -512px; }\n\n\t.slide {\n\t\tposition: absolute;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tdisplay: flex;\n\t\tjustify-content: center;\n\t\toverflow: hidden;\n\t}\n}\n\n@media print {\n\tbody { transform: none !important; }\n\th1 { font-size: 1.8rem; line-height: 1.5;  letter-spacing: -.05rem; font-weight: 300; }\n\t.slide-root { width: 100%; display: flex; flex-wrap: wrap; align-items: stretch; }\n\t.slide-content { transform: none !important; }\n\t.slide {\n\t\tdisplay: flex;\n\t\tjustify-content: center;\n\t\tflex: 1;\n\t\tpadding: 0.5rem;\n\t\tmargin: 0.5rem 0.5rem 4rem 0.5rem;\n\t\tborder: 1px solid rgba(0, 0, 0, 0.2);\n\t\tvisibility: visible !important;\n\t}\n}\n"
  },
  {
    "path": "src/slide.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n    <title>Slide</title>\n    <link rel=\"stylesheet\" href=\"slide.css\">\n    <script src=\"slide.js\"></script>\n    <style media=\"screen\">\n      @import url(https://fonts.googleapis.com/css?family=Lato:400,700&subset=latin,latin-ext);\n      @import url(https://fonts.googleapis.com/css?family=Oswald:400,700);\n      @import url(https://fonts.googleapis.com/css?family=Inconsolata);\n      /* Customize theme: change body, h1, strong, pre or .slide class */\n      body {\n        font-family: 'Lato', sans-serif;\n        background-color: #edd400;\n        color: #453029;\n        line-height: 1.54;\n      }\n      .slide h1 {\n        font-family: 'Oswald', sans-serif;\n        font-weight: 400;\n        font-size: 2.6rem;\n      }\n      .slide pre {\n        font-family: 'Inconsolata';\n        font-size: 0.6rem;\n        line-height: 1.1;\n      }\n      .slide-10 h1 { color: #fff; text-shadow: 1px 1px 3px #453029; }\n      .slide-11 {\n        background: url(\"http://trikita.co/slide/icon.png\"), url(\"http://subtlepatterns2015.subtlepatterns.netdna-cdn.com/patterns/asanoha-400px.png\");\n        background-repeat: no-repeat, repeat;\n        background-size: 35%, auto;\n        background-position: bottom right;\n      }\n      .slide-13 .slide-content {\n        background-image: url(\"http://trikita.co/slide/write_framed.png\"),\n          url(\"http://trikita.co/slide/styles.gif\"),\n          url(\"http://trikita.co/slide/illustrate_framed.png\");\n        background-repeat: no-repeat;\n        background-size: 40%, 40%, 40%;\n        background-position: bottom left, bottom center, bottom right;\n      }\n    </style>\n  </head>\n  <body class=\"slide-16x9\">\n    <pre id=\"slide\">\n      #SLIDE\n      Good speech deserves time it takes\n      Save time for speech\n      Leave presentation to *Slide*\n\n      #Focus on content\n      Learn 5 markup rules\n      to make content look great\n\n      # #1\n      Each paragraph is a slide\n\n      # #2\n      Headers start with #\n\n      # #3\n      Emphasize *words*\n      surrounding them with **asterisks**\n\n      # #4\n      Indent code with 2 spaces\n        /* Day of week: Sakamoto's algorithm */\n        int dow(int y, int m, int d)\n        {\n          static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};\n          y -= m < 3;\n          return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;\n        }\n\n      # #5\n      Lines starting with a dot\n      disable markup such as\n      headlines, code or blank lines\n\n      ↵  = new slide\n      .# = headline\n      ** = emphasize\n      ␣␣ = monospace\n      .. = escape\n\n      # Styling with CSS\n\n      # Selectors\n      ..slide\n      ..slide h1\n      ..slide strong\n      ..slide pre\n      .\n      ..slide-N, where N is slide number\n\n      # Example\n      .\n        .slide-10 h1 {\n          color: #fff;\n          text-shadow: 1px 1px 3px #453029;\n        }\n      .\n\n      # CSS backgrounds\n        .slide-12 {\n          background: url(\"icon.png\"),\n                      url(\"bg.png\");\n          background-repeat: no-repeat, repeat;\n          background-size: 40%, auto;\n          background-position: bottom right;\n        }\n\n\n      # Print mode\n      You can print slide thumbnails\n      to practice your speech\n\n      Slide for Android\n      .\n      .\n      .\n\n      # Links\n      http://trikita.co/slide\n      https://github.com/trikita/slide\n      https://github.com/trikita/slide-html\n      https://play.google.com/store/apps/details?id=trikita.slide\n    </pre>\n  </body>\n</html>\n"
  },
  {
    "path": "src/slide.js",
    "content": "var INDENT_RE = /^(?:( )+|\\t+)/;\n\nfunction trimIndent(s) {\n\tvar indent = (s.match(INDENT_RE)||[''])[0].length;\n\tif (indent > 0) {\n\t\tvar trim = s.substring(0, indent);\n\t\treturn s.replace(new RegExp(trim, 'g'), '');\n\t}\n}\n\nfunction renderSlide(root, slide, index) {\n\tvar lines = slide.split('\\n');\n\tvar emSpanStart = -1;\n\tvar slideWrapper = document.createElement('div');\n\tvar slideContent = document.createElement('div');\n\tvar html = '';\n\tslideWrapper.className = 'slide slide-'+index;\n\tslideContent.className = 'slide-content';\n\tfor (var i = 0 ; i < lines.length; i++) {\n\t\tvar line = lines[i];\n\t\tif (line.startsWith('#')) {\n\t\t\t// Add header\n\t\t\thtml = html + '<h1>' + line.substring(1) + '</h1>';\n\t\t} else if (line.startsWith('  ') || line.startsWith('\\t')) {\n\t\t\t// Add code\n\t\t\thtml = html + '<pre>' + line.replace(/^(  )|\\t/,'') + '</pre>';\n\t\t} else {\n\t\t\t// Unquote dot-quoted lines\n\t\t\tif (line.startsWith('.')) {\n\t\t\t\tline = line.substring(1);\n\t\t\t}\n\t\t\t// Handle emphasis\n\t\t\tfor (var j = 0; j < line.length; j++) {\n\t\t\t\tvar c = line.charAt(j);\n\t\t\t\tif (c == '*') {\n\t\t\t\t\tif (emSpanStart == -1) {\n\t\t\t\t\t\thtml = html + '<strong>';\n\t\t\t\t\t\temSpanStart = html.length;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (emSpanStart != html.length) {\n\t\t\t\t\t\t\thtml = html + '</strong>';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\thtml = html.substring(0, html.length-8) + '*';\n\t\t\t\t\t\t}\n\t\t\t\t\t\temSpanStart = -1;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\thtml = html + c;\n\t\t\t\t}\n\t\t\t}\n\t\t\thtml = html + '<br/>';\n\t\t}\n\t}\n\tslideContent.innerHTML = html;\n\tslideWrapper.appendChild(slideContent);\n\troot.appendChild(slideWrapper);\n\tslideWrapper.style.visibility = \"hidden\";\n}\n\nfunction render(content) {\n\tvar root = document.createElement('div');\n\troot.className = 'slide-root';\n\tdocument.body.appendChild(root);\n\tcontent = trimIndent(content);\n\tvar slides = content.split(/[\\s+]\\n/mg);\n\tfor (var i = 0; i < slides.length; i++) {\n\t\tvar slide = slides[i].trim();\n\t\trenderSlide(root, slide, i);\n\t}\n\treturn root;\n}\n\nfunction resize() {\n\tvar w = window.innerWidth;\n\tvar h = window.innerHeight;\n\tvar bw = document.body.offsetWidth;\n\tvar bh = document.body.offsetHeight;\n\tvar scale = ((w/h < bw/bh) ? w/bw : h/bh);\n\tdocument.body.style.transform = 'scale(' + scale + ')';\n}\n\nvar currentSlide = -1;\n\nfunction goTo(slideIndex) {\n\tcurrentSlide = slideIndex;\n\twindow.location.hash = slideIndex;\n\tvar slides = document.querySelectorAll('.slide');\n\tfor (var i = 0; i < slides.length; i++) {\n\t\tvar el = slides[i];\n\t\tvar slide = el.children[0];\n\t\tvar scaleWidth = (el.offsetWidth * 0.8 / slide.offsetWidth);\n\t\tvar scaleHeight = (el.offsetHeight * 0.8 / slide.offsetHeight);\n\t\tslide.style.transform = 'scale(' + Math.min(scaleWidth, scaleHeight) + ')';\n\t\tif (i == currentSlide) {\n\t\t\tel.style.visibility = '';\n\t\t} else {\n\t\t\tel.style.visibility = 'hidden';\n\t\t}\n\t}\n}\n\nfunction next() {\n\tgoTo(Math.min(currentSlide + 1, document.querySelectorAll('.slide').length - 1));\n}\n\nfunction prev() {\n\tgoTo(Math.max(currentSlide - 1, 0));\n}\n\nwindow.onload = function() {\n\tresize();\n\trender(document.getElementById('slide').innerHTML);\n\tgoTo(window.location.hash.substring(1)||0);\n\twindow.onclick = next;\n\twindow.onresize = resize;\n\twindow.onkeydown = function(e) {\n\t\tif (e.keyCode == 39) {\n\t\t\tnext();\n\t\t} else if (e.keyCode == 37) {\n\t\t\tprev();\n\t\t}\n\t};\n};\n"
  }
]