From 29c04348c1a3dadf7d525705d97118ab4dec6946 Mon Sep 17 00:00:00 2001 From: vale Date: Mon, 23 May 2016 20:17:49 +0200 Subject: [PATCH] Commit blank nginx config --- nginx.conf | 132 ++ parser/markdown/.info | 19 + parser/markdown/assets/github-markdown.css | 657 ++++++ .../markdown/assets/github-markdown.min.css | 1 + parser/markdown/assets/prism.css | 212 ++ parser/markdown/assets/prism.js | 1881 +++++++++++++++++ parser/markdown/assets/prism.min.css | 212 ++ parser/markdown/assets/prism.min.js | 33 + parser/markdown/lib/Parsedown.php | 1528 +++++++++++++ parser/markdown/md.php | 40 + sites-available/default | 68 + sites-available/default-sub | 33 + snippets/fastcgi-php.conf | 20 + snippets/force-ssl.conf | 3 + snippets/md.conf | 13 + snippets/no-www.conf | 5 + snippets/ocsp-vhost.conf | 6 + snippets/php-fpm.conf | 14 + snippets/random.conf | 73 + snippets/snakeoil.conf | 5 + snippets/ssl-fallback.conf | 13 + snippets/ssl-vhost.conf | 15 + snippets/ssl.conf | 19 + snippets/www.conf | 4 + 24 files changed, 5006 insertions(+) create mode 100644 nginx.conf create mode 100644 parser/markdown/.info create mode 100644 parser/markdown/assets/github-markdown.css create mode 100644 parser/markdown/assets/github-markdown.min.css create mode 100644 parser/markdown/assets/prism.css create mode 100644 parser/markdown/assets/prism.js create mode 100644 parser/markdown/assets/prism.min.css create mode 100644 parser/markdown/assets/prism.min.js create mode 100644 parser/markdown/lib/Parsedown.php create mode 100644 parser/markdown/md.php create mode 100644 sites-available/default create mode 100644 sites-available/default-sub create mode 100644 snippets/fastcgi-php.conf create mode 100644 snippets/force-ssl.conf create mode 100644 snippets/md.conf create mode 100644 snippets/no-www.conf create mode 100644 snippets/ocsp-vhost.conf create mode 100644 snippets/php-fpm.conf create mode 100644 snippets/random.conf create mode 100644 snippets/snakeoil.conf create mode 100644 snippets/ssl-fallback.conf create mode 100644 snippets/ssl-vhost.conf create mode 100644 snippets/ssl.conf create mode 100644 snippets/www.conf diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..727decc --- /dev/null +++ b/nginx.conf @@ -0,0 +1,132 @@ +user www-data; +worker_processes 4; +pid /run/nginx.pid; +worker_rlimit_nofile 102400; + +events { + worker_connections 102400; + multi_accept on; + use epoll; +} + +http { + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 70; + types_hash_max_size 4096; + server_tokens off; + +# more_clear_headers 'Server'; +# more_clear_headers 'X-Powered-By'; + + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + add_header X-XSS-Protection "1; mode=block;"; + add_header X-Robts-Tag "none"; + + server_names_hash_max_size 10240; + server_names_hash_bucket_size 10240; + server_name_in_redirect off; + + reset_timedout_connection on; + client_header_timeout 3m; + client_body_timeout 3m; + send_timeout 3m; + connection_pool_size 10240; + client_header_buffer_size 2560k; + large_client_header_buffers 4 2560k; + client_max_body_size 1000M; + client_body_buffer_size 1280k; + request_pool_size 32k; + output_buffers 4 32k; + postpone_output 1460; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # SSL Settings + ## + + #ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE + #ssl_prefer_server_ciphers on; + include snippets/ssl.conf; + + ## + # Logging Settings + ## + + access_log off; + error_log /var/log/nginx/error.log crit; + + ## + # Gzip Settings + ## + + gzip on; + gzip_disable "msie6"; + + gzip_vary on; + gzip_proxied any; + gzip_comp_level 9; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_types image/svg+xml text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript; + + ## + # Open file settings (speeds up serving of static content) + ## + open_file_cache max=200000 inactive=20s; + open_file_cache_valid 30s; + open_file_cache_min_uses 2; + open_file_cache_errors on; + + ## + # Virtual Host Configs + ## + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; + + upstream php-handler { + server 127.0.0.1:9000; + } + + server { + listen 80 default; + listen 443 ssl default; + include snippets/ssl-fallback.conf; + return 444; + } + +# include /etc/nginx/conf.d/*.conf; +# include /etc/nginx/sites-enabled/*; +} + + +#mail { +# # See sample authentication script at: +# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript +# +# # auth_http localhost/auth.php; +# # pop3_capabilities "TOP" "USER"; +# # imap_capabilities "IMAP4rev1" "UIDPLUS"; +# +# server { +# listen localhost:110; +# protocol pop3; +# proxy on; +# } +# +# server { +# listen localhost:143; +# protocol imap; +# proxy on; +# } +#} diff --git a/parser/markdown/.info b/parser/markdown/.info new file mode 100644 index 0000000..1decb01 --- /dev/null +++ b/parser/markdown/.info @@ -0,0 +1,19 @@ +parser: https://github.com/erusev/parsedown +css: https://github.com/sindresorhus/github-markdown-css + + +nginx config: + + location ~ \.md$ { + try_files $uri =404; + fastcgi_pass unix:/var/run/php5-fpm.sock; + fastcgi_param DOCUMENT_ROOT $document_root; + fastcgi_param SCRIPT_NAME $uri; + fastcgi_param SCRIPT_FILENAME /var/www/vhost1/markdown-parser/md.php; + include fastcgi_params; + } + + location ~ ^(.*)\.md/raw$ { + try_files $1.md =404; + default_type text/plain; + } diff --git a/parser/markdown/assets/github-markdown.css b/parser/markdown/assets/github-markdown.css new file mode 100644 index 0000000..8058d71 --- /dev/null +++ b/parser/markdown/assets/github-markdown.css @@ -0,0 +1,657 @@ +@font-face { + font-family: octicons-anchor; + src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format('woff'); +} + +* { + -webkit-text-size-adjust: 100%; + text-size-adjust: 100%; + color: #333; + font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif; + font-size: 16px; + line-height: 1.6; + word-wrap: break-word; +} + +a { + background-color: transparent; +} + +a:active, +a:hover { + outline: 0; +} + +strong { + font-weight: bold; +} + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +img { + border: 0; +} + +hr { + box-sizing: content-box; + height: 0; +} + +pre { + overflow: auto; +} + +code, +kbd, +pre { + font-family: monospace, monospace; + font-size: 1em; +} + +input { + color: inherit; + font: inherit; + margin: 0; +} + +html input[disabled] { + cursor: default; +} + +input { + line-height: normal; +} + +input[type="checkbox"] { + box-sizing: border-box; + padding: 0; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} + +* { + box-sizing: border-box; +} + +input { + font: 13px/1.4 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; +} + +a { + color: #4078c0; + text-decoration: none; +} + +a:hover, +a:active { + text-decoration: underline; +} + +hr { + height: 0; + margin: 15px 0; + overflow: hidden; + background: transparent; + border: 0; + border-bottom: 1px solid #ddd; +} + +hr:before { + display: table; + content: ""; +} + +hr:after { + display: table; + clear: both; + content: ""; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin-top: 15px; + margin-bottom: 15px; + line-height: 1.1; +} + +h1 { + font-size: 30px; +} + +h2 { + font-size: 21px; +} + +h3 { + font-size: 16px; +} + +h4 { + font-size: 14px; +} + +h5 { + font-size: 12px; +} + +h6 { + font-size: 11px; +} + +blockquote { + margin: 0; +} + +ul, +ol { + padding: 0; + margin-top: 0; + margin-bottom: 0; +} + +ol ol, +ul ol { + list-style-type: lower-roman; +} + +ul ul ol, +ul ol ol, +ol ul ol, +ol ol ol { + list-style-type: lower-alpha; +} + +dd { + margin-left: 0; +} + +code { + font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; + font-size: 12px; +} + +pre { + margin-top: 0; + margin-bottom: 0; + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.select::-ms-expand { + opacity: 0; +} + +.octicon { + font: normal normal normal 16px/1 octicons-anchor; + display: inline-block; + text-decoration: none; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.octicon-link:before { + content: '\f05c'; +} + +.markdown-body>*:first-child { + margin-top: 0 !important; +} + +.markdown-body>*:last-child { + margin-bottom: 0 !important; +} + +a:not([href]) { + color: inherit; + text-decoration: none; +} + +.anchor { + display: inline-block; + padding-right: 2px; + margin-left: -18px; +} + +.anchor:focus { + outline: none; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin-top: 1em; + margin-bottom: 16px; + font-weight: bold; + line-height: 1.4; +} + +h1 .octicon-link, +h2 .octicon-link, +h3 .octicon-link, +h4 .octicon-link, +h5 .octicon-link, +h6 .octicon-link { + color: #000; + vertical-align: middle; + visibility: hidden; +} + +h1:hover .anchor, +h2:hover .anchor, +h3:hover .anchor, +h4:hover .anchor, +h5:hover .anchor, +h6:hover .anchor { + text-decoration: none; +} + +h1:hover .anchor .octicon-link, +h2:hover .anchor .octicon-link, +h3:hover .anchor .octicon-link, +h4:hover .anchor .octicon-link, +h5:hover .anchor .octicon-link, +h6:hover .anchor .octicon-link { + visibility: visible; +} + +h1 { + padding-bottom: 0.3em; + font-size: 2.25em; + line-height: 1.2; + border-bottom: 1px solid #eee; +} + +h1 .anchor { + line-height: 1; +} + +h2 { + padding-bottom: 0.3em; + font-size: 1.75em; + line-height: 1.225; + border-bottom: 1px solid #eee; +} + +h2 .anchor { + line-height: 1; +} + +h3 { + font-size: 1.5em; + line-height: 1.43; +} + +h3 .anchor { + line-height: 1.2; +} + +h4 { + font-size: 1.25em; +} + +h4 .anchor { + line-height: 1.2; +} + +h5 { + font-size: 1em; +} + +h5 .anchor { + line-height: 1.1; +} + +h6 { + font-size: 1em; + color: #777; +} + +h6 .anchor { + line-height: 1.1; +} + +p, +blockquote, +ul, +ol, +dl, +table, +pre { + margin-top: 0; + margin-bottom: 16px; +} + +hr { + height: 4px; + padding: 0; + margin: 16px 0; + background-color: #e7e7e7; + border: 0 none; +} + +ul, +ol { + padding-left: 2em; +} + +ul ul, +ul ol, +ol ol, +ol ul { + margin-top: 0; + margin-bottom: 0; +} + +li>p { + margin-top: 16px; +} + +dl { + padding: 0; +} + +dl dt { + padding: 0; + margin-top: 16px; + font-size: 1em; + font-style: italic; + font-weight: bold; +} + +dl dd { + padding: 0 16px; + margin-bottom: 16px; +} + +blockquote { + padding: 0 15px; + color: #777; + border-left: 4px solid #ddd; +} + +blockquote>:first-child { + margin-top: 0; +} + +blockquote>:last-child { + margin-bottom: 0; +} + +table { + display: block; + width: 100%; + overflow: auto; + word-break: normal; + word-break: keep-all; +} + +table th { + font-weight: bold; +} + +table th, +table td { + padding: 6px 13px; + border: 1px solid #ddd; +} + +table tr { + background-color: #fff; + border-top: 1px solid #ccc; +} + +table tr:nth-child(2n) { + background-color: #f8f8f8; +} + +img { + max-width: 100%; + box-sizing: content-box; + background-color: #fff; +} + +code { + padding: 0; + padding-top: 0.2em; + padding-bottom: 0.2em; + margin: 0; + font-size: 85%; + background-color: rgba(0,0,0,0.04); + border-radius: 3px; +} + +code:before, +code:after { + letter-spacing: -0.2em; + content: "\00a0"; +} + +pre>code { + padding: 0; + margin: 0; + font-size: 100%; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; +} + +.highlight { + margin-bottom: 16px; +} + +.highlight pre, +pre { + padding: 16px; + overflow: auto; + font-size: 85%; + line-height: 1.45; + background-color: #f7f7f7; + border-radius: 3px; +} + +.highlight pre { + margin-bottom: 0; + word-break: normal; +} + +pre { + word-wrap: normal; +} + +pre code { + display: inline; + max-width: initial; + padding: 0; + margin: 0; + overflow: initial; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; +} + +pre code:before, +pre code:after { + content: normal; +} + +kbd { + display: inline-block; + padding: 3px 5px; + font-size: 11px; + line-height: 10px; + color: #555; + vertical-align: middle; + background-color: #fcfcfc; + border: solid 1px #ccc; + border-bottom-color: #bbb; + border-radius: 3px; + box-shadow: inset 0 -1px 0 #bbb; +} + +.pl-c { + color: #969896; +} + +.pl-c1, +.pl-s .pl-v { + color: #0086b3; +} + +.pl-e, +.pl-en { + color: #795da3; +} + +.pl-s .pl-s1, +.pl-smi { + color: #333; +} + +.pl-ent { + color: #63a35c; +} + +.pl-k { + color: #a71d5d; +} + +.pl-pds, +.pl-s, +.pl-s .pl-pse .pl-s1, +.pl-sr, +.pl-sr .pl-cce, +.pl-sr .pl-sra, +.pl-sr .pl-sre { + color: #183691; +} + +.pl-v { + color: #ed6a43; +} + +.pl-id { + color: #b52a1d; +} + +.pl-ii { + background-color: #b52a1d; + color: #f8f8f8; +} + +.pl-sr .pl-cce { + color: #63a35c; + font-weight: bold; +} + +.pl-ml { + color: #693a17; +} + +.pl-mh, +.pl-mh .pl-en, +.pl-ms { + color: #1d3e81; + font-weight: bold; +} + +.pl-mq { + color: #008080; +} + +.pl-mi { + color: #333; + font-style: italic; +} + +.pl-mb { + color: #333; + font-weight: bold; +} + +.pl-md { + background-color: #ffecec; + color: #bd2c00; +} + +.pl-mi1 { + background-color: #eaffea; + color: #55a532; +} + +.pl-mdr { + color: #795da3; + font-weight: bold; +} + +.pl-mo { + color: #1d3e81; +} + +kbd { + display: inline-block; + padding: 3px 5px; + font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace; + line-height: 10px; + color: #555; + vertical-align: middle; + background-color: #fcfcfc; + border: solid 1px #ccc; + border-bottom-color: #bbb; + border-radius: 3px; + box-shadow: inset 0 -1px 0 #bbb; +} + +.markdown-body:before { + display: table; + content: ""; +} + +.markdown-body:after { + display: table; + clear: both; + content: ""; +} + +.task-list-item { + list-style-type: none; +} + +.task-list-item+.task-list-item { + margin-top: 3px; +} + +.task-list-item input { + margin: 0 0.35em 0.25em -1.6em; + vertical-align: middle; +} + +:checked+.radio-label { + z-index: 1; + position: relative; + border-color: #4078c0; +} + diff --git a/parser/markdown/assets/github-markdown.min.css b/parser/markdown/assets/github-markdown.min.css new file mode 100644 index 0000000..6ebc0c8 --- /dev/null +++ b/parser/markdown/assets/github-markdown.min.css @@ -0,0 +1 @@ +/* minified (and slightly adjusted) version of github-markdown-css (see ) */ hr,img{box-sizing:content-box}hr:after,hr:before{display:table;content:""}blockquote,input{margin:0}a:not([href]),input{color:inherit}h1,h2{padding-bottom:.3em;border-bottom:1px solid #eee}hr,img{border:0}img,table tr{background-color:#fff}pre,pre code{word-wrap:normal}.anchor,.octicon,kbd{display:inline-block}.markdown-body:after,hr:after{clear:both}@font-face{font-family:octicons-anchor;src:url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format('woff')}*{-webkit-text-size-adjust:100%;text-size-adjust:100%;color:#333;font-family:"Helvetica Neue",Helvetica,"Segoe UI",Arial,freesans,sans-serif;font-size:16px;line-height:1.6;word-wrap:break-word;box-sizing:border-box}a{background-color:transparent;color:#4078c0;text-decoration:none}a:active,a:hover{outline:0;text-decoration:underline}.octicon,a:not([href]),h1:hover .anchor,h2:hover .anchor,h3:hover .anchor,h4:hover .anchor,h5:hover .anchor,h6:hover .anchor{text-decoration:none}strong{font-weight:700}h1{margin:.67em 0}img{max-width:100%}input{line-height:normal;font:13px/1.4 Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}html input[disabled]{cursor:default}input[type=checkbox]{box-sizing:border-box;padding:0}td,th{padding:0}ol,ul{padding:0 0 0 2em}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}dd{margin-left:0}code{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace}pre{font:12px Consolas,"Liberation Mono",Menlo,Courier,monospace}.select::-ms-expand{opacity:0}.octicon{font:normal normal normal 16px/1 octicons-anchor;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.pl-mi,dl dt{font-style:italic}.pl-mb,.pl-mdr,.pl-sr .pl-cce,dl dt,h1,h2,h3,h4,h5,h6,table th{font-weight:700}.octicon-link:before{content:'\f05c'}.markdown-body>:first-child{margin-top:0!important}dl dt,li>p{margin-top:16px}.markdown-body>:last-child{margin-bottom:0!important}.anchor{padding-right:2px;margin-left:-18px}dl,dl dt,hr{padding:0}.anchor:focus{outline:0}h1,h2,h3,h4,h5,h6{margin-top:1em;margin-bottom:16px;line-height:1.4}h1 .octicon-link,h2 .octicon-link,h3 .octicon-link,h4 .octicon-link,h5 .octicon-link,h6 .octicon-link{color:#000;vertical-align:middle;visibility:hidden}blockquote,h6{color:#777}h1:hover .anchor .octicon-link,h2:hover .anchor .octicon-link,h3:hover .anchor .octicon-link,h4:hover .anchor .octicon-link,h5:hover .anchor .octicon-link,h6:hover .anchor .octicon-link{visibility:visible}h1{font-size:2.25em;line-height:1.2}h1 .anchor{line-height:1}h2{font-size:1.75em;line-height:1.225}h2 .anchor{line-height:1}h3{font-size:1.5em;line-height:1.43}h3 .anchor,h4 .anchor{line-height:1.2}h4{font-size:1.25em}dl dt,h5,h6{font-size:1em}h5 .anchor,h6 .anchor{line-height:1.1}blockquote,dl,ol,p,pre,table,ul{margin-top:0;margin-bottom:16px}hr{overflow:hidden;background:#e7e7e7;height:4px;margin:16px 0}ol ol,ol ul,ul ol,ul ul{margin-top:0;margin-bottom:0}dl dd{padding:0 16px;margin-bottom:16px}blockquote{padding:0 15px;border-left:4px solid #ddd}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}table{border-collapse:collapse;border-spacing:0;display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all}table td,table th{padding:6px 13px;border:1px solid #ddd}table tr{border-top:1px solid #ccc}table tr:nth-child(2n){background-color:#f8f8f8}code{padding:.2em 0;margin:0;font-size:85%;background-color:rgba(0,0,0,.04);border-radius:3px}code:after,code:before{letter-spacing:-.2em;content:"\00a0"}pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:0 0;border:0}.highlight{margin-bottom:16px}.highlight pre,pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f7f7f7;border-radius:3px}.highlight pre{margin-bottom:0;word-break:normal}pre code{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;background-color:transparent;border:0}pre code:after,pre code:before{content:normal}.pl-c{color:#969896}.pl-c1,.pl-s .pl-v{color:#0086b3}.pl-e,.pl-en{color:#795da3}.pl-s .pl-s1,.pl-smi{color:#333}.pl-ent{color:#63a35c}.pl-k{color:#a71d5d}.pl-pds,.pl-s,.pl-s .pl-pse .pl-s1,.pl-sr,.pl-sr .pl-cce,.pl-sr .pl-sra,.pl-sr .pl-sre{color:#183691}.pl-v{color:#ed6a43}.pl-id{color:#b52a1d}.pl-ii{background-color:#b52a1d;color:#f8f8f8}.pl-sr .pl-cce{color:#63a35c}.pl-ml{color:#693a17}.pl-mh,.pl-mh .pl-en,.pl-ms{color:#1d3e81;font-weight:700}.pl-mq{color:teal}.pl-mb,.pl-mi{color:#333}.pl-md{background-color:#ffecec;color:#bd2c00}.pl-mi1{background-color:#eaffea;color:#55a532}.pl-mdr{color:#795da3}.pl-mo{color:#1d3e81}kbd{padding:3px 5px;font:11px Consolas,"Liberation Mono",Menlo,Courier,monospace;line-height:10px;color:#555;vertical-align:middle;background-color:#fcfcfc;border:1px solid #ccc;border-bottom-color:#bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.markdown-body:after,.markdown-body:before{display:table;content:""}.task-list-item{list-style-type:none}.task-list-item+.task-list-item{margin-top:3px}.task-list-item input{margin:0 .35em .25em -1.6em;vertical-align:middle}:checked+.radio-label{z-index:1;position:relative;border-color:#4078c0} diff --git a/parser/markdown/assets/prism.css b/parser/markdown/assets/prism.css new file mode 100644 index 0000000..deec86e --- /dev/null +++ b/parser/markdown/assets/prism.css @@ -0,0 +1,212 @@ +/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+bash+c+csharp+cpp+ruby+diff+git+go+http+java+latex+less+lua+makefile+markdown+nginx+php+php-extras+python+sass+scss+sql+twig+yaml&plugins=line-numbers+autolinker+show-language */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol, +.token.deleted { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #a67f59; + background: hsla(0, 0%, 100%, .5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function { + color: #DD4A68; +} + +.token.regex, +.token.important, +.token.variable { + color: #e90; +} + +.token.important, +.token.bold { + font-weight: bold; +} +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} + +pre.line-numbers { + position: relative; + padding-left: 3.8em; + counter-reset: linenumber; +} + +pre.line-numbers > code { + position: relative; +} + +.line-numbers .line-numbers-rows { + position: absolute; + pointer-events: none; + top: 0; + font-size: 100%; + left: -3.8em; + width: 3em; /* works for line-numbers below 1000 lines */ + letter-spacing: -1px; + border-right: 1px solid #999; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + +} + + .line-numbers-rows > span { + pointer-events: none; + display: block; + counter-increment: linenumber; + } + + .line-numbers-rows > span:before { + content: counter(linenumber); + color: #999; + display: block; + padding-right: 0.8em; + text-align: right; + } +.token a { + color: inherit; +} +div.prism-show-language { + position: relative; +} + +div.prism-show-language > div.prism-show-language-label[data-language] { + color: black; + background-color: #CFCFCF; + display: inline-block; + position: absolute; + bottom: auto; + left: auto; + top: 0; + right: 0; + width: auto; + height: auto; + font-size: 0.9em; + border-radius: 0 0 0 5px; + padding: 0 0.5em; + text-shadow: none; + z-index: 1; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + -webkit-transform: none; + -moz-transform: none; + -ms-transform: none; + -o-transform: none; + transform: none; +} + diff --git a/parser/markdown/assets/prism.js b/parser/markdown/assets/prism.js new file mode 100644 index 0000000..6a2f012 --- /dev/null +++ b/parser/markdown/assets/prism.js @@ -0,0 +1,1881 @@ +/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+bash+c+csharp+cpp+ruby+diff+git+go+http+java+latex+less+lua+makefile+markdown+nginx+php+php-extras+python+sass+scss+sql+twig+yaml&plugins=line-numbers+autolinker+show-language */ +var _self = (typeof window !== 'undefined') + ? window // if in browser + : ( + (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) + ? self // if in worker + : {} // if in node js + ); + +/** + * Prism: Lightweight, robust, elegant syntax highlighting + * MIT license http://www.opensource.org/licenses/mit-license.php/ + * @author Lea Verou http://lea.verou.me + */ + +var Prism = (function(){ + +// Private helper vars +var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i; + +var _ = _self.Prism = { + util: { + encode: function (tokens) { + if (tokens instanceof Token) { + return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias); + } else if (_.util.type(tokens) === 'Array') { + return tokens.map(_.util.encode); + } else { + return tokens.replace(/&/g, '&').replace(/ text.length) { + // Something went terribly wrong, ABORT, ABORT! + break tokenloop; + } + + if (str instanceof Token) { + continue; + } + + pattern.lastIndex = 0; + + var match = pattern.exec(str); + + if (match) { + if(lookbehind) { + lookbehindLength = match[1].length; + } + + var from = match.index - 1 + lookbehindLength, + match = match[0].slice(lookbehindLength), + len = match.length, + to = from + len, + before = str.slice(0, from + 1), + after = str.slice(to + 1); + + var args = [i, 1]; + + if (before) { + args.push(before); + } + + var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias); + + args.push(wrapped); + + if (after) { + args.push(after); + } + + Array.prototype.splice.apply(strarr, args); + } + } + } + } + + return strarr; + }, + + hooks: { + all: {}, + + add: function (name, callback) { + var hooks = _.hooks.all; + + hooks[name] = hooks[name] || []; + + hooks[name].push(callback); + }, + + run: function (name, env) { + var callbacks = _.hooks.all[name]; + + if (!callbacks || !callbacks.length) { + return; + } + + for (var i=0, callback; callback = callbacks[i++];) { + callback(env); + } + } + } +}; + +var Token = _.Token = function(type, content, alias) { + this.type = type; + this.content = content; + this.alias = alias; +}; + +Token.stringify = function(o, language, parent) { + if (typeof o == 'string') { + return o; + } + + if (_.util.type(o) === 'Array') { + return o.map(function(element) { + return Token.stringify(element, language, o); + }).join(''); + } + + var env = { + type: o.type, + content: Token.stringify(o.content, language, parent), + tag: 'span', + classes: ['token', o.type], + attributes: {}, + language: language, + parent: parent + }; + + if (env.type == 'comment') { + env.attributes['spellcheck'] = 'true'; + } + + if (o.alias) { + var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias]; + Array.prototype.push.apply(env.classes, aliases); + } + + _.hooks.run('wrap', env); + + var attributes = ''; + + for (var name in env.attributes) { + attributes += (attributes ? ' ' : '') + name + '="' + (env.attributes[name] || '') + '"'; + } + + return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + ''; + +}; + +if (!_self.document) { + if (!_self.addEventListener) { + // in Node.js + return _self.Prism; + } + // In worker + _self.addEventListener('message', function(evt) { + var message = JSON.parse(evt.data), + lang = message.language, + code = message.code, + immediateClose = message.immediateClose; + + _self.postMessage(_.highlight(code, _.languages[lang], lang)); + if (immediateClose) { + _self.close(); + } + }, false); + + return _self.Prism; +} + +// Get current script and highlight +var script = document.getElementsByTagName('script'); + +script = script[script.length - 1]; + +if (script) { + _.filename = script.src; + + if (document.addEventListener && !script.hasAttribute('data-manual')) { + document.addEventListener('DOMContentLoaded', _.highlightAll); + } +} + +return _self.Prism; + +})(); + +if (typeof module !== 'undefined' && module.exports) { + module.exports = Prism; +} + +// hack for components to work correctly in node.js +if (typeof global !== 'undefined') { + global.Prism = Prism; +} +; +Prism.languages.markup = { + 'comment': //, + 'prolog': /<\?[\w\W]+?\?>/, + 'doctype': //, + 'cdata': //i, + 'tag': { + pattern: /<\/?(?!\d)[^\s>\/=.$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i, + inside: { + 'tag': { + pattern: /^<\/?[^\s>\/]+/i, + inside: { + 'punctuation': /^<\/?/, + 'namespace': /^[^\s>\/:]+:/ + } + }, + 'attr-value': { + pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i, + inside: { + 'punctuation': /[=>"']/ + } + }, + 'punctuation': /\/?>/, + 'attr-name': { + pattern: /[^\s>\/]+/, + inside: { + 'namespace': /^[^\s>\/:]+:/ + } + } + + } + }, + 'entity': /&#?[\da-z]{1,8};/i +}; + +// Plugin to make entity title show the real entity, idea by Roman Komarov +Prism.hooks.add('wrap', function(env) { + + if (env.type === 'entity') { + env.attributes['title'] = env.content.replace(/&/, '&'); + } +}); + +Prism.languages.xml = Prism.languages.markup; +Prism.languages.html = Prism.languages.markup; +Prism.languages.mathml = Prism.languages.markup; +Prism.languages.svg = Prism.languages.markup; + +Prism.languages.css = { + 'comment': /\/\*[\w\W]*?\*\//, + 'atrule': { + pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i, + inside: { + 'rule': /@[\w-]+/ + // See rest below + } + }, + 'url': /url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i, + 'selector': /[^\{\}\s][^\{\};]*?(?=\s*\{)/, + 'string': /("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/, + 'property': /(\b|\B)[\w-]+(?=\s*:)/i, + 'important': /\B!important\b/i, + 'function': /[-a-z0-9]+(?=\()/i, + 'punctuation': /[(){};:]/ +}; + +Prism.languages.css['atrule'].inside.rest = Prism.util.clone(Prism.languages.css); + +if (Prism.languages.markup) { + Prism.languages.insertBefore('markup', 'tag', { + 'style': { + pattern: /()[\w\W]*?(?=<\/style>)/i, + lookbehind: true, + inside: Prism.languages.css, + alias: 'language-css' + } + }); + + Prism.languages.insertBefore('inside', 'attr-value', { + 'style-attr': { + pattern: /\s*style=("|').*?\1/i, + inside: { + 'attr-name': { + pattern: /^\s*style/i, + inside: Prism.languages.markup.tag.inside + }, + 'punctuation': /^\s*=\s*['"]|['"]\s*$/, + 'attr-value': { + pattern: /.+/i, + inside: Prism.languages.css + } + }, + alias: 'language-css' + } + }, Prism.languages.markup.tag); +}; +Prism.languages.clike = { + 'comment': [ + { + pattern: /(^|[^\\])\/\*[\w\W]*?\*\//, + lookbehind: true + }, + { + pattern: /(^|[^\\:])\/\/.*/, + lookbehind: true + } + ], + 'string': /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, + 'class-name': { + pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i, + lookbehind: true, + inside: { + punctuation: /(\.|\\)/ + } + }, + 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, + 'boolean': /\b(true|false)\b/, + 'function': /[a-z0-9_]+(?=\()/i, + 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i, + 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/, + 'punctuation': /[{}[\];(),.:]/ +}; + +Prism.languages.javascript = Prism.languages.extend('clike', { + 'keyword': /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/, + 'number': /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/, + // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444) + 'function': /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i +}); + +Prism.languages.insertBefore('javascript', 'keyword', { + 'regex': { + pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/, + lookbehind: true + } +}); + +Prism.languages.insertBefore('javascript', 'class-name', { + 'template-string': { + pattern: /`(?:\\`|\\?[^`])*`/, + inside: { + 'interpolation': { + pattern: /\$\{[^}]+\}/, + inside: { + 'interpolation-punctuation': { + pattern: /^\$\{|\}$/, + alias: 'punctuation' + }, + rest: Prism.languages.javascript + } + }, + 'string': /[\s\S]+/ + } + } +}); + +if (Prism.languages.markup) { + Prism.languages.insertBefore('markup', 'tag', { + 'script': { + pattern: /()[\w\W]*?(?=<\/script>)/i, + lookbehind: true, + inside: Prism.languages.javascript, + alias: 'language-javascript' + } + }); +} + +Prism.languages.js = Prism.languages.javascript; +(function(Prism) { + var insideString = { + variable: [ + // Arithmetic Environment + { + pattern: /\$?\(\([\w\W]+?\)\)/, + inside: { + // If there is a $ sign at the beginning highlight $(( and )) as variable + variable: [{ + pattern: /(^\$\(\([\w\W]+)\)\)/, + lookbehind: true + }, + /^\$\(\(/, + ], + number: /\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee]-?\d+)?)\b/, + // Operators according to https://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic + operator: /--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/, + // If there is no $ sign at the beginning highlight (( and )) as punctuation + punctuation: /\(\(?|\)\)?|,|;/ + } + }, + // Command Substitution + { + pattern: /\$\([^)]+\)|`[^`]+`/, + inside: { + variable: /^\$\(|^`|\)$|`$/ + } + }, + /\$(?:[a-z0-9_#\?\*!@]+|\{[^}]+\})/i + ], + }; + + Prism.languages.bash = { + 'shebang': { + pattern: /^#!\s*\/bin\/bash|^#!\s*\/bin\/sh/, + alias: 'important' + }, + 'comment': { + pattern: /(^|[^"{\\])#.*/, + lookbehind: true + }, + 'string': [ + //Support for Here-Documents https://en.wikipedia.org/wiki/Here_document + { + pattern: /((?:^|[^<])<<\s*)(?:"|')?(\w+?)(?:"|')?\s*\r?\n(?:[\s\S])*?\r?\n\2/g, + lookbehind: true, + inside: insideString + }, + { + pattern: /("|')(?:\\?[\s\S])*?\1/g, + inside: insideString + } + ], + 'variable': insideString.variable, + // Originally based on http://ss64.com/bash/ + 'function': { + pattern: /(^|\s|;|\||&)(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|cut|date|dc|dd|ddrescue|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|enable|env|ethtool|eval|exec|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)(?=$|\s|;|\||&)/, + lookbehind: true + }, + 'keyword': { + pattern: /(^|\s|;|\||&)(?:let|:|\.|if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)(?=$|\s|;|\||&)/, + lookbehind: true + }, + 'boolean': { + pattern: /(^|\s|;|\||&)(?:true|false)(?=$|\s|;|\||&)/, + lookbehind: true + }, + 'operator': /&&?|\|\|?|==?|!=?|<<>|<=?|>=?|=~/, + 'punctuation': /\$?\(\(?|\)\)?|\.\.|[{}[\];]/ + }; + + var inside = insideString.variable[1].inside; + inside['function'] = Prism.languages.bash['function']; + inside.keyword = Prism.languages.bash.keyword; + inside.boolean = Prism.languages.bash.boolean; + inside.operator = Prism.languages.bash.operator; + inside.punctuation = Prism.languages.bash.punctuation; +})(Prism); +Prism.languages.c = Prism.languages.extend('clike', { + 'keyword': /\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/, + 'operator': /\-[>-]?|\+\+?|!=?|<>?=?|==?|&&?|\|?\||[~^%?*\/]/, + 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i +}); + +Prism.languages.insertBefore('c', 'string', { + 'macro': { + // allow for multiline macro definitions + // spaces after the # character compile fine with gcc + pattern: /(^\s*)#\s*[a-z]+([^\r\n\\]|\\.|\\(?:\r\n?|\n))*/im, + lookbehind: true, + alias: 'property', + inside: { + // highlight the path of the include statement as a string + 'string': { + pattern: /(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/, + lookbehind: true + }, + // highlight macro directives as keywords + 'directive': { + pattern: /(#\s*)\b(define|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/, + lookbehind: true, + alias: 'keyword' + } + } + }, + // highlight predefined macros as constants + 'constant': /\b(__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|stdin|stdout|stderr)\b/ +}); + +delete Prism.languages.c['class-name']; +delete Prism.languages.c['boolean']; + +Prism.languages.csharp = Prism.languages.extend('clike', { + 'keyword': /\b(abstract|as|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|async|await|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)\b/, + 'string': [ + /@("|')(\1\1|\\\1|\\?(?!\1)[\s\S])*\1/, + /("|')(\\?.)*?\1/ + ], + 'number': /\b-?(0x[\da-f]+|\d*\.?\d+f?)\b/i +}); + +Prism.languages.insertBefore('csharp', 'keyword', { + 'preprocessor': { + pattern: /(^\s*)#.*/m, + lookbehind: true, + alias: 'property', + inside: { + // highlight preprocessor directives as keywords + 'directive': { + pattern: /(\s*#)\b(define|elif|else|endif|endregion|error|if|line|pragma|region|undef|warning)\b/, + lookbehind: true, + alias: 'keyword' + } + } + } +}); + +Prism.languages.cpp = Prism.languages.extend('c', { + 'keyword': /\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/, + 'boolean': /\b(true|false)\b/, + 'operator': /[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/ +}); + +Prism.languages.insertBefore('cpp', 'keyword', { + 'class-name': { + pattern: /(class\s+)[a-z0-9_]+/i, + lookbehind: true + } +}); +/** + * Original by Samuel Flores + * + * Adds the following new token classes: + * constant, builtin, variable, symbol, regex + */ +(function(Prism) { + Prism.languages.ruby = Prism.languages.extend('clike', { + 'comment': /#(?!\{[^\r\n]*?\}).*/, + 'keyword': /\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/ + }); + + var interpolation = { + pattern: /#\{[^}]+\}/, + inside: { + 'delimiter': { + pattern: /^#\{|\}$/, + alias: 'tag' + }, + rest: Prism.util.clone(Prism.languages.ruby) + } + }; + + Prism.languages.insertBefore('ruby', 'keyword', { + 'regex': [ + { + pattern: /%r([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1[gim]{0,3}/, + inside: { + 'interpolation': interpolation + } + }, + { + pattern: /%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/, + inside: { + 'interpolation': interpolation + } + }, + { + // Here we need to specifically allow interpolation + pattern: /%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/, + inside: { + 'interpolation': interpolation + } + }, + { + pattern: /%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/, + inside: { + 'interpolation': interpolation + } + }, + { + pattern: /%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/, + inside: { + 'interpolation': interpolation + } + }, + { + pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/, + lookbehind: true + } + ], + 'variable': /[@$]+[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/, + 'symbol': /:[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/ + }); + + Prism.languages.insertBefore('ruby', 'number', { + 'builtin': /\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/, + 'constant': /\b[A-Z][a-zA-Z_0-9]*(?:[?!]|\b)/ + }); + + Prism.languages.ruby.string = [ + { + pattern: /%[qQiIwWxs]?([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1/, + inside: { + 'interpolation': interpolation + } + }, + { + pattern: /%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/, + inside: { + 'interpolation': interpolation + } + }, + { + // Here we need to specifically allow interpolation + pattern: /%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/, + inside: { + 'interpolation': interpolation + } + }, + { + pattern: /%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/, + inside: { + 'interpolation': interpolation + } + }, + { + pattern: /%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/, + inside: { + 'interpolation': interpolation + } + }, + { + pattern: /("|')(#\{[^}]+\}|\\(?:\r?\n|\r)|\\?.)*?\1/, + inside: { + 'interpolation': interpolation + } + } + ]; +}(Prism)); +Prism.languages.diff = { + 'coord': [ + // Match all kinds of coord lines (prefixed by "+++", "---" or "***"). + /^(?:\*{3}|-{3}|\+{3}).*$/m, + // Match "@@ ... @@" coord lines in unified diff. + /^@@.*@@$/m, + // Match coord lines in normal diff (starts with a number). + /^\d+.*$/m + ], + + // Match inserted and deleted lines. Support both +/- and >/< styles. + 'deleted': /^[-<].+$/m, + 'inserted': /^[+>].+$/m, + + // Match "different" lines (prefixed with "!") in context diff. + 'diff': { + 'pattern': /^!(?!!).+$/m, + 'alias': 'important' + } +}; +Prism.languages.git = { + /* + * A simple one line comment like in a git status command + * For instance: + * $ git status + * # On branch infinite-scroll + * # Your branch and 'origin/sharedBranches/frontendTeam/infinite-scroll' have diverged, + * # and have 1 and 2 different commits each, respectively. + * nothing to commit (working directory clean) + */ + 'comment': /^#.*/m, + + /* + * Regexp to match the changed lines in a git diff output. Check the example below. + */ + 'deleted': /^[-–].*/m, + 'inserted': /^\+.*/m, + + /* + * a string (double and simple quote) + */ + 'string': /("|')(\\?.)*?\1/m, + + /* + * a git command. It starts with a random prompt finishing by a $, then "git" then some other parameters + * For instance: + * $ git add file.txt + */ + 'command': { + pattern: /^.*\$ git .*$/m, + inside: { + /* + * A git command can contain a parameter starting by a single or a double dash followed by a string + * For instance: + * $ git diff --cached + * $ git log -p + */ + 'parameter': /\s(--|-)\w+/m + } + }, + + /* + * Coordinates displayed in a git diff command + * For instance: + * $ git diff + * diff --git file.txt file.txt + * index 6214953..1d54a52 100644 + * --- file.txt + * +++ file.txt + * @@ -1 +1,2 @@ + * -Here's my tetx file + * +Here's my text file + * +And this is the second line + */ + 'coord': /^@@.*@@$/m, + + /* + * Match a "commit [SHA1]" line in a git log output. + * For instance: + * $ git log + * commit a11a14ef7e26f2ca62d4b35eac455ce636d0dc09 + * Author: lgiraudel + * Date: Mon Feb 17 11:18:34 2014 +0100 + * + * Add of a new line + */ + 'commit_sha1': /^commit \w{40}$/m +}; + +Prism.languages.go = Prism.languages.extend('clike', { + 'keyword': /\b(break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/, + 'builtin': /\b(bool|byte|complex(64|128)|error|float(32|64)|rune|string|u?int(8|16|32|64|)|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(ln)?|real|recover)\b/, + 'boolean': /\b(_|iota|nil|true|false)\b/, + 'operator': /[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./, + 'number': /\b(-?(0x[a-f\d]+|(\d+\.?\d*|\.\d+)(e[-+]?\d+)?)i?)\b/i, + 'string': /("|'|`)(\\?.|\r|\n)*?\1/ +}); +delete Prism.languages.go['class-name']; + +Prism.languages.http = { + 'request-line': { + pattern: /^(POST|GET|PUT|DELETE|OPTIONS|PATCH|TRACE|CONNECT)\b\shttps?:\/\/\S+\sHTTP\/[0-9.]+/m, + inside: { + // HTTP Verb + property: /^(POST|GET|PUT|DELETE|OPTIONS|PATCH|TRACE|CONNECT)\b/, + // Path or query argument + 'attr-name': /:\w+/ + } + }, + 'response-status': { + pattern: /^HTTP\/1.[01] [0-9]+.*/m, + inside: { + // Status, e.g. 200 OK + property: { + pattern: /(^HTTP\/1.[01] )[0-9]+.*/i, + lookbehind: true + } + } + }, + // HTTP header name + 'header-name': { + pattern: /^[\w-]+:(?=.)/m, + alias: 'keyword' + } +}; + +// Create a mapping of Content-Type headers to language definitions +var httpLanguages = { + 'application/json': Prism.languages.javascript, + 'application/xml': Prism.languages.markup, + 'text/xml': Prism.languages.markup, + 'text/html': Prism.languages.markup +}; + +// Insert each content type parser that has its associated language +// currently loaded. +for (var contentType in httpLanguages) { + if (httpLanguages[contentType]) { + var options = {}; + options[contentType] = { + pattern: new RegExp('(content-type:\\s*' + contentType + '[\\w\\W]*?)(?:\\r?\\n|\\r){2}[\\w\\W]*', 'i'), + lookbehind: true, + inside: { + rest: httpLanguages[contentType] + } + }; + Prism.languages.insertBefore('http', 'header-name', options); + } +} +; +Prism.languages.java = Prism.languages.extend('clike', { + 'keyword': /\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/, + 'number': /\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i, + 'operator': { + pattern: /(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m, + lookbehind: true + } +}); +(function(Prism) { + var funcPattern = /\\([^a-z()[\]]|[a-z\*]+)/i, + insideEqu = { + 'equation-command': { + pattern: funcPattern, + alias: 'regex' + } + }; + + Prism.languages.latex = { + 'comment': /%.*/m, + // the verbatim environment prints whitespace to the document + 'cdata': { + pattern: /(\\begin\{((?:verbatim|lstlisting)\*?)\})([\w\W]*?)(?=\\end\{\2\})/, + lookbehind: true + }, + /* + * equations can be between $ $ or \( \) or \[ \] + * (all are multiline) + */ + 'equation': [ + { + pattern: /\$(?:\\?[\w\W])*?\$|\\\((?:\\?[\w\W])*?\\\)|\\\[(?:\\?[\w\W])*?\\\]/, + inside: insideEqu, + alias: 'string' + }, + { + pattern: /(\\begin\{((?:equation|math|eqnarray|align|multline|gather)\*?)\})([\w\W]*?)(?=\\end\{\2\})/, + lookbehind: true, + inside: insideEqu, + alias: 'string' + } + ], + /* + * arguments which are keywords or references are highlighted + * as keywords + */ + 'keyword': { + pattern: /(\\(?:begin|end|ref|cite|label|usepackage|documentclass)(?:\[[^\]]+\])?\{)[^}]+(?=\})/, + lookbehind: true + }, + 'url': { + pattern: /(\\url\{)[^}]+(?=\})/, + lookbehind: true + }, + /* + * section or chapter headlines are highlighted as bold so that + * they stand out more + */ + 'headline': { + pattern: /(\\(?:part|chapter|section|subsection|frametitle|subsubsection|paragraph|subparagraph|subsubparagraph|subsubsubparagraph)\*?(?:\[[^\]]+\])?\{)[^}]+(?=\}(?:\[[^\]]+\])?)/, + lookbehind: true, + alias: 'class-name' + }, + 'function': { + pattern: funcPattern, + alias: 'selector' + }, + 'punctuation': /[[\]{}&]/ + }; +})(Prism); + +/* FIXME : + :extend() is not handled specifically : its highlighting is buggy. + Mixin usage must be inside a ruleset to be highlighted. + At-rules (e.g. import) containing interpolations are buggy. + Detached rulesets are highlighted as at-rules. + A comment before a mixin usage prevents the latter to be properly highlighted. + */ + +Prism.languages.less = Prism.languages.extend('css', { + 'comment': [ + /\/\*[\w\W]*?\*\//, + { + pattern: /(^|[^\\])\/\/.*/, + lookbehind: true + } + ], + 'atrule': { + pattern: /@[\w-]+?(?:\([^{}]+\)|[^(){};])*?(?=\s*\{)/i, + inside: { + 'punctuation': /[:()]/ + } + }, + // selectors and mixins are considered the same + 'selector': { + pattern: /(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\([^{}]*\)|[^{};@])*?(?=\s*\{)/, + inside: { + // mixin parameters + 'variable': /@+[\w-]+/ + } + }, + + 'property': /(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/i, + 'punctuation': /[{}();:,]/, + 'operator': /[+\-*\/]/ +}); + +// Invert function and punctuation positions +Prism.languages.insertBefore('less', 'punctuation', { + 'function': Prism.languages.less.function +}); + +Prism.languages.insertBefore('less', 'property', { + 'variable': [ + // Variable declaration (the colon must be consumed!) + { + pattern: /@[\w-]+\s*:/, + inside: { + "punctuation": /:/ + } + }, + + // Variable usage + /@@?[\w-]+/ + ], + 'mixin-usage': { + pattern: /([{;]\s*)[.#](?!\d)[\w-]+.*?(?=[(;])/, + lookbehind: true, + alias: 'function' + } +}); + +Prism.languages.lua = { + 'comment': /^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m, + // \z may be used to skip the following space + 'string': /(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[\s\S]))*\1|\[(=*)\[[\s\S]*?\]\2\]/, + 'number': /\b0x[a-f\d]+\.?[a-f\d]*(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|\.?\d*(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i, + 'keyword': /\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/, + 'function': /(?!\d)\w+(?=\s*(?:[({]))/, + 'operator': [ + /[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/, + { + // Match ".." but don't break "..." + pattern: /(^|[^.])\.\.(?!\.)/, + lookbehind: true + } + ], + 'punctuation': /[\[\](){},;]|\.+|:+/ +}; +Prism.languages.makefile = { + 'comment': { + pattern: /(^|[^\\])#(?:\\(?:\r\n|[\s\S])|.)*/, + lookbehind: true + }, + 'string': /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, + + // Built-in target names + 'builtin': /\.[A-Z][^:#=\s]+(?=\s*:(?!=))/, + + // Targets + 'symbol': { + pattern: /^[^:=\r\n]+(?=\s*:(?!=))/m, + inside: { + 'variable': /\$+(?:[^(){}:#=\s]+|(?=[({]))/ + } + }, + 'variable': /\$+(?:[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/, + + 'keyword': [ + // Directives + /-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/, + // Functions + { + pattern: /(\()(?:addsuffix|abspath|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:s|list)?)(?=[ \t])/, + lookbehind: true + } + ], + 'operator': /(?:::|[?:+!])?=|[|@]/, + 'punctuation': /[:;(){}]/ +}; +Prism.languages.markdown = Prism.languages.extend('markup', {}); +Prism.languages.insertBefore('markdown', 'prolog', { + 'blockquote': { + // > ... + pattern: /^>(?:[\t ]*>)*/m, + alias: 'punctuation' + }, + 'code': [ + { + // Prefixed by 4 spaces or 1 tab + pattern: /^(?: {4}|\t).+/m, + alias: 'keyword' + }, + { + // `code` + // ``code`` + pattern: /``.+?``|`[^`\n]+`/, + alias: 'keyword' + } + ], + 'title': [ + { + // title 1 + // ======= + + // title 2 + // ------- + pattern: /\w+.*(?:\r?\n|\r)(?:==+|--+)/, + alias: 'important', + inside: { + punctuation: /==+$|--+$/ + } + }, + { + // # title 1 + // ###### title 6 + pattern: /(^\s*)#+.+/m, + lookbehind: true, + alias: 'important', + inside: { + punctuation: /^#+|#+$/ + } + } + ], + 'hr': { + // *** + // --- + // * * * + // ----------- + pattern: /(^\s*)([*-])([\t ]*\2){2,}(?=\s*$)/m, + lookbehind: true, + alias: 'punctuation' + }, + 'list': { + // * item + // + item + // - item + // 1. item + pattern: /(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m, + lookbehind: true, + alias: 'punctuation' + }, + 'url-reference': { + // [id]: http://example.com "Optional title" + // [id]: http://example.com 'Optional title' + // [id]: http://example.com (Optional title) + // [id]: "Optional title" + pattern: /!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/, + inside: { + 'variable': { + pattern: /^(!?\[)[^\]]+/, + lookbehind: true + }, + 'string': /(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/, + 'punctuation': /^[\[\]!:]|[<>]/ + }, + alias: 'url' + }, + 'bold': { + // **strong** + // __strong__ + + // Allow only one line break + pattern: /(^|[^\\])(\*\*|__)(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/, + lookbehind: true, + inside: { + 'punctuation': /^\*\*|^__|\*\*$|__$/ + } + }, + 'italic': { + // *em* + // _em_ + + // Allow only one line break + pattern: /(^|[^\\])([*_])(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/, + lookbehind: true, + inside: { + 'punctuation': /^[*_]|[*_]$/ + } + }, + 'url': { + // [example](http://example.com "Optional title") + // [example] [id] + pattern: /!?\[[^\]]+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)| ?\[[^\]\n]*\])/, + inside: { + 'variable': { + pattern: /(!?\[)[^\]]+(?=\]$)/, + lookbehind: true + }, + 'string': { + pattern: /"(?:\\.|[^"\\])*"(?=\)$)/ + } + } + } +}); + +Prism.languages.markdown['bold'].inside['url'] = Prism.util.clone(Prism.languages.markdown['url']); +Prism.languages.markdown['italic'].inside['url'] = Prism.util.clone(Prism.languages.markdown['url']); +Prism.languages.markdown['bold'].inside['italic'] = Prism.util.clone(Prism.languages.markdown['italic']); +Prism.languages.markdown['italic'].inside['bold'] = Prism.util.clone(Prism.languages.markdown['bold']); +Prism.languages.nginx = Prism.languages.extend('clike', { + 'comment': { + pattern: /(^|[^"{\\])#.*/, + lookbehind: true + }, + 'keyword': /\b(?:CONTENT_|DOCUMENT_|GATEWAY_|HTTP_|HTTPS|if_not_empty|PATH_|QUERY_|REDIRECT_|REMOTE_|REQUEST_|SCGI|SCRIPT_|SERVER_|http|server|events|location|include|accept_mutex|accept_mutex_delay|access_log|add_after_body|add_before_body|add_header|addition_types|aio|alias|allow|ancient_browser|ancient_browser_value|auth|auth_basic|auth_basic_user_file|auth_http|auth_http_header|auth_http_timeout|autoindex|autoindex_exact_size|autoindex_localtime|break|charset|charset_map|charset_types|chunked_transfer_encoding|client_body_buffer_size|client_body_in_file_only|client_body_in_single_buffer|client_body_temp_path|client_body_timeout|client_header_buffer_size|client_header_timeout|client_max_body_size|connection_pool_size|create_full_put_path|daemon|dav_access|dav_methods|debug_connection|debug_points|default_type|deny|devpoll_changes|devpoll_events|directio|directio_alignment|disable_symlinks|empty_gif|env|epoll_events|error_log|error_page|expires|fastcgi_buffer_size|fastcgi_buffers|fastcgi_busy_buffers_size|fastcgi_cache|fastcgi_cache_bypass|fastcgi_cache_key|fastcgi_cache_lock|fastcgi_cache_lock_timeout|fastcgi_cache_methods|fastcgi_cache_min_uses|fastcgi_cache_path|fastcgi_cache_purge|fastcgi_cache_use_stale|fastcgi_cache_valid|fastcgi_connect_timeout|fastcgi_hide_header|fastcgi_ignore_client_abort|fastcgi_ignore_headers|fastcgi_index|fastcgi_intercept_errors|fastcgi_keep_conn|fastcgi_max_temp_file_size|fastcgi_next_upstream|fastcgi_no_cache|fastcgi_param|fastcgi_pass|fastcgi_pass_header|fastcgi_read_timeout|fastcgi_redirect_errors|fastcgi_send_timeout|fastcgi_split_path_info|fastcgi_store|fastcgi_store_access|fastcgi_temp_file_write_size|fastcgi_temp_path|flv|geo|geoip_city|geoip_country|google_perftools_profiles|gzip|gzip_buffers|gzip_comp_level|gzip_disable|gzip_http_version|gzip_min_length|gzip_proxied|gzip_static|gzip_types|gzip_vary|if|if_modified_since|ignore_invalid_headers|image_filter|image_filter_buffer|image_filter_jpeg_quality|image_filter_sharpen|image_filter_transparency|imap_capabilities|imap_client_buffer|include|index|internal|ip_hash|keepalive|keepalive_disable|keepalive_requests|keepalive_timeout|kqueue_changes|kqueue_events|large_client_header_buffers|limit_conn|limit_conn_log_level|limit_conn_zone|limit_except|limit_rate|limit_rate_after|limit_req|limit_req_log_level|limit_req_zone|limit_zone|lingering_close|lingering_time|lingering_timeout|listen|location|lock_file|log_format|log_format_combined|log_not_found|log_subrequest|map|map_hash_bucket_size|map_hash_max_size|master_process|max_ranges|memcached_buffer_size|memcached_connect_timeout|memcached_next_upstream|memcached_pass|memcached_read_timeout|memcached_send_timeout|merge_slashes|min_delete_depth|modern_browser|modern_browser_value|mp4|mp4_buffer_size|mp4_max_buffer_size|msie_padding|msie_refresh|multi_accept|open_file_cache|open_file_cache_errors|open_file_cache_min_uses|open_file_cache_valid|open_log_file_cache|optimize_server_names|override_charset|pcre_jit|perl|perl_modules|perl_require|perl_set|pid|pop3_auth|pop3_capabilities|port_in_redirect|post_action|postpone_output|protocol|proxy|proxy_buffer|proxy_buffer_size|proxy_buffering|proxy_buffers|proxy_busy_buffers_size|proxy_cache|proxy_cache_bypass|proxy_cache_key|proxy_cache_lock|proxy_cache_lock_timeout|proxy_cache_methods|proxy_cache_min_uses|proxy_cache_path|proxy_cache_use_stale|proxy_cache_valid|proxy_connect_timeout|proxy_cookie_domain|proxy_cookie_path|proxy_headers_hash_bucket_size|proxy_headers_hash_max_size|proxy_hide_header|proxy_http_version|proxy_ignore_client_abort|proxy_ignore_headers|proxy_intercept_errors|proxy_max_temp_file_size|proxy_method|proxy_next_upstream|proxy_no_cache|proxy_pass|proxy_pass_error_message|proxy_pass_header|proxy_pass_request_body|proxy_pass_request_headers|proxy_read_timeout|proxy_redirect|proxy_redirect_errors|proxy_send_lowat|proxy_send_timeout|proxy_set_body|proxy_set_header|proxy_ssl_session_reuse|proxy_store|proxy_store_access|proxy_temp_file_write_size|proxy_temp_path|proxy_timeout|proxy_upstream_fail_timeout|proxy_upstream_max_fails|random_index|read_ahead|real_ip_header|recursive_error_pages|request_pool_size|reset_timedout_connection|resolver|resolver_timeout|return|rewrite|root|rtsig_overflow_events|rtsig_overflow_test|rtsig_overflow_threshold|rtsig_signo|satisfy|satisfy_any|secure_link_secret|send_lowat|send_timeout|sendfile|sendfile_max_chunk|server|server_name|server_name_in_redirect|server_names_hash_bucket_size|server_names_hash_max_size|server_tokens|set|set_real_ip_from|smtp_auth|smtp_capabilities|so_keepalive|source_charset|split_clients|ssi|ssi_silent_errors|ssi_types|ssi_value_length|ssl|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_client_certificate|ssl_crl|ssl_dhparam|ssl_engine|ssl_prefer_server_ciphers|ssl_protocols|ssl_session_cache|ssl_session_timeout|ssl_verify_client|ssl_verify_depth|starttls|stub_status|sub_filter|sub_filter_once|sub_filter_types|tcp_nodelay|tcp_nopush|timeout|timer_resolution|try_files|types|types_hash_bucket_size|types_hash_max_size|underscores_in_headers|uninitialized_variable_warn|upstream|use|user|userid|userid_domain|userid_expires|userid_name|userid_p3p|userid_path|userid_service|valid_referers|variables_hash_bucket_size|variables_hash_max_size|worker_connections|worker_cpu_affinity|worker_priority|worker_processes|worker_rlimit_core|worker_rlimit_nofile|worker_rlimit_sigpending|working_directory|xclient|xml_entities|xslt_entities|xslt_stylesheet|xslt_types)\b/i, +}); + +Prism.languages.insertBefore('nginx', 'keyword', { + 'variable': /\$[a-z_]+/i +}); +/** + * Original by Aaron Harun: http://aahacreative.com/2012/07/31/php-syntax-highlighting-prism/ + * Modified by Miles Johnson: http://milesj.me + * + * Supports the following: + * - Extends clike syntax + * - Support for PHP 5.3+ (namespaces, traits, generators, etc) + * - Smarter constant and function matching + * + * Adds the following new token classes: + * constant, delimiter, variable, function, package + */ + +Prism.languages.php = Prism.languages.extend('clike', { + 'keyword': /\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i, + 'constant': /\b[A-Z0-9_]{2,}\b/, + 'comment': { + pattern: /(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/, + lookbehind: true + } +}); + +// Shell-like comments are matched after strings, because they are less +// common than strings containing hashes... +Prism.languages.insertBefore('php', 'class-name', { + 'shell-comment': { + pattern: /(^|[^\\])#.*/, + lookbehind: true, + alias: 'comment' + } +}); + +Prism.languages.insertBefore('php', 'keyword', { + 'delimiter': /\?>|<\?(?:php)?/i, + 'variable': /\$\w+\b/i, + 'package': { + pattern: /(\\|namespace\s+|use\s+)[\w\\]+/, + lookbehind: true, + inside: { + punctuation: /\\/ + } + } +}); + +// Must be defined after the function pattern +Prism.languages.insertBefore('php', 'operator', { + 'property': { + pattern: /(->)[\w]+/, + lookbehind: true + } +}); + +// Add HTML support of the markup language exists +if (Prism.languages.markup) { + + // Tokenize all inline PHP blocks that are wrapped in + // This allows for easy PHP + markup highlighting + Prism.hooks.add('before-highlight', function(env) { + if (env.language !== 'php') { + return; + } + + env.tokenStack = []; + + env.backupCode = env.code; + env.code = env.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/ig, function(match) { + env.tokenStack.push(match); + + return '{{{PHP' + env.tokenStack.length + '}}}'; + }); + }); + + // Restore env.code for other plugins (e.g. line-numbers) + Prism.hooks.add('before-insert', function(env) { + if (env.language === 'php') { + env.code = env.backupCode; + delete env.backupCode; + } + }); + + // Re-insert the tokens after highlighting + Prism.hooks.add('after-highlight', function(env) { + if (env.language !== 'php') { + return; + } + + for (var i = 0, t; t = env.tokenStack[i]; i++) { + // The replace prevents $$, $&, $`, $', $n, $nn from being interpreted as special patterns + env.highlightedCode = env.highlightedCode.replace('{{{PHP' + (i + 1) + '}}}', Prism.highlight(t, env.grammar, 'php').replace(/\$/g, '$$$$')); + } + + env.element.innerHTML = env.highlightedCode; + }); + + // Wrap tokens in classes that are missing them + Prism.hooks.add('wrap', function(env) { + if (env.language === 'php' && env.type === 'markup') { + env.content = env.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g, "$1"); + } + }); + + // Add the rules before all others + Prism.languages.insertBefore('php', 'comment', { + 'markup': { + pattern: /<[^?]\/?(.*?)>/, + inside: Prism.languages.markup + }, + 'php': /\{\{\{PHP[0-9]+\}\}\}/ + }); +} +; +Prism.languages.insertBefore('php', 'variable', { + 'this': /\$this\b/, + 'global': /\$(?:_(?:SERVER|GET|POST|FILES|REQUEST|SESSION|ENV|COOKIE)|GLOBALS|HTTP_RAW_POST_DATA|argc|argv|php_errormsg|http_response_header)/, + 'scope': { + pattern: /\b[\w\\]+::/, + inside: { + keyword: /(static|self|parent)/, + punctuation: /(::|\\)/ + } + } +}); +Prism.languages.python= { + 'triple-quoted-string': { + pattern: /"""[\s\S]+?"""|'''[\s\S]+?'''/, + alias: 'string' + }, + 'comment': { + pattern: /(^|[^\\])#.*/, + lookbehind: true + }, + 'string': /("|')(?:\\?.)*?\1/, + 'function' : { + pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_][a-zA-Z0-9_]*(?=\()/g, + lookbehind: true + }, + 'class-name': { + pattern: /(\bclass\s+)[a-z0-9_]+/i, + lookbehind: true + }, + 'keyword' : /\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/, + 'boolean' : /\b(?:True|False)\b/, + 'number' : /\b-?(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i, + 'operator' : /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/, + 'punctuation' : /[{}[\];(),.:]/ +}; + +(function(Prism) { + Prism.languages.sass = Prism.languages.extend('css', { + // Sass comments don't need to be closed, only indented + 'comment': { + pattern: /^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t]+.+)*/m, + lookbehind: true + } + }); + + Prism.languages.insertBefore('sass', 'atrule', { + // We want to consume the whole line + 'atrule-line': { + // Includes support for = and + shortcuts + pattern: /^(?:[ \t]*)[@+=].+/m, + inside: { + 'atrule': /(?:@[\w-]+|[+=])/m + } + } + }); + delete Prism.languages.sass.atrule; + + + var variable = /((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i; + var operator = [ + /[+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/, + { + pattern: /(\s+)-(?=\s)/, + lookbehind: true + } + ]; + + Prism.languages.insertBefore('sass', 'property', { + // We want to consume the whole line + 'variable-line': { + pattern: /^[ \t]*\$.+/m, + inside: { + 'punctuation': /:/, + 'variable': variable, + 'operator': operator + } + }, + // We want to consume the whole line + 'property-line': { + pattern: /^[ \t]*(?:[^:\s]+ *:.*|:[^:\s]+.*)/m, + inside: { + 'property': [ + /[^:\s]+(?=\s*:)/, + { + pattern: /(:)[^:\s]+/, + lookbehind: true + } + ], + 'punctuation': /:/, + 'variable': variable, + 'operator': operator, + 'important': Prism.languages.sass.important + } + } + }); + delete Prism.languages.sass.property; + delete Prism.languages.sass.important; + + // Now that whole lines for other patterns are consumed, + // what's left should be selectors + delete Prism.languages.sass.selector; + Prism.languages.insertBefore('sass', 'punctuation', { + 'selector': { + pattern: /([ \t]*)\S(?:,?[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,?[^,\r\n]+)*)*/, + lookbehind: true + } + }); + +}(Prism)); +Prism.languages.scss = Prism.languages.extend('css', { + 'comment': { + pattern: /(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/, + lookbehind: true + }, + 'atrule': { + pattern: /@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/, + inside: { + 'rule': /@[\w-]+/ + // See rest below + } + }, + // url, compassified + 'url': /(?:[-a-z]+-)*url(?=\()/i, + // CSS selector regex is not appropriate for Sass + // since there can be lot more things (var, @ directive, nesting..) + // a selector must start at the end of a property or after a brace (end of other rules or nesting) + // it can contain some characters that aren't used for defining rules or end of selector, & (parent selector), or interpolated variable + // the end of a selector is found when there is no rules in it ( {} or {\s}) or if there is a property (because an interpolated var + // can "pass" as a selector- e.g: proper#{$erty}) + // this one was hard to do, so please be careful if you edit this one :) + 'selector': { + // Initial look-ahead is used to prevent matching of blank selectors + pattern: /(?=\S)[^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m, + inside: { + 'placeholder': /%[-_\w]+/ + } + } +}); + +Prism.languages.insertBefore('scss', 'atrule', { + 'keyword': [ + /@(?:if|else(?: if)?|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)/i, + { + pattern: /( +)(?:from|through)(?= )/, + lookbehind: true + } + ] +}); + +Prism.languages.insertBefore('scss', 'property', { + // var and interpolated vars + 'variable': /\$[-_\w]+|#\{\$[-_\w]+\}/ +}); + +Prism.languages.insertBefore('scss', 'function', { + 'placeholder': { + pattern: /%[-_\w]+/, + alias: 'selector' + }, + 'statement': /\B!(?:default|optional)\b/i, + 'boolean': /\b(?:true|false)\b/, + 'null': /\bnull\b/, + 'operator': { + pattern: /(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/, + lookbehind: true + } +}); + +Prism.languages.scss['atrule'].inside.rest = Prism.util.clone(Prism.languages.scss); +Prism.languages.sql= { + 'comment': { + pattern: /(^|[^\\])(?:\/\*[\w\W]*?\*\/|(?:--|\/\/|#).*)/, + lookbehind: true + }, + 'string' : { + pattern: /(^|[^@\\])("|')(?:\\?[\s\S])*?\2/, + lookbehind: true + }, + 'variable': /@[\w.$]+|@("|'|`)(?:\\?[\s\S])+?\1/, + 'function': /\b(?:COUNT|SUM|AVG|MIN|MAX|FIRST|LAST|UCASE|LCASE|MID|LEN|ROUND|NOW|FORMAT)(?=\s*\()/i, // Should we highlight user defined functions too? + 'keyword': /\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR VARYING|CHARACTER (?:SET|VARYING)|CHARSET|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COLUMNS|COMMENT|COMMIT|COMMITTED|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|DATA(?:BASES?)?|DATETIME|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE(?: PRECISION)?|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE KEY|ELSE|ENABLE|ENCLOSED BY|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPE(?:D BY)?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTO|INVOKER|ISOLATION LEVEL|JOIN|KEYS?|KILL|LANGUAGE SQL|LAST|LEFT|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MODIFIES SQL DATA|MODIFY|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL(?: CHAR VARYING| CHARACTER(?: VARYING)?| VARCHAR)?|NATURAL|NCHAR(?: VARCHAR)?|NEXT|NO(?: SQL|CHECK|CYCLE)?|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READ(?:S SQL DATA|TEXT)?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEATABLE|REPLICATION|REQUIRE|RESTORE|RESTRICT|RETURNS?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE MODE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|START(?:ING BY)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED BY|TEXT(?:SIZE)?|THEN|TIMESTAMP|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNPIVOT|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?)\b/i, + 'boolean': /\b(?:TRUE|FALSE|NULL)\b/i, + 'number': /\b-?(?:0x)?\d*\.?[\da-f]+\b/, + 'operator': /[-+*\/=%^~]|&&?|\|?\||!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|IN|LIKE|NOT|OR|IS|DIV|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i, + 'punctuation': /[;[\]()`,.]/ +}; +Prism.languages.twig = { + 'comment': /\{#[\s\S]*?#\}/, + 'tag': { + pattern: /\{\{[\s\S]*?\}\}|\{%[\s\S]*?%\}/, + inside: { + 'ld': { + pattern: /^(?:\{\{\-?|\{%\-?\s*\w+)/, + inside: { + 'punctuation': /^(?:\{\{|\{%)\-?/, + 'keyword': /\w+/ + } + }, + 'rd': { + pattern: /\-?(?:%\}|\}\})$/, + inside: { + 'punctuation': /.*/ + } + }, + 'string': { + pattern: /("|')(?:\\?.)*?\1/, + inside: { + 'punctuation': /^['"]|['"]$/ + } + }, + 'keyword': /\b(?:even|if|odd)\b/, + 'boolean': /\b(?:true|false|null)\b/, + 'number': /\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+([Ee][-+]?\d+)?)\b/, + 'operator': [ + { + pattern: /(\s)(?:and|b\-and|b\-xor|b\-or|ends with|in|is|matches|not|or|same as|starts with)(?=\s)/, + lookbehind: true + }, + /[=<>]=?|!=|\*\*?|\/\/?|\?:?|[-+~%|]/ + ], + 'property': /\b[a-zA-Z_][a-zA-Z0-9_]*\b/, + 'punctuation': /[()\[\]{}:.,]/ + } + }, + + // The rest can be parsed as HTML + 'other': { + // We want non-blank matches + pattern: /\S(?:[\s\S]*\S)?/, + inside: Prism.languages.markup + } +}; + +Prism.languages.yaml = { + 'scalar': { + pattern: /([\-:]\s*(![^\s]+)?[ \t]*[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\3[^\r\n]+)*)/, + lookbehind: true, + alias: 'string' + }, + 'comment': /#.*/, + 'key': { + pattern: /(\s*[:\-,[{\r\n?][ \t]*(![^\s]+)?[ \t]*)[^\r\n{[\]},#]+?(?=\s*:\s)/, + lookbehind: true, + alias: 'atrule' + }, + 'directive': { + pattern: /(^[ \t]*)%.+/m, + lookbehind: true, + alias: 'important' + }, + 'datetime': { + pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)(\d{4}-\d\d?-\d\d?([tT]|[ \t]+)\d\d?:\d{2}:\d{2}(\.\d*)?[ \t]*(Z|[-+]\d\d?(:\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(:\d{2}(\.\d*)?)?)(?=[ \t]*($|,|]|}))/m, + lookbehind: true, + alias: 'number' + }, + 'boolean': { + pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)(true|false)[ \t]*(?=$|,|]|})/im, + lookbehind: true, + alias: 'important' + }, + 'null': { + pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)(null|~)[ \t]*(?=$|,|]|})/im, + lookbehind: true, + alias: 'important' + }, + 'string': { + pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')(?=[ \t]*($|,|]|}))/m, + lookbehind: true + }, + 'number': { + pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)[+\-]?(0x[\da-f]+|0o[0-7]+|(\d+\.?\d*|\.?\d+)(e[\+\-]?\d+)?|\.inf|\.nan)[ \t]*(?=$|,|]|})/im, + lookbehind: true + }, + 'tag': /![^\s]+/, + 'important': /[&*][\w]+/, + 'punctuation': /---|[:[\]{}\-,|>?]|\.\.\./ +}; + +(function() { + +if (typeof self === 'undefined' || !self.Prism || !self.document) { + return; +} + +Prism.hooks.add('complete', function (env) { + if (!env.code) { + return; + } + + // works only for wrapped inside
 (not inline)
+	var pre = env.element.parentNode;
+	var clsReg = /\s*\bline-numbers\b\s*/;
+	if (
+		!pre || !/pre/i.test(pre.nodeName) ||
+			// Abort only if nor the 
 nor the  have the class
+		(!clsReg.test(pre.className) && !clsReg.test(env.element.className))
+	) {
+		return;
+	}
+
+	if (env.element.querySelector(".line-numbers-rows")) {
+		// Abort if line numbers already exists
+		return;
+	}
+
+	if (clsReg.test(env.element.className)) {
+		// Remove the class "line-numbers" from the 
+		env.element.className = env.element.className.replace(clsReg, '');
+	}
+	if (!clsReg.test(pre.className)) {
+		// Add the class "line-numbers" to the 
+		pre.className += ' line-numbers';
+	}
+
+	var match = env.code.match(/\n(?!$)/g);
+	var linesNum = match ? match.length + 1 : 1;
+	var lineNumbersWrapper;
+
+	var lines = new Array(linesNum + 1);
+	lines = lines.join('');
+
+	lineNumbersWrapper = document.createElement('span');
+	lineNumbersWrapper.className = 'line-numbers-rows';
+	lineNumbersWrapper.innerHTML = lines;
+
+	if (pre.hasAttribute('data-start')) {
+		pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
+	}
+
+	env.element.appendChild(lineNumbersWrapper);
+
+});
+
+}());
+(function(){
+
+if (
+	typeof self !== 'undefined' && !self.Prism ||
+	typeof global !== 'undefined' && !global.Prism
+) {
+	return;
+}
+
+var url = /\b([a-z]{3,7}:\/\/|tel:)[\w\-+%~/.:#=?&]+/,
+    email = /\b\S+@[\w.]+[a-z]{2}/,
+    linkMd = /\[([^\]]+)]\(([^)]+)\)/,
+    
+	// Tokens that may contain URLs and emails
+    candidates = ['comment', 'url', 'attr-value', 'string'];
+
+Prism.hooks.add('before-highlight', function(env) {
+	// Abort if grammar has already been processed
+	if (!env.grammar || env.grammar['url-link']) {
+		return;
+	}
+	Prism.languages.DFS(env.grammar, function (key, def, type) {
+		if (candidates.indexOf(type) > -1 && Prism.util.type(def) !== 'Array') {
+			if (!def.pattern) {
+				def = this[key] = {
+					pattern: def
+				};
+			}
+
+			def.inside = def.inside || {};
+
+			if (type == 'comment') {
+				def.inside['md-link'] = linkMd;
+			}
+			if (type == 'attr-value') {
+				Prism.languages.insertBefore('inside', 'punctuation', { 'url-link': url }, def);
+			}
+			else {
+				def.inside['url-link'] = url;
+			}
+
+			def.inside['email-link'] = email;
+		}
+	});
+	env.grammar['url-link'] = url;
+	env.grammar['email-link'] = email;
+});
+
+Prism.hooks.add('wrap', function(env) {
+	if (/-link$/.test(env.type)) {
+		env.tag = 'a';
+		
+		var href = env.content;
+		
+		if (env.type == 'email-link' && href.indexOf('mailto:') != 0) {
+			href = 'mailto:' + href;
+		}
+		else if (env.type == 'md-link') {
+			// Markdown
+			var match = env.content.match(linkMd);
+			
+			href = match[2];
+			env.content = match[1];
+		}
+		
+		env.attributes.href = href;
+	}
+});
+
+})();
+(function(){
+
+if (typeof self === 'undefined' || !self.Prism || !self.document) {
+	return;
+}
+
+// The languages map is built automatically with gulp
+var Languages = /*languages_placeholder[*/{"css":"CSS","clike":"C-like","javascript":"JavaScript","abap":"ABAP","actionscript":"ActionScript","apacheconf":"Apache Configuration","apl":"APL","applescript":"AppleScript","asciidoc":"AsciiDoc","aspnet":"ASP.NET (C#)","autoit":"AutoIt","autohotkey":"AutoHotkey","basic":"BASIC","csharp":"C#","cpp":"C++","coffeescript":"CoffeeScript","css-extras":"CSS Extras","fsharp":"F#","glsl":"GLSL","http":"HTTP","inform7":"Inform 7","latex":"LaTeX","lolcode":"LOLCODE","matlab":"MATLAB","mel":"MEL","nasm":"NASM","nginx":"nginx","nsis":"NSIS","objectivec":"Objective-C","ocaml":"OCaml","parigp":"PARI/GP","php":"PHP","php-extras":"PHP Extras","powershell":"PowerShell","jsx":"React JSX","rest":"reST (reStructuredText)","sas":"SAS","sass":"Sass (Sass)","scss":"Sass (Scss)","sql":"SQL","typescript":"TypeScript","vhdl":"VHDL","vim":"vim","wiki":"Wiki markup","yaml":"YAML"}/*]*/;
+Prism.hooks.add('before-highlight', function(env) {
+	var pre = env.element.parentNode;
+	if (!pre || !/pre/i.test(pre.nodeName)) {
+		return;
+	}
+	var language = Languages[env.language] || (env.language.substring(0, 1).toUpperCase() + env.language.substring(1));
+	pre.setAttribute('data-language', language);
+
+	/* check if the divs already exist */
+	var sib = pre.previousSibling;
+	var div, div2;
+	if (sib && /\s*\bprism-show-language\b\s*/.test(sib.className) &&
+		sib.firstChild &&
+		/\s*\bprism-show-language-label\b\s*/.test(sib.firstChild.className)) {
+		div2 = sib.firstChild;
+		if (div2.getAttribute('data-language') !== language) {
+			div2.setAttribute('data-language', language);
+			div2.innerHTML = language;
+		}
+	} else {
+		div = document.createElement('div');
+		div2 = document.createElement('div');
+
+		div2.className = 'prism-show-language-label';
+		div2.setAttribute('data-language', language);
+		div2.innerHTML = language;
+
+		div.className = 'prism-show-language';
+		div.appendChild(div2);
+
+		pre.parentNode.insertBefore(div, pre);
+	}
+});
+
+})();
+
diff --git a/parser/markdown/assets/prism.min.css b/parser/markdown/assets/prism.min.css
new file mode 100644
index 0000000..deec86e
--- /dev/null
+++ b/parser/markdown/assets/prism.min.css
@@ -0,0 +1,212 @@
+/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+bash+c+csharp+cpp+ruby+diff+git+go+http+java+latex+less+lua+makefile+markdown+nginx+php+php-extras+python+sass+scss+sql+twig+yaml&plugins=line-numbers+autolinker+show-language */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+
+code[class*="language-"],
+pre[class*="language-"] {
+	color: black;
+	text-shadow: 0 1px white;
+	font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+	direction: ltr;
+	text-align: left;
+	white-space: pre;
+	word-spacing: normal;
+	word-break: normal;
+	word-wrap: normal;
+	line-height: 1.5;
+
+	-moz-tab-size: 4;
+	-o-tab-size: 4;
+	tab-size: 4;
+
+	-webkit-hyphens: none;
+	-moz-hyphens: none;
+	-ms-hyphens: none;
+	hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
+	text-shadow: none;
+	background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
+code[class*="language-"]::selection, code[class*="language-"] ::selection {
+	text-shadow: none;
+	background: #b3d4fc;
+}
+
+@media print {
+	code[class*="language-"],
+	pre[class*="language-"] {
+		text-shadow: none;
+	}
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+	padding: 1em;
+	margin: .5em 0;
+	overflow: auto;
+}
+
+:not(pre) > code[class*="language-"],
+pre[class*="language-"] {
+	background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre) > code[class*="language-"] {
+	padding: .1em;
+	border-radius: .3em;
+	white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+	color: slategray;
+}
+
+.token.punctuation {
+	color: #999;
+}
+
+.namespace {
+	opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+	color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+	color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+	color: #a67f59;
+	background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+	color: #07a;
+}
+
+.token.function {
+	color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+	color: #e90;
+}
+
+.token.important,
+.token.bold {
+	font-weight: bold;
+}
+.token.italic {
+	font-style: italic;
+}
+
+.token.entity {
+	cursor: help;
+}
+
+pre.line-numbers {
+	position: relative;
+	padding-left: 3.8em;
+	counter-reset: linenumber;
+}
+
+pre.line-numbers > code {
+	position: relative;
+}
+
+.line-numbers .line-numbers-rows {
+	position: absolute;
+	pointer-events: none;
+	top: 0;
+	font-size: 100%;
+	left: -3.8em;
+	width: 3em; /* works for line-numbers below 1000 lines */
+	letter-spacing: -1px;
+	border-right: 1px solid #999;
+
+	-webkit-user-select: none;
+	-moz-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+
+}
+
+	.line-numbers-rows > span {
+		pointer-events: none;
+		display: block;
+		counter-increment: linenumber;
+	}
+
+		.line-numbers-rows > span:before {
+			content: counter(linenumber);
+			color: #999;
+			display: block;
+			padding-right: 0.8em;
+			text-align: right;
+		}
+.token a {
+	color: inherit;
+}
+div.prism-show-language {
+	position: relative;
+}
+
+div.prism-show-language > div.prism-show-language-label[data-language] {
+	color: black;
+	background-color: #CFCFCF;
+	display: inline-block;
+	position: absolute;
+	bottom: auto;
+	left: auto;
+	top: 0;
+	right: 0;
+	width: auto;
+	height: auto;
+	font-size: 0.9em;
+	border-radius: 0 0 0 5px;
+	padding: 0 0.5em;
+	text-shadow: none;
+	z-index: 1;
+	-webkit-box-shadow: none;
+	-moz-box-shadow: none;
+	box-shadow: none;
+	-webkit-transform: none;
+	-moz-transform: none;
+	-ms-transform: none;
+	-o-transform: none;
+	transform: none;
+}
+
diff --git a/parser/markdown/assets/prism.min.js b/parser/markdown/assets/prism.min.js
new file mode 100644
index 0000000..7f44299
--- /dev/null
+++ b/parser/markdown/assets/prism.min.js
@@ -0,0 +1,33 @@
+/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+bash+c+csharp+cpp+ruby+diff+git+go+http+java+latex+less+lua+makefile+markdown+nginx+php+php-extras+python+sass+scss+sql+twig+yaml&plugins=line-numbers+autolinker+show-language */
+var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=_self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(d instanceof a)){u.lastIndex=0;var m=u.exec(d);if(m){c&&(f=m[1].length);var y=m.index-1+f,m=m[0].slice(f),v=m.length,k=y+v,b=d.slice(0,y+1),w=d.slice(k+1),P=[p,1];b&&P.push(b);var A=new a(i,g?t.tokenize(m,g):m,h);P.push(A),w&&P.push(w),Array.prototype.splice.apply(r,P)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,l=0;r=a[l++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var l={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==l.type&&(l.attributes.spellcheck="true"),e.alias){var i="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(l.classes,i)}t.hooks.run("wrap",l);var o="";for(var s in l.attributes)o+=(o?" ":"")+s+'="'+(l.attributes[s]||"")+'"';return"<"+l.tag+' class="'+l.classes.join(" ")+'" '+o+">"+l.content+""},!_self.document)return _self.addEventListener?(_self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code,l=n.immediateClose;_self.postMessage(t.highlight(r,t.languages[a],a)),l&&_self.close()},!1),_self.Prism):_self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
+Prism.languages.markup={comment://,prolog:/<\?[\w\W]+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=.$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup;
+Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*?(?=\s*\{)/,string:/("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.util.clone(Prism.languages.css),Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/()[\w\W]*?(?=<\/style>)/i,lookbehind:!0,inside:Prism.languages.css,alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag));
+Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/};
+Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,"function":/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),Prism.languages.insertBefore("javascript","class-name",{"template-string":{pattern:/`(?:\\`|\\?[^`])*`/,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/()[\w\W]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.javascript,alias:"language-javascript"}}),Prism.languages.js=Prism.languages.javascript;
+!function(e){var t={variable:[{pattern:/\$?\(\([\w\W]+?\)\)/,inside:{variable:[{pattern:/(^\$\(\([\w\W]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee]-?\d+)?)\b/,operator:/--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\([^)]+\)|`[^`]+`/,inside:{variable:/^\$\(|^`|\)$|`$/}},/\$(?:[a-z0-9_#\?\*!@]+|\{[^}]+\})/i]};e.languages.bash={shebang:{pattern:/^#!\s*\/bin\/bash|^#!\s*\/bin\/sh/,alias:"important"},comment:{pattern:/(^|[^"{\\])#.*/,lookbehind:!0},string:[{pattern:/((?:^|[^<])<<\s*)(?:"|')?(\w+?)(?:"|')?\s*\r?\n(?:[\s\S])*?\r?\n\2/g,lookbehind:!0,inside:t},{pattern:/("|')(?:\\?[\s\S])*?\1/g,inside:t}],variable:t.variable,"function":{pattern:/(^|\s|;|\||&)(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|cut|date|dc|dd|ddrescue|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|enable|env|ethtool|eval|exec|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)(?=$|\s|;|\||&)/,lookbehind:!0},keyword:{pattern:/(^|\s|;|\||&)(?:let|:|\.|if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)(?=$|\s|;|\||&)/,lookbehind:!0},"boolean":{pattern:/(^|\s|;|\||&)(?:true|false)(?=$|\s|;|\||&)/,lookbehind:!0},operator:/&&?|\|\|?|==?|!=?|<<>|<=?|>=?|=~/,punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];]/};var a=t.variable[1].inside;a["function"]=e.languages.bash["function"],a.keyword=e.languages.bash.keyword,a.boolean=e.languages.bash.boolean,a.operator=e.languages.bash.operator,a.punctuation=e.languages.bash.punctuation}(Prism);
+Prism.languages.c=Prism.languages.extend("clike",{keyword:/\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,operator:/\-[>-]?|\+\+?|!=?|<>?=?|==?|&&?|\|?\||[~^%?*\/]/,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i}),Prism.languages.insertBefore("c","string",{macro:{pattern:/(^\s*)#\s*[a-z]+([^\r\n\\]|\\.|\\(?:\r\n?|\n))*/im,lookbehind:!0,alias:"property",inside:{string:{pattern:/(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/,lookbehind:!0},directive:{pattern:/(#\s*)\b(define|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/,lookbehind:!0,alias:"keyword"}}},constant:/\b(__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|stdin|stdout|stderr)\b/}),delete Prism.languages.c["class-name"],delete Prism.languages.c["boolean"];
+Prism.languages.csharp=Prism.languages.extend("clike",{keyword:/\b(abstract|as|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|async|await|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)\b/,string:[/@("|')(\1\1|\\\1|\\?(?!\1)[\s\S])*\1/,/("|')(\\?.)*?\1/],number:/\b-?(0x[\da-f]+|\d*\.?\d+f?)\b/i}),Prism.languages.insertBefore("csharp","keyword",{preprocessor:{pattern:/(^\s*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(\s*#)\b(define|elif|else|endif|endregion|error|if|line|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});
+Prism.languages.cpp=Prism.languages.extend("c",{keyword:/\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,"boolean":/\b(true|false)\b/,operator:/[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/}),Prism.languages.insertBefore("cpp","keyword",{"class-name":{pattern:/(class\s+)[a-z0-9_]+/i,lookbehind:!0}});
+!function(e){e.languages.ruby=e.languages.extend("clike",{comment:/#(?!\{[^\r\n]*?\}).*/,keyword:/\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/});var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.util.clone(e.languages.ruby)}};e.languages.insertBefore("ruby","keyword",{regex:[{pattern:/%r([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1[gim]{0,3}/,inside:{interpolation:n}},{pattern:/%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,inside:{interpolation:n}},{pattern:/%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,inside:{interpolation:n}},{pattern:/%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,inside:{interpolation:n}},{pattern:/%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,inside:{interpolation:n}},{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}],variable:/[@$]+[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/,symbol:/:[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/}),e.languages.insertBefore("ruby","number",{builtin:/\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z][a-zA-Z_0-9]*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:/%[qQiIwWxs]?([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1/,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,inside:{interpolation:n}},{pattern:/("|')(#\{[^}]+\}|\\(?:\r?\n|\r)|\\?.)*?\1/,inside:{interpolation:n}}]}(Prism);
+Prism.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d+.*$/m],deleted:/^[-<].+$/m,inserted:/^[+>].+$/m,diff:{pattern:/^!(?!!).+$/m,alias:"important"}};
+Prism.languages.git={comment:/^#.*/m,deleted:/^[-–].*/m,inserted:/^\+.*/m,string:/("|')(\\?.)*?\1/m,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s(--|-)\w+/m}},coord:/^@@.*@@$/m,commit_sha1:/^commit \w{40}$/m};
+Prism.languages.go=Prism.languages.extend("clike",{keyword:/\b(break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,builtin:/\b(bool|byte|complex(64|128)|error|float(32|64)|rune|string|u?int(8|16|32|64|)|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(ln)?|real|recover)\b/,"boolean":/\b(_|iota|nil|true|false)\b/,operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,number:/\b(-?(0x[a-f\d]+|(\d+\.?\d*|\.\d+)(e[-+]?\d+)?)i?)\b/i,string:/("|'|`)(\\?.|\r|\n)*?\1/}),delete Prism.languages.go["class-name"];
+Prism.languages.http={"request-line":{pattern:/^(POST|GET|PUT|DELETE|OPTIONS|PATCH|TRACE|CONNECT)\b\shttps?:\/\/\S+\sHTTP\/[0-9.]+/m,inside:{property:/^(POST|GET|PUT|DELETE|OPTIONS|PATCH|TRACE|CONNECT)\b/,"attr-name":/:\w+/}},"response-status":{pattern:/^HTTP\/1.[01] [0-9]+.*/m,inside:{property:{pattern:/(^HTTP\/1.[01] )[0-9]+.*/i,lookbehind:!0}}},"header-name":{pattern:/^[\w-]+:(?=.)/m,alias:"keyword"}};var httpLanguages={"application/json":Prism.languages.javascript,"application/xml":Prism.languages.markup,"text/xml":Prism.languages.markup,"text/html":Prism.languages.markup};for(var contentType in httpLanguages)if(httpLanguages[contentType]){var options={};options[contentType]={pattern:new RegExp("(content-type:\\s*"+contentType+"[\\w\\W]*?)(?:\\r?\\n|\\r){2}[\\w\\W]*","i"),lookbehind:!0,inside:{rest:httpLanguages[contentType]}},Prism.languages.insertBefore("http","header-name",options)};
+Prism.languages.java=Prism.languages.extend("clike",{keyword:/\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,number:/\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i,operator:{pattern:/(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m,lookbehind:!0}});
+!function(a){var e=/\\([^a-z()[\]]|[a-z\*]+)/i,n={"equation-command":{pattern:e,alias:"regex"}};a.languages.latex={comment:/%.*/m,cdata:{pattern:/(\\begin\{((?:verbatim|lstlisting)\*?)\})([\w\W]*?)(?=\\end\{\2\})/,lookbehind:!0},equation:[{pattern:/\$(?:\\?[\w\W])*?\$|\\\((?:\\?[\w\W])*?\\\)|\\\[(?:\\?[\w\W])*?\\\]/,inside:n,alias:"string"},{pattern:/(\\begin\{((?:equation|math|eqnarray|align|multline|gather)\*?)\})([\w\W]*?)(?=\\end\{\2\})/,lookbehind:!0,inside:n,alias:"string"}],keyword:{pattern:/(\\(?:begin|end|ref|cite|label|usepackage|documentclass)(?:\[[^\]]+\])?\{)[^}]+(?=\})/,lookbehind:!0},url:{pattern:/(\\url\{)[^}]+(?=\})/,lookbehind:!0},headline:{pattern:/(\\(?:part|chapter|section|subsection|frametitle|subsubsection|paragraph|subparagraph|subsubparagraph|subsubsubparagraph)\*?(?:\[[^\]]+\])?\{)[^}]+(?=\}(?:\[[^\]]+\])?)/,lookbehind:!0,alias:"class-name"},"function":{pattern:e,alias:"selector"},punctuation:/[[\]{}&]/}}(Prism);
+Prism.languages.less=Prism.languages.extend("css",{comment:[/\/\*[\w\W]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-]+?(?:\([^{}]+\)|[^(){};])*?(?=\s*\{)/i,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\([^{}]*\)|[^{};@])*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/i,punctuation:/[{}();:,]/,operator:/[+\-*\/]/}),Prism.languages.insertBefore("less","punctuation",{"function":Prism.languages.less.function}),Prism.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-]+.*?(?=[(;])/,lookbehind:!0,alias:"function"}});
+Prism.languages.lua={comment:/^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,string:/(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[\s\S]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,number:/\b0x[a-f\d]+\.?[a-f\d]*(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|\.?\d*(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,keyword:/\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,"function":/(?!\d)\w+(?=\s*(?:[({]))/,operator:[/[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/,{pattern:/(^|[^.])\.\.(?!\.)/,lookbehind:!0}],punctuation:/[\[\](){},;]|\.+|:+/};
+Prism.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|.)*/,lookbehind:!0},string:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,builtin:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,symbol:{pattern:/^[^:=\r\n]+(?=\s*:(?!=))/m,inside:{variable:/\$+(?:[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:[/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,{pattern:/(\()(?:addsuffix|abspath|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:s|list)?)(?=[ \t])/,lookbehind:!0}],operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/};
+Prism.languages.markdown=Prism.languages.extend("markup",{}),Prism.languages.insertBefore("markdown","prolog",{blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},code:[{pattern:/^(?: {4}|\t).+/m,alias:"keyword"},{pattern:/``.+?``|`[^`\n]+`/,alias:"keyword"}],title:[{pattern:/\w+.*(?:\r?\n|\r)(?:==+|--+)/,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#+.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])([\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:/(^|[^\\])(\*\*|__)(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^\*\*|^__|\*\*$|__$/}},italic:{pattern:/(^|[^\\])([*_])(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^[*_]|[*_]$/}},url:{pattern:/!?\[[^\]]+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)| ?\[[^\]\n]*\])/,inside:{variable:{pattern:/(!?\[)[^\]]+(?=\]$)/,lookbehind:!0},string:{pattern:/"(?:\\.|[^"\\])*"(?=\)$)/}}}}),Prism.languages.markdown.bold.inside.url=Prism.util.clone(Prism.languages.markdown.url),Prism.languages.markdown.italic.inside.url=Prism.util.clone(Prism.languages.markdown.url),Prism.languages.markdown.bold.inside.italic=Prism.util.clone(Prism.languages.markdown.italic),Prism.languages.markdown.italic.inside.bold=Prism.util.clone(Prism.languages.markdown.bold);
+Prism.languages.nginx=Prism.languages.extend("clike",{comment:{pattern:/(^|[^"{\\])#.*/,lookbehind:!0},keyword:/\b(?:CONTENT_|DOCUMENT_|GATEWAY_|HTTP_|HTTPS|if_not_empty|PATH_|QUERY_|REDIRECT_|REMOTE_|REQUEST_|SCGI|SCRIPT_|SERVER_|http|server|events|location|include|accept_mutex|accept_mutex_delay|access_log|add_after_body|add_before_body|add_header|addition_types|aio|alias|allow|ancient_browser|ancient_browser_value|auth|auth_basic|auth_basic_user_file|auth_http|auth_http_header|auth_http_timeout|autoindex|autoindex_exact_size|autoindex_localtime|break|charset|charset_map|charset_types|chunked_transfer_encoding|client_body_buffer_size|client_body_in_file_only|client_body_in_single_buffer|client_body_temp_path|client_body_timeout|client_header_buffer_size|client_header_timeout|client_max_body_size|connection_pool_size|create_full_put_path|daemon|dav_access|dav_methods|debug_connection|debug_points|default_type|deny|devpoll_changes|devpoll_events|directio|directio_alignment|disable_symlinks|empty_gif|env|epoll_events|error_log|error_page|expires|fastcgi_buffer_size|fastcgi_buffers|fastcgi_busy_buffers_size|fastcgi_cache|fastcgi_cache_bypass|fastcgi_cache_key|fastcgi_cache_lock|fastcgi_cache_lock_timeout|fastcgi_cache_methods|fastcgi_cache_min_uses|fastcgi_cache_path|fastcgi_cache_purge|fastcgi_cache_use_stale|fastcgi_cache_valid|fastcgi_connect_timeout|fastcgi_hide_header|fastcgi_ignore_client_abort|fastcgi_ignore_headers|fastcgi_index|fastcgi_intercept_errors|fastcgi_keep_conn|fastcgi_max_temp_file_size|fastcgi_next_upstream|fastcgi_no_cache|fastcgi_param|fastcgi_pass|fastcgi_pass_header|fastcgi_read_timeout|fastcgi_redirect_errors|fastcgi_send_timeout|fastcgi_split_path_info|fastcgi_store|fastcgi_store_access|fastcgi_temp_file_write_size|fastcgi_temp_path|flv|geo|geoip_city|geoip_country|google_perftools_profiles|gzip|gzip_buffers|gzip_comp_level|gzip_disable|gzip_http_version|gzip_min_length|gzip_proxied|gzip_static|gzip_types|gzip_vary|if|if_modified_since|ignore_invalid_headers|image_filter|image_filter_buffer|image_filter_jpeg_quality|image_filter_sharpen|image_filter_transparency|imap_capabilities|imap_client_buffer|include|index|internal|ip_hash|keepalive|keepalive_disable|keepalive_requests|keepalive_timeout|kqueue_changes|kqueue_events|large_client_header_buffers|limit_conn|limit_conn_log_level|limit_conn_zone|limit_except|limit_rate|limit_rate_after|limit_req|limit_req_log_level|limit_req_zone|limit_zone|lingering_close|lingering_time|lingering_timeout|listen|location|lock_file|log_format|log_format_combined|log_not_found|log_subrequest|map|map_hash_bucket_size|map_hash_max_size|master_process|max_ranges|memcached_buffer_size|memcached_connect_timeout|memcached_next_upstream|memcached_pass|memcached_read_timeout|memcached_send_timeout|merge_slashes|min_delete_depth|modern_browser|modern_browser_value|mp4|mp4_buffer_size|mp4_max_buffer_size|msie_padding|msie_refresh|multi_accept|open_file_cache|open_file_cache_errors|open_file_cache_min_uses|open_file_cache_valid|open_log_file_cache|optimize_server_names|override_charset|pcre_jit|perl|perl_modules|perl_require|perl_set|pid|pop3_auth|pop3_capabilities|port_in_redirect|post_action|postpone_output|protocol|proxy|proxy_buffer|proxy_buffer_size|proxy_buffering|proxy_buffers|proxy_busy_buffers_size|proxy_cache|proxy_cache_bypass|proxy_cache_key|proxy_cache_lock|proxy_cache_lock_timeout|proxy_cache_methods|proxy_cache_min_uses|proxy_cache_path|proxy_cache_use_stale|proxy_cache_valid|proxy_connect_timeout|proxy_cookie_domain|proxy_cookie_path|proxy_headers_hash_bucket_size|proxy_headers_hash_max_size|proxy_hide_header|proxy_http_version|proxy_ignore_client_abort|proxy_ignore_headers|proxy_intercept_errors|proxy_max_temp_file_size|proxy_method|proxy_next_upstream|proxy_no_cache|proxy_pass|proxy_pass_error_message|proxy_pass_header|proxy_pass_request_body|proxy_pass_request_headers|proxy_read_timeout|proxy_redirect|proxy_redirect_errors|proxy_send_lowat|proxy_send_timeout|proxy_set_body|proxy_set_header|proxy_ssl_session_reuse|proxy_store|proxy_store_access|proxy_temp_file_write_size|proxy_temp_path|proxy_timeout|proxy_upstream_fail_timeout|proxy_upstream_max_fails|random_index|read_ahead|real_ip_header|recursive_error_pages|request_pool_size|reset_timedout_connection|resolver|resolver_timeout|return|rewrite|root|rtsig_overflow_events|rtsig_overflow_test|rtsig_overflow_threshold|rtsig_signo|satisfy|satisfy_any|secure_link_secret|send_lowat|send_timeout|sendfile|sendfile_max_chunk|server|server_name|server_name_in_redirect|server_names_hash_bucket_size|server_names_hash_max_size|server_tokens|set|set_real_ip_from|smtp_auth|smtp_capabilities|so_keepalive|source_charset|split_clients|ssi|ssi_silent_errors|ssi_types|ssi_value_length|ssl|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_client_certificate|ssl_crl|ssl_dhparam|ssl_engine|ssl_prefer_server_ciphers|ssl_protocols|ssl_session_cache|ssl_session_timeout|ssl_verify_client|ssl_verify_depth|starttls|stub_status|sub_filter|sub_filter_once|sub_filter_types|tcp_nodelay|tcp_nopush|timeout|timer_resolution|try_files|types|types_hash_bucket_size|types_hash_max_size|underscores_in_headers|uninitialized_variable_warn|upstream|use|user|userid|userid_domain|userid_expires|userid_name|userid_p3p|userid_path|userid_service|valid_referers|variables_hash_bucket_size|variables_hash_max_size|worker_connections|worker_cpu_affinity|worker_priority|worker_processes|worker_rlimit_core|worker_rlimit_nofile|worker_rlimit_sigpending|working_directory|xclient|xml_entities|xslt_entities|xslt_stylesheet|xslt_types)\b/i}),Prism.languages.insertBefore("nginx","keyword",{variable:/\$[a-z_]+/i});
+Prism.languages.php=Prism.languages.extend("clike",{keyword:/\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,constant:/\b[A-Z0-9_]{2,}\b/,comment:{pattern:/(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/,lookbehind:!0}}),Prism.languages.insertBefore("php","class-name",{"shell-comment":{pattern:/(^|[^\\])#.*/,lookbehind:!0,alias:"comment"}}),Prism.languages.insertBefore("php","keyword",{delimiter:/\?>|<\?(?:php)?/i,variable:/\$\w+\b/i,"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/,lookbehind:!0,inside:{punctuation:/\\/}}}),Prism.languages.insertBefore("php","operator",{property:{pattern:/(->)[\w]+/,lookbehind:!0}}),Prism.languages.markup&&(Prism.hooks.add("before-highlight",function(e){"php"===e.language&&(e.tokenStack=[],e.backupCode=e.code,e.code=e.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/gi,function(a){return e.tokenStack.push(a),"{{{PHP"+e.tokenStack.length+"}}}"}))}),Prism.hooks.add("before-insert",function(e){"php"===e.language&&(e.code=e.backupCode,delete e.backupCode)}),Prism.hooks.add("after-highlight",function(e){if("php"===e.language){for(var a,n=0;a=e.tokenStack[n];n++)e.highlightedCode=e.highlightedCode.replace("{{{PHP"+(n+1)+"}}}",Prism.highlight(a,e.grammar,"php").replace(/\$/g,"$$$$"));e.element.innerHTML=e.highlightedCode}}),Prism.hooks.add("wrap",function(e){"php"===e.language&&"markup"===e.type&&(e.content=e.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g,'$1'))}),Prism.languages.insertBefore("php","comment",{markup:{pattern:/<[^?]\/?(.*?)>/,inside:Prism.languages.markup},php:/\{\{\{PHP[0-9]+\}\}\}/}));
+Prism.languages.insertBefore("php","variable",{"this":/\$this\b/,global:/\$(?:_(?:SERVER|GET|POST|FILES|REQUEST|SESSION|ENV|COOKIE)|GLOBALS|HTTP_RAW_POST_DATA|argc|argv|php_errormsg|http_response_header)/,scope:{pattern:/\b[\w\\]+::/,inside:{keyword:/(static|self|parent)/,punctuation:/(::|\\)/}}});
+Prism.languages.python={"triple-quoted-string":{pattern:/"""[\s\S]+?"""|'''[\s\S]+?'''/,alias:"string"},comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0},string:/("|')(?:\\?.)*?\1/,"function":{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_][a-zA-Z0-9_]*(?=\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)[a-z0-9_]+/i,lookbehind:!0},keyword:/\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/,"boolean":/\b(?:True|False)\b/,number:/\b-?(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,punctuation:/[{}[\];(),.:]/};
+!function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t]+.+)*/m,lookbehind:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,inside:{atrule:/(?:@[\w-]+|[+=])/m}}}),delete e.languages.sass.atrule;var a=/((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i,t=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/,{pattern:/(\s+)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,inside:{punctuation:/:/,variable:a,operator:t}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s]+.*)/m,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:a,operator:t,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,delete e.languages.sass.selector,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/([ \t]*)\S(?:,?[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,?[^,\r\n]+)*)*/,lookbehind:!0}})}(Prism);
+Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)*url(?=\()/i,selector:{pattern:/(?=\S)[^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m,inside:{placeholder:/%[-_\w]+/}}}),Prism.languages.insertBefore("scss","atrule",{keyword:[/@(?:if|else(?: if)?|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)/i,{pattern:/( +)(?:from|through)(?= )/,lookbehind:!0}]}),Prism.languages.insertBefore("scss","property",{variable:/\$[-_\w]+|#\{\$[-_\w]+\}/}),Prism.languages.insertBefore("scss","function",{placeholder:{pattern:/%[-_\w]+/,alias:"selector"},statement:/\B!(?:default|optional)\b/i,"boolean":/\b(?:true|false)\b/,"null":/\bnull\b/,operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/,lookbehind:!0}}),Prism.languages.scss.atrule.inside.rest=Prism.util.clone(Prism.languages.scss);
+Prism.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\w\W]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},string:{pattern:/(^|[^@\\])("|')(?:\\?[\s\S])*?\2/,lookbehind:!0},variable:/@[\w.$]+|@("|'|`)(?:\\?[\s\S])+?\1/,"function":/\b(?:COUNT|SUM|AVG|MIN|MAX|FIRST|LAST|UCASE|LCASE|MID|LEN|ROUND|NOW|FORMAT)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR VARYING|CHARACTER (?:SET|VARYING)|CHARSET|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COLUMNS|COMMENT|COMMIT|COMMITTED|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|DATA(?:BASES?)?|DATETIME|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE(?: PRECISION)?|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE KEY|ELSE|ENABLE|ENCLOSED BY|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPE(?:D BY)?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTO|INVOKER|ISOLATION LEVEL|JOIN|KEYS?|KILL|LANGUAGE SQL|LAST|LEFT|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MODIFIES SQL DATA|MODIFY|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL(?: CHAR VARYING| CHARACTER(?: VARYING)?| VARCHAR)?|NATURAL|NCHAR(?: VARCHAR)?|NEXT|NO(?: SQL|CHECK|CYCLE)?|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READ(?:S SQL DATA|TEXT)?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEATABLE|REPLICATION|REQUIRE|RESTORE|RESTRICT|RETURNS?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE MODE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|START(?:ING BY)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED BY|TEXT(?:SIZE)?|THEN|TIMESTAMP|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNPIVOT|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?)\b/i,"boolean":/\b(?:TRUE|FALSE|NULL)\b/i,number:/\b-?(?:0x)?\d*\.?[\da-f]+\b/,operator:/[-+*\/=%^~]|&&?|\|?\||!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|IN|LIKE|NOT|OR|IS|DIV|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/};
+Prism.languages.twig={comment:/\{#[\s\S]*?#\}/,tag:{pattern:/\{\{[\s\S]*?\}\}|\{%[\s\S]*?%\}/,inside:{ld:{pattern:/^(?:\{\{\-?|\{%\-?\s*\w+)/,inside:{punctuation:/^(?:\{\{|\{%)\-?/,keyword:/\w+/}},rd:{pattern:/\-?(?:%\}|\}\})$/,inside:{punctuation:/.*/}},string:{pattern:/("|')(?:\\?.)*?\1/,inside:{punctuation:/^['"]|['"]$/}},keyword:/\b(?:even|if|odd)\b/,"boolean":/\b(?:true|false|null)\b/,number:/\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+([Ee][-+]?\d+)?)\b/,operator:[{pattern:/(\s)(?:and|b\-and|b\-xor|b\-or|ends with|in|is|matches|not|or|same as|starts with)(?=\s)/,lookbehind:!0},/[=<>]=?|!=|\*\*?|\/\/?|\?:?|[-+~%|]/],property:/\b[a-zA-Z_][a-zA-Z0-9_]*\b/,punctuation:/[()\[\]{}:.,]/}},other:{pattern:/\S(?:[\s\S]*\S)?/,inside:Prism.languages.markup}};
+Prism.languages.yaml={scalar:{pattern:/([\-:]\s*(![^\s]+)?[ \t]*[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\3[^\r\n]+)*)/,lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:/(\s*[:\-,[{\r\n?][ \t]*(![^\s]+)?[ \t]*)[^\r\n{[\]},#]+?(?=\s*:\s)/,lookbehind:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)(\d{4}-\d\d?-\d\d?([tT]|[ \t]+)\d\d?:\d{2}:\d{2}(\.\d*)?[ \t]*(Z|[-+]\d\d?(:\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(:\d{2}(\.\d*)?)?)(?=[ \t]*($|,|]|}))/m,lookbehind:!0,alias:"number"},"boolean":{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)(true|false)[ \t]*(?=$|,|]|})/im,lookbehind:!0,alias:"important"},"null":{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)(null|~)[ \t]*(?=$|,|]|})/im,lookbehind:!0,alias:"important"},string:{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')(?=[ \t]*($|,|]|}))/m,lookbehind:!0},number:{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)[+\-]?(0x[\da-f]+|0o[0-7]+|(\d+\.?\d*|\.?\d+)(e[\+\-]?\d+)?|\.inf|\.nan)[ \t]*(?=$|,|]|})/im,lookbehind:!0},tag:/![^\s]+/,important:/[&*][\w]+/,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./};
+!function(){"undefined"!=typeof self&&self.Prism&&self.document&&Prism.hooks.add("complete",function(e){if(e.code){var t=e.element.parentNode,s=/\s*\bline-numbers\b\s*/;if(t&&/pre/i.test(t.nodeName)&&(s.test(t.className)||s.test(e.element.className))&&!e.element.querySelector(".line-numbers-rows")){s.test(e.element.className)&&(e.element.className=e.element.className.replace(s,"")),s.test(t.className)||(t.className+=" line-numbers");var n,a=e.code.match(/\n(?!$)/g),l=a?a.length+1:1,m=new Array(l+1);m=m.join(""),n=document.createElement("span"),n.className="line-numbers-rows",n.innerHTML=m,t.hasAttribute("data-start")&&(t.style.counterReset="linenumber "+(parseInt(t.getAttribute("data-start"),10)-1)),e.element.appendChild(n)}}})}();
+!function(){if(("undefined"==typeof self||self.Prism)&&("undefined"==typeof global||global.Prism)){var i=/\b([a-z]{3,7}:\/\/|tel:)[\w\-+%~\/.:#=?&]+/,n=/\b\S+@[\w.]+[a-z]{2}/,e=/\[([^\]]+)]\(([^)]+)\)/,t=["comment","url","attr-value","string"];Prism.hooks.add("before-highlight",function(a){a.grammar&&!a.grammar["url-link"]&&(Prism.languages.DFS(a.grammar,function(a,r,l){t.indexOf(l)>-1&&"Array"!==Prism.util.type(r)&&(r.pattern||(r=this[a]={pattern:r}),r.inside=r.inside||{},"comment"==l&&(r.inside["md-link"]=e),"attr-value"==l?Prism.languages.insertBefore("inside","punctuation",{"url-link":i},r):r.inside["url-link"]=i,r.inside["email-link"]=n)}),a.grammar["url-link"]=i,a.grammar["email-link"]=n)}),Prism.hooks.add("wrap",function(i){if(/-link$/.test(i.type)){i.tag="a";var n=i.content;if("email-link"==i.type&&0!=n.indexOf("mailto:"))n="mailto:"+n;else if("md-link"==i.type){var t=i.content.match(e);n=t[2],i.content=t[1]}i.attributes.href=n}})}}();
+!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var e={css:"CSS",clike:"C-like",javascript:"JavaScript",abap:"ABAP",actionscript:"ActionScript",apacheconf:"Apache Configuration",apl:"APL",applescript:"AppleScript",asciidoc:"AsciiDoc",aspnet:"ASP.NET (C#)",autoit:"AutoIt",autohotkey:"AutoHotkey",basic:"BASIC",csharp:"C#",cpp:"C++",coffeescript:"CoffeeScript","css-extras":"CSS Extras",fsharp:"F#",glsl:"GLSL",http:"HTTP",inform7:"Inform 7",latex:"LaTeX",lolcode:"LOLCODE",matlab:"MATLAB",mel:"MEL",nasm:"NASM",nginx:"nginx",nsis:"NSIS",objectivec:"Objective-C",ocaml:"OCaml",parigp:"PARI/GP",php:"PHP","php-extras":"PHP Extras",powershell:"PowerShell",jsx:"React JSX",rest:"reST (reStructuredText)",sas:"SAS",sass:"Sass (Sass)",scss:"Sass (Scss)",sql:"SQL",typescript:"TypeScript",vhdl:"VHDL",vim:"vim",wiki:"Wiki markup",yaml:"YAML"};Prism.hooks.add("before-highlight",function(a){var s=a.element.parentNode;if(s&&/pre/i.test(s.nodeName)){var t=e[a.language]||a.language.substring(0,1).toUpperCase()+a.language.substring(1);s.setAttribute("data-language",t);var i,r,l=s.previousSibling;l&&/\s*\bprism-show-language\b\s*/.test(l.className)&&l.firstChild&&/\s*\bprism-show-language-label\b\s*/.test(l.firstChild.className)?(r=l.firstChild,r.getAttribute("data-language")!==t&&(r.setAttribute("data-language",t),r.innerHTML=t)):(i=document.createElement("div"),r=document.createElement("div"),r.className="prism-show-language-label",r.setAttribute("data-language",t),r.innerHTML=t,i.className="prism-show-language",i.appendChild(r),s.parentNode.insertBefore(i,s))}})}}();
diff --git a/parser/markdown/lib/Parsedown.php b/parser/markdown/lib/Parsedown.php
new file mode 100644
index 0000000..c8c92a3
--- /dev/null
+++ b/parser/markdown/lib/Parsedown.php
@@ -0,0 +1,1528 @@
+DefinitionData = array();
+
+        # standardize line breaks
+        $text = str_replace(array("\r\n", "\r"), "\n", $text);
+
+        # remove surrounding line breaks
+        $text = trim($text, "\n");
+
+        # split text into lines
+        $lines = explode("\n", $text);
+
+        # iterate through lines to identify blocks
+        $markup = $this->lines($lines);
+
+        # trim line breaks
+        $markup = trim($markup, "\n");
+
+        return $markup;
+    }
+
+    #
+    # Setters
+    #
+
+    function setBreaksEnabled($breaksEnabled)
+    {
+        $this->breaksEnabled = $breaksEnabled;
+
+        return $this;
+    }
+
+    protected $breaksEnabled;
+
+    function setMarkupEscaped($markupEscaped)
+    {
+        $this->markupEscaped = $markupEscaped;
+
+        return $this;
+    }
+
+    protected $markupEscaped;
+
+    function setUrlsLinked($urlsLinked)
+    {
+        $this->urlsLinked = $urlsLinked;
+
+        return $this;
+    }
+
+    protected $urlsLinked = true;
+
+    #
+    # Lines
+    #
+
+    protected $BlockTypes = array(
+        '#' => array('Header'),
+        '*' => array('Rule', 'List'),
+        '+' => array('List'),
+        '-' => array('SetextHeader', 'Table', 'Rule', 'List'),
+        '0' => array('List'),
+        '1' => array('List'),
+        '2' => array('List'),
+        '3' => array('List'),
+        '4' => array('List'),
+        '5' => array('List'),
+        '6' => array('List'),
+        '7' => array('List'),
+        '8' => array('List'),
+        '9' => array('List'),
+        ':' => array('Table'),
+        '<' => array('Comment', 'Markup'),
+        '=' => array('SetextHeader'),
+        '>' => array('Quote'),
+        '[' => array('Reference'),
+        '_' => array('Rule'),
+        '`' => array('FencedCode'),
+        '|' => array('Table'),
+        '~' => array('FencedCode'),
+    );
+
+    # ~
+
+    protected $unmarkedBlockTypes = array(
+        'Code',
+    );
+
+    #
+    # Blocks
+    #
+
+    private function lines(array $lines)
+    {
+        $CurrentBlock = null;
+
+        foreach ($lines as $line)
+        {
+            if (chop($line) === '')
+            {
+                if (isset($CurrentBlock))
+                {
+                    $CurrentBlock['interrupted'] = true;
+                }
+
+                continue;
+            }
+
+            if (strpos($line, "\t") !== false)
+            {
+                $parts = explode("\t", $line);
+
+                $line = $parts[0];
+
+                unset($parts[0]);
+
+                foreach ($parts as $part)
+                {
+                    $shortage = 4 - mb_strlen($line, 'utf-8') % 4;
+
+                    $line .= str_repeat(' ', $shortage);
+                    $line .= $part;
+                }
+            }
+
+            $indent = 0;
+
+            while (isset($line[$indent]) and $line[$indent] === ' ')
+            {
+                $indent ++;
+            }
+
+            $text = $indent > 0 ? substr($line, $indent) : $line;
+
+            # ~
+
+            $Line = array('body' => $line, 'indent' => $indent, 'text' => $text);
+
+            # ~
+
+            if (isset($CurrentBlock['continuable']))
+            {
+                $Block = $this->{'block'.$CurrentBlock['type'].'Continue'}($Line, $CurrentBlock);
+
+                if (isset($Block))
+                {
+                    $CurrentBlock = $Block;
+
+                    continue;
+                }
+                else
+                {
+                    if (method_exists($this, 'block'.$CurrentBlock['type'].'Complete'))
+                    {
+                        $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
+                    }
+                }
+            }
+
+            # ~
+
+            $marker = $text[0];
+
+            # ~
+
+            $blockTypes = $this->unmarkedBlockTypes;
+
+            if (isset($this->BlockTypes[$marker]))
+            {
+                foreach ($this->BlockTypes[$marker] as $blockType)
+                {
+                    $blockTypes []= $blockType;
+                }
+            }
+
+            #
+            # ~
+
+            foreach ($blockTypes as $blockType)
+            {
+                $Block = $this->{'block'.$blockType}($Line, $CurrentBlock);
+
+                if (isset($Block))
+                {
+                    $Block['type'] = $blockType;
+
+                    if ( ! isset($Block['identified']))
+                    {
+                        $Blocks []= $CurrentBlock;
+
+                        $Block['identified'] = true;
+                    }
+
+                    if (method_exists($this, 'block'.$blockType.'Continue'))
+                    {
+                        $Block['continuable'] = true;
+                    }
+
+                    $CurrentBlock = $Block;
+
+                    continue 2;
+                }
+            }
+
+            # ~
+
+            if (isset($CurrentBlock) and ! isset($CurrentBlock['type']) and ! isset($CurrentBlock['interrupted']))
+            {
+                $CurrentBlock['element']['text'] .= "\n".$text;
+            }
+            else
+            {
+                $Blocks []= $CurrentBlock;
+
+                $CurrentBlock = $this->paragraph($Line);
+
+                $CurrentBlock['identified'] = true;
+            }
+        }
+
+        # ~
+
+        if (isset($CurrentBlock['continuable']) and method_exists($this, 'block'.$CurrentBlock['type'].'Complete'))
+        {
+            $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
+        }
+
+        # ~
+
+        $Blocks []= $CurrentBlock;
+
+        unset($Blocks[0]);
+
+        # ~
+
+        $markup = '';
+
+        foreach ($Blocks as $Block)
+        {
+            if (isset($Block['hidden']))
+            {
+                continue;
+            }
+
+            $markup .= "\n";
+            $markup .= isset($Block['markup']) ? $Block['markup'] : $this->element($Block['element']);
+        }
+
+        $markup .= "\n";
+
+        # ~
+
+        return $markup;
+    }
+
+    #
+    # Code
+
+    protected function blockCode($Line, $Block = null)
+    {
+        if (isset($Block) and ! isset($Block['type']) and ! isset($Block['interrupted']))
+        {
+            return;
+        }
+
+        if ($Line['indent'] >= 4)
+        {
+            $text = substr($Line['body'], 4);
+
+            $Block = array(
+                'element' => array(
+                    'name' => 'pre',
+                    'handler' => 'element',
+                    'text' => array(
+                        'name' => 'code',
+                        'text' => $text,
+                    ),
+                ),
+            );
+
+            return $Block;
+        }
+    }
+
+    protected function blockCodeContinue($Line, $Block)
+    {
+        if ($Line['indent'] >= 4)
+        {
+            if (isset($Block['interrupted']))
+            {
+                $Block['element']['text']['text'] .= "\n";
+
+                unset($Block['interrupted']);
+            }
+
+            $Block['element']['text']['text'] .= "\n";
+
+            $text = substr($Line['body'], 4);
+
+            $Block['element']['text']['text'] .= $text;
+
+            return $Block;
+        }
+    }
+
+    protected function blockCodeComplete($Block)
+    {
+        $text = $Block['element']['text']['text'];
+
+        $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
+
+        $Block['element']['text']['text'] = $text;
+
+        return $Block;
+    }
+
+    #
+    # Comment
+
+    protected function blockComment($Line)
+    {
+        if ($this->markupEscaped)
+        {
+            return;
+        }
+
+        if (isset($Line['text'][3]) and $Line['text'][3] === '-' and $Line['text'][2] === '-' and $Line['text'][1] === '!')
+        {
+            $Block = array(
+                'markup' => $Line['body'],
+            );
+
+            if (preg_match('/-->$/', $Line['text']))
+            {
+                $Block['closed'] = true;
+            }
+
+            return $Block;
+        }
+    }
+
+    protected function blockCommentContinue($Line, array $Block)
+    {
+        if (isset($Block['closed']))
+        {
+            return;
+        }
+
+        $Block['markup'] .= "\n" . $Line['body'];
+
+        if (preg_match('/-->$/', $Line['text']))
+        {
+            $Block['closed'] = true;
+        }
+
+        return $Block;
+    }
+
+    #
+    # Fenced Code
+
+    protected function blockFencedCode($Line)
+    {
+        if (preg_match('/^['.$Line['text'][0].']{3,}[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches))
+        {
+            $Element = array(
+                'name' => 'code',
+                'text' => '',
+            );
+
+            if (isset($matches[1]))
+            {
+                $class = 'language-'.$matches[1];
+
+                $Element['attributes'] = array(
+                    'class' => $class,
+                );
+            }
+
+            $Block = array(
+                'char' => $Line['text'][0],
+                'element' => array(
+                    'name' => 'pre',
+                    'handler' => 'element',
+                    'text' => $Element,
+                ),
+            );
+
+            return $Block;
+        }
+    }
+
+    protected function blockFencedCodeContinue($Line, $Block)
+    {
+        if (isset($Block['complete']))
+        {
+            return;
+        }
+
+        if (isset($Block['interrupted']))
+        {
+            $Block['element']['text']['text'] .= "\n";
+
+            unset($Block['interrupted']);
+        }
+
+        if (preg_match('/^'.$Block['char'].'{3,}[ ]*$/', $Line['text']))
+        {
+            $Block['element']['text']['text'] = substr($Block['element']['text']['text'], 1);
+
+            $Block['complete'] = true;
+
+            return $Block;
+        }
+
+        $Block['element']['text']['text'] .= "\n".$Line['body'];;
+
+        return $Block;
+    }
+
+    protected function blockFencedCodeComplete($Block)
+    {
+        $text = $Block['element']['text']['text'];
+
+        $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
+
+        $Block['element']['text']['text'] = $text;
+
+        return $Block;
+    }
+
+    #
+    # Header
+
+    protected function blockHeader($Line)
+    {
+        if (isset($Line['text'][1]))
+        {
+            $level = 1;
+
+            while (isset($Line['text'][$level]) and $Line['text'][$level] === '#')
+            {
+                $level ++;
+            }
+
+            if ($level > 6)
+            {
+                return;
+            }
+
+            $text = trim($Line['text'], '# ');
+
+            $Block = array(
+                'element' => array(
+                    'name' => 'h' . min(6, $level),
+                    'text' => $text,
+                    'handler' => 'line',
+                ),
+            );
+
+            return $Block;
+        }
+    }
+
+    #
+    # List
+
+    protected function blockList($Line)
+    {
+        list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]');
+
+        if (preg_match('/^('.$pattern.'[ ]+)(.*)/', $Line['text'], $matches))
+        {
+            $Block = array(
+                'indent' => $Line['indent'],
+                'pattern' => $pattern,
+                'element' => array(
+                    'name' => $name,
+                    'handler' => 'elements',
+                ),
+            );
+
+            $Block['li'] = array(
+                'name' => 'li',
+                'handler' => 'li',
+                'text' => array(
+                    $matches[2],
+                ),
+            );
+
+            $Block['element']['text'] []= & $Block['li'];
+
+            return $Block;
+        }
+    }
+
+    protected function blockListContinue($Line, array $Block)
+    {
+        if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'(?:[ ]+(.*)|$)/', $Line['text'], $matches))
+        {
+            if (isset($Block['interrupted']))
+            {
+                $Block['li']['text'] []= '';
+
+                unset($Block['interrupted']);
+            }
+
+            unset($Block['li']);
+
+            $text = isset($matches[1]) ? $matches[1] : '';
+
+            $Block['li'] = array(
+                'name' => 'li',
+                'handler' => 'li',
+                'text' => array(
+                    $text,
+                ),
+            );
+
+            $Block['element']['text'] []= & $Block['li'];
+
+            return $Block;
+        }
+
+        if ($Line['text'][0] === '[' and $this->blockReference($Line))
+        {
+            return $Block;
+        }
+
+        if ( ! isset($Block['interrupted']))
+        {
+            $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);
+
+            $Block['li']['text'] []= $text;
+
+            return $Block;
+        }
+
+        if ($Line['indent'] > 0)
+        {
+            $Block['li']['text'] []= '';
+
+            $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);
+
+            $Block['li']['text'] []= $text;
+
+            unset($Block['interrupted']);
+
+            return $Block;
+        }
+    }
+
+    #
+    # Quote
+
+    protected function blockQuote($Line)
+    {
+        if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
+        {
+            $Block = array(
+                'element' => array(
+                    'name' => 'blockquote',
+                    'handler' => 'lines',
+                    'text' => (array) $matches[1],
+                ),
+            );
+
+            return $Block;
+        }
+    }
+
+    protected function blockQuoteContinue($Line, array $Block)
+    {
+        if ($Line['text'][0] === '>' and preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
+        {
+            if (isset($Block['interrupted']))
+            {
+                $Block['element']['text'] []= '';
+
+                unset($Block['interrupted']);
+            }
+
+            $Block['element']['text'] []= $matches[1];
+
+            return $Block;
+        }
+
+        if ( ! isset($Block['interrupted']))
+        {
+            $Block['element']['text'] []= $Line['text'];
+
+            return $Block;
+        }
+    }
+
+    #
+    # Rule
+
+    protected function blockRule($Line)
+    {
+        if (preg_match('/^(['.$Line['text'][0].'])([ ]*\1){2,}[ ]*$/', $Line['text']))
+        {
+            $Block = array(
+                'element' => array(
+                    'name' => 'hr'
+                ),
+            );
+
+            return $Block;
+        }
+    }
+
+    #
+    # Setext
+
+    protected function blockSetextHeader($Line, array $Block = null)
+    {
+        if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
+        {
+            return;
+        }
+
+        if (chop($Line['text'], $Line['text'][0]) === '')
+        {
+            $Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2';
+
+            return $Block;
+        }
+    }
+
+    #
+    # Markup
+
+    protected function blockMarkup($Line)
+    {
+        if ($this->markupEscaped)
+        {
+            return;
+        }
+
+        if (preg_match('/^<(\w*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches))
+        {
+            $element = strtolower($matches[1]);
+
+            if (in_array($element, $this->textLevelElements))
+            {
+                return;
+            }
+
+            $Block = array(
+                'name' => $matches[1],
+                'depth' => 0,
+                'markup' => $Line['text'],
+            );
+
+            $length = strlen($matches[0]);
+
+            $remainder = substr($Line['text'], $length);
+
+            if (trim($remainder) === '')
+            {
+                if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
+                {
+                    $Block['closed'] = true;
+
+                    $Block['void'] = true;
+                }
+            }
+            else
+            {
+                if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
+                {
+                    return;
+                }
+
+                if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder))
+                {
+                    $Block['closed'] = true;
+                }
+            }
+
+            return $Block;
+        }
+    }
+
+    protected function blockMarkupContinue($Line, array $Block)
+    {
+        if (isset($Block['closed']))
+        {
+            return;
+        }
+
+        if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open
+        {
+            $Block['depth'] ++;
+        }
+
+        if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close
+        {
+            if ($Block['depth'] > 0)
+            {
+                $Block['depth'] --;
+            }
+            else
+            {
+                $Block['closed'] = true;
+            }
+        }
+
+        if (isset($Block['interrupted']))
+        {
+            $Block['markup'] .= "\n";
+
+            unset($Block['interrupted']);
+        }
+
+        $Block['markup'] .= "\n".$Line['body'];
+
+        return $Block;
+    }
+
+    #
+    # Reference
+
+    protected function blockReference($Line)
+    {
+        if (preg_match('/^\[(.+?)\]:[ ]*?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches))
+        {
+            $id = strtolower($matches[1]);
+
+            $Data = array(
+                'url' => $matches[2],
+                'title' => null,
+            );
+
+            if (isset($matches[3]))
+            {
+                $Data['title'] = $matches[3];
+            }
+
+            $this->DefinitionData['Reference'][$id] = $Data;
+
+            $Block = array(
+                'hidden' => true,
+            );
+
+            return $Block;
+        }
+    }
+
+    #
+    # Table
+
+    protected function blockTable($Line, array $Block = null)
+    {
+        if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
+        {
+            return;
+        }
+
+        if (strpos($Block['element']['text'], '|') !== false and chop($Line['text'], ' -:|') === '')
+        {
+            $alignments = array();
+
+            $divider = $Line['text'];
+
+            $divider = trim($divider);
+            $divider = trim($divider, '|');
+
+            $dividerCells = explode('|', $divider);
+
+            foreach ($dividerCells as $dividerCell)
+            {
+                $dividerCell = trim($dividerCell);
+
+                if ($dividerCell === '')
+                {
+                    continue;
+                }
+
+                $alignment = null;
+
+                if ($dividerCell[0] === ':')
+                {
+                    $alignment = 'left';
+                }
+
+                if (substr($dividerCell, - 1) === ':')
+                {
+                    $alignment = $alignment === 'left' ? 'center' : 'right';
+                }
+
+                $alignments []= $alignment;
+            }
+
+            # ~
+
+            $HeaderElements = array();
+
+            $header = $Block['element']['text'];
+
+            $header = trim($header);
+            $header = trim($header, '|');
+
+            $headerCells = explode('|', $header);
+
+            foreach ($headerCells as $index => $headerCell)
+            {
+                $headerCell = trim($headerCell);
+
+                $HeaderElement = array(
+                    'name' => 'th',
+                    'text' => $headerCell,
+                    'handler' => 'line',
+                );
+
+                if (isset($alignments[$index]))
+                {
+                    $alignment = $alignments[$index];
+
+                    $HeaderElement['attributes'] = array(
+                        'style' => 'text-align: '.$alignment.';',
+                    );
+                }
+
+                $HeaderElements []= $HeaderElement;
+            }
+
+            # ~
+
+            $Block = array(
+                'alignments' => $alignments,
+                'identified' => true,
+                'element' => array(
+                    'name' => 'table',
+                    'handler' => 'elements',
+                ),
+            );
+
+            $Block['element']['text'] []= array(
+                'name' => 'thead',
+                'handler' => 'elements',
+            );
+
+            $Block['element']['text'] []= array(
+                'name' => 'tbody',
+                'handler' => 'elements',
+                'text' => array(),
+            );
+
+            $Block['element']['text'][0]['text'] []= array(
+                'name' => 'tr',
+                'handler' => 'elements',
+                'text' => $HeaderElements,
+            );
+
+            return $Block;
+        }
+    }
+
+    protected function blockTableContinue($Line, array $Block)
+    {
+        if (isset($Block['interrupted']))
+        {
+            return;
+        }
+
+        if ($Line['text'][0] === '|' or strpos($Line['text'], '|'))
+        {
+            $Elements = array();
+
+            $row = $Line['text'];
+
+            $row = trim($row);
+            $row = trim($row, '|');
+
+            preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]+`|`)+/', $row, $matches);
+
+            foreach ($matches[0] as $index => $cell)
+            {
+                $cell = trim($cell);
+
+                $Element = array(
+                    'name' => 'td',
+                    'handler' => 'line',
+                    'text' => $cell,
+                );
+
+                if (isset($Block['alignments'][$index]))
+                {
+                    $Element['attributes'] = array(
+                        'style' => 'text-align: '.$Block['alignments'][$index].';',
+                    );
+                }
+
+                $Elements []= $Element;
+            }
+
+            $Element = array(
+                'name' => 'tr',
+                'handler' => 'elements',
+                'text' => $Elements,
+            );
+
+            $Block['element']['text'][1]['text'] []= $Element;
+
+            return $Block;
+        }
+    }
+
+    #
+    # ~
+    #
+
+    protected function paragraph($Line)
+    {
+        $Block = array(
+            'element' => array(
+                'name' => 'p',
+                'text' => $Line['text'],
+                'handler' => 'line',
+            ),
+        );
+
+        return $Block;
+    }
+
+    #
+    # Inline Elements
+    #
+
+    protected $InlineTypes = array(
+        '"' => array('SpecialCharacter'),
+        '!' => array('Image'),
+        '&' => array('SpecialCharacter'),
+        '*' => array('Emphasis'),
+        ':' => array('Url'),
+        '<' => array('UrlTag', 'EmailTag', 'Markup', 'SpecialCharacter'),
+        '>' => array('SpecialCharacter'),
+        '[' => array('Link'),
+        '_' => array('Emphasis'),
+        '`' => array('Code'),
+        '~' => array('Strikethrough'),
+        '\\' => array('EscapeSequence'),
+    );
+
+    # ~
+
+    protected $inlineMarkerList = '!"*_&[:<>`~\\';
+
+    #
+    # ~
+    #
+
+    public function line($text)
+    {
+        $markup = '';
+
+        # $excerpt is based on the first occurrence of a marker
+
+        while ($excerpt = strpbrk($text, $this->inlineMarkerList))
+        {
+            $marker = $excerpt[0];
+
+            $markerPosition = strpos($text, $marker);
+
+            $Excerpt = array('text' => $excerpt, 'context' => $text);
+
+            foreach ($this->InlineTypes[$marker] as $inlineType)
+            {
+                $Inline = $this->{'inline'.$inlineType}($Excerpt);
+
+                if ( ! isset($Inline))
+                {
+                    continue;
+                }
+
+                # makes sure that the inline belongs to "our" marker
+
+                if (isset($Inline['position']) and $Inline['position'] > $markerPosition)
+                {
+                    continue;
+                }
+
+                # sets a default inline position
+
+                if ( ! isset($Inline['position']))
+                {
+                    $Inline['position'] = $markerPosition;
+                }
+
+                # the text that comes before the inline
+                $unmarkedText = substr($text, 0, $Inline['position']);
+
+                # compile the unmarked text
+                $markup .= $this->unmarkedText($unmarkedText);
+
+                # compile the inline
+                $markup .= isset($Inline['markup']) ? $Inline['markup'] : $this->element($Inline['element']);
+
+                # remove the examined text
+                $text = substr($text, $Inline['position'] + $Inline['extent']);
+
+                continue 2;
+            }
+
+            # the marker does not belong to an inline
+
+            $unmarkedText = substr($text, 0, $markerPosition + 1);
+
+            $markup .= $this->unmarkedText($unmarkedText);
+
+            $text = substr($text, $markerPosition + 1);
+        }
+
+        $markup .= $this->unmarkedText($text);
+
+        return $markup;
+    }
+
+    #
+    # ~
+    #
+
+    protected function inlineCode($Excerpt)
+    {
+        $marker = $Excerpt['text'][0];
+
+        if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(? strlen($matches[0]),
+                'element' => array(
+                    'name' => 'code',
+                    'text' => $text,
+                ),
+            );
+        }
+    }
+
+    protected function inlineEmailTag($Excerpt)
+    {
+        if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $Excerpt['text'], $matches))
+        {
+            $url = $matches[1];
+
+            if ( ! isset($matches[2]))
+            {
+                $url = 'mailto:' . $url;
+            }
+
+            return array(
+                'extent' => strlen($matches[0]),
+                'element' => array(
+                    'name' => 'a',
+                    'text' => $matches[1],
+                    'attributes' => array(
+                        'href' => $url,
+                    ),
+                ),
+            );
+        }
+    }
+
+    protected function inlineEmphasis($Excerpt)
+    {
+        if ( ! isset($Excerpt['text'][1]))
+        {
+            return;
+        }
+
+        $marker = $Excerpt['text'][0];
+
+        if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches))
+        {
+            $emphasis = 'strong';
+        }
+        elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches))
+        {
+            $emphasis = 'em';
+        }
+        else
+        {
+            return;
+        }
+
+        return array(
+            'extent' => strlen($matches[0]),
+            'element' => array(
+                'name' => $emphasis,
+                'handler' => 'line',
+                'text' => $matches[1],
+            ),
+        );
+    }
+
+    protected function inlineEscapeSequence($Excerpt)
+    {
+        if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters))
+        {
+            return array(
+                'markup' => $Excerpt['text'][1],
+                'extent' => 2,
+            );
+        }
+    }
+
+    protected function inlineImage($Excerpt)
+    {
+        if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[')
+        {
+            return;
+        }
+
+        $Excerpt['text']= substr($Excerpt['text'], 1);
+
+        $Link = $this->inlineLink($Excerpt);
+
+        if ($Link === null)
+        {
+            return;
+        }
+
+        $Inline = array(
+            'extent' => $Link['extent'] + 1,
+            'element' => array(
+                'name' => 'img',
+                'attributes' => array(
+                    'src' => $Link['element']['attributes']['href'],
+                    'alt' => $Link['element']['text'],
+                ),
+            ),
+        );
+
+        $Inline['element']['attributes'] += $Link['element']['attributes'];
+
+        unset($Inline['element']['attributes']['href']);
+
+        return $Inline;
+    }
+
+    protected function inlineLink($Excerpt)
+    {
+        $Element = array(
+            'name' => 'a',
+            'handler' => 'line',
+            'text' => null,
+            'attributes' => array(
+                'href' => null,
+                'title' => null,
+            ),
+        );
+
+        $extent = 0;
+
+        $remainder = $Excerpt['text'];
+
+        if (preg_match('/\[((?:[^][]|(?R))*)\]/', $remainder, $matches))
+        {
+            $Element['text'] = $matches[1];
+
+            $extent += strlen($matches[0]);
+
+            $remainder = substr($remainder, $extent);
+        }
+        else
+        {
+            return;
+        }
+
+        if (preg_match('/^[(]((?:[^ ()]|[(][^ )]+[)])+)(?:[ ]+("[^"]*"|\'[^\']*\'))?[)]/', $remainder, $matches))
+        {
+            $Element['attributes']['href'] = $matches[1];
+
+            if (isset($matches[2]))
+            {
+                $Element['attributes']['title'] = substr($matches[2], 1, - 1);
+            }
+
+            $extent += strlen($matches[0]);
+        }
+        else
+        {
+            if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches))
+            {
+                $definition = strlen($matches[1]) ? $matches[1] : $Element['text'];
+                $definition = strtolower($definition);
+
+                $extent += strlen($matches[0]);
+            }
+            else
+            {
+                $definition = strtolower($Element['text']);
+            }
+
+            if ( ! isset($this->DefinitionData['Reference'][$definition]))
+            {
+                return;
+            }
+
+            $Definition = $this->DefinitionData['Reference'][$definition];
+
+            $Element['attributes']['href'] = $Definition['url'];
+            $Element['attributes']['title'] = $Definition['title'];
+        }
+
+        $Element['attributes']['href'] = str_replace(array('&', '<'), array('&', '<'), $Element['attributes']['href']);
+
+        return array(
+            'extent' => $extent,
+            'element' => $Element,
+        );
+    }
+
+    protected function inlineMarkup($Excerpt)
+    {
+        if ($this->markupEscaped or strpos($Excerpt['text'], '>') === false)
+        {
+            return;
+        }
+
+        if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w*[ ]*>/s', $Excerpt['text'], $matches))
+        {
+            return array(
+                'markup' => $matches[0],
+                'extent' => strlen($matches[0]),
+            );
+        }
+
+        if ($Excerpt['text'][1] === '!' and preg_match('/^/s', $Excerpt['text'], $matches))
+        {
+            return array(
+                'markup' => $matches[0],
+                'extent' => strlen($matches[0]),
+            );
+        }
+
+        if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches))
+        {
+            return array(
+                'markup' => $matches[0],
+                'extent' => strlen($matches[0]),
+            );
+        }
+    }
+
+    protected function inlineSpecialCharacter($Excerpt)
+    {
+        if ($Excerpt['text'][0] === '&' and ! preg_match('/^&#?\w+;/', $Excerpt['text']))
+        {
+            return array(
+                'markup' => '&',
+                'extent' => 1,
+            );
+        }
+
+        $SpecialCharacter = array('>' => 'gt', '<' => 'lt', '"' => 'quot');
+
+        if (isset($SpecialCharacter[$Excerpt['text'][0]]))
+        {
+            return array(
+                'markup' => '&'.$SpecialCharacter[$Excerpt['text'][0]].';',
+                'extent' => 1,
+            );
+        }
+    }
+
+    protected function inlineStrikethrough($Excerpt)
+    {
+        if ( ! isset($Excerpt['text'][1]))
+        {
+            return;
+        }
+
+        if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches))
+        {
+            return array(
+                'extent' => strlen($matches[0]),
+                'element' => array(
+                    'name' => 'del',
+                    'text' => $matches[1],
+                    'handler' => 'line',
+                ),
+            );
+        }
+    }
+
+    protected function inlineUrl($Excerpt)
+    {
+        if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/')
+        {
+            return;
+        }
+
+        if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE))
+        {
+            $Inline = array(
+                'extent' => strlen($matches[0][0]),
+                'position' => $matches[0][1],
+                'element' => array(
+                    'name' => 'a',
+                    'text' => $matches[0][0],
+                    'attributes' => array(
+                        'href' => $matches[0][0],
+                    ),
+                ),
+            );
+
+            return $Inline;
+        }
+    }
+
+    protected function inlineUrlTag($Excerpt)
+    {
+        if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches))
+        {
+            $url = str_replace(array('&', '<'), array('&', '<'), $matches[1]);
+
+            return array(
+                'extent' => strlen($matches[0]),
+                'element' => array(
+                    'name' => 'a',
+                    'text' => $url,
+                    'attributes' => array(
+                        'href' => $url,
+                    ),
+                ),
+            );
+        }
+    }
+
+    # ~
+
+    protected function unmarkedText($text)
+    {
+        if ($this->breaksEnabled)
+        {
+            $text = preg_replace('/[ ]*\n/', "
\n", $text); + } + else + { + $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "
\n", $text); + $text = str_replace(" \n", "\n", $text); + } + + return $text; + } + + # + # Handlers + # + + protected function element(array $Element) + { + $markup = '<'.$Element['name']; + + if (isset($Element['attributes'])) + { + foreach ($Element['attributes'] as $name => $value) + { + if ($value === null) + { + continue; + } + + $markup .= ' '.$name.'="'.$value.'"'; + } + } + + if (isset($Element['text'])) + { + $markup .= '>'; + + if (isset($Element['handler'])) + { + $markup .= $this->{$Element['handler']}($Element['text']); + } + else + { + $markup .= $Element['text']; + } + + $markup .= ''; + } + else + { + $markup .= ' />'; + } + + return $markup; + } + + protected function elements(array $Elements) + { + $markup = ''; + + foreach ($Elements as $Element) + { + $markup .= "\n" . $this->element($Element); + } + + $markup .= "\n"; + + return $markup; + } + + # ~ + + protected function li($lines) + { + $markup = $this->lines($lines); + + $trimmedMarkup = trim($markup); + + if ( ! in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '

') + { + $markup = $trimmedMarkup; + $markup = substr($markup, 3); + + $position = strpos($markup, "

"); + + $markup = substr_replace($markup, '', $position, 4); + } + + return $markup; + } + + # + # Deprecated Methods + # + + function parse($text) + { + $markup = $this->text($text); + + return $markup; + } + + # + # Static Methods + # + + static function instance($name = 'default') + { + if (isset(self::$instances[$name])) + { + return self::$instances[$name]; + } + + $instance = new static(); + + self::$instances[$name] = $instance; + + return $instance; + } + + private static $instances = array(); + + # + # Fields + # + + protected $DefinitionData; + + # + # Read-Only + + protected $specialCharacters = array( + '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!', '|', + ); + + protected $StrongRegex = array( + '*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s', + '_' => '/^__((?:\\\\_|[^_]|_[^_]*_)+?)__(?!_)/us', + ); + + protected $EmRegex = array( + '*' => '/^[*]((?:\\\\\*|[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s', + '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us', + ); + + protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*(?:\s*=\s*(?:[^"\'=<>`\s]+|"[^"]*"|\'[^\']*\'))?'; + + protected $voidElements = array( + 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', + ); + + protected $textLevelElements = array( + 'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont', + 'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing', + 'i', 'rp', 'del', 'code', 'strike', 'marquee', + 'q', 'rt', 'ins', 'font', 'strong', + 's', 'tt', 'sub', 'mark', + 'u', 'xm', 'sup', 'nobr', + 'var', 'ruby', + 'wbr', 'span', + 'time', + ); +} diff --git a/parser/markdown/md.php b/parser/markdown/md.php new file mode 100644 index 0000000..61ee86c --- /dev/null +++ b/parser/markdown/md.php @@ -0,0 +1,40 @@ +text($text); + + $css = trim(file_get_contents('assets/github-markdown.min.css'), "\n"); + //$prism_css = trim(file_get_contents('assets/prism.min.css'), "\n"); + //$prism_js = trim(file_get_contents('assets/prism.min.js'), "\n"); +?> + + + + <?php echo basename($_SERVER['DOCUMENT_ROOT'].$_SERVER['SCRIPT_NAME']);?> + + + +*/ ?> + + + + + + + + + + + +*/ ?> + diff --git a/sites-available/default b/sites-available/default new file mode 100644 index 0000000..8824e0c --- /dev/null +++ b/sites-available/default @@ -0,0 +1,68 @@ +# Server configuration + +upstream php-handler { + server 127.0.0.1:9000; +} + +server { + server_name vapcloud.mooo.com; + + listen 80; + listen 443 ssl spdy; + + include snippets/ssl-vapcloud.mooo.com.conf; + include snippets/force-ssl.conf; + + include snippets/no-www.conf; + + root /var/www/owncloud; + + index index.php; + + client_max_body_size 10G; + fastcgi_buffers 64 4k; + + gzip off; + + rewrite ^/caldav(.*)$ /remote.php/caldav$1 redirect; + rewrite ^/carddav(.*)$ /remote.php/carddav$1 redirect; + rewrite ^/webdav(.*)$ /remote.php/webdav$1 redirect; + + error_page 403 /core/templates/403.php; + error_page 404 /core/templates/404.php; + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + location / { + rewrite ^/.well-known/host-meta /public.php?service=host-meta last; + rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last; + rewrite ^/.well-known/carddav /remote.php/carddav/ redirect; + rewrite ^/.well-known/caldav /remote.php/caldav/ redirect; + rewrite ^(/core/doc/[^\/]+/)$ $1/index.html; + + # First attempt to serve request as file, then + # as directory, then fall back to displaying a 404. + try_files $uri $uri/ /index.php; + } + + # deny access to .htaccess files, if Apache's document root + # concurs with nginx's one + location ~ ^/(?:\.htaccess|data|config|db_structure\.xml|README) { + deny all; + } + + location ~ \.php(?:$|/) { + include snippets/fastcgi-php.conf; + } + + location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ { + expires 30d; + # Optional: Don't log access to assets + access_log off; + } + +} diff --git a/sites-available/default-sub b/sites-available/default-sub new file mode 100644 index 0000000..3470671 --- /dev/null +++ b/sites-available/default-sub @@ -0,0 +1,33 @@ +# Server configuration +server { + server_name sub.domain.tld; + + listen 80; + listen [::]:80; + listen 443 ssl; + listen [::]:443 ssl; + + include snippets/ssl-sub.conf; + include snippets/force-ssl.conf; + + include snippets/no-www.conf; + + root /data/www/default-sub/public_html; + + index index.php index.html index.htm index.md; + + location / { + # First attempt to serve request as file, then + # as directory, then fall back to displaying a 404. + try_files $uri $uri/ =404; + } + + include snippets/php-fpm.conf; + include snippets/md.conf; + + # deny access to .htaccess files, if Apache's document root + # concurs with nginx's one + location ~ /\.ht { + deny all; + } +} diff --git a/snippets/fastcgi-php.conf b/snippets/fastcgi-php.conf new file mode 100644 index 0000000..7b3b5a9 --- /dev/null +++ b/snippets/fastcgi-php.conf @@ -0,0 +1,20 @@ +# regex to split $uri to $fastcgi_script_name and $fastcgi_path +fastcgi_split_path_info ^(.+\.php)(/.+)$; + +include fastcgi_params; + +fastcgi_param PATH_INFO $fastcgi_path_info; +fastcgi_param modHeadersAvailable true; + +# Check that the PHP script exists before passing it +try_files $fastcgi_script_name =404; + +# Bypass the fact that try_files resets $fastcgi_path_info +# see: http://trac.nginx.org/nginx/ticket/321 +set $path_info $fastcgi_path_info; +fastcgi_param PATH_INFO $path_info; + +fastcgi_index index.php; +include fastcgi.conf; + +fastcgi_pass php-handler; diff --git a/snippets/force-ssl.conf b/snippets/force-ssl.conf new file mode 100644 index 0000000..ec2e8c2 --- /dev/null +++ b/snippets/force-ssl.conf @@ -0,0 +1,3 @@ +if ( $scheme != https ) { + return 301 https://$http_host$request_uri; +} diff --git a/snippets/md.conf b/snippets/md.conf new file mode 100644 index 0000000..15d65ab --- /dev/null +++ b/snippets/md.conf @@ -0,0 +1,13 @@ +location ~ \.md$ { + try_files $uri =404; + fastcgi_pass unix:/var/run/php5-fpm.sock; + fastcgi_param DOCUMENT_ROOT $document_root; + fastcgi_param SCRIPT_NAME $uri; + fastcgi_param SCRIPT_FILENAME /etc/nginx/parser/markdown/md.php; + include fastcgi_params; +} + +location ~ ^(.*)\.md/raw$ { + try_files $1.md =404; + default_type text/plain; +} diff --git a/snippets/no-www.conf b/snippets/no-www.conf new file mode 100644 index 0000000..419f0aa --- /dev/null +++ b/snippets/no-www.conf @@ -0,0 +1,5 @@ +if ($host ~* www\.(.*)) { + set $host_without_www $1; + #rewrite ^ $scheme://$host_without_www$request_uri permanent; + return 301 https://$host_without_www$request_uri; +} diff --git a/snippets/ocsp-vhost.conf b/snippets/ocsp-vhost.conf new file mode 100644 index 0000000..e42f6a9 --- /dev/null +++ b/snippets/ocsp-vhost.conf @@ -0,0 +1,6 @@ +# OCSP Stapling config + +ssl_stapling on; +ssl_stapling_verify on; + +ssl_trusted_certificate /etc/letsencrypt/live/domain.tld/chain.pem; diff --git a/snippets/php-fpm.conf b/snippets/php-fpm.conf new file mode 100644 index 0000000..70a07b4 --- /dev/null +++ b/snippets/php-fpm.conf @@ -0,0 +1,14 @@ +# pass the PHP scripts to FastCGI server (php5-fpm) + +#location ~ \.php$ { +# include snippets/fastcgi-php.conf; +# fastcgi_pass unix:/var/run/php5-fpm.sock; +#} + +location ~ \.php$ { + try_files $uri =404; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass unix:/var/run/php5-fpm.sock; + fastcgi_index index.php; + include fastcgi.conf; +} diff --git a/snippets/random.conf b/snippets/random.conf new file mode 100644 index 0000000..ea443c0 --- /dev/null +++ b/snippets/random.conf @@ -0,0 +1,73 @@ +content_by_lua ' + --requires nginx-extras to be installed + --commented some things out because of blank pages + --with "include snippets/random.conf;" in location block + + rand_codes = { + -- 100 --[[Continue]], + -- 101 --[[Switching Protocols]], + -- 102 --[[Processing]], + -- 200 --[[OK]], + -- 201 --[[Created]], + -- 202 --[[Accepted]], + -- 203 --[[Non-Authoritative Information]], + -- 204 --[[No Content]], + -- 205 --[[Reset Content]], + -- 206 --[[Partial Content]], + -- 207 --[[Multi-Status]], + -- 208 --[[Already Reported]], + -- 226 --[[IM Used]], + 300 --[[Multiple Choices]], + 301 --[[Moved Permanently]], + 302 --[[Found]], + 303 --[[See Other]], + -- 304 --[[Not Modified]], + 305 --[[Use Proxy]], + -- 306 --[[(Unused, who cares)]], + -- 307 --[[Temporary Redirect]], + 308 --[[Permanent Redirect]], + 400 --[[Bad Request]], + 401 --[[Unauthorized]], + 402 --[[Payment Required]], + 403 --[[Forbidden]], + 404 --[[Not Found]], + 405 --[[Method Not Allowed]], + 406 --[[Not Acceptable]], + 407 --[[Proxy Authentication Required]], + 408 --[[Request Timeout]], + 409 --[[Conflict]], + 410 --[[Gone]], + 411 --[[Length Required]], + 412 --[[Precondition Failed]], + 413 --[[Payload Too Large]], + 414 --[[URI Too Long]], + 415 --[[Unsupported Media Type]], + 416 --[[Range Not Satisfiable]], + -- 417 --[[Expectation Failed]], + 418 --[[I\'m a teapot <3]], + 421 --[[Misdirected Request]], + -- 422 --[[Unprocessable Entity]], + -- 423 --[[Locked]], + -- 424 --[[Failed Dependency]], + -- 426 --[[Upgrade Required]], + -- 428 --[[Precondition Required]], + -- 429 --[[Too Many Requests]], + -- 431 --[[Request Header Fields Too Large]], + 500 --[[Internal Server Error]], + 501 --[[Not Implemented]], + 502 --[[Bad Gateway]], + 503 --[[Service Unavailable]], + 504 --[[Gateway Timeout]], + 505 --[[HTTP Version Not Supported]], + 506 --[[Variant Also Negotiates]], + 507 --[[Insufficient Storage]], + -- 508 --[[Loop Detected]], + -- 510 --[[Not Extended]], + -- 511 --[[Network Authentication Required]], + 1337 --[[some extra fun]] + } + + ngx.status = rand_codes[math.random(#rand_codes)] + --ngx.say("optional error page content") + ngx.exit(ngx.status) +'; diff --git a/snippets/snakeoil.conf b/snippets/snakeoil.conf new file mode 100644 index 0000000..ad26c3e --- /dev/null +++ b/snippets/snakeoil.conf @@ -0,0 +1,5 @@ +# Self signed certificates generated by the ssl-cert package +# Don't use them in a production server! + +ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; +ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; diff --git a/snippets/ssl-fallback.conf b/snippets/ssl-fallback.conf new file mode 100644 index 0000000..1c5da78 --- /dev/null +++ b/snippets/ssl-fallback.conf @@ -0,0 +1,13 @@ +# For permissions see: https://blog.kamal.io/post/nginx-and-ssl-root-key-security/ +ssl_certificate /etc/nginx/certs/default.crt; +ssl_certificate_key /etc/nginx/certs/default.key; + +ssl_dhparam /etc/nginx/certs/dhparam4096.pem; + +#ssl_trusted_certificate /etc/letsencrypt/live/domain.tld/chain.pem; + +# For preload see: https://hstspreload.appspot.com +add_header Strict-Transport-Security "max-age=31536000; preload"; +# valid for 365 days + + diff --git a/snippets/ssl-vhost.conf b/snippets/ssl-vhost.conf new file mode 100644 index 0000000..8d1e5fc --- /dev/null +++ b/snippets/ssl-vhost.conf @@ -0,0 +1,15 @@ +# For permissions see: https://blog.kamal.io/post/nginx-and-ssl-root-key-security/ +ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem; +ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem; + +ssl_dhparam /etc/letsencrypt/live/domain.tld/dhparams.pem; + +ssl_trusted_certificate /etc/letsencrypt/live/domain.tld/chain.pem; + +# For preload see: https://hstspreload.appspot.com +add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"; +# valid for 365 days + +# Pinned certs: Lets-Enc-x1, Lets-Enc-x2 +add_header Public-Key-Pins-Report-Only 'pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; pin-sha256="sRHdihwgkaib1P1gxX8HFszlD+7/gTfNvuAybgLPNis="; report-uri="https://report-uri.io/report/12345678/reportOnly"; max-age=7776000'; +# valid for 90 days (report-only) diff --git a/snippets/ssl.conf b/snippets/ssl.conf new file mode 100644 index 0000000..e16442d --- /dev/null +++ b/snippets/ssl.conf @@ -0,0 +1,19 @@ +ssl_protocols TLSv1.2 TLSv1.1 TLSv1; +#cipherli.st: ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; +ssl_ciphers "EECDH+AES256GCM:EDH+AES256GCM:AES256+EECDH:AES256+EDH"; +ssl_prefer_server_ciphers on; + +ssl_ecdh_curve secp384r1; + +ssl_session_cache shared:SSL:10m; +ssl_session_timeout 10m; + +ssl_session_tickets off; +ssl_stapling on; +ssl_stapling_verify on; + +#sources +# http://tautt.com/best-nginx-configuration-for-security/ +# https://sherbers.de/howto/nginx/ +# http://blog.rlove.org/2013/12/strong-ssl-crypto.html +# https://cipherli.st diff --git a/snippets/www.conf b/snippets/www.conf new file mode 100644 index 0000000..efce783 --- /dev/null +++ b/snippets/www.conf @@ -0,0 +1,4 @@ +server { + server_name "~^(?!www.).*" ; + return 301 $scheme://www.$host$request_uri; +}