├── .gitignore ├── .travis.yml ├── Dockerfile ├── LICENSE ├── MANIFEST.in ├── README.md ├── docker-compose.yml ├── pbnh ├── __init__.py ├── app │ ├── __init__.py │ ├── static │ │ ├── about.md │ │ ├── asciinema-player.css │ │ ├── asciinema-player.js │ │ ├── codemirror │ │ │ ├── LICENSE │ │ │ ├── codemirror.css │ │ │ ├── codemirror.js │ │ │ ├── fullscreen.css │ │ │ ├── fullscreen.js │ │ │ ├── langs │ │ │ │ ├── apl.js │ │ │ │ ├── asciiarmor.js │ │ │ │ ├── asn.1.js │ │ │ │ ├── asterisk.js │ │ │ │ ├── brainfuck.js │ │ │ │ ├── clike.js │ │ │ │ ├── clojure.js │ │ │ │ ├── cmake.js │ │ │ │ ├── cobol.js │ │ │ │ ├── coffeescript.js │ │ │ │ ├── commonlisp.js │ │ │ │ ├── crystal.js │ │ │ │ ├── css.js │ │ │ │ ├── cypher.js │ │ │ │ ├── d.js │ │ │ │ ├── dart.js │ │ │ │ ├── diff.js │ │ │ │ ├── django.js │ │ │ │ ├── dockerfile.js │ │ │ │ ├── dtd.js │ │ │ │ ├── dylan.js │ │ │ │ ├── ebnf.js │ │ │ │ ├── ecl.js │ │ │ │ ├── eiffel.js │ │ │ │ ├── elm.js │ │ │ │ ├── erlang.js │ │ │ │ ├── factor.js │ │ │ │ ├── fcl.js │ │ │ │ ├── forth.js │ │ │ │ ├── fortran.js │ │ │ │ ├── gas.js │ │ │ │ ├── gfm.js │ │ │ │ ├── gherkin.js │ │ │ │ ├── go.js │ │ │ │ ├── groovy.js │ │ │ │ ├── gss_test.js │ │ │ │ ├── haml.js │ │ │ │ ├── handlebars.js │ │ │ │ ├── haskell-literate.js │ │ │ │ ├── haskell.js │ │ │ │ ├── haxe.js │ │ │ │ ├── htmlembedded.js │ │ │ │ ├── htmlmixed.js │ │ │ │ ├── http.js │ │ │ │ ├── idl.js │ │ │ │ ├── index.html │ │ │ │ ├── jade.js │ │ │ │ ├── javascript.js │ │ │ │ ├── jinja2.js │ │ │ │ ├── jsx.js │ │ │ │ ├── julia.js │ │ │ │ ├── less_test.js │ │ │ │ ├── livescript.js │ │ │ │ ├── lua.js │ │ │ │ ├── markdown.js │ │ │ │ ├── mathematica.js │ │ │ │ ├── mbox.js │ │ │ │ ├── meta.js │ │ │ │ ├── mirc.js │ │ │ │ ├── mllike.js │ │ │ │ ├── modelica.js │ │ │ │ ├── mscgen.js │ │ │ │ ├── mscgen_test.js │ │ │ │ ├── msgenny_test.js │ │ │ │ ├── mumps.js │ │ │ │ ├── nginx.js │ │ │ │ ├── nsis.js │ │ │ │ ├── ntriples.js │ │ │ │ ├── octave.js │ │ │ │ ├── oz.js │ │ │ │ ├── pascal.js │ │ │ │ ├── pegjs.js │ │ │ │ ├── perl.js │ │ │ │ ├── php.js │ │ │ │ ├── pig.js │ │ │ │ ├── powershell.js │ │ │ │ ├── properties.js │ │ │ │ ├── protobuf.js │ │ │ │ ├── puppet.js │ │ │ │ ├── python.js │ │ │ │ ├── q.js │ │ │ │ ├── r.js │ │ │ │ ├── rpm.js │ │ │ │ ├── rst.js │ │ │ │ ├── ruby.js │ │ │ │ ├── rust.js │ │ │ │ ├── sas.js │ │ │ │ ├── sass.js │ │ │ │ ├── scheme.js │ │ │ │ ├── scss_test.js │ │ │ │ ├── shell.js │ │ │ │ ├── sieve.js │ │ │ │ ├── slim.js │ │ │ │ ├── smalltalk.js │ │ │ │ ├── smarty.js │ │ │ │ ├── solr.js │ │ │ │ ├── soy.js │ │ │ │ ├── sparql.js │ │ │ │ ├── spreadsheet.js │ │ │ │ ├── sql.js │ │ │ │ ├── stex.js │ │ │ │ ├── stylus.js │ │ │ │ ├── swift.js │ │ │ │ ├── tcl.js │ │ │ │ ├── textile.js │ │ │ │ ├── tiddlywiki.js │ │ │ │ ├── tiki.js │ │ │ │ ├── toml.js │ │ │ │ ├── tornado.js │ │ │ │ ├── troff.js │ │ │ │ ├── ttcn-cfg.js │ │ │ │ ├── ttcn.js │ │ │ │ ├── turtle.js │ │ │ │ ├── twig.js │ │ │ │ ├── vb.js │ │ │ │ ├── vbscript.js │ │ │ │ ├── velocity.js │ │ │ │ ├── verilog.js │ │ │ │ ├── vhdl.js │ │ │ │ ├── vue.js │ │ │ │ ├── webidl.js │ │ │ │ ├── xml.js │ │ │ │ ├── xquery.js │ │ │ │ ├── xu_test.js │ │ │ │ ├── yacas.js │ │ │ │ ├── yaml-frontmatter.js │ │ │ │ ├── yaml.js │ │ │ │ └── z80.js │ │ │ ├── loadmode.js │ │ │ ├── meta.js │ │ │ └── monokai.css │ │ ├── font-awesome.min.css │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ ├── fontawesome-webfont.woff2 │ │ └── marked.min.js │ ├── templates │ │ ├── 404.html │ │ ├── asciinema.html │ │ ├── index.html │ │ ├── layout.html │ │ ├── markdown.html │ │ ├── paste.html │ │ └── raw.html │ ├── util.py │ └── views.py ├── conf.py ├── db │ ├── __init__.py │ ├── connect.py │ ├── createdb.py │ ├── models.py │ └── paste.py ├── run.py └── tests │ ├── paste_curl_test.py │ ├── paste_psql_test.py │ └── paste_sqlite_test.py ├── sample_config.yml └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | 61 | #Ipython Notebook 62 | .ipynb_checkpoints 63 | 64 | # Virtualenv 65 | venv/ 66 | 67 | # vim swap files 68 | *.swp 69 | 70 | #db files 71 | *.db 72 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | 3 | python: 4 | - "3.4" 5 | - "3.5" 6 | - "3.6" 7 | - "nightly" 8 | 9 | install: 10 | - pip install . 11 | # These should get pulled from setup.py at some point 12 | - pip install nose pycurl 13 | - pip install coveralls 14 | 15 | script: 16 | - nosetests 17 | - coverage run --source=pbnh setup.py -q nosetests 18 | - coveralls 19 | 20 | notifications: 21 | email: false 22 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.6-slim 2 | 3 | MAINTAINER Bryce Handerson 4 | 5 | RUN apt update && apt install -y python3-dev libmagic-dev 6 | 7 | COPY . /src 8 | RUN pip install /src 9 | 10 | ENTRYPOINT ["gunicorn", "--bind", "0.0.0.0:5000", "pbnh.run:app"] 11 | EXPOSE 5000 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Bryce Handerson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include pbnh/app/static * 2 | recursive-include pbnh/app/templates * 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | pbnh 2 | ======== 3 | THIS IS NO LONGER VALID WITH THIS BRANCH 4 | ======== 5 | [![MIT License](https://img.shields.io/badge/license-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 6 | [![Build Status](https://img.shields.io/travis/bhanderson/pbnh.svg)](https://travis-ci.org/bhanderson/pbnh) 7 | [![Coverage Status](https://coveralls.io/repos/github/bhanderson/pbnh/badge.svg?branch=master)](https://coveralls.io/github/bhanderson/pbnh?branch=master) 8 | 9 | pbnh is our implementation of a pastebin server using flask and postgres or sqlite 10 | 11 | It is highly derived from [silverp1's](https://github.com/silverp1) and [buhman's](https://github.com/buhman) project [pb](https://github.com/ptpb/pb) and they deserve the recognition for this idea. 12 | 13 | The syntax highlighting is done using [codemirrors](https://github.com/codemirror/codemirror) javascript library. 14 | 15 | The icons are from [Font Awesome](https://fortawesome.github.io/Font-Awesome/) 16 | 17 | pbnh requires at least Python 3.3 18 | 19 | ## Table of Contents 20 | * [pbnh](#pbnh) 21 | * [Table of contents](#table-of-contents) 22 | * [Installation](#installation) 23 | * [Usage](#usage) 24 | * [Content](#content) 25 | * [Sunset](#sunset) 26 | * [Mime](#mime) 27 | * [Render](#rendering) 28 | * [Tests](#tests) 29 | * [Dependency](#dependency) 30 | 31 | ## Installation 32 | Note, psycopg2 is a C extension module for postgres. You can grab the dependencies by either installing python-psycopg2 from your package manager, or grab libpq-dev as well as python3-dev and gcc if you don't already have them. 33 | 34 | To install the pbnh package: 35 | ``` 36 | $ git clone https://github.com/bhanderson/pbnh.git 37 | $ cd pbnh 38 | $ pip install . 39 | ``` 40 | [![asciicast](https://asciinema.org/a/75sd1vwb395kp997phsowfcvs.png)](https://asciinema.org/a/75sd1vwb395kp997phsowfcvs) 41 | 42 | ## Configuration 43 | To configure pbnh, copy the sample config to ~/.config/pbnh/config.yml and edit it as desired. You can also use the default config in conf.py. 44 | 45 | To configure postgres (assuming debian/ubuntu, other distros should be similar): 46 | ``` 47 | # apt install postgres 48 | # su - postgres 49 | $ createuser -s $USERNAME 50 | python3 db/createdb.py 51 | ``` 52 | 53 | ## Configure using docker-compose 54 | - Install docker-compose by following the instructions here: 55 | https://docs.docker.com/compose/install/ 56 | - Copy `sample_config.yml` to `~/.config/pbnh.yml` and configure as desired 57 | - Build the container with `docker-compose build` 58 | - Launch the container with `docker-compose up` 59 | - The webui should be available at `localhost:5000` 60 | 61 | ## Usage 62 | You can create pastes with the webui or though the cli using curl. Currently the only way to upload anything other than text or a redirect is through the cli. 63 | 64 | Curl has an option for a form id, you can use c or content to specify the contents of a paste. 65 | ``` 66 | curl -F content=@file.txt servername.com 67 | ``` 68 | Or you can cat a file 69 | ``` 70 | cat file.txt | curl -F c=@- servername.com 71 | ``` 72 | [![asciicast](https://asciinema.org/a/8q5x4a0wrhtm7e2feok4b9i67.png)](https://asciinema.org/a/8q5x4a0wrhtm7e2feok4b9i67) 73 | We also support strings 74 | ``` 75 | curl -F content="hello world!" servername.com 76 | ``` 77 | To upload a redirect change the form id to r 78 | ``` 79 | curl -F r="https://www.google.com" servername.com 80 | ``` 81 | There are three different inputs allowed in a curl command they are content, sunset, and mime. Sunset and Mime are optional. 82 | ### content or c 83 | The content is exactly what it sounds like. The content of the file or the string data you want to paste and can be seen in the examples above. 84 | ### redirect or r 85 | You can submit a url to be a 302 redirect by specifying the form as r or redirect 86 | ### sunset 87 | The sunset is the amount of time you want this paste to be available. If sunset is specified you may specify for it to last a maximum of 24 hours. If unspecified the sunset value is 0 and the paste will not be removed. 88 | 89 | Currently there is no support for deleting pastes after you create them with a sunset. The sunset is set but no process is cleaning them up. 90 | ``` 91 | curl -F content=@file.txt -F sunset=10 servername.com 92 | ``` 93 | ### mime 94 | The mime type is the type of file. If you want automatic syntax highlighting through the webui or want an image to be displayed you can set the mimetype. 95 | The default is plain text, pbnh uses [python-magic](https://github.com/ahupp/python-magic) to attempt to guess the buffer mimetype if none is specified. 96 | A list of mimetypes can be found [here](http://www.freeformatter.com/mime-types-list.html). Only specify the second half of the mimetype. 97 | For example for the mimetype 'application/pdf' only specify pdf. 98 | ``` 99 | curl -F content=@file.txt -F mime=plain servername.com 100 | ``` 101 | ## Rendering 102 | You can render files as the browser would want to see them by specifying . in the url 103 | Currently things we render with javascript are 104 | * Markdown (.md) 105 | * RST (.rst) 106 | * asciinema (.asciinema) 107 | ## Tests 108 | To install the dependencies required for running tests, simply run 109 | ``` 110 | pip install -r tests_require.txt 111 | ``` 112 | Tests can be ran by running nosetests in the pbnh directory or by specifying a specific test 113 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | services: 3 | paste: 4 | build: . 5 | ports: 6 | - "5000:5000" 7 | secrets: 8 | - secrets.yml 9 | 10 | secrets: 11 | secrets.yml: 12 | file: ~/.config/.pbnh.yml 13 | -------------------------------------------------------------------------------- /pbnh/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhanderson/pbnh/59bcb27de1a2300f14476349f3182c651a8f88a1/pbnh/__init__.py -------------------------------------------------------------------------------- /pbnh/app/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | 3 | app = Flask(__name__) 4 | #app.config['CONFIG'] = None 5 | from pbnh.app import views 6 | -------------------------------------------------------------------------------- /pbnh/app/static/about.md: -------------------------------------------------------------------------------- 1 | pbnh 2 | ======== 3 | [pbnh](https://github.com/bhanderson/pbnh) is our implementation of a pastebin server using flask and postgres or sqlite 4 | 5 | It is highly derived from [silverp1's](https://github.com/silverp1) and [buhman's](https://github.com/buhman) project [pb](https://github.com/ptpb/pb) and they deserve the recognition for this idea. 6 | 7 | The syntax highlighting is done using [codemirrors](https://github.com/codemirror/codemirror) javascript library. 8 | 9 | The icons are from [Font Awesome](https://fortawesome.github.io/Font-Awesome/) 10 | 11 | ## Table of Contents 12 | * [pbnh](#pbnh) 13 | * [Table of contents](#table-of-contents) 14 | * [Usage](#usage) 15 | * [Content](#content) 16 | * [Sunset](#sunset) 17 | * [Mime](#mime) 18 | * [Render](#render) 19 | 20 | ## Usage 21 | You can create pastes with the webui or though the cli using curl. Currently the only way to upload anything other than text or a redirect is through the cli. 22 | 23 | Curl has an option for a form id, you can use c or content to specify the contents of a paste. 24 | ``` 25 | curl -F content=@file.txt servername.com 26 | ``` 27 | Or you can cat a file 28 | ``` 29 | cat file.txt | curl -F c=@- servername.com 30 | ``` 31 | [![asciicast](https://asciinema.org/a/8q5x4a0wrhtm7e2feok4b9i67.png)](https://asciinema.org/a/8q5x4a0wrhtm7e2feok4b9i67) 32 | We also support strings 33 | ``` 34 | curl -F content="hello world!" servername.com 35 | ``` 36 | To upload a redirect change the form id to r 37 | ``` 38 | curl -F r="https://www.google.com" servername.com 39 | ``` 40 | There are three different inputs allowed in a curl command they are content, sunset, and mime. Sunset and Mime are optional. 41 | ### content or c 42 | The content is exactly what it sounds like. The content of the file or the string data you want to paste and can be seen in the examples above. 43 | ### sunset 44 | The sunset is the amount of time you want this paste to be available. If sunset is specified you may specify for it to last a maximum of 24 hours. If unspecified the sunset value is 0 and the paste will not be removed. 45 | 46 | Currently there is no support for deleting pastes after you create them with a sunset. The sunset is set but no process is cleaning them up. 47 | ``` 48 | curl -F content=@file.txt -F sunset=10 servername.com 49 | ``` 50 | ### mime 51 | The mime type is the type of file. If you want automatic syntax highlighting through the webui or want an image to be displayed you can set the mimetype. 52 | The default is plain text, pbnh uses [python-magic](https://github.com/ahupp/python-magic) to attempt to guess the buffer mimetype if none is specified. 53 | A list of mimetypes can be found [here](http://www.freeformatter.com/mime-types-list.html). Only specify the second half of the mimetype. 54 | For example for the mimetype 'application/pdf' only specify pdf. 55 | ``` 56 | curl -F content=@file.txt -F mime=plain servername.com 57 | ``` 58 | ## Rendering 59 | You can render files as the browser would want to see them by specifying . in the url 60 | Currently things we render with javascript are 61 | * Markdown (.md) 62 | * RST (.rst) 63 | * asciinema (.asciinema) 64 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2016 by Marijn Haverbeke and others 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/fullscreen.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-fullscreen { 2 | position: fixed; 3 | top: 0; left: 0; right: 0; bottom: 0; 4 | height: auto; 5 | z-index: 9; 6 | } 7 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/fullscreen.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineOption("fullScreen", false, function(cm, val, old) { 15 | if (old == CodeMirror.Init) old = false; 16 | if (!old == !val) return; 17 | if (val) setFullscreen(cm); 18 | else setNormal(cm); 19 | }); 20 | 21 | function setFullscreen(cm) { 22 | var wrap = cm.getWrapperElement(); 23 | cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset, 24 | width: wrap.style.width, height: wrap.style.height}; 25 | wrap.style.width = ""; 26 | wrap.style.height = "auto"; 27 | wrap.className += " CodeMirror-fullscreen"; 28 | document.documentElement.style.overflow = "hidden"; 29 | cm.refresh(); 30 | } 31 | 32 | function setNormal(cm) { 33 | var wrap = cm.getWrapperElement(); 34 | wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, ""); 35 | document.documentElement.style.overflow = ""; 36 | var info = cm.state.fullScreenRestore; 37 | wrap.style.width = info.width; wrap.style.height = info.height; 38 | window.scrollTo(info.scrollLeft, info.scrollTop); 39 | cm.refresh(); 40 | } 41 | }); 42 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/apl.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("apl", function() { 15 | var builtInOps = { 16 | ".": "innerProduct", 17 | "\\": "scan", 18 | "/": "reduce", 19 | "⌿": "reduce1Axis", 20 | "⍀": "scan1Axis", 21 | "¨": "each", 22 | "⍣": "power" 23 | }; 24 | var builtInFuncs = { 25 | "+": ["conjugate", "add"], 26 | "−": ["negate", "subtract"], 27 | "×": ["signOf", "multiply"], 28 | "÷": ["reciprocal", "divide"], 29 | "⌈": ["ceiling", "greaterOf"], 30 | "⌊": ["floor", "lesserOf"], 31 | "∣": ["absolute", "residue"], 32 | "⍳": ["indexGenerate", "indexOf"], 33 | "?": ["roll", "deal"], 34 | "⋆": ["exponentiate", "toThePowerOf"], 35 | "⍟": ["naturalLog", "logToTheBase"], 36 | "○": ["piTimes", "circularFuncs"], 37 | "!": ["factorial", "binomial"], 38 | "⌹": ["matrixInverse", "matrixDivide"], 39 | "<": [null, "lessThan"], 40 | "≤": [null, "lessThanOrEqual"], 41 | "=": [null, "equals"], 42 | ">": [null, "greaterThan"], 43 | "≥": [null, "greaterThanOrEqual"], 44 | "≠": [null, "notEqual"], 45 | "≡": ["depth", "match"], 46 | "≢": [null, "notMatch"], 47 | "∈": ["enlist", "membership"], 48 | "⍷": [null, "find"], 49 | "∪": ["unique", "union"], 50 | "∩": [null, "intersection"], 51 | "∼": ["not", "without"], 52 | "∨": [null, "or"], 53 | "∧": [null, "and"], 54 | "⍱": [null, "nor"], 55 | "⍲": [null, "nand"], 56 | "⍴": ["shapeOf", "reshape"], 57 | ",": ["ravel", "catenate"], 58 | "⍪": [null, "firstAxisCatenate"], 59 | "⌽": ["reverse", "rotate"], 60 | "⊖": ["axis1Reverse", "axis1Rotate"], 61 | "⍉": ["transpose", null], 62 | "↑": ["first", "take"], 63 | "↓": [null, "drop"], 64 | "⊂": ["enclose", "partitionWithAxis"], 65 | "⊃": ["diclose", "pick"], 66 | "⌷": [null, "index"], 67 | "⍋": ["gradeUp", null], 68 | "⍒": ["gradeDown", null], 69 | "⊤": ["encode", null], 70 | "⊥": ["decode", null], 71 | "⍕": ["format", "formatByExample"], 72 | "⍎": ["execute", null], 73 | "⊣": ["stop", "left"], 74 | "⊢": ["pass", "right"] 75 | }; 76 | 77 | var isOperator = /[\.\/⌿⍀¨⍣]/; 78 | var isNiladic = /⍬/; 79 | var isFunction = /[\+−×÷⌈⌊∣⍳\?⋆⍟○!⌹<≤=>≥≠≡≢∈⍷∪∩∼∨∧⍱⍲⍴,⍪⌽⊖⍉↑↓⊂⊃⌷⍋⍒⊤⊥⍕⍎⊣⊢]/; 80 | var isArrow = /←/; 81 | var isComment = /[⍝#].*$/; 82 | 83 | var stringEater = function(type) { 84 | var prev; 85 | prev = false; 86 | return function(c) { 87 | prev = c; 88 | if (c === type) { 89 | return prev === "\\"; 90 | } 91 | return true; 92 | }; 93 | }; 94 | return { 95 | startState: function() { 96 | return { 97 | prev: false, 98 | func: false, 99 | op: false, 100 | string: false, 101 | escape: false 102 | }; 103 | }, 104 | token: function(stream, state) { 105 | var ch, funcName; 106 | if (stream.eatSpace()) { 107 | return null; 108 | } 109 | ch = stream.next(); 110 | if (ch === '"' || ch === "'") { 111 | stream.eatWhile(stringEater(ch)); 112 | stream.next(); 113 | state.prev = true; 114 | return "string"; 115 | } 116 | if (/[\[{\(]/.test(ch)) { 117 | state.prev = false; 118 | return null; 119 | } 120 | if (/[\]}\)]/.test(ch)) { 121 | state.prev = true; 122 | return null; 123 | } 124 | if (isNiladic.test(ch)) { 125 | state.prev = false; 126 | return "niladic"; 127 | } 128 | if (/[¯\d]/.test(ch)) { 129 | if (state.func) { 130 | state.func = false; 131 | state.prev = false; 132 | } else { 133 | state.prev = true; 134 | } 135 | stream.eatWhile(/[\w\.]/); 136 | return "number"; 137 | } 138 | if (isOperator.test(ch)) { 139 | return "operator apl-" + builtInOps[ch]; 140 | } 141 | if (isArrow.test(ch)) { 142 | return "apl-arrow"; 143 | } 144 | if (isFunction.test(ch)) { 145 | funcName = "apl-"; 146 | if (builtInFuncs[ch] != null) { 147 | if (state.prev) { 148 | funcName += builtInFuncs[ch][1]; 149 | } else { 150 | funcName += builtInFuncs[ch][0]; 151 | } 152 | } 153 | state.func = true; 154 | state.prev = false; 155 | return "function " + funcName; 156 | } 157 | if (isComment.test(ch)) { 158 | stream.skipToEnd(); 159 | return "comment"; 160 | } 161 | if (ch === "∘" && stream.peek() === ".") { 162 | stream.next(); 163 | return "function jot-dot"; 164 | } 165 | stream.eatWhile(/[\w\$_]/); 166 | state.prev = true; 167 | return "keyword"; 168 | } 169 | }; 170 | }); 171 | 172 | CodeMirror.defineMIME("text/apl", "apl"); 173 | 174 | }); 175 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/asciiarmor.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | function errorIfNotEmpty(stream) { 15 | var nonWS = stream.match(/^\s*\S/); 16 | stream.skipToEnd(); 17 | return nonWS ? "error" : null; 18 | } 19 | 20 | CodeMirror.defineMode("asciiarmor", function() { 21 | return { 22 | token: function(stream, state) { 23 | var m; 24 | if (state.state == "top") { 25 | if (stream.sol() && (m = stream.match(/^-----BEGIN (.*)?-----\s*$/))) { 26 | state.state = "headers"; 27 | state.type = m[1]; 28 | return "tag"; 29 | } 30 | return errorIfNotEmpty(stream); 31 | } else if (state.state == "headers") { 32 | if (stream.sol() && stream.match(/^\w+:/)) { 33 | state.state = "header"; 34 | return "atom"; 35 | } else { 36 | var result = errorIfNotEmpty(stream); 37 | if (result) state.state = "body"; 38 | return result; 39 | } 40 | } else if (state.state == "header") { 41 | stream.skipToEnd(); 42 | state.state = "headers"; 43 | return "string"; 44 | } else if (state.state == "body") { 45 | if (stream.sol() && (m = stream.match(/^-----END (.*)?-----\s*$/))) { 46 | if (m[1] != state.type) return "error"; 47 | state.state = "end"; 48 | return "tag"; 49 | } else { 50 | if (stream.eatWhile(/[A-Za-z0-9+\/=]/)) { 51 | return null; 52 | } else { 53 | stream.next(); 54 | return "error"; 55 | } 56 | } 57 | } else if (state.state == "end") { 58 | return errorIfNotEmpty(stream); 59 | } 60 | }, 61 | blankLine: function(state) { 62 | if (state.state == "headers") state.state = "body"; 63 | }, 64 | startState: function() { 65 | return {state: "top", type: null}; 66 | } 67 | }; 68 | }); 69 | 70 | CodeMirror.defineMIME("application/pgp", "asciiarmor"); 71 | CodeMirror.defineMIME("application/pgp-keys", "asciiarmor"); 72 | CodeMirror.defineMIME("application/pgp-signature", "asciiarmor"); 73 | }); 74 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/brainfuck.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | // Brainfuck mode created by Michael Kaminsky https://github.com/mkaminsky11 5 | 6 | (function(mod) { 7 | if (typeof exports == "object" && typeof module == "object") 8 | mod(require("../../lib/codemirror")) 9 | else if (typeof define == "function" && define.amd) 10 | define(["../../lib/codemirror"], mod) 11 | else 12 | mod(CodeMirror) 13 | })(function(CodeMirror) { 14 | "use strict" 15 | var reserve = "><+-.,[]".split(""); 16 | /* 17 | comments can be either: 18 | placed behind lines 19 | 20 | +++ this is a comment 21 | 22 | where reserved characters cannot be used 23 | or in a loop 24 | [ 25 | this is ok to use [ ] and stuff 26 | ] 27 | or preceded by # 28 | */ 29 | CodeMirror.defineMode("brainfuck", function() { 30 | return { 31 | startState: function() { 32 | return { 33 | commentLine: false, 34 | left: 0, 35 | right: 0, 36 | commentLoop: false 37 | } 38 | }, 39 | token: function(stream, state) { 40 | if (stream.eatSpace()) return null 41 | if(stream.sol()){ 42 | state.commentLine = false; 43 | } 44 | var ch = stream.next().toString(); 45 | if(reserve.indexOf(ch) !== -1){ 46 | if(state.commentLine === true){ 47 | if(stream.eol()){ 48 | state.commentLine = false; 49 | } 50 | return "comment"; 51 | } 52 | if(ch === "]" || ch === "["){ 53 | if(ch === "["){ 54 | state.left++; 55 | } 56 | else{ 57 | state.right++; 58 | } 59 | return "bracket"; 60 | } 61 | else if(ch === "+" || ch === "-"){ 62 | return "keyword"; 63 | } 64 | else if(ch === "<" || ch === ">"){ 65 | return "atom"; 66 | } 67 | else if(ch === "." || ch === ","){ 68 | return "def"; 69 | } 70 | } 71 | else{ 72 | state.commentLine = true; 73 | if(stream.eol()){ 74 | state.commentLine = false; 75 | } 76 | return "comment"; 77 | } 78 | if(stream.eol()){ 79 | state.commentLine = false; 80 | } 81 | } 82 | }; 83 | }); 84 | CodeMirror.defineMIME("text/x-brainfuck","brainfuck") 85 | }); 86 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/cmake.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) 8 | define(["../../lib/codemirror"], mod); 9 | else 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("cmake", function () { 15 | var variable_regex = /({)?[a-zA-Z0-9_]+(})?/; 16 | 17 | function tokenString(stream, state) { 18 | var current, prev, found_var = false; 19 | while (!stream.eol() && (current = stream.next()) != state.pending) { 20 | if (current === '$' && prev != '\\' && state.pending == '"') { 21 | found_var = true; 22 | break; 23 | } 24 | prev = current; 25 | } 26 | if (found_var) { 27 | stream.backUp(1); 28 | } 29 | if (current == state.pending) { 30 | state.continueString = false; 31 | } else { 32 | state.continueString = true; 33 | } 34 | return "string"; 35 | } 36 | 37 | function tokenize(stream, state) { 38 | var ch = stream.next(); 39 | 40 | // Have we found a variable? 41 | if (ch === '$') { 42 | if (stream.match(variable_regex)) { 43 | return 'variable-2'; 44 | } 45 | return 'variable'; 46 | } 47 | // Should we still be looking for the end of a string? 48 | if (state.continueString) { 49 | // If so, go through the loop again 50 | stream.backUp(1); 51 | return tokenString(stream, state); 52 | } 53 | // Do we just have a function on our hands? 54 | // In 'cmake_minimum_required (VERSION 2.8.8)', 'cmake_minimum_required' is matched 55 | if (stream.match(/(\s+)?\w+\(/) || stream.match(/(\s+)?\w+\ \(/)) { 56 | stream.backUp(1); 57 | return 'def'; 58 | } 59 | if (ch == "#") { 60 | stream.skipToEnd(); 61 | return "comment"; 62 | } 63 | // Have we found a string? 64 | if (ch == "'" || ch == '"') { 65 | // Store the type (single or double) 66 | state.pending = ch; 67 | // Perform the looping function to find the end 68 | return tokenString(stream, state); 69 | } 70 | if (ch == '(' || ch == ')') { 71 | return 'bracket'; 72 | } 73 | if (ch.match(/[0-9]/)) { 74 | return 'number'; 75 | } 76 | stream.eatWhile(/[\w-]/); 77 | return null; 78 | } 79 | return { 80 | startState: function () { 81 | var state = {}; 82 | state.inDefinition = false; 83 | state.inInclude = false; 84 | state.continueString = false; 85 | state.pending = false; 86 | return state; 87 | }, 88 | token: function (stream, state) { 89 | if (stream.eatSpace()) return null; 90 | return tokenize(stream, state); 91 | } 92 | }; 93 | }); 94 | 95 | CodeMirror.defineMIME("text/x-cmake", "cmake"); 96 | 97 | }); 98 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/commonlisp.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("commonlisp", function (config) { 15 | var specialForm = /^(block|let*|return-from|catch|load-time-value|setq|eval-when|locally|symbol-macrolet|flet|macrolet|tagbody|function|multiple-value-call|the|go|multiple-value-prog1|throw|if|progn|unwind-protect|labels|progv|let|quote)$/; 16 | var assumeBody = /^with|^def|^do|^prog|case$|^cond$|bind$|when$|unless$/; 17 | var numLiteral = /^(?:[+\-]?(?:\d+|\d*\.\d+)(?:[efd][+\-]?\d+)?|[+\-]?\d+(?:\/[+\-]?\d+)?|#b[+\-]?[01]+|#o[+\-]?[0-7]+|#x[+\-]?[\da-f]+)/; 18 | var symbol = /[^\s'`,@()\[\]";]/; 19 | var type; 20 | 21 | function readSym(stream) { 22 | var ch; 23 | while (ch = stream.next()) { 24 | if (ch == "\\") stream.next(); 25 | else if (!symbol.test(ch)) { stream.backUp(1); break; } 26 | } 27 | return stream.current(); 28 | } 29 | 30 | function base(stream, state) { 31 | if (stream.eatSpace()) {type = "ws"; return null;} 32 | if (stream.match(numLiteral)) return "number"; 33 | var ch = stream.next(); 34 | if (ch == "\\") ch = stream.next(); 35 | 36 | if (ch == '"') return (state.tokenize = inString)(stream, state); 37 | else if (ch == "(") { type = "open"; return "bracket"; } 38 | else if (ch == ")" || ch == "]") { type = "close"; return "bracket"; } 39 | else if (ch == ";") { stream.skipToEnd(); type = "ws"; return "comment"; } 40 | else if (/['`,@]/.test(ch)) return null; 41 | else if (ch == "|") { 42 | if (stream.skipTo("|")) { stream.next(); return "symbol"; } 43 | else { stream.skipToEnd(); return "error"; } 44 | } else if (ch == "#") { 45 | var ch = stream.next(); 46 | if (ch == "[") { type = "open"; return "bracket"; } 47 | else if (/[+\-=\.']/.test(ch)) return null; 48 | else if (/\d/.test(ch) && stream.match(/^\d*#/)) return null; 49 | else if (ch == "|") return (state.tokenize = inComment)(stream, state); 50 | else if (ch == ":") { readSym(stream); return "meta"; } 51 | else return "error"; 52 | } else { 53 | var name = readSym(stream); 54 | if (name == ".") return null; 55 | type = "symbol"; 56 | if (name == "nil" || name == "t" || name.charAt(0) == ":") return "atom"; 57 | if (state.lastType == "open" && (specialForm.test(name) || assumeBody.test(name))) return "keyword"; 58 | if (name.charAt(0) == "&") return "variable-2"; 59 | return "variable"; 60 | } 61 | } 62 | 63 | function inString(stream, state) { 64 | var escaped = false, next; 65 | while (next = stream.next()) { 66 | if (next == '"' && !escaped) { state.tokenize = base; break; } 67 | escaped = !escaped && next == "\\"; 68 | } 69 | return "string"; 70 | } 71 | 72 | function inComment(stream, state) { 73 | var next, last; 74 | while (next = stream.next()) { 75 | if (next == "#" && last == "|") { state.tokenize = base; break; } 76 | last = next; 77 | } 78 | type = "ws"; 79 | return "comment"; 80 | } 81 | 82 | return { 83 | startState: function () { 84 | return {ctx: {prev: null, start: 0, indentTo: 0}, lastType: null, tokenize: base}; 85 | }, 86 | 87 | token: function (stream, state) { 88 | if (stream.sol() && typeof state.ctx.indentTo != "number") 89 | state.ctx.indentTo = state.ctx.start + 1; 90 | 91 | type = null; 92 | var style = state.tokenize(stream, state); 93 | if (type != "ws") { 94 | if (state.ctx.indentTo == null) { 95 | if (type == "symbol" && assumeBody.test(stream.current())) 96 | state.ctx.indentTo = state.ctx.start + config.indentUnit; 97 | else 98 | state.ctx.indentTo = "next"; 99 | } else if (state.ctx.indentTo == "next") { 100 | state.ctx.indentTo = stream.column(); 101 | } 102 | state.lastType = type; 103 | } 104 | if (type == "open") state.ctx = {prev: state.ctx, start: stream.column(), indentTo: null}; 105 | else if (type == "close") state.ctx = state.ctx.prev || state.ctx; 106 | return style; 107 | }, 108 | 109 | indent: function (state, _textAfter) { 110 | var i = state.ctx.indentTo; 111 | return typeof i == "number" ? i : state.ctx.start + 1; 112 | }, 113 | 114 | closeBrackets: {pairs: "()[]{}\"\""}, 115 | lineComment: ";;", 116 | blockCommentStart: "#|", 117 | blockCommentEnd: "|#" 118 | }; 119 | }); 120 | 121 | CodeMirror.defineMIME("text/x-common-lisp", "commonlisp"); 122 | 123 | }); 124 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/diff.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("diff", function() { 15 | 16 | var TOKEN_NAMES = { 17 | '+': 'positive', 18 | '-': 'negative', 19 | '@': 'meta' 20 | }; 21 | 22 | return { 23 | token: function(stream) { 24 | var tw_pos = stream.string.search(/[\t ]+?$/); 25 | 26 | if (!stream.sol() || tw_pos === 0) { 27 | stream.skipToEnd(); 28 | return ("error " + ( 29 | TOKEN_NAMES[stream.string.charAt(0)] || '')).replace(/ $/, ''); 30 | } 31 | 32 | var token_name = TOKEN_NAMES[stream.peek()] || stream.skipToEnd(); 33 | 34 | if (tw_pos === -1) { 35 | stream.skipToEnd(); 36 | } else { 37 | stream.pos = tw_pos; 38 | } 39 | 40 | return token_name; 41 | } 42 | }; 43 | }); 44 | 45 | CodeMirror.defineMIME("text/x-diff", "diff"); 46 | 47 | }); 48 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/dockerfile.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("../../addon/mode/simple")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "../../addon/mode/simple"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | // Collect all Dockerfile directives 15 | var instructions = ["from", "maintainer", "run", "cmd", "expose", "env", 16 | "add", "copy", "entrypoint", "volume", "user", 17 | "workdir", "onbuild"], 18 | instructionRegex = "(" + instructions.join('|') + ")", 19 | instructionOnlyLine = new RegExp(instructionRegex + "\\s*$", "i"), 20 | instructionWithArguments = new RegExp(instructionRegex + "(\\s+)", "i"); 21 | 22 | CodeMirror.defineSimpleMode("dockerfile", { 23 | start: [ 24 | // Block comment: This is a line starting with a comment 25 | { 26 | regex: /#.*$/, 27 | token: "comment" 28 | }, 29 | // Highlight an instruction without any arguments (for convenience) 30 | { 31 | regex: instructionOnlyLine, 32 | token: "variable-2" 33 | }, 34 | // Highlight an instruction followed by arguments 35 | { 36 | regex: instructionWithArguments, 37 | token: ["variable-2", null], 38 | next: "arguments" 39 | }, 40 | { 41 | regex: /./, 42 | token: null 43 | } 44 | ], 45 | arguments: [ 46 | { 47 | // Line comment without instruction arguments is an error 48 | regex: /#.*$/, 49 | token: "error", 50 | next: "start" 51 | }, 52 | { 53 | regex: /[^#]+\\$/, 54 | token: null 55 | }, 56 | { 57 | // Match everything except for the inline comment 58 | regex: /[^#]+/, 59 | token: null, 60 | next: "start" 61 | }, 62 | { 63 | regex: /$/, 64 | token: null, 65 | next: "start" 66 | }, 67 | // Fail safe return to start 68 | { 69 | token: null, 70 | next: "start" 71 | } 72 | ], 73 | meta: { 74 | lineComment: "#" 75 | } 76 | }); 77 | 78 | CodeMirror.defineMIME("text/x-dockerfile", "dockerfile"); 79 | }); 80 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/dtd.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | /* 5 | DTD mode 6 | Ported to CodeMirror by Peter Kroon 7 | Report bugs/issues here: https://github.com/codemirror/CodeMirror/issues 8 | GitHub: @peterkroon 9 | */ 10 | 11 | (function(mod) { 12 | if (typeof exports == "object" && typeof module == "object") // CommonJS 13 | mod(require("../../lib/codemirror")); 14 | else if (typeof define == "function" && define.amd) // AMD 15 | define(["../../lib/codemirror"], mod); 16 | else // Plain browser env 17 | mod(CodeMirror); 18 | })(function(CodeMirror) { 19 | "use strict"; 20 | 21 | CodeMirror.defineMode("dtd", function(config) { 22 | var indentUnit = config.indentUnit, type; 23 | function ret(style, tp) {type = tp; return style;} 24 | 25 | function tokenBase(stream, state) { 26 | var ch = stream.next(); 27 | 28 | if (ch == "<" && stream.eat("!") ) { 29 | if (stream.eatWhile(/[\-]/)) { 30 | state.tokenize = tokenSGMLComment; 31 | return tokenSGMLComment(stream, state); 32 | } else if (stream.eatWhile(/[\w]/)) return ret("keyword", "doindent"); 33 | } else if (ch == "<" && stream.eat("?")) { //xml declaration 34 | state.tokenize = inBlock("meta", "?>"); 35 | return ret("meta", ch); 36 | } else if (ch == "#" && stream.eatWhile(/[\w]/)) return ret("atom", "tag"); 37 | else if (ch == "|") return ret("keyword", "seperator"); 38 | else if (ch.match(/[\(\)\[\]\-\.,\+\?>]/)) return ret(null, ch);//if(ch === ">") return ret(null, "endtag"); else 39 | else if (ch.match(/[\[\]]/)) return ret("rule", ch); 40 | else if (ch == "\"" || ch == "'") { 41 | state.tokenize = tokenString(ch); 42 | return state.tokenize(stream, state); 43 | } else if (stream.eatWhile(/[a-zA-Z\?\+\d]/)) { 44 | var sc = stream.current(); 45 | if( sc.substr(sc.length-1,sc.length).match(/\?|\+/) !== null )stream.backUp(1); 46 | return ret("tag", "tag"); 47 | } else if (ch == "%" || ch == "*" ) return ret("number", "number"); 48 | else { 49 | stream.eatWhile(/[\w\\\-_%.{,]/); 50 | return ret(null, null); 51 | } 52 | } 53 | 54 | function tokenSGMLComment(stream, state) { 55 | var dashes = 0, ch; 56 | while ((ch = stream.next()) != null) { 57 | if (dashes >= 2 && ch == ">") { 58 | state.tokenize = tokenBase; 59 | break; 60 | } 61 | dashes = (ch == "-") ? dashes + 1 : 0; 62 | } 63 | return ret("comment", "comment"); 64 | } 65 | 66 | function tokenString(quote) { 67 | return function(stream, state) { 68 | var escaped = false, ch; 69 | while ((ch = stream.next()) != null) { 70 | if (ch == quote && !escaped) { 71 | state.tokenize = tokenBase; 72 | break; 73 | } 74 | escaped = !escaped && ch == "\\"; 75 | } 76 | return ret("string", "tag"); 77 | }; 78 | } 79 | 80 | function inBlock(style, terminator) { 81 | return function(stream, state) { 82 | while (!stream.eol()) { 83 | if (stream.match(terminator)) { 84 | state.tokenize = tokenBase; 85 | break; 86 | } 87 | stream.next(); 88 | } 89 | return style; 90 | }; 91 | } 92 | 93 | return { 94 | startState: function(base) { 95 | return {tokenize: tokenBase, 96 | baseIndent: base || 0, 97 | stack: []}; 98 | }, 99 | 100 | token: function(stream, state) { 101 | if (stream.eatSpace()) return null; 102 | var style = state.tokenize(stream, state); 103 | 104 | var context = state.stack[state.stack.length-1]; 105 | if (stream.current() == "[" || type === "doindent" || type == "[") state.stack.push("rule"); 106 | else if (type === "endtag") state.stack[state.stack.length-1] = "endtag"; 107 | else if (stream.current() == "]" || type == "]" || (type == ">" && context == "rule")) state.stack.pop(); 108 | else if (type == "[") state.stack.push("["); 109 | return style; 110 | }, 111 | 112 | indent: function(state, textAfter) { 113 | var n = state.stack.length; 114 | 115 | if( textAfter.match(/\]\s+|\]/) )n=n-1; 116 | else if(textAfter.substr(textAfter.length-1, textAfter.length) === ">"){ 117 | if(textAfter.substr(0,1) === "<") {} 118 | else if( type == "doindent" && textAfter.length > 1 ) {} 119 | else if( type == "doindent")n--; 120 | else if( type == ">" && textAfter.length > 1) {} 121 | else if( type == "tag" && textAfter !== ">") {} 122 | else if( type == "tag" && state.stack[state.stack.length-1] == "rule")n--; 123 | else if( type == "tag")n++; 124 | else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule" && type === ">")n--; 125 | else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule") {} 126 | else if( textAfter.substr(0,1) !== "<" && textAfter.substr(0,1) === ">" )n=n-1; 127 | else if( textAfter === ">") {} 128 | else n=n-1; 129 | //over rule them all 130 | if(type == null || type == "]")n--; 131 | } 132 | 133 | return state.baseIndent + n * indentUnit; 134 | }, 135 | 136 | electricChars: "]>" 137 | }; 138 | }); 139 | 140 | CodeMirror.defineMIME("application/xml-dtd", "dtd"); 141 | 142 | }); 143 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/eiffel.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("eiffel", function() { 15 | function wordObj(words) { 16 | var o = {}; 17 | for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true; 18 | return o; 19 | } 20 | var keywords = wordObj([ 21 | 'note', 22 | 'across', 23 | 'when', 24 | 'variant', 25 | 'until', 26 | 'unique', 27 | 'undefine', 28 | 'then', 29 | 'strip', 30 | 'select', 31 | 'retry', 32 | 'rescue', 33 | 'require', 34 | 'rename', 35 | 'reference', 36 | 'redefine', 37 | 'prefix', 38 | 'once', 39 | 'old', 40 | 'obsolete', 41 | 'loop', 42 | 'local', 43 | 'like', 44 | 'is', 45 | 'inspect', 46 | 'infix', 47 | 'include', 48 | 'if', 49 | 'frozen', 50 | 'from', 51 | 'external', 52 | 'export', 53 | 'ensure', 54 | 'end', 55 | 'elseif', 56 | 'else', 57 | 'do', 58 | 'creation', 59 | 'create', 60 | 'check', 61 | 'alias', 62 | 'agent', 63 | 'separate', 64 | 'invariant', 65 | 'inherit', 66 | 'indexing', 67 | 'feature', 68 | 'expanded', 69 | 'deferred', 70 | 'class', 71 | 'Void', 72 | 'True', 73 | 'Result', 74 | 'Precursor', 75 | 'False', 76 | 'Current', 77 | 'create', 78 | 'attached', 79 | 'detachable', 80 | 'as', 81 | 'and', 82 | 'implies', 83 | 'not', 84 | 'or' 85 | ]); 86 | var operators = wordObj([":=", "and then","and", "or","<<",">>"]); 87 | 88 | function chain(newtok, stream, state) { 89 | state.tokenize.push(newtok); 90 | return newtok(stream, state); 91 | } 92 | 93 | function tokenBase(stream, state) { 94 | if (stream.eatSpace()) return null; 95 | var ch = stream.next(); 96 | if (ch == '"'||ch == "'") { 97 | return chain(readQuoted(ch, "string"), stream, state); 98 | } else if (ch == "-"&&stream.eat("-")) { 99 | stream.skipToEnd(); 100 | return "comment"; 101 | } else if (ch == ":"&&stream.eat("=")) { 102 | return "operator"; 103 | } else if (/[0-9]/.test(ch)) { 104 | stream.eatWhile(/[xXbBCc0-9\.]/); 105 | stream.eat(/[\?\!]/); 106 | return "ident"; 107 | } else if (/[a-zA-Z_0-9]/.test(ch)) { 108 | stream.eatWhile(/[a-zA-Z_0-9]/); 109 | stream.eat(/[\?\!]/); 110 | return "ident"; 111 | } else if (/[=+\-\/*^%<>~]/.test(ch)) { 112 | stream.eatWhile(/[=+\-\/*^%<>~]/); 113 | return "operator"; 114 | } else { 115 | return null; 116 | } 117 | } 118 | 119 | function readQuoted(quote, style, unescaped) { 120 | return function(stream, state) { 121 | var escaped = false, ch; 122 | while ((ch = stream.next()) != null) { 123 | if (ch == quote && (unescaped || !escaped)) { 124 | state.tokenize.pop(); 125 | break; 126 | } 127 | escaped = !escaped && ch == "%"; 128 | } 129 | return style; 130 | }; 131 | } 132 | 133 | return { 134 | startState: function() { 135 | return {tokenize: [tokenBase]}; 136 | }, 137 | 138 | token: function(stream, state) { 139 | var style = state.tokenize[state.tokenize.length-1](stream, state); 140 | if (style == "ident") { 141 | var word = stream.current(); 142 | style = keywords.propertyIsEnumerable(stream.current()) ? "keyword" 143 | : operators.propertyIsEnumerable(stream.current()) ? "operator" 144 | : /^[A-Z][A-Z_0-9]*$/g.test(word) ? "tag" 145 | : /^0[bB][0-1]+$/g.test(word) ? "number" 146 | : /^0[cC][0-7]+$/g.test(word) ? "number" 147 | : /^0[xX][a-fA-F0-9]+$/g.test(word) ? "number" 148 | : /^([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+)$/g.test(word) ? "number" 149 | : /^[0-9]+$/g.test(word) ? "number" 150 | : "variable"; 151 | } 152 | return style; 153 | }, 154 | lineComment: "--" 155 | }; 156 | }); 157 | 158 | CodeMirror.defineMIME("text/x-eiffel", "eiffel"); 159 | 160 | }); 161 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/factor.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | // Factor syntax highlight - simple mode 5 | // 6 | // by Dimage Sapelkin (https://github.com/kerabromsmu) 7 | 8 | (function(mod) { 9 | if (typeof exports == "object" && typeof module == "object") // CommonJS 10 | mod(require("../../lib/codemirror"), require("../../addon/mode/simple")); 11 | else if (typeof define == "function" && define.amd) // AMD 12 | define(["../../lib/codemirror", "../../addon/mode/simple"], mod); 13 | else // Plain browser env 14 | mod(CodeMirror); 15 | })(function(CodeMirror) { 16 | "use strict"; 17 | 18 | CodeMirror.defineSimpleMode("factor", { 19 | // The start state contains the rules that are intially used 20 | start: [ 21 | // comments 22 | {regex: /#?!.*/, token: "comment"}, 23 | // strings """, multiline --> state 24 | {regex: /"""/, token: "string", next: "string3"}, 25 | {regex: /"/, token: "string", next: "string"}, 26 | // numbers: dec, hex, unicode, bin, fractional, complex 27 | {regex: /(?:[+-]?)(?:0x[\d,a-f]+)|(?:0o[0-7]+)|(?:0b[0,1]+)|(?:\d+.?\d*)/, token: "number"}, 28 | //{regex: /[+-]?/} //fractional 29 | // definition: defining word, defined word, etc 30 | {regex: /(\:)(\s+)(\S+)(\s+)(\()/, token: ["keyword", null, "def", null, "keyword"], next: "stack"}, 31 | // vocabulary using --> state 32 | {regex: /USING\:/, token: "keyword", next: "vocabulary"}, 33 | // vocabulary definition/use 34 | {regex: /(USE\:|IN\:)(\s+)(\S+)/, token: ["keyword", null, "variable-2"]}, 35 | // 36 | {regex: /<\S+>/, token: "builtin"}, 37 | // "keywords", incl. ; t f . [ ] { } defining words 38 | {regex: /;|t|f|if|\.|\[|\]|\{|\}|MAIN:/, token: "keyword"}, 39 | // any id (?) 40 | {regex: /\S+/, token: "variable"}, 41 | 42 | { 43 | regex: /./, 44 | token: null 45 | } 46 | ], 47 | vocabulary: [ 48 | {regex: /;/, token: "keyword", next: "start"}, 49 | {regex: /\S+/, token: "variable-2"}, 50 | { 51 | regex: /./, 52 | token: null 53 | } 54 | ], 55 | string: [ 56 | {regex: /(?:[^\\]|\\.)*?"/, token: "string", next: "start"}, 57 | {regex: /.*/, token: "string"} 58 | ], 59 | string3: [ 60 | {regex: /(?:[^\\]|\\.)*?"""/, token: "string", next: "start"}, 61 | {regex: /.*/, token: "string"} 62 | ], 63 | stack: [ 64 | {regex: /\)/, token: "meta", next: "start"}, 65 | {regex: /--/, token: "meta"}, 66 | {regex: /\S+/, token: "variable-3"}, 67 | { 68 | regex: /./, 69 | token: null 70 | } 71 | ], 72 | // The meta property contains global information about the mode. It 73 | // can contain properties like lineComment, which are supported by 74 | // all modes, and also directives like dontIndentStates, which are 75 | // specific to simple modes. 76 | meta: { 77 | dontIndentStates: ["start", "vocabulary", "string", "string3", "stack"], 78 | lineComment: [ "!", "#!" ] 79 | } 80 | }); 81 | 82 | CodeMirror.defineMIME("text/x-factor", "factor"); 83 | }); 84 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/fcl.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("fcl", function(config) { 15 | var indentUnit = config.indentUnit; 16 | 17 | var keywords = { 18 | "term": true, 19 | "method": true, "accu": true, 20 | "rule": true, "then": true, "is": true, "and": true, "or": true, 21 | "if": true, "default": true 22 | }; 23 | 24 | var start_blocks = { 25 | "var_input": true, 26 | "var_output": true, 27 | "fuzzify": true, 28 | "defuzzify": true, 29 | "function_block": true, 30 | "ruleblock": true 31 | }; 32 | 33 | var end_blocks = { 34 | "end_ruleblock": true, 35 | "end_defuzzify": true, 36 | "end_function_block": true, 37 | "end_fuzzify": true, 38 | "end_var": true 39 | }; 40 | 41 | var atoms = { 42 | "true": true, "false": true, "nan": true, 43 | "real": true, "min": true, "max": true, "cog": true, "cogs": true 44 | }; 45 | 46 | var isOperatorChar = /[+\-*&^%:=<>!|\/]/; 47 | 48 | function tokenBase(stream, state) { 49 | var ch = stream.next(); 50 | 51 | if (/[\d\.]/.test(ch)) { 52 | if (ch == ".") { 53 | stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/); 54 | } else if (ch == "0") { 55 | stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/); 56 | } else { 57 | stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/); 58 | } 59 | return "number"; 60 | } 61 | 62 | if (ch == "/" || ch == "(") { 63 | if (stream.eat("*")) { 64 | state.tokenize = tokenComment; 65 | return tokenComment(stream, state); 66 | } 67 | if (stream.eat("/")) { 68 | stream.skipToEnd(); 69 | return "comment"; 70 | } 71 | } 72 | if (isOperatorChar.test(ch)) { 73 | stream.eatWhile(isOperatorChar); 74 | return "operator"; 75 | } 76 | stream.eatWhile(/[\w\$_\xa1-\uffff]/); 77 | 78 | var cur = stream.current().toLowerCase(); 79 | if (keywords.propertyIsEnumerable(cur) || 80 | start_blocks.propertyIsEnumerable(cur) || 81 | end_blocks.propertyIsEnumerable(cur)) { 82 | return "keyword"; 83 | } 84 | if (atoms.propertyIsEnumerable(cur)) return "atom"; 85 | return "variable"; 86 | } 87 | 88 | 89 | function tokenComment(stream, state) { 90 | var maybeEnd = false, ch; 91 | while (ch = stream.next()) { 92 | if ((ch == "/" || ch == ")") && maybeEnd) { 93 | state.tokenize = tokenBase; 94 | break; 95 | } 96 | maybeEnd = (ch == "*"); 97 | } 98 | return "comment"; 99 | } 100 | 101 | function Context(indented, column, type, align, prev) { 102 | this.indented = indented; 103 | this.column = column; 104 | this.type = type; 105 | this.align = align; 106 | this.prev = prev; 107 | } 108 | 109 | function pushContext(state, col, type) { 110 | return state.context = new Context(state.indented, col, type, null, state.context); 111 | } 112 | 113 | function popContext(state) { 114 | if (!state.context.prev) return; 115 | var t = state.context.type; 116 | if (t == "end_block") 117 | state.indented = state.context.indented; 118 | return state.context = state.context.prev; 119 | } 120 | 121 | // Interface 122 | 123 | return { 124 | startState: function(basecolumn) { 125 | return { 126 | tokenize: null, 127 | context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), 128 | indented: 0, 129 | startOfLine: true 130 | }; 131 | }, 132 | 133 | token: function(stream, state) { 134 | var ctx = state.context; 135 | if (stream.sol()) { 136 | if (ctx.align == null) ctx.align = false; 137 | state.indented = stream.indentation(); 138 | state.startOfLine = true; 139 | } 140 | if (stream.eatSpace()) return null; 141 | 142 | var style = (state.tokenize || tokenBase)(stream, state); 143 | if (style == "comment") return style; 144 | if (ctx.align == null) ctx.align = true; 145 | 146 | var cur = stream.current().toLowerCase(); 147 | 148 | if (start_blocks.propertyIsEnumerable(cur)) pushContext(state, stream.column(), "end_block"); 149 | else if (end_blocks.propertyIsEnumerable(cur)) popContext(state); 150 | 151 | state.startOfLine = false; 152 | return style; 153 | }, 154 | 155 | indent: function(state, textAfter) { 156 | if (state.tokenize != tokenBase && state.tokenize != null) return 0; 157 | var ctx = state.context; 158 | 159 | var closing = end_blocks.propertyIsEnumerable(textAfter); 160 | if (ctx.align) return ctx.column + (closing ? 0 : 1); 161 | else return ctx.indented + (closing ? 0 : indentUnit); 162 | }, 163 | 164 | electricChars: "ryk", 165 | fold: "brace", 166 | blockCommentStart: "(*", 167 | blockCommentEnd: "*)", 168 | lineComment: "//" 169 | }; 170 | }); 171 | 172 | CodeMirror.defineMIME("text/x-fcl", "fcl"); 173 | }); 174 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/gfm.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("../markdown/markdown"), require("../../addon/mode/overlay")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "../markdown/markdown", "../../addon/mode/overlay"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | var urlRE = /^((?:(?:aaas?|about|acap|adiumxtra|af[ps]|aim|apt|attachment|aw|beshare|bitcoin|bolo|callto|cap|chrome(?:-extension)?|cid|coap|com-eventbrite-attendee|content|crid|cvs|data|dav|dict|dlna-(?:playcontainer|playsingle)|dns|doi|dtn|dvb|ed2k|facetime|feed|file|finger|fish|ftp|geo|gg|git|gizmoproject|go|gopher|gtalk|h323|hcp|https?|iax|icap|icon|im|imap|info|ipn|ipp|irc[6s]?|iris(?:\.beep|\.lwz|\.xpc|\.xpcs)?|itms|jar|javascript|jms|keyparc|lastfm|ldaps?|magnet|mailto|maps|market|message|mid|mms|ms-help|msnim|msrps?|mtqp|mumble|mupdate|mvn|news|nfs|nih?|nntp|notes|oid|opaquelocktoken|palm|paparazzi|platform|pop|pres|proxy|psyc|query|res(?:ource)?|rmi|rsync|rtmp|rtsp|secondlife|service|session|sftp|sgn|shttp|sieve|sips?|skype|sm[bs]|snmp|soap\.beeps?|soldat|spotify|ssh|steam|svn|tag|teamspeak|tel(?:net)?|tftp|things|thismessage|tip|tn3270|tv|udp|unreal|urn|ut2004|vemmi|ventrilo|view-source|webcal|wss?|wtai|wyciwyg|xcon(?:-userid)?|xfire|xmlrpc\.beeps?|xmpp|xri|ymsgr|z39\.50[rs]?):(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i 15 | 16 | CodeMirror.defineMode("gfm", function(config, modeConfig) { 17 | var codeDepth = 0; 18 | function blankLine(state) { 19 | state.code = false; 20 | return null; 21 | } 22 | var gfmOverlay = { 23 | startState: function() { 24 | return { 25 | code: false, 26 | codeBlock: false, 27 | ateSpace: false 28 | }; 29 | }, 30 | copyState: function(s) { 31 | return { 32 | code: s.code, 33 | codeBlock: s.codeBlock, 34 | ateSpace: s.ateSpace 35 | }; 36 | }, 37 | token: function(stream, state) { 38 | state.combineTokens = null; 39 | 40 | // Hack to prevent formatting override inside code blocks (block and inline) 41 | if (state.codeBlock) { 42 | if (stream.match(/^```+/)) { 43 | state.codeBlock = false; 44 | return null; 45 | } 46 | stream.skipToEnd(); 47 | return null; 48 | } 49 | if (stream.sol()) { 50 | state.code = false; 51 | } 52 | if (stream.sol() && stream.match(/^```+/)) { 53 | stream.skipToEnd(); 54 | state.codeBlock = true; 55 | return null; 56 | } 57 | // If this block is changed, it may need to be updated in Markdown mode 58 | if (stream.peek() === '`') { 59 | stream.next(); 60 | var before = stream.pos; 61 | stream.eatWhile('`'); 62 | var difference = 1 + stream.pos - before; 63 | if (!state.code) { 64 | codeDepth = difference; 65 | state.code = true; 66 | } else { 67 | if (difference === codeDepth) { // Must be exact 68 | state.code = false; 69 | } 70 | } 71 | return null; 72 | } else if (state.code) { 73 | stream.next(); 74 | return null; 75 | } 76 | // Check if space. If so, links can be formatted later on 77 | if (stream.eatSpace()) { 78 | state.ateSpace = true; 79 | return null; 80 | } 81 | if (stream.sol() || state.ateSpace) { 82 | state.ateSpace = false; 83 | if (modeConfig.gitHubSpice !== false) { 84 | if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?:[a-f0-9]{7,40}\b)/)) { 85 | // User/Project@SHA 86 | // User@SHA 87 | // SHA 88 | state.combineTokens = true; 89 | return "link"; 90 | } else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) { 91 | // User/Project#Num 92 | // User#Num 93 | // #Num 94 | state.combineTokens = true; 95 | return "link"; 96 | } 97 | } 98 | } 99 | if (stream.match(urlRE) && 100 | stream.string.slice(stream.start - 2, stream.start) != "](" && 101 | (stream.start == 0 || /\W/.test(stream.string.charAt(stream.start - 1)))) { 102 | // URLs 103 | // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls 104 | // And then (issue #1160) simplified to make it not crash the Chrome Regexp engine 105 | // And then limited url schemes to the CommonMark list, so foo:bar isn't matched as a URL 106 | state.combineTokens = true; 107 | return "link"; 108 | } 109 | stream.next(); 110 | return null; 111 | }, 112 | blankLine: blankLine 113 | }; 114 | 115 | var markdownConfig = { 116 | underscoresBreakWords: false, 117 | taskLists: true, 118 | fencedCodeBlocks: '```', 119 | strikethrough: true 120 | }; 121 | for (var attr in modeConfig) { 122 | markdownConfig[attr] = modeConfig[attr]; 123 | } 124 | markdownConfig.name = "markdown"; 125 | return CodeMirror.overlayMode(CodeMirror.getMode(config, markdownConfig), gfmOverlay); 126 | 127 | }, "markdown"); 128 | 129 | CodeMirror.defineMIME("text/x-gfm", "gfm"); 130 | }); 131 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/gss_test.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function() { 5 | "use strict"; 6 | 7 | var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-gss"); 8 | function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "gss"); } 9 | 10 | MT("atComponent", 11 | "[def @component] {", 12 | "[tag foo] {", 13 | " [property color]: [keyword black];", 14 | "}", 15 | "}"); 16 | 17 | })(); 18 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/handlebars.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("../../addon/mode/simple"), require("../../addon/mode/multiplex")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "../../addon/mode/simple", "../../addon/mode/multiplex"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineSimpleMode("handlebars-tags", { 15 | start: [ 16 | { regex: /\{\{!--/, push: "dash_comment", token: "comment" }, 17 | { regex: /\{\{!/, push: "comment", token: "comment" }, 18 | { regex: /\{\{/, push: "handlebars", token: "tag" } 19 | ], 20 | handlebars: [ 21 | { regex: /\}\}/, pop: true, token: "tag" }, 22 | 23 | // Double and single quotes 24 | { regex: /"(?:[^\\"]|\\.)*"?/, token: "string" }, 25 | { regex: /'(?:[^\\']|\\.)*'?/, token: "string" }, 26 | 27 | // Handlebars keywords 28 | { regex: />|[#\/]([A-Za-z_]\w*)/, token: "keyword" }, 29 | { regex: /(?:else|this)\b/, token: "keyword" }, 30 | 31 | // Numeral 32 | { regex: /\d+/i, token: "number" }, 33 | 34 | // Atoms like = and . 35 | { regex: /=|~|@|true|false/, token: "atom" }, 36 | 37 | // Paths 38 | { regex: /(?:\.\.\/)*(?:[A-Za-z_][\w\.]*)+/, token: "variable-2" } 39 | ], 40 | dash_comment: [ 41 | { regex: /--\}\}/, pop: true, token: "comment" }, 42 | 43 | // Commented code 44 | { regex: /./, token: "comment"} 45 | ], 46 | comment: [ 47 | { regex: /\}\}/, pop: true, token: "comment" }, 48 | { regex: /./, token: "comment" } 49 | ] 50 | }); 51 | 52 | CodeMirror.defineMode("handlebars", function(config, parserConfig) { 53 | var handlebars = CodeMirror.getMode(config, "handlebars-tags"); 54 | if (!parserConfig || !parserConfig.base) return handlebars; 55 | return CodeMirror.multiplexingMode( 56 | CodeMirror.getMode(config, parserConfig.base), 57 | {open: "{{", close: "}}", mode: handlebars, parseDelimiters: true} 58 | ); 59 | }); 60 | 61 | CodeMirror.defineMIME("text/x-handlebars-template", "handlebars"); 62 | }); 63 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/haskell-literate.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function (mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("../haskell/haskell")) 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "../haskell/haskell"], mod) 9 | else // Plain browser env 10 | mod(CodeMirror) 11 | })(function (CodeMirror) { 12 | "use strict" 13 | 14 | CodeMirror.defineMode("haskell-literate", function (config, parserConfig) { 15 | var baseMode = CodeMirror.getMode(config, (parserConfig && parserConfig.base) || "haskell") 16 | 17 | return { 18 | startState: function () { 19 | return { 20 | inCode: false, 21 | baseState: CodeMirror.startState(baseMode) 22 | } 23 | }, 24 | token: function (stream, state) { 25 | if (stream.sol()) { 26 | if (state.inCode = stream.eat(">")) 27 | return "meta" 28 | } 29 | if (state.inCode) { 30 | return baseMode.token(stream, state.baseState) 31 | } else { 32 | stream.skipToEnd() 33 | return "comment" 34 | } 35 | }, 36 | innerMode: function (state) { 37 | return state.inCode ? {state: state.baseState, mode: baseMode} : null 38 | } 39 | } 40 | }, "haskell") 41 | 42 | CodeMirror.defineMIME("text/x-literate-haskell", "haskell-literate") 43 | }); 44 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/htmlembedded.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), 7 | require("../../addon/mode/multiplex")); 8 | else if (typeof define == "function" && define.amd) // AMD 9 | define(["../../lib/codemirror", "../htmlmixed/htmlmixed", 10 | "../../addon/mode/multiplex"], mod); 11 | else // Plain browser env 12 | mod(CodeMirror); 13 | })(function(CodeMirror) { 14 | "use strict"; 15 | 16 | CodeMirror.defineMode("htmlembedded", function(config, parserConfig) { 17 | return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), { 18 | open: parserConfig.open || parserConfig.scriptStartRegex || "<%", 19 | close: parserConfig.close || parserConfig.scriptEndRegex || "%>", 20 | mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec) 21 | }); 22 | }, "htmlmixed"); 23 | 24 | CodeMirror.defineMIME("application/x-ejs", {name: "htmlembedded", scriptingModeSpec:"javascript"}); 25 | CodeMirror.defineMIME("application/x-aspx", {name: "htmlembedded", scriptingModeSpec:"text/x-csharp"}); 26 | CodeMirror.defineMIME("application/x-jsp", {name: "htmlembedded", scriptingModeSpec:"text/x-java"}); 27 | CodeMirror.defineMIME("application/x-erb", {name: "htmlembedded", scriptingModeSpec:"ruby"}); 28 | }); 29 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/http.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("http", function() { 15 | function failFirstLine(stream, state) { 16 | stream.skipToEnd(); 17 | state.cur = header; 18 | return "error"; 19 | } 20 | 21 | function start(stream, state) { 22 | if (stream.match(/^HTTP\/\d\.\d/)) { 23 | state.cur = responseStatusCode; 24 | return "keyword"; 25 | } else if (stream.match(/^[A-Z]+/) && /[ \t]/.test(stream.peek())) { 26 | state.cur = requestPath; 27 | return "keyword"; 28 | } else { 29 | return failFirstLine(stream, state); 30 | } 31 | } 32 | 33 | function responseStatusCode(stream, state) { 34 | var code = stream.match(/^\d+/); 35 | if (!code) return failFirstLine(stream, state); 36 | 37 | state.cur = responseStatusText; 38 | var status = Number(code[0]); 39 | if (status >= 100 && status < 200) { 40 | return "positive informational"; 41 | } else if (status >= 200 && status < 300) { 42 | return "positive success"; 43 | } else if (status >= 300 && status < 400) { 44 | return "positive redirect"; 45 | } else if (status >= 400 && status < 500) { 46 | return "negative client-error"; 47 | } else if (status >= 500 && status < 600) { 48 | return "negative server-error"; 49 | } else { 50 | return "error"; 51 | } 52 | } 53 | 54 | function responseStatusText(stream, state) { 55 | stream.skipToEnd(); 56 | state.cur = header; 57 | return null; 58 | } 59 | 60 | function requestPath(stream, state) { 61 | stream.eatWhile(/\S/); 62 | state.cur = requestProtocol; 63 | return "string-2"; 64 | } 65 | 66 | function requestProtocol(stream, state) { 67 | if (stream.match(/^HTTP\/\d\.\d$/)) { 68 | state.cur = header; 69 | return "keyword"; 70 | } else { 71 | return failFirstLine(stream, state); 72 | } 73 | } 74 | 75 | function header(stream) { 76 | if (stream.sol() && !stream.eat(/[ \t]/)) { 77 | if (stream.match(/^.*?:/)) { 78 | return "atom"; 79 | } else { 80 | stream.skipToEnd(); 81 | return "error"; 82 | } 83 | } else { 84 | stream.skipToEnd(); 85 | return "string"; 86 | } 87 | } 88 | 89 | function body(stream) { 90 | stream.skipToEnd(); 91 | return null; 92 | } 93 | 94 | return { 95 | token: function(stream, state) { 96 | var cur = state.cur; 97 | if (cur != header && cur != body && stream.eatSpace()) return null; 98 | return cur(stream, state); 99 | }, 100 | 101 | blankLine: function(state) { 102 | state.cur = body; 103 | }, 104 | 105 | startState: function() { 106 | return {cur: start}; 107 | } 108 | }; 109 | }); 110 | 111 | CodeMirror.defineMIME("message/http", "http"); 112 | 113 | }); 114 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/jinja2.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("jinja2", function() { 15 | var keywords = ["and", "as", "block", "endblock", "by", "cycle", "debug", "else", "elif", 16 | "extends", "filter", "endfilter", "firstof", "for", 17 | "endfor", "if", "endif", "ifchanged", "endifchanged", 18 | "ifequal", "endifequal", "ifnotequal", 19 | "endifnotequal", "in", "include", "load", "not", "now", "or", 20 | "parsed", "regroup", "reversed", "spaceless", 21 | "endspaceless", "ssi", "templatetag", "openblock", 22 | "closeblock", "openvariable", "closevariable", 23 | "openbrace", "closebrace", "opencomment", 24 | "closecomment", "widthratio", "url", "with", "endwith", 25 | "get_current_language", "trans", "endtrans", "noop", "blocktrans", 26 | "endblocktrans", "get_available_languages", 27 | "get_current_language_bidi", "plural"], 28 | operator = /^[+\-*&%=<>!?|~^]/, 29 | sign = /^[:\[\(\{]/, 30 | atom = ["true", "false"], 31 | number = /^(\d[+\-\*\/])?\d+(\.\d+)?/; 32 | 33 | keywords = new RegExp("((" + keywords.join(")|(") + "))\\b"); 34 | atom = new RegExp("((" + atom.join(")|(") + "))\\b"); 35 | 36 | function tokenBase (stream, state) { 37 | var ch = stream.peek(); 38 | 39 | //Comment 40 | if (state.incomment) { 41 | if(!stream.skipTo("#}")) { 42 | stream.skipToEnd(); 43 | } else { 44 | stream.eatWhile(/\#|}/); 45 | state.incomment = false; 46 | } 47 | return "comment"; 48 | //Tag 49 | } else if (state.intag) { 50 | //After operator 51 | if(state.operator) { 52 | state.operator = false; 53 | if(stream.match(atom)) { 54 | return "atom"; 55 | } 56 | if(stream.match(number)) { 57 | return "number"; 58 | } 59 | } 60 | //After sign 61 | if(state.sign) { 62 | state.sign = false; 63 | if(stream.match(atom)) { 64 | return "atom"; 65 | } 66 | if(stream.match(number)) { 67 | return "number"; 68 | } 69 | } 70 | 71 | if(state.instring) { 72 | if(ch == state.instring) { 73 | state.instring = false; 74 | } 75 | stream.next(); 76 | return "string"; 77 | } else if(ch == "'" || ch == '"') { 78 | state.instring = ch; 79 | stream.next(); 80 | return "string"; 81 | } else if(stream.match(state.intag + "}") || stream.eat("-") && stream.match(state.intag + "}")) { 82 | state.intag = false; 83 | return "tag"; 84 | } else if(stream.match(operator)) { 85 | state.operator = true; 86 | return "operator"; 87 | } else if(stream.match(sign)) { 88 | state.sign = true; 89 | } else { 90 | if(stream.eat(" ") || stream.sol()) { 91 | if(stream.match(keywords)) { 92 | return "keyword"; 93 | } 94 | if(stream.match(atom)) { 95 | return "atom"; 96 | } 97 | if(stream.match(number)) { 98 | return "number"; 99 | } 100 | if(stream.sol()) { 101 | stream.next(); 102 | } 103 | } else { 104 | stream.next(); 105 | } 106 | 107 | } 108 | return "variable"; 109 | } else if (stream.eat("{")) { 110 | if (ch = stream.eat("#")) { 111 | state.incomment = true; 112 | if(!stream.skipTo("#}")) { 113 | stream.skipToEnd(); 114 | } else { 115 | stream.eatWhile(/\#|}/); 116 | state.incomment = false; 117 | } 118 | return "comment"; 119 | //Open tag 120 | } else if (ch = stream.eat(/\{|%/)) { 121 | //Cache close tag 122 | state.intag = ch; 123 | if(ch == "{") { 124 | state.intag = "}"; 125 | } 126 | stream.eat("-"); 127 | return "tag"; 128 | } 129 | } 130 | stream.next(); 131 | }; 132 | 133 | return { 134 | startState: function () { 135 | return {tokenize: tokenBase}; 136 | }, 137 | token: function (stream, state) { 138 | return state.tokenize(stream, state); 139 | } 140 | }; 141 | }); 142 | }); 143 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/less_test.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function() { 5 | "use strict"; 6 | 7 | var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-less"); 8 | function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "less"); } 9 | 10 | MT("variable", 11 | "[variable-2 @base]: [atom #f04615];", 12 | "[qualifier .class] {", 13 | " [property width]: [variable percentage]([number 0.5]); [comment // returns `50%`]", 14 | " [property color]: [variable saturate]([variable-2 @base], [number 5%]);", 15 | "}"); 16 | 17 | MT("amp", 18 | "[qualifier .child], [qualifier .sibling] {", 19 | " [qualifier .parent] [atom &] {", 20 | " [property color]: [keyword black];", 21 | " }", 22 | " [atom &] + [atom &] {", 23 | " [property color]: [keyword red];", 24 | " }", 25 | "}"); 26 | 27 | MT("mixin", 28 | "[qualifier .mixin] ([variable dark]; [variable-2 @color]) {", 29 | " [property color]: [atom darken]([variable-2 @color], [number 10%]);", 30 | "}", 31 | "[qualifier .mixin] ([variable light]; [variable-2 @color]) {", 32 | " [property color]: [atom lighten]([variable-2 @color], [number 10%]);", 33 | "}", 34 | "[qualifier .mixin] ([variable-2 @_]; [variable-2 @color]) {", 35 | " [property display]: [atom block];", 36 | "}", 37 | "[variable-2 @switch]: [variable light];", 38 | "[qualifier .class] {", 39 | " [qualifier .mixin]([variable-2 @switch]; [atom #888]);", 40 | "}"); 41 | 42 | MT("nest", 43 | "[qualifier .one] {", 44 | " [def @media] ([property width]: [number 400px]) {", 45 | " [property font-size]: [number 1.2em];", 46 | " [def @media] [attribute print] [keyword and] [property color] {", 47 | " [property color]: [keyword blue];", 48 | " }", 49 | " }", 50 | "}"); 51 | 52 | 53 | MT("interpolation", ".@{[variable foo]} { [property font-weight]: [atom bold]; }"); 54 | })(); 55 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/mbox.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | var rfc2822 = [ 15 | "From", "Sender", "Reply-To", "To", "Cc", "Bcc", "Message-ID", 16 | "In-Reply-To", "References", "Resent-From", "Resent-Sender", "Resent-To", 17 | "Resent-Cc", "Resent-Bcc", "Resent-Message-ID", "Return-Path", "Received" 18 | ]; 19 | var rfc2822NoEmail = [ 20 | "Date", "Subject", "Comments", "Keywords", "Resent-Date" 21 | ]; 22 | 23 | CodeMirror.registerHelper("hintWords", "mbox", rfc2822.concat(rfc2822NoEmail)); 24 | 25 | var whitespace = /^[ \t]/; 26 | var separator = /^From /; // See RFC 4155 27 | var rfc2822Header = new RegExp("^(" + rfc2822.join("|") + "): "); 28 | var rfc2822HeaderNoEmail = new RegExp("^(" + rfc2822NoEmail.join("|") + "): "); 29 | var header = /^[^:]+:/; // Optional fields defined in RFC 2822 30 | var email = /^[^ ]+@[^ ]+/; 31 | var untilEmail = /^.*?(?=[^ ]+?@[^ ]+)/; 32 | var bracketedEmail = /^<.*?>/; 33 | var untilBracketedEmail = /^.*?(?=<.*>)/; 34 | 35 | function styleForHeader(header) { 36 | if (header === "Subject") return "header"; 37 | return "string"; 38 | } 39 | 40 | function readToken(stream, state) { 41 | if (stream.sol()) { 42 | // From last line 43 | state.inSeparator = false; 44 | if (state.inHeader && stream.match(whitespace)) { 45 | // Header folding 46 | return null; 47 | } else { 48 | state.inHeader = false; 49 | state.header = null; 50 | } 51 | 52 | if (stream.match(separator)) { 53 | state.inHeaders = true; 54 | state.inSeparator = true; 55 | return "atom"; 56 | } 57 | 58 | var match; 59 | var emailPermitted = false; 60 | if ((match = stream.match(rfc2822HeaderNoEmail)) || 61 | (emailPermitted = true) && (match = stream.match(rfc2822Header))) { 62 | state.inHeaders = true; 63 | state.inHeader = true; 64 | state.emailPermitted = emailPermitted; 65 | state.header = match[1]; 66 | return "atom"; 67 | } 68 | 69 | // Use vim's heuristics: recognize custom headers only if the line is in a 70 | // block of legitimate headers. 71 | if (state.inHeaders && (match = stream.match(header))) { 72 | state.inHeader = true; 73 | state.emailPermitted = true; 74 | state.header = match[1]; 75 | return "atom"; 76 | } 77 | 78 | state.inHeaders = false; 79 | stream.skipToEnd(); 80 | return null; 81 | } 82 | 83 | if (state.inSeparator) { 84 | if (stream.match(email)) return "link"; 85 | if (stream.match(untilEmail)) return "atom"; 86 | stream.skipToEnd(); 87 | return "atom"; 88 | } 89 | 90 | if (state.inHeader) { 91 | var style = styleForHeader(state.header); 92 | 93 | if (state.emailPermitted) { 94 | if (stream.match(bracketedEmail)) return style + " link"; 95 | if (stream.match(untilBracketedEmail)) return style; 96 | } 97 | stream.skipToEnd(); 98 | return style; 99 | } 100 | 101 | stream.skipToEnd(); 102 | return null; 103 | }; 104 | 105 | CodeMirror.defineMode("mbox", function() { 106 | return { 107 | startState: function() { 108 | return { 109 | // Is in a mbox separator 110 | inSeparator: false, 111 | // Is in a mail header 112 | inHeader: false, 113 | // If bracketed email is permitted. Only applicable when inHeader 114 | emailPermitted: false, 115 | // Name of current header 116 | header: null, 117 | // Is in a region of mail headers 118 | inHeaders: false 119 | }; 120 | }, 121 | token: readToken, 122 | blankLine: function(state) { 123 | state.inHeaders = state.inSeparator = state.inHeader = false; 124 | } 125 | }; 126 | }); 127 | 128 | CodeMirror.defineMIME("application/mbox", "mbox"); 129 | }); 130 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/mscgen_test.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function() { 5 | var mode = CodeMirror.getMode({indentUnit: 2}, "mscgen"); 6 | function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } 7 | 8 | MT("empty chart", 9 | "[keyword msc][bracket {]", 10 | "[base ]", 11 | "[bracket }]" 12 | ); 13 | 14 | MT("comments", 15 | "[comment // a single line comment]", 16 | "[comment # another single line comment /* and */ ignored here]", 17 | "[comment /* A multi-line comment even though it contains]", 18 | "[comment msc keywords and \"quoted text\"*/]"); 19 | 20 | MT("strings", 21 | "[string \"// a string\"]", 22 | "[string \"a string running over]", 23 | "[string two lines\"]", 24 | "[string \"with \\\"escaped quote\"]" 25 | ); 26 | 27 | MT("xù/ msgenny keywords classify as 'base'", 28 | "[base watermark]", 29 | "[base alt loop opt ref else break par seq assert]" 30 | ); 31 | 32 | MT("mscgen options classify as keyword", 33 | "[keyword hscale]", "[keyword width]", "[keyword arcgradient]", "[keyword wordwraparcs]" 34 | ); 35 | 36 | MT("mscgen arcs classify as keyword", 37 | "[keyword note]","[keyword abox]","[keyword rbox]","[keyword box]", 38 | "[keyword |||...---]", "[keyword ..--==::]", 39 | "[keyword ->]", "[keyword <-]", "[keyword <->]", 40 | "[keyword =>]", "[keyword <=]", "[keyword <=>]", 41 | "[keyword =>>]", "[keyword <<=]", "[keyword <<=>>]", 42 | "[keyword >>]", "[keyword <<]", "[keyword <<>>]", 43 | "[keyword -x]", "[keyword x-]", "[keyword -X]", "[keyword X-]", 44 | "[keyword :>]", "[keyword <:]", "[keyword <:>]" 45 | ); 46 | 47 | MT("within an attribute list, attributes classify as attribute", 48 | "[bracket [[][attribute label]", 49 | "[attribute id]","[attribute url]","[attribute idurl]", 50 | "[attribute linecolor]","[attribute linecolour]","[attribute textcolor]","[attribute textcolour]","[attribute textbgcolor]","[attribute textbgcolour]", 51 | "[attribute arclinecolor]","[attribute arclinecolour]","[attribute arctextcolor]","[attribute arctextcolour]","[attribute arctextbgcolor]","[attribute arctextbgcolour]", 52 | "[attribute arcskip][bracket ]]]" 53 | ); 54 | 55 | MT("outside an attribute list, attributes classify as base", 56 | "[base label]", 57 | "[base id]","[base url]","[base idurl]", 58 | "[base linecolor]","[base linecolour]","[base textcolor]","[base textcolour]","[base textbgcolor]","[base textbgcolour]", 59 | "[base arclinecolor]","[base arclinecolour]","[base arctextcolor]","[base arctextcolour]","[base arctextbgcolor]","[base arctextbgcolour]", 60 | "[base arcskip]" 61 | ); 62 | 63 | MT("a typical program", 64 | "[comment # typical mscgen program]", 65 | "[keyword msc][base ][bracket {]", 66 | "[keyword wordwraparcs][operator =][string \"true\"][base , ][keyword hscale][operator =][string \"0.8\"][keyword arcgradient][operator =][base 30;]", 67 | "[base a][bracket [[][attribute label][operator =][string \"Entity A\"][bracket ]]][base ,]", 68 | "[base b][bracket [[][attribute label][operator =][string \"Entity B\"][bracket ]]][base ,]", 69 | "[base c][bracket [[][attribute label][operator =][string \"Entity C\"][bracket ]]][base ;]", 70 | "[base a ][keyword =>>][base b][bracket [[][attribute label][operator =][string \"Hello entity B\"][bracket ]]][base ;]", 71 | "[base a ][keyword <<][base b][bracket [[][attribute label][operator =][string \"Here's an answer dude!\"][bracket ]]][base ;]", 72 | "[base c ][keyword :>][base *][bracket [[][attribute label][operator =][string \"What about me?\"][base , ][attribute textcolor][operator =][base red][bracket ]]][base ;]", 73 | "[bracket }]" 74 | ); 75 | })(); 76 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/msgenny_test.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function() { 5 | var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-msgenny"); 6 | function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "msgenny"); } 7 | 8 | MT("comments", 9 | "[comment // a single line comment]", 10 | "[comment # another single line comment /* and */ ignored here]", 11 | "[comment /* A multi-line comment even though it contains]", 12 | "[comment msc keywords and \"quoted text\"*/]"); 13 | 14 | MT("strings", 15 | "[string \"// a string\"]", 16 | "[string \"a string running over]", 17 | "[string two lines\"]", 18 | "[string \"with \\\"escaped quote\"]" 19 | ); 20 | 21 | MT("xù/ msgenny keywords classify as 'keyword'", 22 | "[keyword watermark]", 23 | "[keyword alt]","[keyword loop]","[keyword opt]","[keyword ref]","[keyword else]","[keyword break]","[keyword par]","[keyword seq]","[keyword assert]" 24 | ); 25 | 26 | MT("mscgen options classify as keyword", 27 | "[keyword hscale]", "[keyword width]", "[keyword arcgradient]", "[keyword wordwraparcs]" 28 | ); 29 | 30 | MT("mscgen arcs classify as keyword", 31 | "[keyword note]","[keyword abox]","[keyword rbox]","[keyword box]", 32 | "[keyword |||...---]", "[keyword ..--==::]", 33 | "[keyword ->]", "[keyword <-]", "[keyword <->]", 34 | "[keyword =>]", "[keyword <=]", "[keyword <=>]", 35 | "[keyword =>>]", "[keyword <<=]", "[keyword <<=>>]", 36 | "[keyword >>]", "[keyword <<]", "[keyword <<>>]", 37 | "[keyword -x]", "[keyword x-]", "[keyword -X]", "[keyword X-]", 38 | "[keyword :>]", "[keyword <:]", "[keyword <:>]" 39 | ); 40 | 41 | MT("within an attribute list, mscgen/ xù attributes classify as base", 42 | "[base [[label]", 43 | "[base idurl id url]", 44 | "[base linecolor linecolour textcolor textcolour textbgcolor textbgcolour]", 45 | "[base arclinecolor arclinecolour arctextcolor arctextcolour arctextbgcolor arctextbgcolour]", 46 | "[base arcskip]]]" 47 | ); 48 | 49 | MT("outside an attribute list, mscgen/ xù attributes classify as base", 50 | "[base label]", 51 | "[base idurl id url]", 52 | "[base linecolor linecolour textcolor textcolour textbgcolor textbgcolour]", 53 | "[base arclinecolor arclinecolour arctextcolor arctextcolour arctextbgcolor arctextbgcolour]", 54 | "[base arcskip]" 55 | ); 56 | 57 | MT("a typical program", 58 | "[comment # typical msgenny program]", 59 | "[keyword wordwraparcs][operator =][string \"true\"][base , ][keyword hscale][operator =][string \"0.8\"][base , ][keyword arcgradient][operator =][base 30;]", 60 | "[base a : ][string \"Entity A\"][base ,]", 61 | "[base b : Entity B,]", 62 | "[base c : Entity C;]", 63 | "[base a ][keyword =>>][base b: ][string \"Hello entity B\"][base ;]", 64 | "[base a ][keyword alt][base c][bracket {]", 65 | "[base a ][keyword <<][base b: ][string \"Here's an answer dude!\"][base ;]", 66 | "[keyword ---][base : ][string \"sorry, won't march - comm glitch\"]", 67 | "[base a ][keyword x-][base b: ][string \"Here's an answer dude! (won't arrive...)\"][base ;]", 68 | "[bracket }]", 69 | "[base c ][keyword :>][base *: What about me?;]" 70 | ); 71 | })(); 72 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/octave.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("octave", function() { 15 | function wordRegexp(words) { 16 | return new RegExp("^((" + words.join(")|(") + "))\\b"); 17 | } 18 | 19 | var singleOperators = new RegExp("^[\\+\\-\\*/&|\\^~<>!@'\\\\]"); 20 | var singleDelimiters = new RegExp('^[\\(\\[\\{\\},:=;]'); 21 | var doubleOperators = new RegExp("^((==)|(~=)|(<=)|(>=)|(<<)|(>>)|(\\.[\\+\\-\\*/\\^\\\\]))"); 22 | var doubleDelimiters = new RegExp("^((!=)|(\\+=)|(\\-=)|(\\*=)|(/=)|(&=)|(\\|=)|(\\^=))"); 23 | var tripleDelimiters = new RegExp("^((>>=)|(<<=))"); 24 | var expressionEnd = new RegExp("^[\\]\\)]"); 25 | var identifiers = new RegExp("^[_A-Za-z\xa1-\uffff][_A-Za-z0-9\xa1-\uffff]*"); 26 | 27 | var builtins = wordRegexp([ 28 | 'error', 'eval', 'function', 'abs', 'acos', 'atan', 'asin', 'cos', 29 | 'cosh', 'exp', 'log', 'prod', 'sum', 'log10', 'max', 'min', 'sign', 'sin', 'sinh', 30 | 'sqrt', 'tan', 'reshape', 'break', 'zeros', 'default', 'margin', 'round', 'ones', 31 | 'rand', 'syn', 'ceil', 'floor', 'size', 'clear', 'zeros', 'eye', 'mean', 'std', 'cov', 32 | 'det', 'eig', 'inv', 'norm', 'rank', 'trace', 'expm', 'logm', 'sqrtm', 'linspace', 'plot', 33 | 'title', 'xlabel', 'ylabel', 'legend', 'text', 'grid', 'meshgrid', 'mesh', 'num2str', 34 | 'fft', 'ifft', 'arrayfun', 'cellfun', 'input', 'fliplr', 'flipud', 'ismember' 35 | ]); 36 | 37 | var keywords = wordRegexp([ 38 | 'return', 'case', 'switch', 'else', 'elseif', 'end', 'endif', 'endfunction', 39 | 'if', 'otherwise', 'do', 'for', 'while', 'try', 'catch', 'classdef', 'properties', 'events', 40 | 'methods', 'global', 'persistent', 'endfor', 'endwhile', 'printf', 'sprintf', 'disp', 'until', 41 | 'continue', 'pkg' 42 | ]); 43 | 44 | 45 | // tokenizers 46 | function tokenTranspose(stream, state) { 47 | if (!stream.sol() && stream.peek() === '\'') { 48 | stream.next(); 49 | state.tokenize = tokenBase; 50 | return 'operator'; 51 | } 52 | state.tokenize = tokenBase; 53 | return tokenBase(stream, state); 54 | } 55 | 56 | 57 | function tokenComment(stream, state) { 58 | if (stream.match(/^.*%}/)) { 59 | state.tokenize = tokenBase; 60 | return 'comment'; 61 | }; 62 | stream.skipToEnd(); 63 | return 'comment'; 64 | } 65 | 66 | function tokenBase(stream, state) { 67 | // whitespaces 68 | if (stream.eatSpace()) return null; 69 | 70 | // Handle one line Comments 71 | if (stream.match('%{')){ 72 | state.tokenize = tokenComment; 73 | stream.skipToEnd(); 74 | return 'comment'; 75 | } 76 | 77 | if (stream.match(/^[%#]/)){ 78 | stream.skipToEnd(); 79 | return 'comment'; 80 | } 81 | 82 | // Handle Number Literals 83 | if (stream.match(/^[0-9\.+-]/, false)) { 84 | if (stream.match(/^[+-]?0x[0-9a-fA-F]+[ij]?/)) { 85 | stream.tokenize = tokenBase; 86 | return 'number'; }; 87 | if (stream.match(/^[+-]?\d*\.\d+([EeDd][+-]?\d+)?[ij]?/)) { return 'number'; }; 88 | if (stream.match(/^[+-]?\d+([EeDd][+-]?\d+)?[ij]?/)) { return 'number'; }; 89 | } 90 | if (stream.match(wordRegexp(['nan','NaN','inf','Inf']))) { return 'number'; }; 91 | 92 | // Handle Strings 93 | if (stream.match(/^"([^"]|(""))*"/)) { return 'string'; } ; 94 | if (stream.match(/^'([^']|(''))*'/)) { return 'string'; } ; 95 | 96 | // Handle words 97 | if (stream.match(keywords)) { return 'keyword'; } ; 98 | if (stream.match(builtins)) { return 'builtin'; } ; 99 | if (stream.match(identifiers)) { return 'variable'; } ; 100 | 101 | if (stream.match(singleOperators) || stream.match(doubleOperators)) { return 'operator'; }; 102 | if (stream.match(singleDelimiters) || stream.match(doubleDelimiters) || stream.match(tripleDelimiters)) { return null; }; 103 | 104 | if (stream.match(expressionEnd)) { 105 | state.tokenize = tokenTranspose; 106 | return null; 107 | }; 108 | 109 | 110 | // Handle non-detected items 111 | stream.next(); 112 | return 'error'; 113 | }; 114 | 115 | 116 | return { 117 | startState: function() { 118 | return { 119 | tokenize: tokenBase 120 | }; 121 | }, 122 | 123 | token: function(stream, state) { 124 | var style = state.tokenize(stream, state); 125 | if (style === 'number' || style === 'variable'){ 126 | state.tokenize = tokenTranspose; 127 | } 128 | return style; 129 | } 130 | }; 131 | }); 132 | 133 | CodeMirror.defineMIME("text/x-octave", "octave"); 134 | 135 | }); 136 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/pascal.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("pascal", function() { 15 | function words(str) { 16 | var obj = {}, words = str.split(" "); 17 | for (var i = 0; i < words.length; ++i) obj[words[i]] = true; 18 | return obj; 19 | } 20 | var keywords = words("and array begin case const div do downto else end file for forward integer " + 21 | "boolean char function goto if in label mod nil not of or packed procedure " + 22 | "program record repeat set string then to type until var while with"); 23 | var atoms = {"null": true}; 24 | 25 | var isOperatorChar = /[+\-*&%=<>!?|\/]/; 26 | 27 | function tokenBase(stream, state) { 28 | var ch = stream.next(); 29 | if (ch == "#" && state.startOfLine) { 30 | stream.skipToEnd(); 31 | return "meta"; 32 | } 33 | if (ch == '"' || ch == "'") { 34 | state.tokenize = tokenString(ch); 35 | return state.tokenize(stream, state); 36 | } 37 | if (ch == "(" && stream.eat("*")) { 38 | state.tokenize = tokenComment; 39 | return tokenComment(stream, state); 40 | } 41 | if (/[\[\]{}\(\),;\:\.]/.test(ch)) { 42 | return null; 43 | } 44 | if (/\d/.test(ch)) { 45 | stream.eatWhile(/[\w\.]/); 46 | return "number"; 47 | } 48 | if (ch == "/") { 49 | if (stream.eat("/")) { 50 | stream.skipToEnd(); 51 | return "comment"; 52 | } 53 | } 54 | if (isOperatorChar.test(ch)) { 55 | stream.eatWhile(isOperatorChar); 56 | return "operator"; 57 | } 58 | stream.eatWhile(/[\w\$_]/); 59 | var cur = stream.current(); 60 | if (keywords.propertyIsEnumerable(cur)) return "keyword"; 61 | if (atoms.propertyIsEnumerable(cur)) return "atom"; 62 | return "variable"; 63 | } 64 | 65 | function tokenString(quote) { 66 | return function(stream, state) { 67 | var escaped = false, next, end = false; 68 | while ((next = stream.next()) != null) { 69 | if (next == quote && !escaped) {end = true; break;} 70 | escaped = !escaped && next == "\\"; 71 | } 72 | if (end || !escaped) state.tokenize = null; 73 | return "string"; 74 | }; 75 | } 76 | 77 | function tokenComment(stream, state) { 78 | var maybeEnd = false, ch; 79 | while (ch = stream.next()) { 80 | if (ch == ")" && maybeEnd) { 81 | state.tokenize = null; 82 | break; 83 | } 84 | maybeEnd = (ch == "*"); 85 | } 86 | return "comment"; 87 | } 88 | 89 | // Interface 90 | 91 | return { 92 | startState: function() { 93 | return {tokenize: null}; 94 | }, 95 | 96 | token: function(stream, state) { 97 | if (stream.eatSpace()) return null; 98 | var style = (state.tokenize || tokenBase)(stream, state); 99 | if (style == "comment" || style == "meta") return style; 100 | return style; 101 | }, 102 | 103 | electricChars: "{}" 104 | }; 105 | }); 106 | 107 | CodeMirror.defineMIME("text/x-pascal", "pascal"); 108 | 109 | }); 110 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/pegjs.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("../javascript/javascript")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "../javascript/javascript"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("pegjs", function (config) { 15 | var jsMode = CodeMirror.getMode(config, "javascript"); 16 | 17 | function identifier(stream) { 18 | return stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/); 19 | } 20 | 21 | return { 22 | startState: function () { 23 | return { 24 | inString: false, 25 | stringType: null, 26 | inComment: false, 27 | inCharacterClass: false, 28 | braced: 0, 29 | lhs: true, 30 | localState: null 31 | }; 32 | }, 33 | token: function (stream, state) { 34 | if (stream) 35 | 36 | //check for state changes 37 | if (!state.inString && !state.inComment && ((stream.peek() == '"') || (stream.peek() == "'"))) { 38 | state.stringType = stream.peek(); 39 | stream.next(); // Skip quote 40 | state.inString = true; // Update state 41 | } 42 | if (!state.inString && !state.inComment && stream.match(/^\/\*/)) { 43 | state.inComment = true; 44 | } 45 | 46 | //return state 47 | if (state.inString) { 48 | while (state.inString && !stream.eol()) { 49 | if (stream.peek() === state.stringType) { 50 | stream.next(); // Skip quote 51 | state.inString = false; // Clear flag 52 | } else if (stream.peek() === '\\') { 53 | stream.next(); 54 | stream.next(); 55 | } else { 56 | stream.match(/^.[^\\\"\']*/); 57 | } 58 | } 59 | return state.lhs ? "property string" : "string"; // Token style 60 | } else if (state.inComment) { 61 | while (state.inComment && !stream.eol()) { 62 | if (stream.match(/\*\//)) { 63 | state.inComment = false; // Clear flag 64 | } else { 65 | stream.match(/^.[^\*]*/); 66 | } 67 | } 68 | return "comment"; 69 | } else if (state.inCharacterClass) { 70 | while (state.inCharacterClass && !stream.eol()) { 71 | if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./))) { 72 | state.inCharacterClass = false; 73 | } 74 | } 75 | } else if (stream.peek() === '[') { 76 | stream.next(); 77 | state.inCharacterClass = true; 78 | return 'bracket'; 79 | } else if (stream.match(/^\/\//)) { 80 | stream.skipToEnd(); 81 | return "comment"; 82 | } else if (state.braced || stream.peek() === '{') { 83 | if (state.localState === null) { 84 | state.localState = jsMode.startState(); 85 | } 86 | var token = jsMode.token(stream, state.localState); 87 | var text = stream.current(); 88 | if (!token) { 89 | for (var i = 0; i < text.length; i++) { 90 | if (text[i] === '{') { 91 | state.braced++; 92 | } else if (text[i] === '}') { 93 | state.braced--; 94 | } 95 | }; 96 | } 97 | return token; 98 | } else if (identifier(stream)) { 99 | if (stream.peek() === ':') { 100 | return 'variable'; 101 | } 102 | return 'variable-2'; 103 | } else if (['[', ']', '(', ')'].indexOf(stream.peek()) != -1) { 104 | stream.next(); 105 | return 'bracket'; 106 | } else if (!stream.eatSpace()) { 107 | stream.next(); 108 | } 109 | return null; 110 | } 111 | }; 112 | }, "javascript"); 113 | 114 | }); 115 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/properties.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("properties", function() { 15 | return { 16 | token: function(stream, state) { 17 | var sol = stream.sol() || state.afterSection; 18 | var eol = stream.eol(); 19 | 20 | state.afterSection = false; 21 | 22 | if (sol) { 23 | if (state.nextMultiline) { 24 | state.inMultiline = true; 25 | state.nextMultiline = false; 26 | } else { 27 | state.position = "def"; 28 | } 29 | } 30 | 31 | if (eol && ! state.nextMultiline) { 32 | state.inMultiline = false; 33 | state.position = "def"; 34 | } 35 | 36 | if (sol) { 37 | while(stream.eatSpace()) {} 38 | } 39 | 40 | var ch = stream.next(); 41 | 42 | if (sol && (ch === "#" || ch === "!" || ch === ";")) { 43 | state.position = "comment"; 44 | stream.skipToEnd(); 45 | return "comment"; 46 | } else if (sol && ch === "[") { 47 | state.afterSection = true; 48 | stream.skipTo("]"); stream.eat("]"); 49 | return "header"; 50 | } else if (ch === "=" || ch === ":") { 51 | state.position = "quote"; 52 | return null; 53 | } else if (ch === "\\" && state.position === "quote") { 54 | if (stream.eol()) { // end of line? 55 | // Multiline value 56 | state.nextMultiline = true; 57 | } 58 | } 59 | 60 | return state.position; 61 | }, 62 | 63 | startState: function() { 64 | return { 65 | position : "def", // Current position, "def", "quote" or "comment" 66 | nextMultiline : false, // Is the next line multiline value 67 | inMultiline : false, // Is the current line a multiline value 68 | afterSection : false // Did we just open a section 69 | }; 70 | } 71 | 72 | }; 73 | }); 74 | 75 | CodeMirror.defineMIME("text/x-properties", "properties"); 76 | CodeMirror.defineMIME("text/x-ini", "properties"); 77 | 78 | }); 79 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/protobuf.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | function wordRegexp(words) { 15 | return new RegExp("^((" + words.join(")|(") + "))\\b", "i"); 16 | }; 17 | 18 | var keywordArray = [ 19 | "package", "message", "import", "syntax", 20 | "required", "optional", "repeated", "reserved", "default", "extensions", "packed", 21 | "bool", "bytes", "double", "enum", "float", "string", 22 | "int32", "int64", "uint32", "uint64", "sint32", "sint64", "fixed32", "fixed64", "sfixed32", "sfixed64" 23 | ]; 24 | var keywords = wordRegexp(keywordArray); 25 | 26 | CodeMirror.registerHelper("hintWords", "protobuf", keywordArray); 27 | 28 | var identifiers = new RegExp("^[_A-Za-z\xa1-\uffff][_A-Za-z0-9\xa1-\uffff]*"); 29 | 30 | function tokenBase(stream) { 31 | // whitespaces 32 | if (stream.eatSpace()) return null; 33 | 34 | // Handle one line Comments 35 | if (stream.match("//")) { 36 | stream.skipToEnd(); 37 | return "comment"; 38 | } 39 | 40 | // Handle Number Literals 41 | if (stream.match(/^[0-9\.+-]/, false)) { 42 | if (stream.match(/^[+-]?0x[0-9a-fA-F]+/)) 43 | return "number"; 44 | if (stream.match(/^[+-]?\d*\.\d+([EeDd][+-]?\d+)?/)) 45 | return "number"; 46 | if (stream.match(/^[+-]?\d+([EeDd][+-]?\d+)?/)) 47 | return "number"; 48 | } 49 | 50 | // Handle Strings 51 | if (stream.match(/^"([^"]|(""))*"/)) { return "string"; } 52 | if (stream.match(/^'([^']|(''))*'/)) { return "string"; } 53 | 54 | // Handle words 55 | if (stream.match(keywords)) { return "keyword"; } 56 | if (stream.match(identifiers)) { return "variable"; } ; 57 | 58 | // Handle non-detected items 59 | stream.next(); 60 | return null; 61 | }; 62 | 63 | CodeMirror.defineMode("protobuf", function() { 64 | return {token: tokenBase}; 65 | }); 66 | 67 | CodeMirror.defineMIME("text/x-protobuf", "protobuf"); 68 | }); 69 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/rpm.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("rpm-changes", function() { 15 | var headerSeperator = /^-+$/; 16 | var headerLine = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ?\d{1,2} \d{2}:\d{2}(:\d{2})? [A-Z]{3,4} \d{4} - /; 17 | var simpleEmail = /^[\w+.-]+@[\w.-]+/; 18 | 19 | return { 20 | token: function(stream) { 21 | if (stream.sol()) { 22 | if (stream.match(headerSeperator)) { return 'tag'; } 23 | if (stream.match(headerLine)) { return 'tag'; } 24 | } 25 | if (stream.match(simpleEmail)) { return 'string'; } 26 | stream.next(); 27 | return null; 28 | } 29 | }; 30 | }); 31 | 32 | CodeMirror.defineMIME("text/x-rpm-changes", "rpm-changes"); 33 | 34 | // Quick and dirty spec file highlighting 35 | 36 | CodeMirror.defineMode("rpm-spec", function() { 37 | var arch = /^(i386|i586|i686|x86_64|ppc64le|ppc64|ppc|ia64|s390x|s390|sparc64|sparcv9|sparc|noarch|alphaev6|alpha|hppa|mipsel)/; 38 | 39 | var preamble = /^[a-zA-Z0-9()]+:/; 40 | var section = /^%(debug_package|package|description|prep|build|install|files|clean|changelog|preinstall|preun|postinstall|postun|pretrans|posttrans|pre|post|triggerin|triggerun|verifyscript|check|triggerpostun|triggerprein|trigger)/; 41 | var control_flow_complex = /^%(ifnarch|ifarch|if)/; // rpm control flow macros 42 | var control_flow_simple = /^%(else|endif)/; // rpm control flow macros 43 | var operators = /^(\!|\?|\<\=|\<|\>\=|\>|\=\=|\&\&|\|\|)/; // operators in control flow macros 44 | 45 | return { 46 | startState: function () { 47 | return { 48 | controlFlow: false, 49 | macroParameters: false, 50 | section: false 51 | }; 52 | }, 53 | token: function (stream, state) { 54 | var ch = stream.peek(); 55 | if (ch == "#") { stream.skipToEnd(); return "comment"; } 56 | 57 | if (stream.sol()) { 58 | if (stream.match(preamble)) { return "header"; } 59 | if (stream.match(section)) { return "atom"; } 60 | } 61 | 62 | if (stream.match(/^\$\w+/)) { return "def"; } // Variables like '$RPM_BUILD_ROOT' 63 | if (stream.match(/^\$\{\w+\}/)) { return "def"; } // Variables like '${RPM_BUILD_ROOT}' 64 | 65 | if (stream.match(control_flow_simple)) { return "keyword"; } 66 | if (stream.match(control_flow_complex)) { 67 | state.controlFlow = true; 68 | return "keyword"; 69 | } 70 | if (state.controlFlow) { 71 | if (stream.match(operators)) { return "operator"; } 72 | if (stream.match(/^(\d+)/)) { return "number"; } 73 | if (stream.eol()) { state.controlFlow = false; } 74 | } 75 | 76 | if (stream.match(arch)) { 77 | if (stream.eol()) { state.controlFlow = false; } 78 | return "number"; 79 | } 80 | 81 | // Macros like '%make_install' or '%attr(0775,root,root)' 82 | if (stream.match(/^%[\w]+/)) { 83 | if (stream.match(/^\(/)) { state.macroParameters = true; } 84 | return "keyword"; 85 | } 86 | if (state.macroParameters) { 87 | if (stream.match(/^\d+/)) { return "number";} 88 | if (stream.match(/^\)/)) { 89 | state.macroParameters = false; 90 | return "keyword"; 91 | } 92 | } 93 | 94 | // Macros like '%{defined fedora}' 95 | if (stream.match(/^%\{\??[\w \-\:\!]+\}/)) { 96 | if (stream.eol()) { state.controlFlow = false; } 97 | return "def"; 98 | } 99 | 100 | //TODO: Include bash script sub-parser (CodeMirror supports that) 101 | stream.next(); 102 | return null; 103 | } 104 | }; 105 | }); 106 | 107 | CodeMirror.defineMIME("text/x-rpm-spec", "rpm-spec"); 108 | 109 | }); 110 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/rust.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("../../addon/mode/simple")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "../../addon/mode/simple"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineSimpleMode("rust",{ 15 | start: [ 16 | // string and byte string 17 | {regex: /b?"/, token: "string", next: "string"}, 18 | // raw string and raw byte string 19 | {regex: /b?r"/, token: "string", next: "string_raw"}, 20 | {regex: /b?r#+"/, token: "string", next: "string_raw_hash"}, 21 | // character 22 | {regex: /'(?:[^'\\]|\\(?:[nrt0'"]|x[\da-fA-F]{2}|u\{[\da-fA-F]{6}\}))'/, token: "string-2"}, 23 | // byte 24 | {regex: /b'(?:[^']|\\(?:['\\nrt0]|x[\da-fA-F]{2}))'/, token: "string-2"}, 25 | 26 | {regex: /(?:(?:[0-9][0-9_]*)(?:(?:[Ee][+-]?[0-9_]+)|\.[0-9_]+(?:[Ee][+-]?[0-9_]+)?)(?:f32|f64)?)|(?:0(?:b[01_]+|(?:o[0-7_]+)|(?:x[0-9a-fA-F_]+))|(?:[0-9][0-9_]*))(?:u8|u16|u32|u64|i8|i16|i32|i64|isize|usize)?/, 27 | token: "number"}, 28 | {regex: /(let(?:\s+mut)?|fn|enum|mod|struct|type)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/, token: ["keyword", null, "def"]}, 29 | {regex: /(?:abstract|alignof|as|box|break|continue|const|crate|do|else|enum|extern|fn|for|final|if|impl|in|loop|macro|match|mod|move|offsetof|override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\b/, token: "keyword"}, 30 | {regex: /\b(?:Self|isize|usize|char|bool|u8|u16|u32|u64|f16|f32|f64|i8|i16|i32|i64|str|Option)\b/, token: "atom"}, 31 | {regex: /\b(?:true|false|Some|None|Ok|Err)\b/, token: "builtin"}, 32 | {regex: /\b(fn)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/, 33 | token: ["keyword", null ,"def"]}, 34 | {regex: /#!?\[.*\]/, token: "meta"}, 35 | {regex: /\/\/.*/, token: "comment"}, 36 | {regex: /\/\*/, token: "comment", next: "comment"}, 37 | {regex: /[-+\/*=<>!]+/, token: "operator"}, 38 | {regex: /[a-zA-Z_]\w*!/,token: "variable-3"}, 39 | {regex: /[a-zA-Z_]\w*/, token: "variable"}, 40 | {regex: /[\{\[\(]/, indent: true}, 41 | {regex: /[\}\]\)]/, dedent: true} 42 | ], 43 | string: [ 44 | {regex: /"/, token: "string", next: "start"}, 45 | {regex: /(?:[^\\"]|\\(?:.|$))*/, token: "string"} 46 | ], 47 | string_raw: [ 48 | {regex: /"/, token: "string", next: "start"}, 49 | {regex: /[^"]*/, token: "string"} 50 | ], 51 | string_raw_hash: [ 52 | {regex: /"#+/, token: "string", next: "start"}, 53 | {regex: /(?:[^"]|"(?!#))*/, token: "string"} 54 | ], 55 | comment: [ 56 | {regex: /.*?\*\//, token: "comment", next: "start"}, 57 | {regex: /.*/, token: "comment"} 58 | ], 59 | meta: { 60 | dontIndentStates: ["comment"], 61 | electricInput: /^\s*\}$/, 62 | blockCommentStart: "/*", 63 | blockCommentEnd: "*/", 64 | lineComment: "//", 65 | fold: "brace" 66 | } 67 | }); 68 | 69 | 70 | CodeMirror.defineMIME("text/x-rustsrc", "rust"); 71 | }); 72 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/scss_test.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function() { 5 | var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss"); 6 | function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); } 7 | 8 | MT('url_with_quotation', 9 | "[tag foo] { [property background]:[atom url]([string test.jpg]) }"); 10 | 11 | MT('url_with_double_quotes', 12 | "[tag foo] { [property background]:[atom url]([string \"test.jpg\"]) }"); 13 | 14 | MT('url_with_single_quotes', 15 | "[tag foo] { [property background]:[atom url]([string \'test.jpg\']) }"); 16 | 17 | MT('string', 18 | "[def @import] [string \"compass/css3\"]"); 19 | 20 | MT('important_keyword', 21 | "[tag foo] { [property background]:[atom url]([string \'test.jpg\']) [keyword !important] }"); 22 | 23 | MT('variable', 24 | "[variable-2 $blue]:[atom #333]"); 25 | 26 | MT('variable_as_attribute', 27 | "[tag foo] { [property color]:[variable-2 $blue] }"); 28 | 29 | MT('numbers', 30 | "[tag foo] { [property padding]:[number 10px] [number 10] [number 10em] [number 8in] }"); 31 | 32 | MT('number_percentage', 33 | "[tag foo] { [property width]:[number 80%] }"); 34 | 35 | MT('selector', 36 | "[builtin #hello][qualifier .world]{}"); 37 | 38 | MT('singleline_comment', 39 | "[comment // this is a comment]"); 40 | 41 | MT('multiline_comment', 42 | "[comment /*foobar*/]"); 43 | 44 | MT('attribute_with_hyphen', 45 | "[tag foo] { [property font-size]:[number 10px] }"); 46 | 47 | MT('string_after_attribute', 48 | "[tag foo] { [property content]:[string \"::\"] }"); 49 | 50 | MT('directives', 51 | "[def @include] [qualifier .mixin]"); 52 | 53 | MT('basic_structure', 54 | "[tag p] { [property background]:[keyword red]; }"); 55 | 56 | MT('nested_structure', 57 | "[tag p] { [tag a] { [property color]:[keyword red]; } }"); 58 | 59 | MT('mixin', 60 | "[def @mixin] [tag table-base] {}"); 61 | 62 | MT('number_without_semicolon', 63 | "[tag p] {[property width]:[number 12]}", 64 | "[tag a] {[property color]:[keyword red];}"); 65 | 66 | MT('atom_in_nested_block', 67 | "[tag p] { [tag a] { [property color]:[atom #000]; } }"); 68 | 69 | MT('interpolation_in_property', 70 | "[tag foo] { #{[variable-2 $hello]}:[number 2]; }"); 71 | 72 | MT('interpolation_in_selector', 73 | "[tag foo]#{[variable-2 $hello]} { [property color]:[atom #000]; }"); 74 | 75 | MT('interpolation_error', 76 | "[tag foo]#{[variable foo]} { [property color]:[atom #000]; }"); 77 | 78 | MT("divide_operator", 79 | "[tag foo] { [property width]:[number 4] [operator /] [number 2] }"); 80 | 81 | MT('nested_structure_with_id_selector', 82 | "[tag p] { [builtin #hello] { [property color]:[keyword red]; } }"); 83 | 84 | MT('indent_mixin', 85 | "[def @mixin] [tag container] (", 86 | " [variable-2 $a]: [number 10],", 87 | " [variable-2 $b]: [number 10])", 88 | "{}"); 89 | 90 | MT('indent_nested', 91 | "[tag foo] {", 92 | " [tag bar] {", 93 | " }", 94 | "}"); 95 | 96 | MT('indent_parentheses', 97 | "[tag foo] {", 98 | " [property color]: [atom darken]([variable-2 $blue],", 99 | " [number 9%]);", 100 | "}"); 101 | 102 | MT('indent_vardef', 103 | "[variable-2 $name]:", 104 | " [string 'val'];", 105 | "[tag tag] {", 106 | " [tag inner] {", 107 | " [property margin]: [number 3px];", 108 | " }", 109 | "}"); 110 | })(); 111 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/shell.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode('shell', function() { 15 | 16 | var words = {}; 17 | function define(style, string) { 18 | var split = string.split(' '); 19 | for(var i = 0; i < split.length; i++) { 20 | words[split[i]] = style; 21 | } 22 | }; 23 | 24 | // Atoms 25 | define('atom', 'true false'); 26 | 27 | // Keywords 28 | define('keyword', 'if then do else elif while until for in esac fi fin ' + 29 | 'fil done exit set unset export function'); 30 | 31 | // Commands 32 | define('builtin', 'ab awk bash beep cat cc cd chown chmod chroot clear cp ' + 33 | 'curl cut diff echo find gawk gcc get git grep kill killall ln ls make ' + 34 | 'mkdir openssl mv nc node npm ping ps restart rm rmdir sed service sh ' + 35 | 'shopt shred source sort sleep ssh start stop su sudo tee telnet top ' + 36 | 'touch vi vim wall wc wget who write yes zsh'); 37 | 38 | function tokenBase(stream, state) { 39 | if (stream.eatSpace()) return null; 40 | 41 | var sol = stream.sol(); 42 | var ch = stream.next(); 43 | 44 | if (ch === '\\') { 45 | stream.next(); 46 | return null; 47 | } 48 | if (ch === '\'' || ch === '"' || ch === '`') { 49 | state.tokens.unshift(tokenString(ch)); 50 | return tokenize(stream, state); 51 | } 52 | if (ch === '#') { 53 | if (sol && stream.eat('!')) { 54 | stream.skipToEnd(); 55 | return 'meta'; // 'comment'? 56 | } 57 | stream.skipToEnd(); 58 | return 'comment'; 59 | } 60 | if (ch === '$') { 61 | state.tokens.unshift(tokenDollar); 62 | return tokenize(stream, state); 63 | } 64 | if (ch === '+' || ch === '=') { 65 | return 'operator'; 66 | } 67 | if (ch === '-') { 68 | stream.eat('-'); 69 | stream.eatWhile(/\w/); 70 | return 'attribute'; 71 | } 72 | if (/\d/.test(ch)) { 73 | stream.eatWhile(/\d/); 74 | if(stream.eol() || !/\w/.test(stream.peek())) { 75 | return 'number'; 76 | } 77 | } 78 | stream.eatWhile(/[\w-]/); 79 | var cur = stream.current(); 80 | if (stream.peek() === '=' && /\w+/.test(cur)) return 'def'; 81 | return words.hasOwnProperty(cur) ? words[cur] : null; 82 | } 83 | 84 | function tokenString(quote) { 85 | return function(stream, state) { 86 | var next, end = false, escaped = false; 87 | while ((next = stream.next()) != null) { 88 | if (next === quote && !escaped) { 89 | end = true; 90 | break; 91 | } 92 | if (next === '$' && !escaped && quote !== '\'') { 93 | escaped = true; 94 | stream.backUp(1); 95 | state.tokens.unshift(tokenDollar); 96 | break; 97 | } 98 | escaped = !escaped && next === '\\'; 99 | } 100 | if (end || !escaped) { 101 | state.tokens.shift(); 102 | } 103 | return (quote === '`' || quote === ')' ? 'quote' : 'string'); 104 | }; 105 | }; 106 | 107 | var tokenDollar = function(stream, state) { 108 | if (state.tokens.length > 1) stream.eat('$'); 109 | var ch = stream.next(), hungry = /\w/; 110 | if (ch === '{') hungry = /[^}]/; 111 | if (ch === '(') { 112 | state.tokens[0] = tokenString(')'); 113 | return tokenize(stream, state); 114 | } 115 | if (!/\d/.test(ch)) { 116 | stream.eatWhile(hungry); 117 | stream.eat('}'); 118 | } 119 | state.tokens.shift(); 120 | return 'def'; 121 | }; 122 | 123 | function tokenize(stream, state) { 124 | return (state.tokens[0] || tokenBase) (stream, state); 125 | }; 126 | 127 | return { 128 | startState: function() {return {tokens:[]};}, 129 | token: function(stream, state) { 130 | return tokenize(stream, state); 131 | }, 132 | lineComment: '#', 133 | fold: "brace" 134 | }; 135 | }); 136 | 137 | CodeMirror.defineMIME('text/x-sh', 'shell'); 138 | 139 | }); 140 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/sieve.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("sieve", function(config) { 15 | function words(str) { 16 | var obj = {}, words = str.split(" "); 17 | for (var i = 0; i < words.length; ++i) obj[words[i]] = true; 18 | return obj; 19 | } 20 | 21 | var keywords = words("if elsif else stop require"); 22 | var atoms = words("true false not"); 23 | var indentUnit = config.indentUnit; 24 | 25 | function tokenBase(stream, state) { 26 | 27 | var ch = stream.next(); 28 | if (ch == "/" && stream.eat("*")) { 29 | state.tokenize = tokenCComment; 30 | return tokenCComment(stream, state); 31 | } 32 | 33 | if (ch === '#') { 34 | stream.skipToEnd(); 35 | return "comment"; 36 | } 37 | 38 | if (ch == "\"") { 39 | state.tokenize = tokenString(ch); 40 | return state.tokenize(stream, state); 41 | } 42 | 43 | if (ch == "(") { 44 | state._indent.push("("); 45 | // add virtual angel wings so that editor behaves... 46 | // ...more sane incase of broken brackets 47 | state._indent.push("{"); 48 | return null; 49 | } 50 | 51 | if (ch === "{") { 52 | state._indent.push("{"); 53 | return null; 54 | } 55 | 56 | if (ch == ")") { 57 | state._indent.pop(); 58 | state._indent.pop(); 59 | } 60 | 61 | if (ch === "}") { 62 | state._indent.pop(); 63 | return null; 64 | } 65 | 66 | if (ch == ",") 67 | return null; 68 | 69 | if (ch == ";") 70 | return null; 71 | 72 | 73 | if (/[{}\(\),;]/.test(ch)) 74 | return null; 75 | 76 | // 1*DIGIT "K" / "M" / "G" 77 | if (/\d/.test(ch)) { 78 | stream.eatWhile(/[\d]/); 79 | stream.eat(/[KkMmGg]/); 80 | return "number"; 81 | } 82 | 83 | // ":" (ALPHA / "_") *(ALPHA / DIGIT / "_") 84 | if (ch == ":") { 85 | stream.eatWhile(/[a-zA-Z_]/); 86 | stream.eatWhile(/[a-zA-Z0-9_]/); 87 | 88 | return "operator"; 89 | } 90 | 91 | stream.eatWhile(/\w/); 92 | var cur = stream.current(); 93 | 94 | // "text:" *(SP / HTAB) (hash-comment / CRLF) 95 | // *(multiline-literal / multiline-dotstart) 96 | // "." CRLF 97 | if ((cur == "text") && stream.eat(":")) 98 | { 99 | state.tokenize = tokenMultiLineString; 100 | return "string"; 101 | } 102 | 103 | if (keywords.propertyIsEnumerable(cur)) 104 | return "keyword"; 105 | 106 | if (atoms.propertyIsEnumerable(cur)) 107 | return "atom"; 108 | 109 | return null; 110 | } 111 | 112 | function tokenMultiLineString(stream, state) 113 | { 114 | state._multiLineString = true; 115 | // the first line is special it may contain a comment 116 | if (!stream.sol()) { 117 | stream.eatSpace(); 118 | 119 | if (stream.peek() == "#") { 120 | stream.skipToEnd(); 121 | return "comment"; 122 | } 123 | 124 | stream.skipToEnd(); 125 | return "string"; 126 | } 127 | 128 | if ((stream.next() == ".") && (stream.eol())) 129 | { 130 | state._multiLineString = false; 131 | state.tokenize = tokenBase; 132 | } 133 | 134 | return "string"; 135 | } 136 | 137 | function tokenCComment(stream, state) { 138 | var maybeEnd = false, ch; 139 | while ((ch = stream.next()) != null) { 140 | if (maybeEnd && ch == "/") { 141 | state.tokenize = tokenBase; 142 | break; 143 | } 144 | maybeEnd = (ch == "*"); 145 | } 146 | return "comment"; 147 | } 148 | 149 | function tokenString(quote) { 150 | return function(stream, state) { 151 | var escaped = false, ch; 152 | while ((ch = stream.next()) != null) { 153 | if (ch == quote && !escaped) 154 | break; 155 | escaped = !escaped && ch == "\\"; 156 | } 157 | if (!escaped) state.tokenize = tokenBase; 158 | return "string"; 159 | }; 160 | } 161 | 162 | return { 163 | startState: function(base) { 164 | return {tokenize: tokenBase, 165 | baseIndent: base || 0, 166 | _indent: []}; 167 | }, 168 | 169 | token: function(stream, state) { 170 | if (stream.eatSpace()) 171 | return null; 172 | 173 | return (state.tokenize || tokenBase)(stream, state);; 174 | }, 175 | 176 | indent: function(state, _textAfter) { 177 | var length = state._indent.length; 178 | if (_textAfter && (_textAfter[0] == "}")) 179 | length--; 180 | 181 | if (length <0) 182 | length = 0; 183 | 184 | return length * indentUnit; 185 | }, 186 | 187 | electricChars: "}" 188 | }; 189 | }); 190 | 191 | CodeMirror.defineMIME("application/sieve", "sieve"); 192 | 193 | }); 194 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/smalltalk.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode('smalltalk', function(config) { 15 | 16 | var specialChars = /[+\-\/\\*~<>=@%|&?!.,:;^]/; 17 | var keywords = /true|false|nil|self|super|thisContext/; 18 | 19 | var Context = function(tokenizer, parent) { 20 | this.next = tokenizer; 21 | this.parent = parent; 22 | }; 23 | 24 | var Token = function(name, context, eos) { 25 | this.name = name; 26 | this.context = context; 27 | this.eos = eos; 28 | }; 29 | 30 | var State = function() { 31 | this.context = new Context(next, null); 32 | this.expectVariable = true; 33 | this.indentation = 0; 34 | this.userIndentationDelta = 0; 35 | }; 36 | 37 | State.prototype.userIndent = function(indentation) { 38 | this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0; 39 | }; 40 | 41 | var next = function(stream, context, state) { 42 | var token = new Token(null, context, false); 43 | var aChar = stream.next(); 44 | 45 | if (aChar === '"') { 46 | token = nextComment(stream, new Context(nextComment, context)); 47 | 48 | } else if (aChar === '\'') { 49 | token = nextString(stream, new Context(nextString, context)); 50 | 51 | } else if (aChar === '#') { 52 | if (stream.peek() === '\'') { 53 | stream.next(); 54 | token = nextSymbol(stream, new Context(nextSymbol, context)); 55 | } else { 56 | if (stream.eatWhile(/[^\s.{}\[\]()]/)) 57 | token.name = 'string-2'; 58 | else 59 | token.name = 'meta'; 60 | } 61 | 62 | } else if (aChar === '$') { 63 | if (stream.next() === '<') { 64 | stream.eatWhile(/[^\s>]/); 65 | stream.next(); 66 | } 67 | token.name = 'string-2'; 68 | 69 | } else if (aChar === '|' && state.expectVariable) { 70 | token.context = new Context(nextTemporaries, context); 71 | 72 | } else if (/[\[\]{}()]/.test(aChar)) { 73 | token.name = 'bracket'; 74 | token.eos = /[\[{(]/.test(aChar); 75 | 76 | if (aChar === '[') { 77 | state.indentation++; 78 | } else if (aChar === ']') { 79 | state.indentation = Math.max(0, state.indentation - 1); 80 | } 81 | 82 | } else if (specialChars.test(aChar)) { 83 | stream.eatWhile(specialChars); 84 | token.name = 'operator'; 85 | token.eos = aChar !== ';'; // ; cascaded message expression 86 | 87 | } else if (/\d/.test(aChar)) { 88 | stream.eatWhile(/[\w\d]/); 89 | token.name = 'number'; 90 | 91 | } else if (/[\w_]/.test(aChar)) { 92 | stream.eatWhile(/[\w\d_]/); 93 | token.name = state.expectVariable ? (keywords.test(stream.current()) ? 'keyword' : 'variable') : null; 94 | 95 | } else { 96 | token.eos = state.expectVariable; 97 | } 98 | 99 | return token; 100 | }; 101 | 102 | var nextComment = function(stream, context) { 103 | stream.eatWhile(/[^"]/); 104 | return new Token('comment', stream.eat('"') ? context.parent : context, true); 105 | }; 106 | 107 | var nextString = function(stream, context) { 108 | stream.eatWhile(/[^']/); 109 | return new Token('string', stream.eat('\'') ? context.parent : context, false); 110 | }; 111 | 112 | var nextSymbol = function(stream, context) { 113 | stream.eatWhile(/[^']/); 114 | return new Token('string-2', stream.eat('\'') ? context.parent : context, false); 115 | }; 116 | 117 | var nextTemporaries = function(stream, context) { 118 | var token = new Token(null, context, false); 119 | var aChar = stream.next(); 120 | 121 | if (aChar === '|') { 122 | token.context = context.parent; 123 | token.eos = true; 124 | 125 | } else { 126 | stream.eatWhile(/[^|]/); 127 | token.name = 'variable'; 128 | } 129 | 130 | return token; 131 | }; 132 | 133 | return { 134 | startState: function() { 135 | return new State; 136 | }, 137 | 138 | token: function(stream, state) { 139 | state.userIndent(stream.indentation()); 140 | 141 | if (stream.eatSpace()) { 142 | return null; 143 | } 144 | 145 | var token = state.context.next(stream, state.context, state); 146 | state.context = token.context; 147 | state.expectVariable = token.eos; 148 | 149 | return token.name; 150 | }, 151 | 152 | blankLine: function(state) { 153 | state.userIndent(0); 154 | }, 155 | 156 | indent: function(state, textAfter) { 157 | var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta; 158 | return (state.indentation + i) * config.indentUnit; 159 | }, 160 | 161 | electricChars: ']' 162 | }; 163 | 164 | }); 165 | 166 | CodeMirror.defineMIME('text/x-stsrc', {name: 'smalltalk'}); 167 | 168 | }); 169 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/solr.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("solr", function() { 15 | "use strict"; 16 | 17 | var isStringChar = /[^\s\|\!\+\-\*\?\~\^\&\:\(\)\[\]\{\}\^\"\\]/; 18 | var isOperatorChar = /[\|\!\+\-\*\?\~\^\&]/; 19 | var isOperatorString = /^(OR|AND|NOT|TO)$/i; 20 | 21 | function isNumber(word) { 22 | return parseFloat(word, 10).toString() === word; 23 | } 24 | 25 | function tokenString(quote) { 26 | return function(stream, state) { 27 | var escaped = false, next; 28 | while ((next = stream.next()) != null) { 29 | if (next == quote && !escaped) break; 30 | escaped = !escaped && next == "\\"; 31 | } 32 | 33 | if (!escaped) state.tokenize = tokenBase; 34 | return "string"; 35 | }; 36 | } 37 | 38 | function tokenOperator(operator) { 39 | return function(stream, state) { 40 | var style = "operator"; 41 | if (operator == "+") 42 | style += " positive"; 43 | else if (operator == "-") 44 | style += " negative"; 45 | else if (operator == "|") 46 | stream.eat(/\|/); 47 | else if (operator == "&") 48 | stream.eat(/\&/); 49 | else if (operator == "^") 50 | style += " boost"; 51 | 52 | state.tokenize = tokenBase; 53 | return style; 54 | }; 55 | } 56 | 57 | function tokenWord(ch) { 58 | return function(stream, state) { 59 | var word = ch; 60 | while ((ch = stream.peek()) && ch.match(isStringChar) != null) { 61 | word += stream.next(); 62 | } 63 | 64 | state.tokenize = tokenBase; 65 | if (isOperatorString.test(word)) 66 | return "operator"; 67 | else if (isNumber(word)) 68 | return "number"; 69 | else if (stream.peek() == ":") 70 | return "field"; 71 | else 72 | return "string"; 73 | }; 74 | } 75 | 76 | function tokenBase(stream, state) { 77 | var ch = stream.next(); 78 | if (ch == '"') 79 | state.tokenize = tokenString(ch); 80 | else if (isOperatorChar.test(ch)) 81 | state.tokenize = tokenOperator(ch); 82 | else if (isStringChar.test(ch)) 83 | state.tokenize = tokenWord(ch); 84 | 85 | return (state.tokenize != tokenBase) ? state.tokenize(stream, state) : null; 86 | } 87 | 88 | return { 89 | startState: function() { 90 | return { 91 | tokenize: tokenBase 92 | }; 93 | }, 94 | 95 | token: function(stream, state) { 96 | if (stream.eatSpace()) return null; 97 | return state.tokenize(stream, state); 98 | } 99 | }; 100 | }); 101 | 102 | CodeMirror.defineMIME("text/x-solr", "solr"); 103 | 104 | }); 105 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/spreadsheet.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("spreadsheet", function () { 15 | return { 16 | startState: function () { 17 | return { 18 | stringType: null, 19 | stack: [] 20 | }; 21 | }, 22 | token: function (stream, state) { 23 | if (!stream) return; 24 | 25 | //check for state changes 26 | if (state.stack.length === 0) { 27 | //strings 28 | if ((stream.peek() == '"') || (stream.peek() == "'")) { 29 | state.stringType = stream.peek(); 30 | stream.next(); // Skip quote 31 | state.stack.unshift("string"); 32 | } 33 | } 34 | 35 | //return state 36 | //stack has 37 | switch (state.stack[0]) { 38 | case "string": 39 | while (state.stack[0] === "string" && !stream.eol()) { 40 | if (stream.peek() === state.stringType) { 41 | stream.next(); // Skip quote 42 | state.stack.shift(); // Clear flag 43 | } else if (stream.peek() === "\\") { 44 | stream.next(); 45 | stream.next(); 46 | } else { 47 | stream.match(/^.[^\\\"\']*/); 48 | } 49 | } 50 | return "string"; 51 | 52 | case "characterClass": 53 | while (state.stack[0] === "characterClass" && !stream.eol()) { 54 | if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./))) 55 | state.stack.shift(); 56 | } 57 | return "operator"; 58 | } 59 | 60 | var peek = stream.peek(); 61 | 62 | //no stack 63 | switch (peek) { 64 | case "[": 65 | stream.next(); 66 | state.stack.unshift("characterClass"); 67 | return "bracket"; 68 | case ":": 69 | stream.next(); 70 | return "operator"; 71 | case "\\": 72 | if (stream.match(/\\[a-z]+/)) return "string-2"; 73 | else { 74 | stream.next(); 75 | return "atom"; 76 | } 77 | case ".": 78 | case ",": 79 | case ";": 80 | case "*": 81 | case "-": 82 | case "+": 83 | case "^": 84 | case "<": 85 | case "/": 86 | case "=": 87 | stream.next(); 88 | return "atom"; 89 | case "$": 90 | stream.next(); 91 | return "builtin"; 92 | } 93 | 94 | if (stream.match(/\d+/)) { 95 | if (stream.match(/^\w+/)) return "error"; 96 | return "number"; 97 | } else if (stream.match(/^[a-zA-Z_]\w*/)) { 98 | if (stream.match(/(?=[\(.])/, false)) return "keyword"; 99 | return "variable-2"; 100 | } else if (["[", "]", "(", ")", "{", "}"].indexOf(peek) != -1) { 101 | stream.next(); 102 | return "bracket"; 103 | } else if (!stream.eatSpace()) { 104 | stream.next(); 105 | } 106 | return null; 107 | } 108 | }; 109 | }); 110 | 111 | CodeMirror.defineMIME("text/x-spreadsheet", "spreadsheet"); 112 | }); 113 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/tcl.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | //tcl mode by Ford_Lawnmower :: Based on Velocity mode by Steve O'Hara 5 | 6 | (function(mod) { 7 | if (typeof exports == "object" && typeof module == "object") // CommonJS 8 | mod(require("../../lib/codemirror")); 9 | else if (typeof define == "function" && define.amd) // AMD 10 | define(["../../lib/codemirror"], mod); 11 | else // Plain browser env 12 | mod(CodeMirror); 13 | })(function(CodeMirror) { 14 | "use strict"; 15 | 16 | CodeMirror.defineMode("tcl", function() { 17 | function parseWords(str) { 18 | var obj = {}, words = str.split(" "); 19 | for (var i = 0; i < words.length; ++i) obj[words[i]] = true; 20 | return obj; 21 | } 22 | var keywords = parseWords("Tcl safe after append array auto_execok auto_import auto_load " + 23 | "auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror " + 24 | "binary break catch cd close concat continue dde eof encoding error " + 25 | "eval exec exit expr fblocked fconfigure fcopy file fileevent filename " + 26 | "filename flush for foreach format gets glob global history http if " + 27 | "incr info interp join lappend lindex linsert list llength load lrange " + 28 | "lreplace lsearch lset lsort memory msgcat namespace open package parray " + 29 | "pid pkg::create pkg_mkIndex proc puts pwd re_syntax read regex regexp " + 30 | "registry regsub rename resource return scan seek set socket source split " + 31 | "string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord " + 32 | "tcl_wordBreakAfter tcl_startOfPreviousWord tcl_wordBreakBefore tcltest " + 33 | "tclvars tell time trace unknown unset update uplevel upvar variable " + 34 | "vwait"); 35 | var functions = parseWords("if elseif else and not or eq ne in ni for foreach while switch"); 36 | var isOperatorChar = /[+\-*&%=<>!?^\/\|]/; 37 | function chain(stream, state, f) { 38 | state.tokenize = f; 39 | return f(stream, state); 40 | } 41 | function tokenBase(stream, state) { 42 | var beforeParams = state.beforeParams; 43 | state.beforeParams = false; 44 | var ch = stream.next(); 45 | if ((ch == '"' || ch == "'") && state.inParams) { 46 | return chain(stream, state, tokenString(ch)); 47 | } else if (/[\[\]{}\(\),;\.]/.test(ch)) { 48 | if (ch == "(" && beforeParams) state.inParams = true; 49 | else if (ch == ")") state.inParams = false; 50 | return null; 51 | } else if (/\d/.test(ch)) { 52 | stream.eatWhile(/[\w\.]/); 53 | return "number"; 54 | } else if (ch == "#") { 55 | if (stream.eat("*")) 56 | return chain(stream, state, tokenComment); 57 | if (ch == "#" && stream.match(/ *\[ *\[/)) 58 | return chain(stream, state, tokenUnparsed); 59 | stream.skipToEnd(); 60 | return "comment"; 61 | } else if (ch == '"') { 62 | stream.skipTo(/"/); 63 | return "comment"; 64 | } else if (ch == "$") { 65 | stream.eatWhile(/[$_a-z0-9A-Z\.{:]/); 66 | stream.eatWhile(/}/); 67 | state.beforeParams = true; 68 | return "builtin"; 69 | } else if (isOperatorChar.test(ch)) { 70 | stream.eatWhile(isOperatorChar); 71 | return "comment"; 72 | } else { 73 | stream.eatWhile(/[\w\$_{}\xa1-\uffff]/); 74 | var word = stream.current().toLowerCase(); 75 | if (keywords && keywords.propertyIsEnumerable(word)) 76 | return "keyword"; 77 | if (functions && functions.propertyIsEnumerable(word)) { 78 | state.beforeParams = true; 79 | return "keyword"; 80 | } 81 | return null; 82 | } 83 | } 84 | function tokenString(quote) { 85 | return function(stream, state) { 86 | var escaped = false, next, end = false; 87 | while ((next = stream.next()) != null) { 88 | if (next == quote && !escaped) { 89 | end = true; 90 | break; 91 | } 92 | escaped = !escaped && next == "\\"; 93 | } 94 | if (end) state.tokenize = tokenBase; 95 | return "string"; 96 | }; 97 | } 98 | function tokenComment(stream, state) { 99 | var maybeEnd = false, ch; 100 | while (ch = stream.next()) { 101 | if (ch == "#" && maybeEnd) { 102 | state.tokenize = tokenBase; 103 | break; 104 | } 105 | maybeEnd = (ch == "*"); 106 | } 107 | return "comment"; 108 | } 109 | function tokenUnparsed(stream, state) { 110 | var maybeEnd = 0, ch; 111 | while (ch = stream.next()) { 112 | if (ch == "#" && maybeEnd == 2) { 113 | state.tokenize = tokenBase; 114 | break; 115 | } 116 | if (ch == "]") 117 | maybeEnd++; 118 | else if (ch != " ") 119 | maybeEnd = 0; 120 | } 121 | return "meta"; 122 | } 123 | return { 124 | startState: function() { 125 | return { 126 | tokenize: tokenBase, 127 | beforeParams: false, 128 | inParams: false 129 | }; 130 | }, 131 | token: function(stream, state) { 132 | if (stream.eatSpace()) return null; 133 | return state.tokenize(stream, state); 134 | } 135 | }; 136 | }); 137 | CodeMirror.defineMIME("text/x-tcl", "tcl"); 138 | 139 | }); 140 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/toml.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("toml", function () { 15 | return { 16 | startState: function () { 17 | return { 18 | inString: false, 19 | stringType: "", 20 | lhs: true, 21 | inArray: 0 22 | }; 23 | }, 24 | token: function (stream, state) { 25 | //check for state changes 26 | if (!state.inString && ((stream.peek() == '"') || (stream.peek() == "'"))) { 27 | state.stringType = stream.peek(); 28 | stream.next(); // Skip quote 29 | state.inString = true; // Update state 30 | } 31 | if (stream.sol() && state.inArray === 0) { 32 | state.lhs = true; 33 | } 34 | //return state 35 | if (state.inString) { 36 | while (state.inString && !stream.eol()) { 37 | if (stream.peek() === state.stringType) { 38 | stream.next(); // Skip quote 39 | state.inString = false; // Clear flag 40 | } else if (stream.peek() === '\\') { 41 | stream.next(); 42 | stream.next(); 43 | } else { 44 | stream.match(/^.[^\\\"\']*/); 45 | } 46 | } 47 | return state.lhs ? "property string" : "string"; // Token style 48 | } else if (state.inArray && stream.peek() === ']') { 49 | stream.next(); 50 | state.inArray--; 51 | return 'bracket'; 52 | } else if (state.lhs && stream.peek() === '[' && stream.skipTo(']')) { 53 | stream.next();//skip closing ] 54 | // array of objects has an extra open & close [] 55 | if (stream.peek() === ']') stream.next(); 56 | return "atom"; 57 | } else if (stream.peek() === "#") { 58 | stream.skipToEnd(); 59 | return "comment"; 60 | } else if (stream.eatSpace()) { 61 | return null; 62 | } else if (state.lhs && stream.eatWhile(function (c) { return c != '=' && c != ' '; })) { 63 | return "property"; 64 | } else if (state.lhs && stream.peek() === "=") { 65 | stream.next(); 66 | state.lhs = false; 67 | return null; 68 | } else if (!state.lhs && stream.match(/^\d\d\d\d[\d\-\:\.T]*Z/)) { 69 | return 'atom'; //date 70 | } else if (!state.lhs && (stream.match('true') || stream.match('false'))) { 71 | return 'atom'; 72 | } else if (!state.lhs && stream.peek() === '[') { 73 | state.inArray++; 74 | stream.next(); 75 | return 'bracket'; 76 | } else if (!state.lhs && stream.match(/^\-?\d+(?:\.\d+)?/)) { 77 | return 'number'; 78 | } else if (!stream.eatSpace()) { 79 | stream.next(); 80 | } 81 | return null; 82 | } 83 | }; 84 | }); 85 | 86 | CodeMirror.defineMIME('text/x-toml', 'toml'); 87 | 88 | }); 89 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/tornado.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), 7 | require("../../addon/mode/overlay")); 8 | else if (typeof define == "function" && define.amd) // AMD 9 | define(["../../lib/codemirror", "../htmlmixed/htmlmixed", 10 | "../../addon/mode/overlay"], mod); 11 | else // Plain browser env 12 | mod(CodeMirror); 13 | })(function(CodeMirror) { 14 | "use strict"; 15 | 16 | CodeMirror.defineMode("tornado:inner", function() { 17 | var keywords = ["and","as","assert","autoescape","block","break","class","comment","context", 18 | "continue","datetime","def","del","elif","else","end","escape","except", 19 | "exec","extends","false","finally","for","from","global","if","import","in", 20 | "include","is","json_encode","lambda","length","linkify","load","module", 21 | "none","not","or","pass","print","put","raise","raw","return","self","set", 22 | "squeeze","super","true","try","url_escape","while","with","without","xhtml_escape","yield"]; 23 | keywords = new RegExp("^((" + keywords.join(")|(") + "))\\b"); 24 | 25 | function tokenBase (stream, state) { 26 | stream.eatWhile(/[^\{]/); 27 | var ch = stream.next(); 28 | if (ch == "{") { 29 | if (ch = stream.eat(/\{|%|#/)) { 30 | state.tokenize = inTag(ch); 31 | return "tag"; 32 | } 33 | } 34 | } 35 | function inTag (close) { 36 | if (close == "{") { 37 | close = "}"; 38 | } 39 | return function (stream, state) { 40 | var ch = stream.next(); 41 | if ((ch == close) && stream.eat("}")) { 42 | state.tokenize = tokenBase; 43 | return "tag"; 44 | } 45 | if (stream.match(keywords)) { 46 | return "keyword"; 47 | } 48 | return close == "#" ? "comment" : "string"; 49 | }; 50 | } 51 | return { 52 | startState: function () { 53 | return {tokenize: tokenBase}; 54 | }, 55 | token: function (stream, state) { 56 | return state.tokenize(stream, state); 57 | } 58 | }; 59 | }); 60 | 61 | CodeMirror.defineMode("tornado", function(config) { 62 | var htmlBase = CodeMirror.getMode(config, "text/html"); 63 | var tornadoInner = CodeMirror.getMode(config, "tornado:inner"); 64 | return CodeMirror.overlayMode(htmlBase, tornadoInner); 65 | }); 66 | 67 | CodeMirror.defineMIME("text/x-tornado", "tornado"); 68 | }); 69 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/troff.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) 8 | define(["../../lib/codemirror"], mod); 9 | else 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode('troff', function() { 15 | 16 | var words = {}; 17 | 18 | function tokenBase(stream) { 19 | if (stream.eatSpace()) return null; 20 | 21 | var sol = stream.sol(); 22 | var ch = stream.next(); 23 | 24 | if (ch === '\\') { 25 | if (stream.match('fB') || stream.match('fR') || stream.match('fI') || 26 | stream.match('u') || stream.match('d') || 27 | stream.match('%') || stream.match('&')) { 28 | return 'string'; 29 | } 30 | if (stream.match('m[')) { 31 | stream.skipTo(']'); 32 | stream.next(); 33 | return 'string'; 34 | } 35 | if (stream.match('s+') || stream.match('s-')) { 36 | stream.eatWhile(/[\d-]/); 37 | return 'string'; 38 | } 39 | if (stream.match('\(') || stream.match('*\(')) { 40 | stream.eatWhile(/[\w-]/); 41 | return 'string'; 42 | } 43 | return 'string'; 44 | } 45 | if (sol && (ch === '.' || ch === '\'')) { 46 | if (stream.eat('\\') && stream.eat('\"')) { 47 | stream.skipToEnd(); 48 | return 'comment'; 49 | } 50 | } 51 | if (sol && ch === '.') { 52 | if (stream.match('B ') || stream.match('I ') || stream.match('R ')) { 53 | return 'attribute'; 54 | } 55 | if (stream.match('TH ') || stream.match('SH ') || stream.match('SS ') || stream.match('HP ')) { 56 | stream.skipToEnd(); 57 | return 'quote'; 58 | } 59 | if ((stream.match(/[A-Z]/) && stream.match(/[A-Z]/)) || (stream.match(/[a-z]/) && stream.match(/[a-z]/))) { 60 | return 'attribute'; 61 | } 62 | } 63 | stream.eatWhile(/[\w-]/); 64 | var cur = stream.current(); 65 | return words.hasOwnProperty(cur) ? words[cur] : null; 66 | } 67 | 68 | function tokenize(stream, state) { 69 | return (state.tokens[0] || tokenBase) (stream, state); 70 | }; 71 | 72 | return { 73 | startState: function() {return {tokens:[]};}, 74 | token: function(stream, state) { 75 | return tokenize(stream, state); 76 | } 77 | }; 78 | }); 79 | 80 | CodeMirror.defineMIME('text/troff', 'troff'); 81 | CodeMirror.defineMIME('text/x-troff', 'troff'); 82 | CodeMirror.defineMIME('application/x-troff', 'troff'); 83 | 84 | }); 85 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/turtle.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("turtle", function(config) { 15 | var indentUnit = config.indentUnit; 16 | var curPunc; 17 | 18 | function wordRegexp(words) { 19 | return new RegExp("^(?:" + words.join("|") + ")$", "i"); 20 | } 21 | var ops = wordRegexp([]); 22 | var keywords = wordRegexp(["@prefix", "@base", "a"]); 23 | var operatorChars = /[*+\-<>=&|]/; 24 | 25 | function tokenBase(stream, state) { 26 | var ch = stream.next(); 27 | curPunc = null; 28 | if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) { 29 | stream.match(/^[^\s\u00a0>]*>?/); 30 | return "atom"; 31 | } 32 | else if (ch == "\"" || ch == "'") { 33 | state.tokenize = tokenLiteral(ch); 34 | return state.tokenize(stream, state); 35 | } 36 | else if (/[{}\(\),\.;\[\]]/.test(ch)) { 37 | curPunc = ch; 38 | return null; 39 | } 40 | else if (ch == "#") { 41 | stream.skipToEnd(); 42 | return "comment"; 43 | } 44 | else if (operatorChars.test(ch)) { 45 | stream.eatWhile(operatorChars); 46 | return null; 47 | } 48 | else if (ch == ":") { 49 | return "operator"; 50 | } else { 51 | stream.eatWhile(/[_\w\d]/); 52 | if(stream.peek() == ":") { 53 | return "variable-3"; 54 | } else { 55 | var word = stream.current(); 56 | 57 | if(keywords.test(word)) { 58 | return "meta"; 59 | } 60 | 61 | if(ch >= "A" && ch <= "Z") { 62 | return "comment"; 63 | } else { 64 | return "keyword"; 65 | } 66 | } 67 | var word = stream.current(); 68 | if (ops.test(word)) 69 | return null; 70 | else if (keywords.test(word)) 71 | return "meta"; 72 | else 73 | return "variable"; 74 | } 75 | } 76 | 77 | function tokenLiteral(quote) { 78 | return function(stream, state) { 79 | var escaped = false, ch; 80 | while ((ch = stream.next()) != null) { 81 | if (ch == quote && !escaped) { 82 | state.tokenize = tokenBase; 83 | break; 84 | } 85 | escaped = !escaped && ch == "\\"; 86 | } 87 | return "string"; 88 | }; 89 | } 90 | 91 | function pushContext(state, type, col) { 92 | state.context = {prev: state.context, indent: state.indent, col: col, type: type}; 93 | } 94 | function popContext(state) { 95 | state.indent = state.context.indent; 96 | state.context = state.context.prev; 97 | } 98 | 99 | return { 100 | startState: function() { 101 | return {tokenize: tokenBase, 102 | context: null, 103 | indent: 0, 104 | col: 0}; 105 | }, 106 | 107 | token: function(stream, state) { 108 | if (stream.sol()) { 109 | if (state.context && state.context.align == null) state.context.align = false; 110 | state.indent = stream.indentation(); 111 | } 112 | if (stream.eatSpace()) return null; 113 | var style = state.tokenize(stream, state); 114 | 115 | if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") { 116 | state.context.align = true; 117 | } 118 | 119 | if (curPunc == "(") pushContext(state, ")", stream.column()); 120 | else if (curPunc == "[") pushContext(state, "]", stream.column()); 121 | else if (curPunc == "{") pushContext(state, "}", stream.column()); 122 | else if (/[\]\}\)]/.test(curPunc)) { 123 | while (state.context && state.context.type == "pattern") popContext(state); 124 | if (state.context && curPunc == state.context.type) popContext(state); 125 | } 126 | else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state); 127 | else if (/atom|string|variable/.test(style) && state.context) { 128 | if (/[\}\]]/.test(state.context.type)) 129 | pushContext(state, "pattern", stream.column()); 130 | else if (state.context.type == "pattern" && !state.context.align) { 131 | state.context.align = true; 132 | state.context.col = stream.column(); 133 | } 134 | } 135 | 136 | return style; 137 | }, 138 | 139 | indent: function(state, textAfter) { 140 | var firstChar = textAfter && textAfter.charAt(0); 141 | var context = state.context; 142 | if (/[\]\}]/.test(firstChar)) 143 | while (context && context.type == "pattern") context = context.prev; 144 | 145 | var closing = context && firstChar == context.type; 146 | if (!context) 147 | return 0; 148 | else if (context.type == "pattern") 149 | return context.col; 150 | else if (context.align) 151 | return context.col + (closing ? 0 : 1); 152 | else 153 | return context.indent + (closing ? 0 : indentUnit); 154 | }, 155 | 156 | lineComment: "#" 157 | }; 158 | }); 159 | 160 | CodeMirror.defineMIME("text/turtle", "turtle"); 161 | 162 | }); 163 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/twig.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("../../addon/mode/multiplex")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "../../addon/mode/multiplex"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("twig:inner", function() { 15 | var keywords = ["and", "as", "autoescape", "endautoescape", "block", "do", "endblock", "else", "elseif", "extends", "for", "endfor", "embed", "endembed", "filter", "endfilter", "flush", "from", "if", "endif", "in", "is", "include", "import", "not", "or", "set", "spaceless", "endspaceless", "with", "endwith", "trans", "endtrans", "blocktrans", "endblocktrans", "macro", "endmacro", "use", "verbatim", "endverbatim"], 16 | operator = /^[+\-*&%=<>!?|~^]/, 17 | sign = /^[:\[\(\{]/, 18 | atom = ["true", "false", "null", "empty", "defined", "divisibleby", "divisible by", "even", "odd", "iterable", "sameas", "same as"], 19 | number = /^(\d[+\-\*\/])?\d+(\.\d+)?/; 20 | 21 | keywords = new RegExp("((" + keywords.join(")|(") + "))\\b"); 22 | atom = new RegExp("((" + atom.join(")|(") + "))\\b"); 23 | 24 | function tokenBase (stream, state) { 25 | var ch = stream.peek(); 26 | 27 | //Comment 28 | if (state.incomment) { 29 | if (!stream.skipTo("#}")) { 30 | stream.skipToEnd(); 31 | } else { 32 | stream.eatWhile(/\#|}/); 33 | state.incomment = false; 34 | } 35 | return "comment"; 36 | //Tag 37 | } else if (state.intag) { 38 | //After operator 39 | if (state.operator) { 40 | state.operator = false; 41 | if (stream.match(atom)) { 42 | return "atom"; 43 | } 44 | if (stream.match(number)) { 45 | return "number"; 46 | } 47 | } 48 | //After sign 49 | if (state.sign) { 50 | state.sign = false; 51 | if (stream.match(atom)) { 52 | return "atom"; 53 | } 54 | if (stream.match(number)) { 55 | return "number"; 56 | } 57 | } 58 | 59 | if (state.instring) { 60 | if (ch == state.instring) { 61 | state.instring = false; 62 | } 63 | stream.next(); 64 | return "string"; 65 | } else if (ch == "'" || ch == '"') { 66 | state.instring = ch; 67 | stream.next(); 68 | return "string"; 69 | } else if (stream.match(state.intag + "}") || stream.eat("-") && stream.match(state.intag + "}")) { 70 | state.intag = false; 71 | return "tag"; 72 | } else if (stream.match(operator)) { 73 | state.operator = true; 74 | return "operator"; 75 | } else if (stream.match(sign)) { 76 | state.sign = true; 77 | } else { 78 | if (stream.eat(" ") || stream.sol()) { 79 | if (stream.match(keywords)) { 80 | return "keyword"; 81 | } 82 | if (stream.match(atom)) { 83 | return "atom"; 84 | } 85 | if (stream.match(number)) { 86 | return "number"; 87 | } 88 | if (stream.sol()) { 89 | stream.next(); 90 | } 91 | } else { 92 | stream.next(); 93 | } 94 | 95 | } 96 | return "variable"; 97 | } else if (stream.eat("{")) { 98 | if (ch = stream.eat("#")) { 99 | state.incomment = true; 100 | if (!stream.skipTo("#}")) { 101 | stream.skipToEnd(); 102 | } else { 103 | stream.eatWhile(/\#|}/); 104 | state.incomment = false; 105 | } 106 | return "comment"; 107 | //Open tag 108 | } else if (ch = stream.eat(/\{|%/)) { 109 | //Cache close tag 110 | state.intag = ch; 111 | if (ch == "{") { 112 | state.intag = "}"; 113 | } 114 | stream.eat("-"); 115 | return "tag"; 116 | } 117 | } 118 | stream.next(); 119 | }; 120 | 121 | return { 122 | startState: function () { 123 | return {}; 124 | }, 125 | token: function (stream, state) { 126 | return tokenBase(stream, state); 127 | } 128 | }; 129 | }); 130 | 131 | CodeMirror.defineMode("twig", function(config, parserConfig) { 132 | var twigInner = CodeMirror.getMode(config, "twig:inner"); 133 | if (!parserConfig || !parserConfig.base) return twigInner; 134 | return CodeMirror.multiplexingMode( 135 | CodeMirror.getMode(config, parserConfig.base), { 136 | open: /\{[{#%]/, close: /[}#%]\}/, mode: twigInner, parseDelimiters: true 137 | } 138 | ); 139 | }); 140 | CodeMirror.defineMIME("text/x-twig", "twig"); 141 | }); 142 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/vue.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function (mod) { 5 | "use strict"; 6 | if (typeof exports === "object" && typeof module === "object") {// CommonJS 7 | mod(require("../../lib/codemirror"), 8 | require("../../addon/mode/overlay"), 9 | require("../xml/xml"), 10 | require("../javascript/javascript"), 11 | require("../coffeescript/coffeescript"), 12 | require("../css/css"), 13 | require("../sass/sass"), 14 | require("../stylus/stylus"), 15 | require("../jade/jade"), 16 | require("../handlebars/handlebars")); 17 | } else if (typeof define === "function" && define.amd) { // AMD 18 | define(["../../lib/codemirror", 19 | "../../addon/mode/overlay", 20 | "../xml/xml", 21 | "../javascript/javascript", 22 | "../coffeescript/coffeescript", 23 | "../css/css", 24 | "../sass/sass", 25 | "../stylus/stylus", 26 | "../jade/jade", 27 | "../handlebars/handlebars"], mod); 28 | } else { // Plain browser env 29 | mod(CodeMirror); 30 | } 31 | })(function (CodeMirror) { 32 | var tagLanguages = { 33 | script: [ 34 | ["lang", /coffee(script)?/, "coffeescript"], 35 | ["type", /^(?:text|application)\/(?:x-)?coffee(?:script)?$/, "coffeescript"] 36 | ], 37 | style: [ 38 | ["lang", /^stylus$/i, "stylus"], 39 | ["lang", /^sass$/i, "sass"], 40 | ["type", /^(text\/)?(x-)?styl(us)?$/i, "stylus"], 41 | ["type", /^text\/sass/i, "sass"] 42 | ], 43 | template: [ 44 | ["lang", /^vue-template$/i, "vue"], 45 | ["lang", /^jade$/i, "jade"], 46 | ["lang", /^handlebars$/i, "handlebars"], 47 | ["type", /^(text\/)?(x-)?jade$/i, "jade"], 48 | ["type", /^text\/x-handlebars-template$/i, "handlebars"], 49 | [null, null, "vue-template"] 50 | ] 51 | }; 52 | 53 | CodeMirror.defineMode("vue-template", function (config, parserConfig) { 54 | var mustacheOverlay = { 55 | token: function (stream) { 56 | if (stream.match(/^\{\{.*?\}\}/)) return "meta mustache"; 57 | while (stream.next() && !stream.match("{{", false)) {} 58 | return null; 59 | } 60 | }; 61 | return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || "text/html"), mustacheOverlay); 62 | }); 63 | 64 | CodeMirror.defineMode("vue", function (config) { 65 | return CodeMirror.getMode(config, {name: "htmlmixed", tags: tagLanguages}); 66 | }, "htmlmixed", "xml", "javascript", "coffeescript", "css", "sass", "stylus", "jade", "handlebars"); 67 | 68 | CodeMirror.defineMIME("script/x-vue", "vue"); 69 | }); 70 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/xu_test.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function() { 5 | var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-xu"); 6 | function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "xu"); } 7 | 8 | MT("empty chart", 9 | "[keyword msc][bracket {]", 10 | "[base ]", 11 | "[bracket }]" 12 | ); 13 | 14 | MT("comments", 15 | "[comment // a single line comment]", 16 | "[comment # another single line comment /* and */ ignored here]", 17 | "[comment /* A multi-line comment even though it contains]", 18 | "[comment msc keywords and \"quoted text\"*/]"); 19 | 20 | MT("strings", 21 | "[string \"// a string\"]", 22 | "[string \"a string running over]", 23 | "[string two lines\"]", 24 | "[string \"with \\\"escaped quote\"]" 25 | ); 26 | 27 | MT("xù/ msgenny keywords classify as 'keyword'", 28 | "[keyword watermark]", 29 | "[keyword alt]","[keyword loop]","[keyword opt]","[keyword ref]","[keyword else]","[keyword break]","[keyword par]","[keyword seq]","[keyword assert]" 30 | ); 31 | 32 | MT("mscgen options classify as keyword", 33 | "[keyword hscale]", "[keyword width]", "[keyword arcgradient]", "[keyword wordwraparcs]" 34 | ); 35 | 36 | MT("mscgen arcs classify as keyword", 37 | "[keyword note]","[keyword abox]","[keyword rbox]","[keyword box]", 38 | "[keyword |||...---]", "[keyword ..--==::]", 39 | "[keyword ->]", "[keyword <-]", "[keyword <->]", 40 | "[keyword =>]", "[keyword <=]", "[keyword <=>]", 41 | "[keyword =>>]", "[keyword <<=]", "[keyword <<=>>]", 42 | "[keyword >>]", "[keyword <<]", "[keyword <<>>]", 43 | "[keyword -x]", "[keyword x-]", "[keyword -X]", "[keyword X-]", 44 | "[keyword :>]", "[keyword <:]", "[keyword <:>]" 45 | ); 46 | 47 | MT("within an attribute list, attributes classify as attribute", 48 | "[bracket [[][attribute label]", 49 | "[attribute id]","[attribute url]","[attribute idurl]", 50 | "[attribute linecolor]","[attribute linecolour]","[attribute textcolor]","[attribute textcolour]","[attribute textbgcolor]","[attribute textbgcolour]", 51 | "[attribute arclinecolor]","[attribute arclinecolour]","[attribute arctextcolor]","[attribute arctextcolour]","[attribute arctextbgcolor]","[attribute arctextbgcolour]", 52 | "[attribute arcskip][bracket ]]]" 53 | ); 54 | 55 | MT("outside an attribute list, attributes classify as base", 56 | "[base label]", 57 | "[base id]","[base url]","[base idurl]", 58 | "[base linecolor]","[base linecolour]","[base textcolor]","[base textcolour]","[base textbgcolor]","[base textbgcolour]", 59 | "[base arclinecolor]","[base arclinecolour]","[base arctextcolor]","[base arctextcolour]","[base arctextbgcolor]","[base arctextbgcolour]", 60 | "[base arcskip]" 61 | ); 62 | 63 | MT("a typical program", 64 | "[comment # typical mscgen program]", 65 | "[keyword msc][base ][bracket {]", 66 | "[keyword wordwraparcs][operator =][string \"true\"][keyword hscale][operator =][string \"0.8\"][keyword arcgradient][operator =][base 30;]", 67 | "[base a][bracket [[][attribute label][operator =][string \"Entity A\"][bracket ]]][base ,]", 68 | "[base b][bracket [[][attribute label][operator =][string \"Entity B\"][bracket ]]][base ,]", 69 | "[base c][bracket [[][attribute label][operator =][string \"Entity C\"][bracket ]]][base ;]", 70 | "[base a ][keyword =>>][base b][bracket [[][attribute label][operator =][string \"Hello entity B\"][bracket ]]][base ;]", 71 | "[base a ][keyword <<][base b][bracket [[][attribute label][operator =][string \"Here's an answer dude!\"][bracket ]]][base ;]", 72 | "[base c ][keyword :>][base *][bracket [[][attribute label][operator =][string \"What about me?\"][base , ][attribute textcolor][operator =][base red][bracket ]]][base ;]", 73 | "[bracket }]" 74 | ); 75 | })(); 76 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/yaml-frontmatter.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function (mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("../yaml/yaml")) 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "../yaml/yaml"], mod) 9 | else // Plain browser env 10 | mod(CodeMirror) 11 | })(function (CodeMirror) { 12 | 13 | var START = 0, FRONTMATTER = 1, BODY = 2 14 | 15 | // a mixed mode for Markdown text with an optional YAML front matter 16 | CodeMirror.defineMode("yaml-frontmatter", function (config, parserConfig) { 17 | var yamlMode = CodeMirror.getMode(config, "yaml") 18 | var innerMode = CodeMirror.getMode(config, parserConfig && parserConfig.base || "gfm") 19 | 20 | function curMode(state) { 21 | return state.state == BODY ? innerMode : yamlMode 22 | } 23 | 24 | return { 25 | startState: function () { 26 | return { 27 | state: START, 28 | inner: CodeMirror.startState(yamlMode) 29 | } 30 | }, 31 | copyState: function (state) { 32 | return { 33 | state: state.state, 34 | inner: CodeMirror.copyState(curMode(state), state.inner) 35 | } 36 | }, 37 | token: function (stream, state) { 38 | if (state.state == START) { 39 | if (stream.match(/---/, false)) { 40 | state.state = FRONTMATTER 41 | return yamlMode.token(stream, state.inner) 42 | } else { 43 | state.state = BODY 44 | state.inner = CodeMirror.startState(innerMode) 45 | return innerMode.token(stream, state.inner) 46 | } 47 | } else if (state.state == FRONTMATTER) { 48 | var end = stream.sol() && stream.match(/---/, false) 49 | var style = yamlMode.token(stream, state.inner) 50 | if (end) { 51 | state.state = BODY 52 | state.inner = CodeMirror.startState(innerMode) 53 | } 54 | return style 55 | } else { 56 | return innerMode.token(stream, state.inner) 57 | } 58 | }, 59 | innerMode: function (state) { 60 | return {mode: curMode(state), state: state.inner} 61 | }, 62 | blankLine: function (state) { 63 | var mode = curMode(state) 64 | if (mode.blankLine) return mode.blankLine(state.inner) 65 | } 66 | } 67 | }) 68 | }); 69 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/yaml.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("yaml", function() { 15 | 16 | var cons = ['true', 'false', 'on', 'off', 'yes', 'no']; 17 | var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i'); 18 | 19 | return { 20 | token: function(stream, state) { 21 | var ch = stream.peek(); 22 | var esc = state.escaped; 23 | state.escaped = false; 24 | /* comments */ 25 | if (ch == "#" && (stream.pos == 0 || /\s/.test(stream.string.charAt(stream.pos - 1)))) { 26 | stream.skipToEnd(); 27 | return "comment"; 28 | } 29 | 30 | if (stream.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/)) 31 | return "string"; 32 | 33 | if (state.literal && stream.indentation() > state.keyCol) { 34 | stream.skipToEnd(); return "string"; 35 | } else if (state.literal) { state.literal = false; } 36 | if (stream.sol()) { 37 | state.keyCol = 0; 38 | state.pair = false; 39 | state.pairStart = false; 40 | /* document start */ 41 | if(stream.match(/---/)) { return "def"; } 42 | /* document end */ 43 | if (stream.match(/\.\.\./)) { return "def"; } 44 | /* array list item */ 45 | if (stream.match(/\s*-\s+/)) { return 'meta'; } 46 | } 47 | /* inline pairs/lists */ 48 | if (stream.match(/^(\{|\}|\[|\])/)) { 49 | if (ch == '{') 50 | state.inlinePairs++; 51 | else if (ch == '}') 52 | state.inlinePairs--; 53 | else if (ch == '[') 54 | state.inlineList++; 55 | else 56 | state.inlineList--; 57 | return 'meta'; 58 | } 59 | 60 | /* list seperator */ 61 | if (state.inlineList > 0 && !esc && ch == ',') { 62 | stream.next(); 63 | return 'meta'; 64 | } 65 | /* pairs seperator */ 66 | if (state.inlinePairs > 0 && !esc && ch == ',') { 67 | state.keyCol = 0; 68 | state.pair = false; 69 | state.pairStart = false; 70 | stream.next(); 71 | return 'meta'; 72 | } 73 | 74 | /* start of value of a pair */ 75 | if (state.pairStart) { 76 | /* block literals */ 77 | if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; }; 78 | /* references */ 79 | if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; } 80 | /* numbers */ 81 | if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; } 82 | if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; } 83 | /* keywords */ 84 | if (stream.match(keywordRegex)) { return 'keyword'; } 85 | } 86 | 87 | /* pairs (associative arrays) -> key */ 88 | if (!state.pair && stream.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)) { 89 | state.pair = true; 90 | state.keyCol = stream.indentation(); 91 | return "atom"; 92 | } 93 | if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; } 94 | 95 | /* nothing found, continue */ 96 | state.pairStart = false; 97 | state.escaped = (ch == '\\'); 98 | stream.next(); 99 | return null; 100 | }, 101 | startState: function() { 102 | return { 103 | pair: false, 104 | pairStart: false, 105 | keyCol: 0, 106 | inlinePairs: 0, 107 | inlineList: 0, 108 | literal: false, 109 | escaped: false 110 | }; 111 | } 112 | }; 113 | }); 114 | 115 | CodeMirror.defineMIME("text/x-yaml", "yaml"); 116 | 117 | }); 118 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/langs/z80.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode('z80', function(_config, parserConfig) { 15 | var ez80 = parserConfig.ez80; 16 | var keywords1, keywords2; 17 | if (ez80) { 18 | keywords1 = /^(exx?|(ld|cp)([di]r?)?|[lp]ea|pop|push|ad[cd]|cpl|daa|dec|inc|neg|sbc|sub|and|bit|[cs]cf|x?or|res|set|r[lr]c?a?|r[lr]d|s[lr]a|srl|djnz|nop|[de]i|halt|im|in([di]mr?|ir?|irx|2r?)|ot(dmr?|[id]rx|imr?)|out(0?|[di]r?|[di]2r?)|tst(io)?|slp)(\.([sl]?i)?[sl])?\b/i; 19 | keywords2 = /^(((call|j[pr]|rst|ret[in]?)(\.([sl]?i)?[sl])?)|(rs|st)mix)\b/i; 20 | } else { 21 | keywords1 = /^(exx?|(ld|cp|in)([di]r?)?|pop|push|ad[cd]|cpl|daa|dec|inc|neg|sbc|sub|and|bit|[cs]cf|x?or|res|set|r[lr]c?a?|r[lr]d|s[lr]a|srl|djnz|nop|rst|[de]i|halt|im|ot[di]r|out[di]?)\b/i; 22 | keywords2 = /^(call|j[pr]|ret[in]?|b_?(call|jump))\b/i; 23 | } 24 | 25 | var variables1 = /^(af?|bc?|c|de?|e|hl?|l|i[xy]?|r|sp)\b/i; 26 | var variables2 = /^(n?[zc]|p[oe]?|m)\b/i; 27 | var errors = /^([hl][xy]|i[xy][hl]|slia|sll)\b/i; 28 | var numbers = /^([\da-f]+h|[0-7]+o|[01]+b|\d+d?)\b/i; 29 | 30 | return { 31 | startState: function() { 32 | return { 33 | context: 0 34 | }; 35 | }, 36 | token: function(stream, state) { 37 | if (!stream.column()) 38 | state.context = 0; 39 | 40 | if (stream.eatSpace()) 41 | return null; 42 | 43 | var w; 44 | 45 | if (stream.eatWhile(/\w/)) { 46 | if (ez80 && stream.eat('.')) { 47 | stream.eatWhile(/\w/); 48 | } 49 | w = stream.current(); 50 | 51 | if (stream.indentation()) { 52 | if ((state.context == 1 || state.context == 4) && variables1.test(w)) { 53 | state.context = 4; 54 | return 'var2'; 55 | } 56 | 57 | if (state.context == 2 && variables2.test(w)) { 58 | state.context = 4; 59 | return 'var3'; 60 | } 61 | 62 | if (keywords1.test(w)) { 63 | state.context = 1; 64 | return 'keyword'; 65 | } else if (keywords2.test(w)) { 66 | state.context = 2; 67 | return 'keyword'; 68 | } else if (state.context == 4 && numbers.test(w)) { 69 | return 'number'; 70 | } 71 | 72 | if (errors.test(w)) 73 | return 'error'; 74 | } else if (stream.match(numbers)) { 75 | return 'number'; 76 | } else { 77 | return null; 78 | } 79 | } else if (stream.eat(';')) { 80 | stream.skipToEnd(); 81 | return 'comment'; 82 | } else if (stream.eat('"')) { 83 | while (w = stream.next()) { 84 | if (w == '"') 85 | break; 86 | 87 | if (w == '\\') 88 | stream.next(); 89 | } 90 | return 'string'; 91 | } else if (stream.eat('\'')) { 92 | if (stream.match(/\\?.'/)) 93 | return 'number'; 94 | } else if (stream.eat('.') || stream.sol() && stream.eat('#')) { 95 | state.context = 5; 96 | 97 | if (stream.eatWhile(/\w/)) 98 | return 'def'; 99 | } else if (stream.eat('$')) { 100 | if (stream.eatWhile(/[\da-f]/i)) 101 | return 'number'; 102 | } else if (stream.eat('%')) { 103 | if (stream.eatWhile(/[01]/)) 104 | return 'number'; 105 | } else { 106 | stream.next(); 107 | } 108 | return null; 109 | } 110 | }; 111 | }); 112 | 113 | CodeMirror.defineMIME("text/x-z80", "z80"); 114 | CodeMirror.defineMIME("text/x-ez80", { name: "z80", ez80: true }); 115 | 116 | }); 117 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/loadmode.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), "cjs"); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], function(CM) { mod(CM, "amd"); }); 9 | else // Plain browser env 10 | mod(CodeMirror, "plain"); 11 | })(function(CodeMirror, env) { 12 | if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js"; 13 | 14 | var loading = {}; 15 | function splitCallback(cont, n) { 16 | var countDown = n; 17 | return function() { if (--countDown == 0) cont(); }; 18 | } 19 | function ensureDeps(mode, cont) { 20 | var deps = CodeMirror.modes[mode].dependencies; 21 | if (!deps) return cont(); 22 | var missing = []; 23 | for (var i = 0; i < deps.length; ++i) { 24 | if (!CodeMirror.modes.hasOwnProperty(deps[i])) 25 | missing.push(deps[i]); 26 | } 27 | if (!missing.length) return cont(); 28 | var split = splitCallback(cont, missing.length); 29 | for (var i = 0; i < missing.length; ++i) 30 | CodeMirror.requireMode(missing[i], split); 31 | } 32 | 33 | CodeMirror.requireMode = function(mode, cont) { 34 | if (typeof mode != "string") mode = mode.name; 35 | if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont); 36 | if (loading.hasOwnProperty(mode)) return loading[mode].push(cont); 37 | 38 | var file = CodeMirror.modeURL.replace(/%N/g, mode); 39 | if (env == "plain") { 40 | var script = document.createElement("script"); 41 | script.src = file; 42 | var others = document.getElementsByTagName("script")[0]; 43 | var list = loading[mode] = [cont]; 44 | CodeMirror.on(script, "load", function() { 45 | ensureDeps(mode, function() { 46 | for (var i = 0; i < list.length; ++i) list[i](); 47 | }); 48 | }); 49 | others.parentNode.insertBefore(script, others); 50 | } else if (env == "cjs") { 51 | require(file); 52 | cont(); 53 | } else if (env == "amd") { 54 | requirejs([file], cont); 55 | } 56 | }; 57 | 58 | CodeMirror.autoLoadMode = function(instance, mode) { 59 | if (!CodeMirror.modes.hasOwnProperty(mode)) 60 | CodeMirror.requireMode(mode, function() { 61 | instance.setOption("mode", instance.getOption("mode")); 62 | }); 63 | }; 64 | }); 65 | -------------------------------------------------------------------------------- /pbnh/app/static/codemirror/monokai.css: -------------------------------------------------------------------------------- 1 | /* Based on Sublime Text's Monokai theme */ 2 | 3 | .cm-s-monokai.CodeMirror { background: #272822; color: #f8f8f2; } 4 | .cm-s-monokai div.CodeMirror-selected { background: #49483E; } 5 | .cm-s-monokai .CodeMirror-line::selection, .cm-s-monokai .CodeMirror-line > span::selection, .cm-s-monokai .CodeMirror-line > span > span::selection { background: rgba(73, 72, 62, .99); } 6 | .cm-s-monokai .CodeMirror-line::-moz-selection, .cm-s-monokai .CodeMirror-line > span::-moz-selection, .cm-s-monokai .CodeMirror-line > span > span::-moz-selection { background: rgba(73, 72, 62, .99); } 7 | .cm-s-monokai .CodeMirror-gutters { background: #272822; border-right: 0px; } 8 | .cm-s-monokai .CodeMirror-guttermarker { color: white; } 9 | .cm-s-monokai .CodeMirror-guttermarker-subtle { color: #d0d0d0; } 10 | .cm-s-monokai .CodeMirror-linenumber { color: #d0d0d0; } 11 | .cm-s-monokai .CodeMirror-cursor { border-left: 1px solid #f8f8f0; } 12 | 13 | .cm-s-monokai span.cm-comment { color: #75715e; } 14 | .cm-s-monokai span.cm-atom { color: #ae81ff; } 15 | .cm-s-monokai span.cm-number { color: #ae81ff; } 16 | 17 | .cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute { color: #a6e22e; } 18 | .cm-s-monokai span.cm-keyword { color: #f92672; } 19 | .cm-s-monokai span.cm-builtin { color: #66d9ef; } 20 | .cm-s-monokai span.cm-string { color: #e6db74; } 21 | 22 | .cm-s-monokai span.cm-variable { color: #f8f8f2; } 23 | .cm-s-monokai span.cm-variable-2 { color: #9effff; } 24 | .cm-s-monokai span.cm-variable-3 { color: #66d9ef; } 25 | .cm-s-monokai span.cm-def { color: #fd971f; } 26 | .cm-s-monokai span.cm-bracket { color: #f8f8f2; } 27 | .cm-s-monokai span.cm-tag { color: #f92672; } 28 | .cm-s-monokai span.cm-header { color: #ae81ff; } 29 | .cm-s-monokai span.cm-link { color: #ae81ff; } 30 | .cm-s-monokai span.cm-error { background: #f92672; color: #f8f8f0; } 31 | 32 | .cm-s-monokai .CodeMirror-activeline-background { background: #373831; } 33 | .cm-s-monokai .CodeMirror-matchingbracket { 34 | text-decoration: underline; 35 | color: white !important; 36 | } 37 | -------------------------------------------------------------------------------- /pbnh/app/static/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhanderson/pbnh/59bcb27de1a2300f14476349f3182c651a8f88a1/pbnh/app/static/fontawesome-webfont.eot -------------------------------------------------------------------------------- /pbnh/app/static/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhanderson/pbnh/59bcb27de1a2300f14476349f3182c651a8f88a1/pbnh/app/static/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /pbnh/app/static/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhanderson/pbnh/59bcb27de1a2300f14476349f3182c651a8f88a1/pbnh/app/static/fontawesome-webfont.woff -------------------------------------------------------------------------------- /pbnh/app/static/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhanderson/pbnh/59bcb27de1a2300f14476349f3182c651a8f88a1/pbnh/app/static/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /pbnh/app/templates/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Paste Not Found 4 | 5 | 41 | 42 | 43 |

Paste Not Found

44 |

Sorry, but the paste you were trying to view does not exist, or you 45 | have selected an invalid extension.

46 | 47 | 48 | -------------------------------------------------------------------------------- /pbnh/app/templates/asciinema.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /pbnh/app/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 | 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /pbnh/app/templates/layout.html: -------------------------------------------------------------------------------- 1 | 2 | pbnh 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
20 |
28 |
36 |
44 | 45 | 54 | 55 | 56 | 57 | 94 | 95 | {% block body %}{% endblock %} 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /pbnh/app/templates/markdown.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | pbnh 4 | 5 | 6 | 7 |
8 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /pbnh/app/templates/paste.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |

If you are seeing this your paste is really big and 4 | is taking a while to load. You can always add .<extension>to the 5 | end of it to load the paste directly to the browser with the correct 6 | mimetype

7 | 10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /pbnh/app/templates/raw.html: -------------------------------------------------------------------------------- 1 | {{paste}} 2 | -------------------------------------------------------------------------------- /pbnh/app/util.py: -------------------------------------------------------------------------------- 1 | import io 2 | import magic 3 | import mimetypes 4 | import tempfile 5 | 6 | from pbnh.db import paste 7 | from pbnh.app import app 8 | from datetime import datetime, timezone, timedelta 9 | 10 | 11 | def getConfig(): 12 | if app.config.get('CONFIG'): 13 | return app.config.get('CONFIG').get('database') 14 | else: 15 | return conf.get_config().get('database') 16 | 17 | def fileData(files, addr=None, sunset=None, mimestr=None): 18 | config = getConfig() 19 | try: 20 | buf = files.stream 21 | if buf and isinstance(buf, io.BytesIO) or isinstance(buf, 22 | io.BufferedRandom) or isinstance(buf, tempfile.SpooledTemporaryFile): 23 | data = buf.read() 24 | mime = getMime(data=data, mimestr=mimestr) 25 | with paste.Paster(dialect=config.get('dialect'), dbname=config.get('dbname'), 26 | driver=config.get('driver'), host=config.get('host'), 27 | password=config.get('password'), port=config.get('port'), 28 | username=config.get('username')) as pstr: 29 | j = pstr.create(data, mime=mime, ip=addr, 30 | sunset=sunset) 31 | return j 32 | except IOError as e: 33 | return 'caught exception in filedata' + str(e) 34 | return 'File save error' 35 | 36 | def stringData(inputstr, addr=None, sunset=None, mime=None): 37 | config = getConfig() 38 | with paste.Paster(dialect=config.get('dialect'), dbname=config.get('dbname'), 39 | driver=config.get('driver'), host=config.get('host'), 40 | password=config.get('password'), port=config.get('port'), 41 | username=config.get('username')) as pstr: 42 | j = pstr.create(inputstr.encode('utf-8'), mime=mime, ip=addr, sunset=sunset) 43 | return j 44 | return 'String save error' 45 | 46 | def getSunsetFromStr(sunsetstr): 47 | if sunsetstr: 48 | try: 49 | plustime = int(sunsetstr) 50 | return datetime.now(timezone.utc) + timedelta(seconds=plustime) 51 | except ValueError: 52 | return None 53 | return None 54 | 55 | def getMime(data=None, mimestr=None): 56 | if mimestr: 57 | return mimetypes.guess_type('file.{0}'.format(mimestr))[0] 58 | elif data: 59 | return magic.from_buffer(data, mime=True) 60 | return 'text/plain' 61 | 62 | def getPaste(paste_id): 63 | config = getConfig() 64 | with paste.Paster(dialect=config.get('dialect'), dbname=config.get('dbname'), 65 | driver=config.get('driver'), host=config.get('host'), 66 | password=config.get('password'), 67 | port=str(config.get('port')), 68 | username=config.get('username')) as pstr: 69 | try: 70 | return pstr.query(hashid=paste_id) 71 | except ValueError: 72 | return None 73 | return None 74 | -------------------------------------------------------------------------------- /pbnh/conf.py: -------------------------------------------------------------------------------- 1 | import yaml 2 | import copy 3 | 4 | DEFAULTS = { 5 | "server": { 6 | "bind_ip": "0.0.0.0", 7 | "bind_port": 5001, 8 | "debug": True, 9 | }, 10 | "database": { 11 | "dbname": "pastedb", 12 | "dialect": "sqlite", 13 | "driver": None, 14 | "host": None, 15 | "password": None, 16 | "port": None, 17 | "username": None 18 | } 19 | } 20 | 21 | def get_config(): 22 | try: 23 | with open('secrets.yml') as config: 24 | return yaml.load(config) 25 | except IOError: 26 | return copy.copy(DEFAULTS) 27 | -------------------------------------------------------------------------------- /pbnh/db/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhanderson/pbnh/59bcb27de1a2300f14476349f3182c651a8f88a1/pbnh/db/__init__.py -------------------------------------------------------------------------------- /pbnh/db/connect.py: -------------------------------------------------------------------------------- 1 | class DBConnect(): 2 | """create db connection string""" 3 | def __init__(self, dialect=None, driver=None, username=None, password=None, 4 | host=None, port=None, dbname=None): 5 | self._connect = dialect 6 | if driver: 7 | self._connect += '+' + driver 8 | self._connect += '://' 9 | if username: 10 | self._connect += username 11 | if password: 12 | self._connect += ':' + password 13 | if host: 14 | self._connect += '@' 15 | self._connect += host 16 | if port: 17 | self._connect += ':' + str(port) 18 | elif dialect == 'postgresql' and username: 19 | self._connect += '@localhost' 20 | if dbname: 21 | self._connect += '/' + dbname 22 | 23 | def __repr__(self): 24 | return self._connect 25 | 26 | @property 27 | def connect(self): 28 | """Connection string read-only property""" 29 | return self._connect 30 | -------------------------------------------------------------------------------- /pbnh/db/createdb.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from sqlalchemy import create_engine 3 | from sqlalchemy_utils import create_database 4 | 5 | from pbnh import conf 6 | from pbnh import app 7 | from pbnh.db import models 8 | from pbnh.db.connect import DBConnect 9 | 10 | 11 | class CreateDB(): 12 | def __init__(self, dialect=None, driver=None, username=None, password=None, 13 | host=None, port=None, dbname=None): 14 | """Grab connection information to pass to DBConnect""" 15 | self.dialect = dialect or 'sqlite' 16 | self.dbname = dbname or app.app.config['CONFIG'].get('database').get('dbname') 17 | self.driver = driver 18 | self.username = username 19 | self.password = password 20 | self.host = host 21 | self.port = port 22 | 23 | def create(self): 24 | connection = DBConnect( 25 | dialect=self.dialect, 26 | driver=self.driver, 27 | username=self.username, 28 | password=self.password, 29 | host=self.host, 30 | port=self.port, 31 | dbname=self.dbname 32 | ) 33 | print(connection) 34 | create_database(str(connection)) 35 | engine = create_engine(str(connection)) 36 | models.Base.metadata.create_all(engine) 37 | return connection 38 | 39 | 40 | def main(): 41 | config = conf.get_config().get('database') 42 | parser = argparse.ArgumentParser(description='Initialize a paste db') 43 | parser.add_argument('-t', '--type', default=config.get('dialect'), 44 | help='sqlite or postgresql') 45 | parser.add_argument('-n', '--dbname', default=config.get('dbname'), 46 | help='name of the database to be created') 47 | parser.add_argument('-d', '--driver', default=config.get('driver'), 48 | help='database driver for sqlalchemy to use') 49 | parser.add_argument('-u', '--username', default=config.get('username'), 50 | help='username to use for the database connection') 51 | parser.add_argument('-p', '--password', default=config.get('password'), 52 | help='password to use for the database connection') 53 | parser.add_argument('-s', '--server', default=config.get('host'), 54 | help='host of the database') 55 | parser.add_argument('-P', '--port', default=config.get('port'), 56 | help='port the database listens on') 57 | args = parser.parse_args() 58 | newdb = CreateDB(dialect=args.type, driver=args.driver, username=args.username, 59 | password=args.password, host=args.server, port=args.port, 60 | dbname=args.dbname) 61 | print(newdb.create()) 62 | 63 | if __name__ == "__main__": 64 | main() 65 | -------------------------------------------------------------------------------- /pbnh/db/models.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Column, DateTime, Integer, LargeBinary, String, UniqueConstraint 2 | from sqlalchemy.ext.declarative import declarative_base 3 | from sqlalchemy.sql import func 4 | 5 | Base = declarative_base() 6 | 7 | class Paste(Base): 8 | """Class to define the paste table 9 | 10 | paste 11 | ------------- 12 | id (PK) int 13 | hashid string (hash of data) 14 | ip string (will be of "ip address" type in pg) 15 | mime string 16 | timestamp datetime 17 | sunset datetime 18 | data blob 19 | """ 20 | __tablename__ = 'paste' 21 | 22 | id = Column(Integer, primary_key=True) 23 | hashid = Column(String, nullable=False) 24 | ip = Column(String) 25 | timestamp = Column(DateTime, default=func.now()) 26 | mime = Column(String, default='text/plain') 27 | sunset = Column(DateTime) 28 | data = Column(LargeBinary) 29 | 30 | __table_args__ = (UniqueConstraint('hashid', name='unique_hash'),) 31 | -------------------------------------------------------------------------------- /pbnh/db/paste.py: -------------------------------------------------------------------------------- 1 | import codecs 2 | import hashlib 3 | from sqlalchemy import create_engine 4 | from sqlalchemy.exc import IntegrityError, DataError 5 | from sqlalchemy.orm import sessionmaker 6 | 7 | from pbnh.db import models 8 | from pbnh.db.connect import DBConnect 9 | 10 | class Paster(): 11 | def __init__(self, dialect='sqlite', driver=None, username=None, password=None, 12 | host=None, port=None, dbname='pastedb'): 13 | """Grab connection information to pass to DBConnect""" 14 | self.dialect = dialect 15 | self.dbname = dbname 16 | self.driver = driver 17 | self.username = username 18 | self.password = password 19 | self.host = host 20 | self.port = port 21 | 22 | def __enter__(self): 23 | connection = DBConnect(dialect=self.dialect, driver=self.driver, username=self.username, 24 | password=self.password, host=self.host, port=self.port, 25 | dbname=self.dbname).connect 26 | if self.dialect == 'postgresql': 27 | self.engine = create_engine(connection, pool_size=1) 28 | else: 29 | self.engine = create_engine(connection) 30 | Session = sessionmaker(bind=self.engine) 31 | self.session = Session() 32 | return self 33 | 34 | def __exit__(self, exception_type, exception_value, traceback): 35 | self.session.close() 36 | self.engine.dispose() 37 | 38 | def create(self, data, ip=None, mime=None, sunset=None, 39 | timestamp=None): 40 | sha1 = hashlib.sha1(data).hexdigest() 41 | collision = self.query(hashid=sha1) 42 | if collision: 43 | pasteid = collision.get('id') 44 | else: 45 | paste = models.Paste( 46 | hashid = sha1, 47 | ip = ip, 48 | mime = mime, 49 | sunset = sunset, 50 | timestamp = timestamp, 51 | data = data 52 | ) 53 | try: 54 | self.session.add(paste) 55 | self.session.commit() 56 | except IntegrityError: 57 | pasteid = 'HASH COLLISION' 58 | self.session.rollback() 59 | else: 60 | pasteid = paste.id 61 | return {'id': pasteid, 'hashid': sha1} 62 | 63 | def query(self, id=None, hashid=None): 64 | result = None 65 | if id: 66 | try: 67 | result = (self.session.query(models.Paste) 68 | .filter(models.Paste.id == id).first()) 69 | except DataError: 70 | self.session.rollback() 71 | raise ValueError 72 | elif hashid: 73 | try: 74 | result = (self.session.query(models.Paste) 75 | .filter(models.Paste.hashid == hashid).first()) 76 | except DataError: 77 | self.session.rollback() 78 | raise ValueError 79 | else: 80 | return None 81 | if result: 82 | result = { 83 | 'id': result.id, 84 | 'hashid': result.hashid, 85 | 'ip': result.ip, 86 | 'mime': result.mime, 87 | 'timestamp': result.timestamp, 88 | 'sunset': result.sunset, 89 | 'data': result.data 90 | } 91 | 92 | return result 93 | 94 | def delete(self, id=None, hashid=None): 95 | if id: 96 | result = (self.session.query(models.Paste) 97 | .filter(models.Paste.id == id).first()) 98 | elif hashid: 99 | result = (self.session.query(models.Paste) 100 | .filter(models.Paste.hashid == hashid).first()) 101 | else: 102 | return None 103 | self.session.delete(result) 104 | self.session.commit() 105 | -------------------------------------------------------------------------------- /pbnh/run.py: -------------------------------------------------------------------------------- 1 | from pbnh.app import app 2 | -------------------------------------------------------------------------------- /pbnh/tests/paste_psql_test.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from datetime import datetime 4 | from sqlalchemy_utils import drop_database 5 | 6 | from pbnh.db.createdb import CreateDB 7 | from pbnh.db.connect import DBConnect 8 | from pbnh.db import paste 9 | 10 | dialect = 'postgresql' 11 | dbname = 'testdb' 12 | 13 | class TestPaster(unittest.TestCase): 14 | def setUp(self): 15 | self.newdb = CreateDB(dialect=dialect, dbname=dbname) 16 | self.newdb.create() 17 | 18 | def tearDown(self): 19 | drop_database(str(DBConnect(dialect=dialect, dbname=dbname))) 20 | 21 | def test_create_new(self): 22 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 23 | created = p.create(b'This is a test paste') 24 | self.assertEqual( 25 | created, 26 | { 27 | 'id': 1, 28 | 'hashid': 'f872a542a8289d2273f6cb455198e06126f4ec30' 29 | } 30 | ) 31 | 32 | def test_create_dupe(self): 33 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 34 | created = p.create(b'This is a test paste') 35 | created = p.create(b'This is a test paste') 36 | self.assertEqual( 37 | created, 38 | { 39 | 'id': 1, 40 | 'hashid': 'f872a542a8289d2273f6cb455198e06126f4ec30' 41 | } 42 | ) 43 | 44 | def test_query_id(self): 45 | timestamp = datetime.now() 46 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 47 | p.create(b'This is a test paste', timestamp=timestamp) 48 | lookup = p.query(id=1) 49 | self.assertEqual( 50 | lookup, 51 | { 52 | 'id': 1, 53 | 'hashid': 'f872a542a8289d2273f6cb455198e06126f4ec30', 54 | 'ip': None, 55 | 'mime': 'text/plain', 56 | 'sunset': None, 57 | 'timestamp': timestamp, 58 | 'data': b'This is a test paste' 59 | } 60 | ) 61 | 62 | def test_query_hash(self): 63 | timestamp = datetime.now() 64 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 65 | p.create(b'This is a test paste', timestamp=timestamp) 66 | lookup = p.query(hashid='f872a542a8289d2273f6cb455198e06126f4ec30') 67 | self.assertEqual( 68 | lookup, 69 | { 70 | 'id': 1, 71 | 'hashid': 'f872a542a8289d2273f6cb455198e06126f4ec30', 72 | 'ip': None, 73 | 'mime': 'text/plain', 74 | 'sunset': None, 75 | 'timestamp': timestamp, 76 | 'data': b'This is a test paste' 77 | } 78 | ) 79 | 80 | def test_query_disaster(self): 81 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 82 | p.create(b'This is a test paste') 83 | with self.assertRaises(ValueError): 84 | p.query(id='f872a542a8289d2273f6cb455198e06126f4ec30') 85 | 86 | def test_query_none(self): 87 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 88 | p.create(b'This is a test paste') 89 | lookup = p.query() 90 | self.assertEqual(lookup, None) 91 | 92 | def test_delete_id(self): 93 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 94 | p.create(b'This is a test paste') 95 | p.delete(id=1) 96 | lookup = p.query(id=1) 97 | self.assertEqual(lookup, None) 98 | 99 | def test_delete_hash(self): 100 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 101 | p.create(b'This is a test paste') 102 | p.delete(hashid='f872a542a8289d2273f6cb455198e06126f4ec30') 103 | lookup = p.query(id=1) 104 | self.assertEqual(lookup, None) 105 | 106 | def test_delete_none(self): 107 | timestamp = datetime.now() 108 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 109 | p.create(b'This is a test paste', timestamp=timestamp) 110 | p.delete() 111 | lookup = p.query(id=1) 112 | self.assertEqual( 113 | lookup, 114 | { 115 | 'id': 1, 116 | 'hashid': 'f872a542a8289d2273f6cb455198e06126f4ec30', 117 | 'ip': None, 118 | 'mime': 'text/plain', 119 | 'sunset': None, 120 | 'timestamp': timestamp, 121 | 'data': b'This is a test paste' 122 | } 123 | ) 124 | -------------------------------------------------------------------------------- /pbnh/tests/paste_sqlite_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | import unittest 3 | 4 | from datetime import datetime 5 | 6 | from pbnh.db.createdb import CreateDB 7 | from pbnh.db import paste 8 | 9 | dialect = 'sqlite' 10 | dbname = '/tmp/pbnh_test.db' 11 | 12 | class TestPaster(unittest.TestCase): 13 | def setUp(self): 14 | self.newdb = CreateDB(dialect=dialect, dbname=dbname) 15 | self.newdb.create() 16 | 17 | def tearDown(self): 18 | os.remove('/tmp/pbnh_test.db') 19 | 20 | def test_create_new(self): 21 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 22 | created = p.create(b'This is a test paste') 23 | self.assertEqual( 24 | created, 25 | { 26 | 'id': 1, 27 | 'hashid': 'f872a542a8289d2273f6cb455198e06126f4ec30' 28 | } 29 | ) 30 | 31 | def test_create_dupe(self): 32 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 33 | created = p.create(b'This is a test paste') 34 | created = p.create(b'This is a test paste') 35 | self.assertEqual( 36 | created, 37 | { 38 | 'id': 1, 39 | 'hashid': 'f872a542a8289d2273f6cb455198e06126f4ec30' 40 | } 41 | ) 42 | 43 | def test_query_id(self): 44 | timestamp = datetime.now() 45 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 46 | p.create(b'This is a test paste', timestamp=timestamp) 47 | lookup = p.query(id=1) 48 | self.assertEqual( 49 | lookup, 50 | { 51 | 'id': 1, 52 | 'hashid': 'f872a542a8289d2273f6cb455198e06126f4ec30', 53 | 'ip': None, 54 | 'mime': 'text/plain', 55 | 'sunset': None, 56 | 'timestamp': timestamp, 57 | 'data': b'This is a test paste' 58 | } 59 | ) 60 | 61 | def test_query_hash(self): 62 | timestamp = datetime.now() 63 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 64 | p.create(b'This is a test paste', timestamp=timestamp) 65 | lookup = p.query(hashid='f872a542a8289d2273f6cb455198e06126f4ec30') 66 | self.assertEqual( 67 | lookup, 68 | { 69 | 'id': 1, 70 | 'hashid': 'f872a542a8289d2273f6cb455198e06126f4ec30', 71 | 'ip': None, 72 | 'mime': 'text/plain', 73 | 'sunset': None, 74 | 'timestamp': timestamp, 75 | 'data': b'This is a test paste' 76 | } 77 | ) 78 | 79 | def test_query_disaster(self): 80 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 81 | p.create(b'This is a test paste') 82 | lookup = p.query(id='f872a542a8289d2273f6cb455198e06126f4ec30') 83 | self.assertEqual(lookup, None) 84 | 85 | def test_query_none(self): 86 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 87 | p.create(b'This is a test paste') 88 | lookup = p.query() 89 | self.assertEqual(lookup, None) 90 | 91 | def test_delete_id(self): 92 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 93 | p.create(b'This is a test paste') 94 | p.delete(id=1) 95 | lookup = p.query(id=1) 96 | self.assertEqual(lookup, None) 97 | 98 | def test_delete_hash(self): 99 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 100 | p.create(b'This is a test paste') 101 | p.delete(hashid='f872a542a8289d2273f6cb455198e06126f4ec30') 102 | lookup = p.query(id=1) 103 | self.assertEqual(lookup, None) 104 | 105 | def test_delete_none(self): 106 | timestamp = datetime.now() 107 | with paste.Paster(dialect=dialect, dbname=dbname) as p: 108 | p.create(b'This is a test paste', timestamp=timestamp) 109 | p.delete() 110 | lookup = p.query(id=1) 111 | self.assertEqual( 112 | lookup, 113 | { 114 | 'id': 1, 115 | 'hashid': 'f872a542a8289d2273f6cb455198e06126f4ec30', 116 | 'ip': None, 117 | 'mime': 'text/plain', 118 | 'sunset': None, 119 | 'timestamp': timestamp, 120 | 'data': b'This is a test paste' 121 | } 122 | ) 123 | -------------------------------------------------------------------------------- /sample_config.yml: -------------------------------------------------------------------------------- 1 | # Copy this file to secrets.yml and edit the options 2 | server: 3 | bind_ip : "0.0.0.0" 4 | bind_port : 5001 5 | debug : True 6 | 7 | database: 8 | dbname : "database_name" 9 | dialect : "postgresql or sqlite" 10 | driver : null 11 | host : "pbnh_db.local" 12 | password : "hunter2" 13 | port : 5432 14 | username : "pbnh_username" 15 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name='pbnh', 5 | version='0.2', 6 | description='A Better Pastebin', 7 | author='Bryce Handerson, Ethan Madden', 8 | author_email='maddene@madden.ninja', 9 | url='https://github.com/bhanderson/pbnh', 10 | packages=find_packages(exclude=['docs', 'tests*']), 11 | include_package_data=True, 12 | install_requires=[ 13 | 'docutils', 14 | 'Flask', 15 | 'gunicorn', 16 | 'psycopg2', 17 | 'python-magic', 18 | 'pyYAML<6', 19 | 'SQLAlchemy', 20 | 'SQLAlchemy-utils' 21 | ], 22 | tests_require=[ 23 | 'nose', 24 | 'pycurl', 25 | ] 26 | ) 27 | --------------------------------------------------------------------------------