Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ea95a285c9 | |||
| 0fde428806 | |||
| 8fc7ff1ca7 | |||
| ae4e2eb8d5 | |||
| 528e4be1fe | |||
| bd42883330 | |||
| b6ac0a73b4 | |||
| aebc3da5bc | |||
| 7a4a4f9006 | |||
| 1341aa5a56 | |||
| 5e05f250f4 | |||
| 6cf7be3afb | |||
| 6aceacad18 | |||
| a3a23be1c2 | |||
| e8e8024021 | |||
| 1806d60ca7 | |||
| 2c5f2e589f | |||
| 847d228c0a | |||
| 576948acee | |||
| fa6d91db20 | |||
| 989bcdf130 | |||
| 000104c99d | |||
| f2bd0ec10e | |||
| 97dab302d8 | |||
| 55e258e093 | |||
| 7b22a4773d | |||
| 14cd1436c3 | |||
| c112e1ea62 | |||
| bd8385ea60 | |||
| 6dbc7f359b | |||
| e773f53da1 | |||
| 35a7747d6d | |||
| 0d173cfcef | |||
| 0480536a20 | |||
| 333bbf6eb8 | |||
| 6bdcd6872e | |||
| 9d3c1d0847 | |||
| def326676c | |||
| d343179764 |
@@ -3,6 +3,8 @@
|
||||
/config.json
|
||||
/config.example.json
|
||||
/data
|
||||
/data/*
|
||||
/test_data
|
||||
/access.log
|
||||
/error.log
|
||||
/coverage
|
||||
@@ -0,0 +1,2 @@
|
||||
/node_modules
|
||||
/src/lib
|
||||
@@ -6,13 +6,8 @@ cache:
|
||||
npm: true
|
||||
directories:
|
||||
- node_modules
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- graphviz
|
||||
install:
|
||||
- npm install
|
||||
- npm install node-plantuml
|
||||
before_script:
|
||||
- npm install -g jshint
|
||||
script:
|
||||
|
||||
@@ -14,6 +14,7 @@ A static blog using Markdown pulled from your git repository.
|
||||
* **[How it works](#how-it-works)**
|
||||
* **[Installation](#installation)**
|
||||
* **[Writing an article](#writing-an-article)**
|
||||
* **[Modules](#modules)**
|
||||
* **[Configuration](#configuration)**
|
||||
|
||||
## How it works
|
||||
@@ -80,7 +81,7 @@ On the `/rss` endpoint, the servers gives you a RSS feed based on the list of ar
|
||||
#### 1. Download and install the latest version from the repo
|
||||
```bash
|
||||
git clone https://github.com/klemek/gitblog.md.git
|
||||
npm install
|
||||
npm install --production
|
||||
```
|
||||
#### 2. Create your config file
|
||||
```bash
|
||||
@@ -131,7 +132,10 @@ You need to [create a new repository](https://github.com/new) on your favorite G
|
||||
```bash
|
||||
#gitblog.md/
|
||||
cd data
|
||||
git init
|
||||
git remote add origin <url_of_your_repo.git>
|
||||
git add .
|
||||
git commit -m "initial commit"
|
||||
git push -u origin master
|
||||
```
|
||||
|
||||
@@ -156,7 +160,7 @@ Here are the steps for Github, if you use another platform adapt it your way (he
|
||||
```json
|
||||
"webhook": {
|
||||
"endpoint": "/webhook",
|
||||
"secret": "sha1=<value>",
|
||||
"secret": "<value>",
|
||||
"signature_header": "X-Hub-Signature"
|
||||
},
|
||||
```
|
||||
@@ -192,6 +196,20 @@ On that same folder, you can place resources like images and reference them in r
|
||||
|
||||
Any URL like `/year/month/day/anything/` will redirect to this article (and link to correct resources)
|
||||
|
||||
## Modules
|
||||
[back to top](#gitblog-md)
|
||||
|
||||
* **RSS**
|
||||
It allows your users to use the feed to be updated as soon as a new article is out
|
||||
* **Webhook**
|
||||
It update your blog from your online repo when it's updated
|
||||
* **Prism**
|
||||
It highlight code blocks to be more readable (more info [here](https://prismjs.com/), you will need the corresponding CSS file on your templates)
|
||||
* **MathJax**
|
||||
It allows you to add math equations to your articles by simply writing LaTeX between `$$` for full size (and between $ for inline) (more info [here](https://www.mathjax.org/))
|
||||
* **PlantUML**
|
||||
It allows you to add UML diagrams with PlantUML Syntax between `@startuml` and `@enduml` (more info [here](http://www.plantuml.com))
|
||||
|
||||
## Configuration
|
||||
[back to top](#gitblog-md)
|
||||
|
||||
@@ -212,7 +230,17 @@ Any URL like `/year/month/day/anything/` will redirect to this article (and link
|
||||
activate the webhook endpoint and its features
|
||||
* `prism` (default: true)
|
||||
activate Prism code highlighting
|
||||
* `mathjax` (default: true)
|
||||
activate MathJax equations formatting
|
||||
* `plantuml` (default: true)
|
||||
activate PlantUML diagram rendering
|
||||
* `home`
|
||||
* `title` (default: GitBlog.md)
|
||||
the title of your blog, **strongly advised to be changed**
|
||||
given to the template to complete page title and metadata
|
||||
* `description` (default: A static blog using Markdown pulled from your git repository)
|
||||
the description of your blog, **strongly advised to be changed**
|
||||
given to the template to complete page title and metadata
|
||||
* `index` (default: index.ejs)
|
||||
the name of the home page template on the data directory
|
||||
it will receive `articles`, a list of articles for rendering
|
||||
@@ -248,4 +276,9 @@ Any URL like `/year/month/day/anything/` will redirect to this article (and link
|
||||
* `pull_command`: (default: git pull)
|
||||
the command used by the server on webhook trigger
|
||||
* `showdown`
|
||||
Options to be applied to Showdown renderer (see [showdown options](https://github.com/showdownjs/showdown#valid-options) for more info)
|
||||
Options to be applied to Showdown renderer (see [showdown options](https://github.com/showdownjs/showdown/wiki/Showdown-Options) for more info)
|
||||
* `mathjax`
|
||||
* `output_format`: (default: svg)
|
||||
specify the output format between svg, html or MathMl (mml)
|
||||
* `speak_text`: (default: true)
|
||||
activate the alternate text in equations
|
||||
|
||||
Generated
+70
-146
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gitblog.md",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.3",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -1257,8 +1257,7 @@
|
||||
"abab": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz",
|
||||
"integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w=="
|
||||
},
|
||||
"accepts": {
|
||||
"version": "1.3.7",
|
||||
@@ -1272,14 +1271,12 @@
|
||||
"acorn": {
|
||||
"version": "5.7.3",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
|
||||
"integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw=="
|
||||
},
|
||||
"acorn-globals": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.2.tgz",
|
||||
"integrity": "sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"acorn": "^6.0.1",
|
||||
"acorn-walk": "^6.0.1"
|
||||
@@ -1288,22 +1285,19 @@
|
||||
"acorn": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz",
|
||||
"integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"acorn-walk": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz",
|
||||
"integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw=="
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
|
||||
"integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^2.0.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
@@ -1373,8 +1367,7 @@
|
||||
"array-equal": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
|
||||
"integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
|
||||
"dev": true
|
||||
"integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM="
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "1.1.1",
|
||||
@@ -1392,7 +1385,6 @@
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
||||
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
@@ -1400,8 +1392,7 @@
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
||||
"dev": true
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
|
||||
},
|
||||
"assign-symbols": {
|
||||
"version": "1.0.0",
|
||||
@@ -1425,14 +1416,12 @@
|
||||
"async-limiter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
|
||||
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||
"dev": true
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"atob": {
|
||||
"version": "2.1.2",
|
||||
@@ -1443,14 +1432,12 @@
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
|
||||
"dev": true
|
||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
|
||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
|
||||
},
|
||||
"babel-cli": {
|
||||
"version": "6.26.0",
|
||||
@@ -2311,7 +2298,6 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
@@ -2353,8 +2339,7 @@
|
||||
"browser-process-hrtime": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz",
|
||||
"integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw=="
|
||||
},
|
||||
"browser-resolve": {
|
||||
"version": "1.11.3",
|
||||
@@ -2457,8 +2442,7 @@
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
|
||||
"dev": true
|
||||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
@@ -2604,7 +2588,6 @@
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
@@ -2680,8 +2663,7 @@
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"dev": true
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"coveralls": {
|
||||
"version": "3.0.4",
|
||||
@@ -2723,14 +2705,12 @@
|
||||
"cssom": {
|
||||
"version": "0.3.6",
|
||||
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz",
|
||||
"integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==",
|
||||
"dev": true
|
||||
"integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A=="
|
||||
},
|
||||
"cssstyle": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.2.tgz",
|
||||
"integrity": "sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cssom": "0.3.x"
|
||||
}
|
||||
@@ -2739,7 +2719,6 @@
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
@@ -2748,7 +2727,6 @@
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
|
||||
"integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"abab": "^2.0.0",
|
||||
"whatwg-mimetype": "^2.2.0",
|
||||
@@ -2759,7 +2737,6 @@
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz",
|
||||
"integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash.sortby": "^4.7.0",
|
||||
"tr46": "^1.0.1",
|
||||
@@ -2790,8 +2767,7 @@
|
||||
"deep-is": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
|
||||
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
|
||||
"dev": true
|
||||
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
|
||||
},
|
||||
"define-properties": {
|
||||
"version": "1.1.3",
|
||||
@@ -2858,8 +2834,7 @@
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"dev": true
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"delegate": {
|
||||
"version": "3.2.0",
|
||||
@@ -2902,7 +2877,6 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
|
||||
"integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"webidl-conversions": "^4.0.2"
|
||||
}
|
||||
@@ -2911,7 +2885,6 @@
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.1.0"
|
||||
@@ -2996,7 +2969,6 @@
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz",
|
||||
"integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esprima": "^3.1.3",
|
||||
"estraverse": "^4.2.0",
|
||||
@@ -3009,7 +2981,6 @@
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
@@ -3017,20 +2988,17 @@
|
||||
"esprima": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
|
||||
"integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=",
|
||||
"dev": true
|
||||
"integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM="
|
||||
},
|
||||
"estraverse": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
|
||||
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
|
||||
"dev": true
|
||||
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
|
||||
},
|
||||
"esutils": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
|
||||
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
|
||||
"dev": true
|
||||
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
|
||||
},
|
||||
"etag": {
|
||||
"version": "1.8.1",
|
||||
@@ -3184,8 +3152,7 @@
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||
"dev": true
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
},
|
||||
"extend-shallow": {
|
||||
"version": "3.0.2",
|
||||
@@ -3221,26 +3188,22 @@
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
||||
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
|
||||
"dev": true
|
||||
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
|
||||
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
|
||||
"dev": true
|
||||
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
|
||||
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
|
||||
"dev": true
|
||||
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
|
||||
},
|
||||
"fast-levenshtein": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||
"dev": true
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
|
||||
},
|
||||
"fast-safe-stringify": {
|
||||
"version": "2.0.6",
|
||||
@@ -3305,14 +3268,12 @@
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
|
||||
"dev": true
|
||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
@@ -3930,7 +3891,6 @@
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
@@ -4026,14 +3986,12 @@
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
|
||||
"dev": true
|
||||
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
|
||||
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.5.5",
|
||||
"har-schema": "^2.0.0"
|
||||
@@ -4157,7 +4115,6 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
|
||||
"integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"whatwg-encoding": "^1.0.1"
|
||||
}
|
||||
@@ -4178,7 +4135,6 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"jsprim": "^1.2.2",
|
||||
@@ -4440,8 +4396,7 @@
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
|
||||
"dev": true
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
|
||||
},
|
||||
"is-windows": {
|
||||
"version": "1.0.2",
|
||||
@@ -4469,8 +4424,7 @@
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
|
||||
"dev": true
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||
},
|
||||
"istanbul-lib-coverage": {
|
||||
"version": "2.0.5",
|
||||
@@ -6680,14 +6634,12 @@
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
|
||||
"dev": true
|
||||
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
|
||||
},
|
||||
"jsdom": {
|
||||
"version": "11.12.0",
|
||||
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz",
|
||||
"integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"abab": "^2.0.0",
|
||||
"acorn": "^5.5.3",
|
||||
@@ -6732,20 +6684,17 @@
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
|
||||
"dev": true
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
|
||||
"dev": true
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
|
||||
},
|
||||
"json5": {
|
||||
"version": "0.5.1",
|
||||
@@ -6757,7 +6706,6 @@
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
@@ -6797,8 +6745,7 @@
|
||||
"left-pad": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
|
||||
"integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA=="
|
||||
},
|
||||
"leven": {
|
||||
"version": "2.1.0",
|
||||
@@ -6810,7 +6757,6 @@
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
|
||||
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"prelude-ls": "~1.1.2",
|
||||
"type-check": "~0.3.2"
|
||||
@@ -6840,14 +6786,12 @@
|
||||
"lodash": {
|
||||
"version": "4.17.11",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
|
||||
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
|
||||
},
|
||||
"lodash.sortby": {
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
|
||||
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
|
||||
"dev": true
|
||||
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg="
|
||||
},
|
||||
"log-driver": {
|
||||
"version": "1.2.7",
|
||||
@@ -6931,6 +6875,21 @@
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"mathjax": {
|
||||
"version": "2.7.5",
|
||||
"resolved": "https://registry.npmjs.org/mathjax/-/mathjax-2.7.5.tgz",
|
||||
"integrity": "sha512-OzsJNitEHAJB3y4IIlPCAvS0yoXwYjlo2Y4kmm9KQzyIBZt2d8yKRalby3uTRNN4fZQiGL2iMXjpdP1u2Rq2DQ=="
|
||||
},
|
||||
"mathjax-node": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/mathjax-node/-/mathjax-node-2.1.1.tgz",
|
||||
"integrity": "sha1-JcgPSU91QEGP/Pqcx1bf0hUCAb0=",
|
||||
"requires": {
|
||||
"is-fullwidth-code-point": "^2.0.0",
|
||||
"jsdom": "^11.0.0",
|
||||
"mathjax": "^2.7.2"
|
||||
}
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
@@ -7237,14 +7196,12 @@
|
||||
"nwsapi": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz",
|
||||
"integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw=="
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@@ -7366,7 +7323,6 @@
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
|
||||
"integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"deep-is": "~0.1.3",
|
||||
"fast-levenshtein": "~2.0.4",
|
||||
@@ -7379,8 +7335,7 @@
|
||||
"wordwrap": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
|
||||
"dev": true
|
||||
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -7496,8 +7451,7 @@
|
||||
"parse5": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
|
||||
"integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA=="
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.3.3",
|
||||
@@ -7549,8 +7503,7 @@
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
|
||||
"dev": true
|
||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
|
||||
},
|
||||
"pify": {
|
||||
"version": "3.0.0",
|
||||
@@ -7624,8 +7577,7 @@
|
||||
"pn": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
|
||||
"integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA=="
|
||||
},
|
||||
"posix-character-classes": {
|
||||
"version": "0.1.1",
|
||||
@@ -7636,8 +7588,7 @@
|
||||
"prelude-ls": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
|
||||
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
|
||||
"dev": true
|
||||
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
|
||||
},
|
||||
"preserve": {
|
||||
"version": "0.2.0",
|
||||
@@ -7722,8 +7673,7 @@
|
||||
"psl": {
|
||||
"version": "1.1.32",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz",
|
||||
"integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==",
|
||||
"dev": true
|
||||
"integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g=="
|
||||
},
|
||||
"pump": {
|
||||
"version": "3.0.0",
|
||||
@@ -7738,8 +7688,7 @@
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"dev": true
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.7.0",
|
||||
@@ -8308,7 +8257,6 @@
|
||||
"version": "2.88.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
|
||||
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
@@ -8335,20 +8283,17 @@
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
|
||||
"dev": true
|
||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
|
||||
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"psl": "^1.1.24",
|
||||
"punycode": "^1.4.1"
|
||||
@@ -8360,7 +8305,6 @@
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz",
|
||||
"integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash": "^4.17.11"
|
||||
}
|
||||
@@ -8369,7 +8313,6 @@
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz",
|
||||
"integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"request-promise-core": "1.1.2",
|
||||
"stealthy-require": "^1.1.1",
|
||||
@@ -8829,8 +8772,7 @@
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||
},
|
||||
"select": {
|
||||
"version": "1.1.2",
|
||||
@@ -9152,7 +9094,6 @@
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
|
||||
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asn1": "~0.2.3",
|
||||
"assert-plus": "^1.0.0",
|
||||
@@ -9200,8 +9141,7 @@
|
||||
"stealthy-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
|
||||
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
|
||||
"dev": true
|
||||
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
|
||||
},
|
||||
"string-length": {
|
||||
"version": "2.0.0",
|
||||
@@ -9363,8 +9303,7 @@
|
||||
"symbol-tree": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
|
||||
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="
|
||||
},
|
||||
"test-exclude": {
|
||||
"version": "5.2.3",
|
||||
@@ -9461,7 +9400,6 @@
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"psl": "^1.1.28",
|
||||
"punycode": "^2.1.1"
|
||||
@@ -9471,7 +9409,6 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
|
||||
"integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
@@ -9486,7 +9423,6 @@
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
@@ -9494,14 +9430,12 @@
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
|
||||
"dev": true
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
|
||||
},
|
||||
"type-check": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
|
||||
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"prelude-ls": "~1.1.2"
|
||||
}
|
||||
@@ -9625,7 +9559,6 @@
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
|
||||
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
@@ -9672,8 +9605,7 @@
|
||||
"uuid": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
|
||||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
|
||||
},
|
||||
"v8flags": {
|
||||
"version": "2.1.1",
|
||||
@@ -9703,7 +9635,6 @@
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
||||
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
@@ -9714,7 +9645,6 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
|
||||
"integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browser-process-hrtime": "^0.1.2"
|
||||
}
|
||||
@@ -9731,14 +9661,12 @@
|
||||
"webidl-conversions": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
|
||||
"integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
|
||||
},
|
||||
"whatwg-encoding": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
|
||||
"integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"iconv-lite": "0.4.24"
|
||||
}
|
||||
@@ -9746,14 +9674,12 @@
|
||||
"whatwg-mimetype": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
|
||||
"integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
|
||||
"dev": true
|
||||
"integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g=="
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
|
||||
"integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash.sortby": "^4.7.0",
|
||||
"tr46": "^1.0.1",
|
||||
@@ -9842,7 +9768,6 @@
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
|
||||
"integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
@@ -9855,8 +9780,7 @@
|
||||
"xml-name-validator": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
|
||||
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw=="
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
|
||||
+12
-3
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"nodePort": 5000,
|
||||
"name": "gitblog.md",
|
||||
"version": "1.0.2",
|
||||
"version": "1.2.0",
|
||||
"description": "A static blog using Markdown pulled from your git repository.",
|
||||
"main": "src/server.js",
|
||||
"dependencies": {
|
||||
@@ -9,6 +8,7 @@
|
||||
"crypto": "^1.0.1",
|
||||
"ejs": "^2.6.2",
|
||||
"express": "^4.17.1",
|
||||
"mathjax-node": "^2.1.1",
|
||||
"ncp": "^2.0.0",
|
||||
"node-prismjs": "^0.1.2",
|
||||
"prismjs": "^1.16.0",
|
||||
@@ -37,5 +37,14 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/klemek/gitblog.md/issues"
|
||||
},
|
||||
"homepage": "https://github.com/klemek/gitblog.md#readme"
|
||||
"homepage": "https://github.com/klemek/gitblog.md#readme",
|
||||
"jest": {
|
||||
"collectCoverageFrom": [
|
||||
"src/**/*.js",
|
||||
"!/node_modules/",
|
||||
"!src/server.js",
|
||||
"!src/postinstall.js",
|
||||
"!src/lib/*.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,25 @@ If you see this page, that means it's working
|
||||
|
||||
## Guide to Markdown formatting
|
||||
|
||||
* [Headers](#headers)
|
||||
* [Emphasis](#emphasis)
|
||||
* [Lists](#lists)
|
||||
* [Links](#links)
|
||||
* [Images](#images)
|
||||
* [Code and Syntax Highlighting](#codeandsyntaxhighlighting)
|
||||
* [Tables](#tables)
|
||||
* [Blockquotes](#blockquotes)
|
||||
* [Inline HTML](#inlinehtml)
|
||||
* [Horizontal Rule](#horizontalrule)
|
||||
* [Line Breaks](#linebreaks)
|
||||
* [Check Boxes](#checkboxes)
|
||||
* [Spoilers](#spoilers)
|
||||
* [Math Equations](#mathequations)
|
||||
* [UML](#uml)
|
||||
* [Youtube Videos](#youtubevideos)
|
||||
|
||||
### Headers
|
||||
[Back to top](#top)
|
||||
|
||||
# H1
|
||||
## H2
|
||||
@@ -22,6 +40,7 @@ Alt-H2
|
||||
------
|
||||
|
||||
### Emphasis
|
||||
[Back to top](#top)
|
||||
|
||||
Emphasis, aka italics, with *asterisks* or _underscores_.
|
||||
|
||||
@@ -32,6 +51,7 @@ Combined emphasis with **asterisks and _underscores_**.
|
||||
Strikethrough uses two tildes. ~~Scratch this.~~
|
||||
|
||||
### Lists
|
||||
[Back to top](#top)
|
||||
|
||||
1. First ordered list item
|
||||
2. Another item
|
||||
@@ -51,6 +71,7 @@ Strikethrough uses two tildes. ~~Scratch this.~~
|
||||
+ Or pluses
|
||||
|
||||
### Links
|
||||
[Back to top](#top)
|
||||
|
||||
[I'm an inline-style link](https://www.google.com)
|
||||
|
||||
@@ -75,6 +96,7 @@ Some text to show that the reference links can follow later.
|
||||
[link text itself]: http://www.reddit.com
|
||||
|
||||
### Images
|
||||
[Back to top](#top)
|
||||
|
||||
Here's our logo (hover to see the title text):
|
||||
|
||||
@@ -88,6 +110,7 @@ Reference-style:
|
||||
|
||||
|
||||
### Code and Syntax Highlighting
|
||||
[Back to top](#top)
|
||||
|
||||
Inline `code` has `back-ticks around` it.
|
||||
|
||||
@@ -108,6 +131,7 @@ But let's throw in a <b>tag</b>.
|
||||
|
||||
|
||||
### Tables
|
||||
[Back to top](#top)
|
||||
|
||||
Colons can be used to align columns.
|
||||
|
||||
@@ -127,6 +151,7 @@ Markdown | Less | Pretty
|
||||
1 | 2 | 3
|
||||
|
||||
### Blockquotes
|
||||
[Back to top](#top)
|
||||
|
||||
> Blockquotes are very handy in email to emulate reply text.
|
||||
> This line is part of the same quote.
|
||||
@@ -136,6 +161,7 @@ Quote break.
|
||||
> This is a very long line that will still be quoted properly when it wraps. Oh boy let's keep writing to make sure this is long enough to actually wrap for everyone. Oh, you can *put* **Markdown** into a blockquote.
|
||||
|
||||
### Inline HTML
|
||||
[Back to top](#top)
|
||||
|
||||
<dl>
|
||||
<dt>Definition list</dt>
|
||||
@@ -146,6 +172,7 @@ Quote break.
|
||||
</dl>
|
||||
|
||||
### Horizontal Rule
|
||||
[Back to top](#top)
|
||||
|
||||
Three or more...
|
||||
|
||||
@@ -162,6 +189,7 @@ ___
|
||||
Underscores
|
||||
|
||||
### Line Breaks
|
||||
[Back to top](#top)
|
||||
|
||||
Here's a line for us to start with.
|
||||
|
||||
@@ -169,3 +197,65 @@ This line is separated from the one above by two newlines, so it will be a *sepa
|
||||
|
||||
This line is also a separate paragraph, but...
|
||||
This line is only separated by a single newline, so it's a separate line in the *same paragraph*.
|
||||
|
||||
### Check Boxes
|
||||
[Back to top](#top)
|
||||
|
||||
* [x] Task completed
|
||||
* [] Task to do
|
||||
|
||||
### Spoilers
|
||||
[Back to top](#top)
|
||||
|
||||
<details><summary>Title of the spoiler (click)</summary><p>
|
||||
Content of the spoiler
|
||||
|
||||
On several lines
|
||||
</p></details>
|
||||
|
||||
### Math Equations
|
||||
[Back to top](#top)
|
||||
|
||||
You can use LaTeX equations with MathJax for full equations and inline ones (based on the number of $) :
|
||||
|
||||
$$
|
||||
\large{\beta=\sum_{i}^{\alpha }\frac{x^{i}}{\alpha}}
|
||||
$$
|
||||
|
||||
|
||||
Where $\alpha$ is cool
|
||||
|
||||
### UML
|
||||
[Back to top](#top)
|
||||
|
||||
You can use PlantUML diagrams with `@startuml` and `@enduml` tags :
|
||||
|
||||
@startuml
|
||||
title Article
|
||||
cloud web
|
||||
node nodejs {
|
||||
TCP -right- [express]
|
||||
[showdown]
|
||||
}
|
||||
package data {
|
||||
package "2019/06/18" {
|
||||
component index [
|
||||
index.md
|
||||
image.png
|
||||
...
|
||||
]
|
||||
}
|
||||
}
|
||||
web -down-> TCP : 1. /2019/06/18/title
|
||||
express -down-> index : 2. fetch
|
||||
index -up-> showdown : 3. markdown
|
||||
showdown -left-> express : 4. html
|
||||
express -up-> web : 5. html
|
||||
@enduml
|
||||
|
||||
### Youtube Videos
|
||||
[Back to top](#top)
|
||||
|
||||
Just use the "embedded" export on Youtube with dimensions of 535x300 for best results
|
||||
|
||||
<iframe width="535" height="300" src="https://www.youtube.com/embed/FTQbiNvZqaY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
@@ -2,8 +2,8 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Error <%= error %></title>
|
||||
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||
<title><%= info.title %> - Error <%= error %></title>
|
||||
<%- include('head'); %>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<hr>
|
||||
<footer>
|
||||
<small>@<%= new Date().getFullYear() %> - Made with <a href="https://github.com/klemek/gitblog.md">GitBlog.md</a>
|
||||
<small><a href="/rss">RSS feed</a> - <%= new Date().getFullYear() %> - Made with <a
|
||||
href="https://github.com/klemek/gitblog.md">GitBlog.md</a> (v<%= info.version %>)
|
||||
</small>
|
||||
</footer>
|
||||
@@ -0,0 +1,25 @@
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<% if(locals.article){ %>
|
||||
<%- `<meta property="og:title" content="${info.title} - ${article.title}">` %>
|
||||
<%- `<meta property="twitter:title" content="${info.title} - ${article.title}">` %>
|
||||
<%- `<meta property="og:description" content="${info.description}">` %>
|
||||
<%- `<meta property="twitter:description" content="${info.description}">` %>
|
||||
<%- `<meta property="org:url" content="${info.host + article.url}">` %>
|
||||
<% if (article.thumbnail) { %>
|
||||
<%- `<meta property="og:image" content="${info.host}/${article.thumbnail}">` %>
|
||||
<%- `<meta property="twitter:image" content="${info.host}/${article.thumbnail}">` %>
|
||||
<% } %>
|
||||
<link rel="stylesheet" type="text/css" href="/prism.css">
|
||||
<% } else { %>
|
||||
<%- `<meta property="og:title" content="${info.title} - Home">` %>
|
||||
<%- `<meta property="twitter:title" content="${info.title} - Home">` %>
|
||||
<%- `<meta property="og:description" content="${info.description}">` %>
|
||||
<%- `<meta property="twitter:description" content="${info.description}">` %>
|
||||
<%- `<meta property="org:url" content="${info.host}/">` %>
|
||||
<% } %>
|
||||
|
||||
<link rel="alternate" type="application/rss+xml" title="RSS feed" href="/rss"/>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||
@@ -2,13 +2,13 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>GitBlog.md - Home</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title><%= info.title %> - Home</title>
|
||||
<%- include('head'); %>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>GitBlog.md</h1>
|
||||
A static blog using Markdown pulled from your git repository
|
||||
<h1><%= info.title %></h1>
|
||||
<%= info.description %>
|
||||
<h2>Articles in this blog :</h2>
|
||||
<% articles.forEach((article) => { %>
|
||||
<div class="article">
|
||||
|
||||
@@ -8,7 +8,7 @@ body, html {
|
||||
}
|
||||
|
||||
body {
|
||||
font: 14px/1.45 -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif;
|
||||
font: 15px sans-serif;
|
||||
color: #111;
|
||||
-webkit-text-size-adjust: none;
|
||||
background-color: #F5F5F5;
|
||||
@@ -16,8 +16,8 @@ body {
|
||||
}
|
||||
|
||||
main {
|
||||
max-width: 75ch;
|
||||
padding: 2ch;
|
||||
max-width: 42rem;
|
||||
padding: 2rem;
|
||||
margin: auto;
|
||||
background-color: #F0F0F0;
|
||||
min-height: 100vh;
|
||||
@@ -58,7 +58,7 @@ blockquote {
|
||||
border-left: 0.5em solid #ccc;
|
||||
padding-left: 1em;
|
||||
margin: 0.25em 0;
|
||||
color: #333;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
blockquote > p {
|
||||
@@ -108,7 +108,7 @@ main.article div.header a.link-home {
|
||||
line-height: 2.4;
|
||||
}
|
||||
|
||||
main.article div.header h1, main.article div.header h2, div.article h3 {
|
||||
main.article div.header h1, main.article div.header h2 {
|
||||
margin-top: 0.85em;
|
||||
margin-bottom: 0.25em;
|
||||
font-size: 2em;
|
||||
@@ -123,11 +123,19 @@ main.article div.header span.time, div.article span.time {
|
||||
}
|
||||
|
||||
div.article {
|
||||
margin-left: 1em;
|
||||
margin: 0 1em 1em 1em;
|
||||
}
|
||||
|
||||
div.article h3 {
|
||||
font-size: 1.3em;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
div.article img{
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin-right:1em;
|
||||
margin-top:0.25em;
|
||||
}
|
||||
|
||||
#text {
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>GitBlog.md - <%= article.title %></title>
|
||||
<link rel="stylesheet" type="text/css" href="/prism.css">
|
||||
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||
<title><%= info.title %> - <%= article.title %></title>
|
||||
<%- include('head'); %>
|
||||
</head>
|
||||
<body>
|
||||
<main class="article">
|
||||
|
||||
+19
-6
@@ -2,6 +2,7 @@ const express = require('express');
|
||||
const app = express();
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const pjson = require('../package.json');
|
||||
|
||||
app.enable('trust proxy');
|
||||
|
||||
@@ -35,6 +36,7 @@ module.exports = (config) => {
|
||||
|
||||
const articles = {};
|
||||
let lastRSS = '';
|
||||
let host;
|
||||
|
||||
/**
|
||||
* Fetch articles from the data folder and send success as a response
|
||||
@@ -71,6 +73,12 @@ module.exports = (config) => {
|
||||
* @param code - code to send along the page
|
||||
*/
|
||||
const render = (res, vPath, data, code = 200) => {
|
||||
data.info = {
|
||||
title: config['home']['title'],
|
||||
description: config['home']['description'],
|
||||
host: host,
|
||||
version: pjson.version
|
||||
};
|
||||
res.render(vPath, data, (err, html) => {
|
||||
if (err) {
|
||||
res.sendStatus(500);
|
||||
@@ -96,6 +104,14 @@ module.exports = (config) => {
|
||||
});
|
||||
};
|
||||
|
||||
app.use((req, res, next) => {
|
||||
if (!host) {
|
||||
host = 'http://' + req.headers.host;
|
||||
console.log(cons.ok, 'Currently hosted on ' + host);
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
//log request at result end
|
||||
app.use((req, res, next) => {
|
||||
if (config['access_log']) {
|
||||
@@ -144,7 +160,7 @@ module.exports = (config) => {
|
||||
});
|
||||
lastRSS = feed.xml();
|
||||
}
|
||||
res.type('rss').send(lastRSS);
|
||||
res.type(req.headers['user-agent'].match(/Mozilla/) ? 'text/xml' : 'rss').send(lastRSS);
|
||||
} else {
|
||||
showError(req.path, 404, res);
|
||||
}
|
||||
@@ -154,10 +170,7 @@ module.exports = (config) => {
|
||||
app.post(config['webhook']['endpoint'], (req, res) => {
|
||||
if (config['modules']['webhook']) {
|
||||
if (config['webhook']['signature_header'] && config['webhook']['secret']) {
|
||||
const payload = JSON.stringify(req.body);
|
||||
if (!payload) {
|
||||
return res.sendStatus(403);
|
||||
}
|
||||
const payload = JSON.stringify(req.body) || '';
|
||||
const hmac = crypto.createHmac('sha1', config['webhook']['secret']);
|
||||
const digest = 'sha1=' + hmac.update(payload).digest('hex');
|
||||
const checksum = req.headers[config['webhook']['signature_header']];
|
||||
@@ -224,7 +237,7 @@ module.exports = (config) => {
|
||||
});
|
||||
|
||||
// serve all static files via get
|
||||
app.get('*', express.static(config['data_dir']));
|
||||
app.get('*', express.static(path.join(__dirname, '..', config['data_dir'])));
|
||||
// catch express.static errors (mostly not found) by displaying 404
|
||||
app.get('*', (req, res) => {
|
||||
showError(req.path, 404, res);
|
||||
|
||||
+13
-2
@@ -7,9 +7,13 @@
|
||||
"modules": {
|
||||
"rss": true,
|
||||
"webhook": true,
|
||||
"prism": true
|
||||
"prism": true,
|
||||
"mathjax": true,
|
||||
"plantuml": true
|
||||
},
|
||||
"home": {
|
||||
"title": "GitBlog.md",
|
||||
"description": "A static blog using Markdown pulled from your git repository",
|
||||
"index": "index.ejs",
|
||||
"error": "error.ejs",
|
||||
"hidden": [
|
||||
@@ -33,7 +37,7 @@
|
||||
"endpoint": "/webhook",
|
||||
"secret": "",
|
||||
"signature_header": "",
|
||||
"pull_command": "git pull"
|
||||
"pull_command": "git pull origin master"
|
||||
},
|
||||
"showdown": {
|
||||
"parseImgDimensions": true,
|
||||
@@ -42,5 +46,12 @@
|
||||
"tasklists": true,
|
||||
"openLinksInNewWindow": true,
|
||||
"emoji": true
|
||||
},
|
||||
"mathjax": {
|
||||
"output_format": "svg",
|
||||
"speak_text": true
|
||||
},
|
||||
"plantuml": {
|
||||
"output_format": "svg"
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -10,6 +10,10 @@ const fs = require('fs');
|
||||
const merge = (ref, src) => {
|
||||
if (typeof ref !== typeof src) {
|
||||
return ref;
|
||||
} else if (ref.length && !src.length) {
|
||||
return ref;
|
||||
} else if (ref.length && src.length) {
|
||||
return src;
|
||||
} else if (typeof ref === 'object') {
|
||||
const out = {};
|
||||
Object.keys(ref).forEach((key) => out[key] = merge(ref[key], src[key]));
|
||||
@@ -25,7 +29,7 @@ module.exports = () => {
|
||||
let config = JSON.parse(configData);
|
||||
return merge(refConfig, config);
|
||||
} catch (error) {
|
||||
console.error('Failed to load config.json : ' + error);
|
||||
console.log('\x1b[33m⚠\x1b[0m %s', 'Failed to load config.json : ' + error);
|
||||
return refConfig;
|
||||
}
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
+95
-12
@@ -1,36 +1,119 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const showdown = require('showdown');
|
||||
const Prism = require('node-prismjs');
|
||||
|
||||
module.exports = (config) => {
|
||||
const converter = new showdown.Converter(config['showdown']);
|
||||
return {
|
||||
render: (file, cb) => {
|
||||
fs.readFile(file, {encoding: 'UTF-8'}, (err, data) => {
|
||||
if (err)
|
||||
return cb(err);
|
||||
|
||||
if (config['modules']['prism']) {
|
||||
const renderShowDown = (data, cb) => {
|
||||
const html = converter.makeHtml(data);
|
||||
cb(html);
|
||||
};
|
||||
|
||||
let Prism;
|
||||
if (config['modules']['prism'])
|
||||
Prism = require('node-prismjs');
|
||||
|
||||
const renderPrism = (data, cb) => {
|
||||
if (!config['modules']['prism'])
|
||||
return cb(data);
|
||||
const codeRegex = /```([\w-]+)\r?\n((?:(?!```)[\s\S])*)\r?\n```/m;
|
||||
let match;
|
||||
while ((match = codeRegex.exec(data))) {
|
||||
const lang = match[1].trim();
|
||||
const code = match[2].trim();
|
||||
try {
|
||||
const block = Prism.highlight(code, Prism.languages[lang] || Prism.languages.autoit, lang);
|
||||
data = data.slice(0, match.index) + `<pre><code class="${lang} language-${lang}">` + block + '</code></pre>' + data.slice(match.index + match[0].length);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
cb(data);
|
||||
};
|
||||
|
||||
if (config['modules']['plantuml']) {
|
||||
require('./script_loader')(path.join(__dirname, 'lib', 'plantuml_synchro.js'));
|
||||
}
|
||||
|
||||
const renderPlantUML = (data, cb) => {
|
||||
if (!config['modules']['plantuml'])
|
||||
return cb(data);
|
||||
const umlRegex = /@startuml\r?\n((?:(?!@enduml)[\s\S])*)\r?\n@enduml/m;
|
||||
let match;
|
||||
while ((match = umlRegex.exec(data))) {
|
||||
const code = match[1].trim();
|
||||
const s = unescape(encodeURIComponent(code)); // jshint ignore:line
|
||||
const compressed = global['zip_deflate'](s);
|
||||
const url = `http://www.plantuml.com/plantuml/${config['plantuml']['output_format']}/${encode64(compressed)}`;// jshint ignore:line
|
||||
data = data.slice(0, match.index) + `<img alt="generated PlantUML diagram" src="${url}">` + data.slice(match.index + match[0].length);
|
||||
}
|
||||
cb(data);
|
||||
};
|
||||
|
||||
const html = converter.makeHtml(data);
|
||||
let mjAPI;
|
||||
if (config['modules']['mathjax']) {
|
||||
mjAPI = require('mathjax-node');
|
||||
mjAPI.config({
|
||||
MathJax: {
|
||||
tex2jax: {
|
||||
inlineMath: [['$', '$']],
|
||||
displayMath: [['$$', '$$']]
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const renderMathJax = (data, cb) => {
|
||||
if (!config['modules']['mathjax'])
|
||||
return cb(data);
|
||||
|
||||
const doMJ = (match, format) => {
|
||||
const eq = match[1].trim();
|
||||
const output = config['mathjax']['output_format'];
|
||||
const mjConf = {
|
||||
math: eq,
|
||||
format: format,
|
||||
speakText: config['mathjax']['speak_text']
|
||||
};
|
||||
mjConf[output] = true;
|
||||
mjAPI.typeset(mjConf, (res) => {
|
||||
data = data.slice(0, match.index) + res[output] + data.slice(match.index + match[0].length);
|
||||
renderMathJax(data, (data2) => {
|
||||
cb(data2);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const eqRegex = /\$\$((?:(?!\$\$)[\s\S])*)\$\$/m;
|
||||
const inlineEqRegex = /\$([^$\n]*)\$/;
|
||||
|
||||
let match;
|
||||
if ((match = eqRegex.exec(data))) {
|
||||
doMJ(match, 'TeX');
|
||||
} else if ((match = inlineEqRegex.exec(data))) {
|
||||
doMJ(match, 'inline-TeX');
|
||||
} else {
|
||||
cb(data);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
renderShowDown: config['test'] ? renderShowDown : undefined,
|
||||
renderPrism: config['test'] ? renderPrism : undefined,
|
||||
renderPlantUML: config['test'] ? renderPlantUML : undefined,
|
||||
renderMathJax: config['test'] ? renderMathJax : undefined,
|
||||
render: (file, cb) => {
|
||||
fs.readFile(file, {encoding: 'UTF-8'}, (err, data) => {
|
||||
if (err)
|
||||
return cb(err);
|
||||
|
||||
renderPrism(data, (data) => {
|
||||
renderPlantUML(data, (data) => {
|
||||
renderMathJax(data, (data) => {
|
||||
renderShowDown(data, (html) => {
|
||||
cb(null, html);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
const fs = require('fs');
|
||||
|
||||
/**
|
||||
* Import client-side script into the "global" var
|
||||
* @param scriptPath
|
||||
*/
|
||||
module.exports = (scriptPath) => {
|
||||
eval.call(global, fs.readFileSync(scriptPath, {encoding: 'UTF-8'}));
|
||||
};
|
||||
|
||||
+63
-28
@@ -13,19 +13,24 @@ const config = require('../src/config')();
|
||||
|
||||
config['test'] = true;
|
||||
config['data_dir'] = dataDir;
|
||||
config['webhook']['endpoint'] = '/webhooktest';
|
||||
config['rss']['endpoint'] = '/rsstest';
|
||||
config['rss']['length'] = 2;
|
||||
config['home']['index'] = testIndex;
|
||||
config['home']['error'] = testError;
|
||||
config['article']['template'] = testTemplate;
|
||||
config['home']['hidden'].push('.test');
|
||||
config['rss']['endpoint'] = '/rsstest';
|
||||
config['rss']['length'] = 2;
|
||||
config['webhook']['endpoint'] = '/webhooktest';
|
||||
config['access_log'] = path.join(dataDir, 'access.log');
|
||||
config['error_log'] = path.join(dataDir, 'error.log');
|
||||
|
||||
const app = require('../src/app')(config);
|
||||
|
||||
beforeEach((done, fail) => {
|
||||
config['data_dir'] = dataDir;
|
||||
config['article']['index'] = 'index.md';
|
||||
config['home']['hidden'] = ['.ejs', '.test'];
|
||||
config['access_log'] = '';
|
||||
config['error_log'] = '';
|
||||
config['modules']['rss'] = true;
|
||||
config['modules']['webhook'] = true;
|
||||
|
||||
utils.deleteFolderSync(dataDir);
|
||||
fs.mkdirSync(dataDir);
|
||||
app.reload(done, fail);
|
||||
@@ -37,17 +42,22 @@ afterAll(() => {
|
||||
}
|
||||
});
|
||||
|
||||
describe('Test reload', () => {
|
||||
test('reload fail', (done, fail) => {
|
||||
config['data_dir'] = '';
|
||||
app.reload(fail, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test request logging', () => {
|
||||
test('test no log', (done) => {
|
||||
const tmp = config['access_log'];
|
||||
config['access_log'] = '';
|
||||
request(app).get('/rsstest').then(() => {
|
||||
config['access_log'] = tmp;
|
||||
expect(fs.existsSync(path.join(dataDir, 'access.log'))).toBe(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('test get 200', (done) => {
|
||||
config['access_log'] = path.join(dataDir, 'access.log');
|
||||
request(app).get('/rsstest').then(() => {
|
||||
fs.readFile(path.join(dataDir, 'access.log'), {encoding: 'UTF-8'}, (err, data) => {
|
||||
expect(err).toBeNull();
|
||||
@@ -57,6 +67,7 @@ describe('Test request logging', () => {
|
||||
});
|
||||
});
|
||||
test('test post 400', (done) => {
|
||||
config['access_log'] = path.join(dataDir, 'access.log');
|
||||
request(app).post('/rsstest').then(() => {
|
||||
fs.readFile(path.join(dataDir, 'access.log'), {encoding: 'UTF-8'}, (err, data) => {
|
||||
expect(err).toBeNull();
|
||||
@@ -66,6 +77,7 @@ describe('Test request logging', () => {
|
||||
});
|
||||
});
|
||||
test('test 2 requests', (done) => {
|
||||
config['access_log'] = path.join(dataDir, 'access.log');
|
||||
request(app).get('/rss').then(() => {
|
||||
request(app).post('/rsstest').then(() => {
|
||||
fs.readFile(path.join(dataDir, 'access.log'), {encoding: 'UTF-8'}, (err, data) => {
|
||||
@@ -81,22 +93,16 @@ describe('Test request logging', () => {
|
||||
|
||||
describe('Test error logging', () => {
|
||||
test('test no log', (done) => {
|
||||
const tmp = config['home']['hidden'];
|
||||
config['home']['hidden'] = null;
|
||||
const tmp2 = config['errpr_log'];
|
||||
config['error_log'] = '';
|
||||
request(app).get('/somefile.txt').then(() => {
|
||||
config['home']['hidden'] = tmp;
|
||||
config['error_log'] = tmp2;
|
||||
expect(fs.existsSync(path.join(dataDir, 'error.log'))).toBe(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('test null error ', (done) => {
|
||||
const tmp = config['home']['hidden'];
|
||||
config['home']['hidden'] = null;
|
||||
config['error_log'] = path.join(dataDir, 'error.log');
|
||||
request(app).get('/somefile.txt').then(() => {
|
||||
config['home']['hidden'] = tmp;
|
||||
fs.readFile(path.join(dataDir, 'error.log'), {encoding: 'UTF-8'}, (err, data) => {
|
||||
expect(err).toBeNull();
|
||||
const start = data.split('\n').slice(0, 2).join('\n');
|
||||
@@ -123,6 +129,13 @@ describe('Test root path', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('500 render error', (done) => {
|
||||
fs.writeFileSync(path.join(dataDir, testIndex), 'articles <%= null.length %>');
|
||||
request(app).get('/').then((response) => {
|
||||
expect(response.statusCode).toBe(500);
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('200 no articles', (done) => {
|
||||
fs.writeFileSync(path.join(dataDir, testIndex), 'articles <%= articles.length %>');
|
||||
request(app).get('/').then((response) => {
|
||||
@@ -156,18 +169,35 @@ describe('Test RSS feed', () => {
|
||||
config['modules']['rss'] = false;
|
||||
request(app).get('/rsstest').then((response) => {
|
||||
expect(response.statusCode).toBe(404);
|
||||
config['modules']['rss'] = true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('200 empty rss', (done) => {
|
||||
request(app).get('/rsstest').then((response) => {
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.type).toBe('application/rss+xml');
|
||||
expect(response.text.length).toBeGreaterThan(0);
|
||||
expect(response.text.split('<item>').length).toBe(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('200 Mozilla fix', (done) => {
|
||||
request(app).get('/rsstest').set('user-agent', 'Mozilla Firefox 64.0').then((response) => {
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.type).toBe('text/xml');
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('200 rss cache', (done) => {
|
||||
request(app).get('/rsstest').then(() => {
|
||||
request(app).get('/rsstest').then((response) => {
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.text.length).toBeGreaterThan(0);
|
||||
expect(response.text.split('<item>').length).toBe(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
test('200 2 rss items', (done, fail) => {
|
||||
utils.createEmptyDirs([
|
||||
path.join(dataDir, '2019', '05', '05'),
|
||||
@@ -213,7 +243,6 @@ describe('Test webhook', () => {
|
||||
config['modules']['webhook'] = false;
|
||||
request(app).post('/webhooktest').then((response) => {
|
||||
expect(response.statusCode).toBe(400);
|
||||
config['modules']['webhook'] = true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -244,14 +273,6 @@ describe('Test webhook', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('403 no payload', (done) => {
|
||||
config['webhook']['signature_header'] = 'testheader';
|
||||
config['webhook']['secret'] = 'testvalue';
|
||||
request(app).post('/webhooktest').then((response) => {
|
||||
expect(response.statusCode).toBe(403);
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('403 wrong secret', (done) => {
|
||||
config['webhook']['signature_header'] = 'testheader';
|
||||
config['webhook']['secret'] = 'testvalue';
|
||||
@@ -282,6 +303,19 @@ describe('Test articles rendering', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('500 no index', (done, fail) => {
|
||||
utils.createEmptyDirs([path.join(dataDir, '2019', '05', '05'),]);
|
||||
fs.writeFileSync(path.join(dataDir, '2019', '05', '05', 'index.md'), '# Hello');
|
||||
fs.writeFileSync(path.join(dataDir, testTemplate), '<%- article.content %><%- `<a href="${article.url}">reload</a>` %>');
|
||||
app.reload(() => {
|
||||
config['article']['index'] = 'invalid.md';
|
||||
request(app).get('/2019/05/05/hello/').then((response) => {
|
||||
expect(response.statusCode).toBe(500);
|
||||
done();
|
||||
});
|
||||
}, fail);
|
||||
});
|
||||
|
||||
test('500 no template', (done, fail) => {
|
||||
utils.createEmptyDirs([path.join(dataDir, '2019', '05', '05'),]);
|
||||
fs.writeFileSync(path.join(dataDir, '2019', '05', '05', 'index.md'), '# Hello');
|
||||
@@ -359,9 +393,10 @@ describe('Test static files', () => {
|
||||
});
|
||||
});
|
||||
test('200 valid file', (done) => {
|
||||
fs.writeFileSync(path.join(dataDir, 'somefile.txt'), 'filecontent');
|
||||
request(app).get('/somefile.txt').then((response) => {
|
||||
fs.writeFileSync(path.join(dataDir, 'somefile.css'), 'filecontent');
|
||||
request(app).get('/somefile.css').then((response) => {
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.type).toBe('text/css');
|
||||
expect(response.text).toBe('filecontent');
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -65,3 +65,17 @@ test('wrong config fixed', () => {
|
||||
expect(config['node_port']).toBe(3000);
|
||||
expect(config['data_dir']).toBe('data2');
|
||||
});
|
||||
|
||||
test('array parsing', () => {
|
||||
fs.writeFileSync(configFile, '{"home":{"hidden":["item1","item2"]}}');
|
||||
const config = require('../src/config')();
|
||||
expect(config).toBeDefined();
|
||||
expect(config['home']['hidden']).toEqual(['item1', 'item2']);
|
||||
});
|
||||
|
||||
test('array fix', () => {
|
||||
fs.writeFileSync(configFile, '{"home":{"hidden":{}}}');
|
||||
const config = require('../src/config')();
|
||||
expect(config).toBeDefined();
|
||||
expect(config['home']['hidden']).toEqual(['.ejs']);
|
||||
});
|
||||
@@ -22,6 +22,7 @@ const config = {
|
||||
const fw = require('../src/file_walker')(config);
|
||||
|
||||
beforeEach(() => {
|
||||
config['data_dir'] = dataDir;
|
||||
utils.deleteFolderSync(dataDir);
|
||||
fs.mkdirSync(dataDir);
|
||||
});
|
||||
@@ -193,7 +194,6 @@ describe('Test article fetching', () => {
|
||||
fw.fetchArticles((err, list) => {
|
||||
expect(err).not.toBeNull();
|
||||
expect(list).not.toBeDefined();
|
||||
config['data_dir'] = dataDir;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
+157
-51
@@ -7,18 +7,31 @@ const dataDir = 'test_data';
|
||||
const file = path.join(dataDir, 'test.md');
|
||||
|
||||
const config = {
|
||||
'test': true,
|
||||
'modules': {
|
||||
'prism': true,
|
||||
'mathjax': true,
|
||||
'plantuml': true
|
||||
},
|
||||
'showdown': {
|
||||
'simplifiedAutoLink': true,
|
||||
'smartIndentationFix': true
|
||||
},
|
||||
'mathjax': {
|
||||
'output_format': 'html',
|
||||
'speak_text': false
|
||||
},
|
||||
'plantuml': {
|
||||
'output_format': 'svg'
|
||||
}
|
||||
};
|
||||
|
||||
const renderer = require('../src/renderer')(config);
|
||||
|
||||
beforeEach(() => {
|
||||
config['modules']['prism'] = true;
|
||||
config['modules']['mathjax'] = true;
|
||||
config['modules']['plantuml'] = true;
|
||||
utils.deleteFolderSync(dataDir);
|
||||
fs.mkdirSync(dataDir);
|
||||
});
|
||||
@@ -29,68 +42,161 @@ afterAll(() => {
|
||||
}
|
||||
});
|
||||
|
||||
test('invalid file', (done) => {
|
||||
describe('Test Showdown', () => {
|
||||
test('normal', (done) => {
|
||||
renderer.renderShowDown('# Hello', (html) => {
|
||||
expect(html).toBe('<h1 id="hello">Hello</h1>');
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('custom rules', (done) => {
|
||||
renderer.renderShowDown('www.google.com', (html) => {
|
||||
expect(html).toBe('<p><a href="http://www.google.com">www.google.com</a></p>');
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('code format', (done) => {
|
||||
renderer.renderShowDown('```python\nprint("hello")\n```\n\n```python\nprint("hello")\n```', (html) => {
|
||||
expect(html).toBe('<pre><code class="python language-python">print("hello")\n</code></pre>\n<pre><code class="python language-python">print("hello")\n</code></pre>');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test Prism', () => {
|
||||
test('no prism', (done) => {
|
||||
config['modules']['prism'] = false;
|
||||
renderer.renderPrism('```python\nprint("hello")\n```\n\n```python\nprint("hello")\n```', (data) => {
|
||||
expect(data).toBe('```python\nprint("hello")\n```\n\n```python\nprint("hello")\n```');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('prism correct', (done) => {
|
||||
renderer.renderPrism('```python\nprint("hello")\n```', (data) => {
|
||||
expect(data).not.toBe('<pre><code class="python language-python">print("hello")\n</code></pre>');
|
||||
expect(data.indexOf('<pre><code class="python language-python">')).toBe(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('prism invalid lang', (done) => {
|
||||
renderer.renderPrism('```pythdon\nprint("hello")\n```', (data) => {
|
||||
expect(data).not.toBe('<pre><code class="pythdon language-pythdon">print("hello")\n</code></pre>');
|
||||
expect(data.indexOf('<pre><code class="pythdon language-pythdon">')).toBe(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('prism mutliple code blocks', (done) => {
|
||||
renderer.renderPrism('```python\n\n```\n```python\n\n```', (data) => {
|
||||
expect(data).toBe('<pre><code class="python language-python"></code></pre>\n<pre><code class="python language-python"></code></pre>');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test PlantUML', () => {
|
||||
test('no plantuml', (done) => {
|
||||
config['modules']['plantuml'] = false;
|
||||
renderer.renderPlantUML('@startuml\nBob -> Alice : hello\n@enduml', (data) => {
|
||||
expect(data).toBe('@startuml\nBob -> Alice : hello\n@enduml');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('plantuml correct', (done) => {
|
||||
renderer.renderPlantUML('@startuml\nBob -> Alice : hello\n@enduml', (data) => {
|
||||
expect(data).toBe('<img alt="generated PlantUML diagram" src="http://www.plantuml.com/plantuml/svg/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000">');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('plantuml multiple uml', (done) => {
|
||||
renderer.renderPlantUML('@startuml\nBob -> Alice : hello\n@enduml\n@startuml\nBob -> Alice : hello\n@enduml', (data) => {
|
||||
expect(data).toBe('<img alt="generated PlantUML diagram" src="http://www.plantuml.com/plantuml/svg/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000">\n<img alt="generated PlantUML diagram" src="http://www.plantuml.com/plantuml/svg/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000">');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('Test MathJax', () => {
|
||||
test('no mathjax', (done) => {
|
||||
config['modules']['mathjax'] = false;
|
||||
renderer.renderMathJax('$$\nhello\n$$\ntest$test$', (data) => {
|
||||
expect(data).toBe('$$\nhello\n$$\ntest$test$');
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('full eq', (done) => {
|
||||
renderer.renderMathJax('$$\n\nA\n\n$$', (data) => {
|
||||
expect(data).toBe('<span class=\"mjx-chtml MJXc-display\" style=\"text-align: center;\">' +
|
||||
'<span class=\"mjx-math\"><span class=\"mjx-mrow\"><span class=\"mjx-mi\">' +
|
||||
'<span class=\"mjx-char MJXc-TeX-math-I\" style=\"padding-top: 0.519em; padding-bottom: 0.298em;\">' +
|
||||
'A' +
|
||||
'</span></span></span></span></span>');
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('inline eq', (done) => {
|
||||
renderer.renderMathJax('start $a$ end', (data) => {
|
||||
expect(data).toBe('start ' +
|
||||
'<span class=\"mjx-chtml\">' +
|
||||
'<span class=\"mjx-math\"><span class=\"mjx-mrow\"><span class=\"mjx-mi\">' +
|
||||
'<span class=\"mjx-char MJXc-TeX-math-I\" style=\"padding-top: 0.225em; padding-bottom: 0.298em;\">' +
|
||||
'a' +
|
||||
'</span></span></span></span></span>' +
|
||||
' end');
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('fake inline eq', (done) => {
|
||||
renderer.renderMathJax('i have $6\nyou have $5', (data) => {
|
||||
expect(data).toBe('i have $6\nyou have $5');
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('multiple eq', (done) => {
|
||||
renderer.renderMathJax('$$\n\nA\n\n$$\nstart $a$ end\n$$\n\nA\n\n$$', (data) => {
|
||||
expect(data).toBe('' +
|
||||
'<span class=\"mjx-chtml MJXc-display\" style=\"text-align: center;\">' +
|
||||
'<span class=\"mjx-math\"><span class=\"mjx-mrow\"><span class=\"mjx-mi\">' +
|
||||
'<span class=\"mjx-char MJXc-TeX-math-I\" style=\"padding-top: 0.519em; padding-bottom: 0.298em;\">' +
|
||||
'A' +
|
||||
'</span></span></span></span></span>\n' +
|
||||
'start ' +
|
||||
'<span class=\"mjx-chtml\">' +
|
||||
'<span class=\"mjx-math\"><span class=\"mjx-mrow\"><span class=\"mjx-mi\">' +
|
||||
'<span class=\"mjx-char MJXc-TeX-math-I\" style=\"padding-top: 0.225em; padding-bottom: 0.298em;\">' +
|
||||
'a' +
|
||||
'</span></span></span></span></span>' +
|
||||
' end\n' +
|
||||
'<span class=\"mjx-chtml MJXc-display\" style=\"text-align: center;\">' +
|
||||
'<span class=\"mjx-math\"><span class=\"mjx-mrow\"><span class=\"mjx-mi\">' +
|
||||
'<span class=\"mjx-char MJXc-TeX-math-I\" style=\"padding-top: 0.519em; padding-bottom: 0.298em;\">' +
|
||||
'A' +
|
||||
'</span></span></span></span></span>');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test render', () => {
|
||||
test('invalid file', (done) => {
|
||||
renderer.render('invalid file', (err, html) => {
|
||||
expect(err).not.toBeNull();
|
||||
expect(html).not.toBeDefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('normal file', (done) => {
|
||||
test('normal file', (done) => {
|
||||
fs.writeFileSync(file, `# Hello`);
|
||||
renderer.render(file, (err, html) => {
|
||||
expect(err).toBeNull();
|
||||
expect(html).toBe('<h1 id="hello">Hello</h1>');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('custom rules', (done) => {
|
||||
fs.writeFileSync(file, `www.google.com`);
|
||||
renderer.render(file, (err, html) => {
|
||||
expect(err).toBeNull();
|
||||
expect(html).toBe('<p><a href="http://www.google.com">www.google.com</a></p>');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('no prism', (done) => {
|
||||
config['modules']['prism'] = false;
|
||||
fs.writeFileSync(file, '```python\nprint("hello")\n```\n\n```python\nprint("hello")\n```');
|
||||
renderer.render(file, (err, html) => {
|
||||
expect(err).toBeNull();
|
||||
expect(html).toBe('<pre><code class="python language-python">print("hello")\n</code></pre>\n<pre><code class="python language-python">print("hello")\n</code></pre>');
|
||||
config['modules']['prism'] = true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('prism correct', (done) => {
|
||||
fs.writeFileSync(file, '```python\nprint("hello")\n```');
|
||||
renderer.render(file, (err, html) => {
|
||||
expect(err).toBeNull();
|
||||
expect(html).not.toBe('<pre><code class="python language-python">print("hello")\n</code></pre>');
|
||||
expect(html.indexOf('<pre><code class="python language-python">')).toBe(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('prism invalid lang', (done) => {
|
||||
fs.writeFileSync(file, '```pythdon\nprint("hello")\n```');
|
||||
renderer.render(file, (err, html) => {
|
||||
expect(err).toBeNull();
|
||||
expect(html).not.toBe('<pre><code class="pythdon language-pythdon">print("hello")\n</code></pre>');
|
||||
expect(html.indexOf('<pre><code class="pythdon language-pythdon">')).toBe(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('prism mutliple code blocks', (done) => {
|
||||
fs.writeFileSync(file, '```python\n\n```\n\n```python\n\n```');
|
||||
renderer.render(file, (err, html) => {
|
||||
expect(err).toBeNull();
|
||||
expect(html).toBe('<pre><code class="python language-python"></code></pre>\n<pre><code class="python language-python"></code></pre>');
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
/* jshint -W117 */
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const utils = require('./test_utils');
|
||||
|
||||
const dataDir = 'test_data';
|
||||
|
||||
beforeEach(() => {
|
||||
utils.deleteFolderSync(dataDir);
|
||||
fs.mkdirSync(dataDir);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
if (fs.existsSync(dataDir)) {
|
||||
utils.deleteFolderSync(dataDir);
|
||||
}
|
||||
});
|
||||
|
||||
test('load 1 script', () => {
|
||||
const file = path.join(dataDir, 'test.js');
|
||||
fs.writeFileSync(file, `
|
||||
var a = 5;
|
||||
function b(){
|
||||
return a;
|
||||
}`);
|
||||
require('../src/script_loader')(file);
|
||||
expect(global['b']).toBeDefined();
|
||||
expect(global['b']()).toBe(5);
|
||||
});
|
||||
|
||||
test('load 2 script', () => {
|
||||
const file1 = path.join(dataDir, 'test.js');
|
||||
fs.writeFileSync(file1, `
|
||||
var a = 5;
|
||||
function b(){
|
||||
return a;
|
||||
}`);
|
||||
const file2 = path.join(dataDir, 'test2.js');
|
||||
fs.writeFileSync(file2, `
|
||||
var a = 9;
|
||||
function b(){
|
||||
return a;
|
||||
}`);
|
||||
require('../src/script_loader')(file1);
|
||||
expect(global['b']).toBeDefined();
|
||||
expect(global['b']()).toBe(5);
|
||||
|
||||
require('../src/script_loader.js')(file2);
|
||||
expect(global['b']).toBeDefined();
|
||||
expect(global['b']()).toBe(9);
|
||||
});
|
||||
Reference in New Issue
Block a user