├── .gitignore ├── Makefile ├── README.md ├── css ├── ditto.css └── github.css ├── docs ├── features.md ├── how_do_i_run_ditto_locally.md ├── how_do_i_use_ditto.md ├── how_does_it_work.md ├── images │ └── layout.png ├── maths_demo.md └── why_use_ditto.md ├── index.html ├── js ├── ditto.js ├── highlight.js └── marked.js ├── scripts └── install.sh ├── sidebar.md ├── templates ├── index.html └── sidebar.md └── ver ├── 0.1 ├── ditto.css ├── ditto.js ├── index.html ├── marked.js └── sidebar.md ├── 0.11 ├── ditto.css ├── ditto.js ├── index.html ├── marked.js └── sidebar.md ├── 0.12 ├── ditto.css ├── ditto.js ├── github.css ├── highlight.js ├── index.html ├── marked.js └── sidebar.md ├── 0.13 ├── ditto.css ├── ditto.js ├── github.css ├── highlight.js ├── index.html ├── marked.js └── sidebar.md ├── 0.14 ├── ditto.css ├── ditto.js ├── github.css ├── highlight.js ├── index.html ├── marked.js └── sidebar.md ├── 0.15 ├── ditto.css ├── ditto.js ├── github.css ├── highlight.js ├── index.html ├── marked.js └── sidebar.md └── latest ├── ditto.css ├── ditto.js ├── github.css ├── highlight.js ├── index.html ├── marked.js └── sidebar.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | 3 | build/ 4 | dist/ 5 | 6 | *.egg* 7 | .rope* 8 | run.sh 9 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | default: 2 | @echo "targets:" 3 | @echo " - version: make a new ditto version" 4 | @echo " - update_latest: update latest ditto version" 5 | @echo " - run_server: run local http server" 6 | 7 | latest: 8 | @mkdir -p ver/latest; \ 9 | cp index.html ver/latest; \ 10 | cp css/* ver/latest; \ 11 | cp js/* ver/latest; \ 12 | cp templates/* ver/latest; \ 13 | sed -i 's/VER/latest/g' ver/latest/index.html; \ 14 | echo "updated latest!" 15 | 16 | version: latest 17 | @read -p "enter new version name: " new_version; \ 18 | mkdir -p ver; \ 19 | mkdir ver/$$new_version; \ 20 | cp css/* ver/$$new_version; \ 21 | cp js/* ver/$$new_version; \ 22 | cp templates/* ver/$$new_version; \ 23 | sed -i 's/VER/'$$new_version'/g' ver/$$new_version/index.html; \ 24 | echo "done :)" 25 | 26 | run_server: 27 | python -m SimpleHTTPServer 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ditto 2 | `ditto` inspired by [flatdoc](http://ricostacruz.com/flatdoc/) is a markdown code 3 | documentation system, capable of producing documentation similar to 4 | [Three.js][2] and [Backbone.js][3], check out live demo [here][1]. It is 5 | designed for people who use Github Pages to host their code documentation, but 6 | you can also host it yourself. 7 | 8 | You want to use ditto because 9 | - Docs are in markdown 10 | - No build process needed (markdown files are rendered on the browser) 11 | - Deployable via GitHub Pages 12 | 13 | 14 | 15 | ## How do I start? 16 | Enter the following command and follow instructions: 17 | 18 | 19 | curl -L https://git.io/v6T7r > install.sh && sh install.sh 20 | 21 | 22 | Or alternatively see this page for [instructions][4]. 23 | 24 | 25 | 26 | ### LICENSE 27 | 28 | The MIT License (MIT) 29 | 30 | Copyright (c) 2014 Chris Choi 31 | 32 | Permission is hereby granted, free of charge, to any person obtaining a copy 33 | of this software and associated documentation files (the "Software"), to deal 34 | in the Software without restriction, including without limitation the rights 35 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 36 | copies of the Software, and to permit persons to whom the Software is 37 | furnished to do so, subject to the following conditions: 38 | 39 | The above copyright notice and this permission notice shall be included in 40 | all copies or substantial portions of the Software. 41 | 42 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 43 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 44 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 45 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 46 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 47 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 48 | THE SOFTWARE. 49 | 50 | 51 | 52 | [1]: http://chutsu.github.io/ditto 53 | [2]: http://threejs.org/docs/ 54 | [3]: http://backbonejs.org/ 55 | [4]: http://chutsu.github.io/ditto/#docs/how_do_i_use_ditto 56 | -------------------------------------------------------------------------------- /css/ditto.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #333; 3 | margin: 0; 4 | padding: 0; 5 | 6 | font-family: Verdana, Arial; 7 | font-size: 0.8em; 8 | } 9 | 10 | #sidebar { 11 | position: fixed; 12 | width: 220px; 13 | height: 100%; 14 | 15 | overflow-y: scroll; 16 | overflow: -moz-scrollbars-vertical; 17 | 18 | margin-right: 20px; 19 | margin-top: 0; 20 | padding-left: 25px; 21 | padding-top: 0; 22 | 23 | box-shadow: 0 0 40px #CCC; 24 | -webkit-box-shadow: 0 0 40px #CCC; 25 | -moz-box-shadow: 0 0 40px #CCC; 26 | border-right: 1px solid #BBB; 27 | } 28 | 29 | #sidebar h1 { 30 | font-size: 25px; 31 | margin-bottom: 0px; 32 | padding-bottom: 0px; 33 | } 34 | 35 | #sidebar h1 a:link, #sidebar h1 a:visited { 36 | color: #333; 37 | } 38 | 39 | #sidebar h2 { 40 | font-size: 15px; 41 | } 42 | 43 | #sidebar h5 { 44 | margin-top: 20px; 45 | margin-bottom: 0; 46 | } 47 | 48 | #sidebar a:visited, #sidebar a:link { 49 | color: #4682BE; 50 | text-decoration: none; 51 | } 52 | 53 | #sidebar ul { 54 | list-style-type: none; 55 | margin: 0; 56 | padding-left: 10px; 57 | padding-top: 0; 58 | } 59 | 60 | #sidebar ul li:before { /* a hack to have dashes as a list style */ 61 | content: "-"; 62 | position: relative; 63 | left: -5px; 64 | } 65 | 66 | #sidebar ul li { 67 | margin-top: 0; 68 | margin-bottom: 2px; 69 | margin-left: 10px; 70 | padding: 0; 71 | 72 | text-indent: -5px; /* to compensate for the padding for the dash */ 73 | font-size: 12px; 74 | } 75 | 76 | #content { 77 | width: 580px; 78 | 79 | margin-left: 300px; 80 | padding-top: 10px; 81 | padding-bottom: 150px; 82 | 83 | text-align: justify; 84 | font-size: 1.0em; 85 | } 86 | 87 | #content pre { 88 | margin-left: auto; 89 | margin-right: auto; 90 | 91 | padding-top: 10px; 92 | padding-bottom: 10px; 93 | padding-left: 13px; 94 | padding-right: 13px; 95 | 96 | color: #FFF; 97 | white-space: pre-wrap; /* css-3 */ 98 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 99 | white-space: -pre-wrap; /* Opera 4-6 */ 100 | white-space: -o-pre-wrap; /* Opera 7 */ 101 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 102 | 103 | background: #F7FAFB; 104 | border-radius: 5px; 105 | } 106 | 107 | #content pre code { 108 | padding-top: 0px; 109 | padding-bottom: 0px; 110 | padding-left: 0; 111 | font-size: 1.1em; 112 | border: none; 113 | } 114 | 115 | #content code { 116 | padding-left: 5px; 117 | padding-right: 5px; 118 | padding-top: 1px; 119 | padding-bottom: 1px; 120 | 121 | color: #555; 122 | font-size: 10px; 123 | font-weight: normal; 124 | font-family: Consolas, monospace; 125 | 126 | background: #F7FAFB; 127 | border: 1px solid #E3EDF3; 128 | border-radius: 2px; 129 | } 130 | 131 | #content h2 { 132 | margin-top: 50px; 133 | margin-bottom: 0px; 134 | 135 | padding-top: 20px; 136 | padding-bottom: 0px; 137 | 138 | font-size: 18px; 139 | text-align: left; 140 | 141 | border-top: 2px solid #666; 142 | } 143 | 144 | #content h3 { 145 | margin-top: 50px; 146 | margin-bottom: 0px; 147 | 148 | padding-top: 20px; 149 | padding-bottom: 0px; 150 | 151 | text-align: left; 152 | border-top: 1px dotted #777; 153 | } 154 | 155 | #content hr { 156 | border: 0; 157 | height: 0; 158 | border-top: 1px solid rgba(0, 0, 0, 0.1); 159 | border-bottom: 1px solid rgba(255, 255, 255, 0.3); 160 | } 161 | 162 | #content img { 163 | max-width: 90%; 164 | display: block; 165 | 166 | margin-left: auto; 167 | margin-right: auto; 168 | margin-top: 40px; 169 | margin-bottom: 40px; 170 | 171 | border-radius: 5px; 172 | } 173 | 174 | #content ul { 175 | display: block; 176 | list-style-type: none; 177 | } 178 | 179 | #content ul li:before { /* a hack to have dashes as a list style */ 180 | content: "-"; 181 | position: relative; 182 | left: -5px; 183 | } 184 | 185 | #content ul li { 186 | text-indent: -5px; /* to compensate for the padding for the dash */ 187 | font-size: 13px; 188 | } 189 | 190 | #content ul li.link { 191 | color: #4682BE; 192 | text-decoration: none; 193 | font-size: 13px; 194 | font-weight: bold; 195 | cursor: pointer; 196 | } 197 | 198 | #content a:link, #content a:visited { 199 | color: #4682BE; 200 | text-decoration: none; 201 | } 202 | 203 | #back_to_top { 204 | display: none; 205 | position: fixed; 206 | 207 | height: 20px; 208 | line-height: 20px; 209 | width: 50px; 210 | top: 20px; 211 | 212 | margin-left: 890px; 213 | 214 | color: #FFF; 215 | vertical-align: middle; 216 | text-align: center; 217 | font-size: 10px; 218 | 219 | border-radius: 5px; 220 | background-color: #AAA; 221 | } 222 | 223 | #back_to_top:hover { 224 | background-color: #444; 225 | cursor: pointer; 226 | } 227 | 228 | #edit { 229 | display: none; 230 | position: fixed; 231 | 232 | height: 20px; 233 | line-height: 20px; 234 | width: 50px; 235 | top: 50px; 236 | 237 | margin-left: 890px; 238 | 239 | color: #FFF; 240 | vertical-align: middle; 241 | text-align: center; 242 | font-size: 10px; 243 | 244 | border-radius: 5px; 245 | background-color: #AAA; 246 | } 247 | 248 | #edit:hover { 249 | background-color: #444; 250 | cursor: pointer; 251 | } 252 | 253 | #loading, #error { 254 | display: none; 255 | position: fixed; 256 | 257 | height: 17px; 258 | top: 45%; 259 | 260 | margin-left: 560px; 261 | 262 | font-size: 14px; 263 | font-weight: bold; 264 | } 265 | 266 | input[type=search] { 267 | display: block; 268 | width: 180px; 269 | 270 | text-align: left; 271 | } 272 | 273 | .search_results{ 274 | 275 | 276 | } 277 | 278 | .fragments { 279 | margin: 0; 280 | padding: 10px; 281 | /* border: 1px solid #777; */ 282 | /* border-radius: 5px; */ 283 | } 284 | 285 | .fragment { 286 | padding-left: 10px; 287 | padding-right: 10px; 288 | padding-top: 0px; 289 | padding-bottom: 0px; 290 | 291 | /* border: 1px solid #777; */ 292 | /* border-radius: 5px; */ 293 | } 294 | 295 | .search_results .link { 296 | margin-top: 35px; 297 | } 298 | 299 | #content ul li { 300 | text-align: left; 301 | } 302 | 303 | #content ul .fragments li:before { 304 | content: ""; 305 | position: relative; 306 | left: 0px; 307 | } 308 | 309 | #content ul li.fragment:before { 310 | content: ""; 311 | margin: 0; 312 | padding: 0; 313 | } 314 | 315 | #content img.github_badges { 316 | display: inline; 317 | margin-top: 0; 318 | margin-bottom: 0; 319 | } 320 | 321 | #content .youtube_video { 322 | margin-top: 20px; 323 | } 324 | 325 | #hide { 326 | display: none; 327 | } 328 | -------------------------------------------------------------------------------- /css/github.css: -------------------------------------------------------------------------------- 1 | /* 2 | github.com style (c) Vasily Polovnyov 3 | */ 4 | 5 | .hljs { 6 | display: block; 7 | overflow-x: auto; 8 | padding: 0.5em; 9 | color: #333; 10 | background: #f8f8f8; 11 | -webkit-text-size-adjust: none; 12 | } 13 | 14 | .hljs-comment, 15 | .diff .hljs-header { 16 | color: #998; 17 | font-style: italic; 18 | } 19 | 20 | .hljs-keyword, 21 | .css .rule .hljs-keyword, 22 | .hljs-winutils, 23 | .nginx .hljs-title, 24 | .hljs-subst, 25 | .hljs-request, 26 | .hljs-status { 27 | color: #333; 28 | font-weight: bold; 29 | } 30 | 31 | .hljs-number, 32 | .hljs-hexcolor, 33 | .ruby .hljs-constant { 34 | color: #008080; 35 | } 36 | 37 | .hljs-string, 38 | .hljs-tag .hljs-value, 39 | .hljs-doctag, 40 | .tex .hljs-formula { 41 | color: #d14; 42 | } 43 | 44 | .hljs-title, 45 | .hljs-id, 46 | .scss .hljs-preprocessor { 47 | color: #900; 48 | font-weight: bold; 49 | } 50 | 51 | .hljs-list .hljs-keyword, 52 | .hljs-subst { 53 | font-weight: normal; 54 | } 55 | 56 | .hljs-class .hljs-title, 57 | .hljs-type, 58 | .vhdl .hljs-literal, 59 | .tex .hljs-command { 60 | color: #458; 61 | font-weight: bold; 62 | } 63 | 64 | .hljs-tag, 65 | .hljs-tag .hljs-title, 66 | .hljs-rule .hljs-property, 67 | .django .hljs-tag .hljs-keyword { 68 | color: #000080; 69 | font-weight: normal; 70 | } 71 | 72 | .hljs-attribute, 73 | .hljs-variable, 74 | .lisp .hljs-body, 75 | .hljs-name { 76 | color: #008080; 77 | } 78 | 79 | .hljs-regexp { 80 | color: #009926; 81 | } 82 | 83 | .hljs-symbol, 84 | .ruby .hljs-symbol .hljs-string, 85 | .lisp .hljs-keyword, 86 | .clojure .hljs-keyword, 87 | .scheme .hljs-keyword, 88 | .tex .hljs-special, 89 | .hljs-prompt { 90 | color: #990073; 91 | } 92 | 93 | .hljs-built_in { 94 | color: #0086b3; 95 | } 96 | 97 | .hljs-preprocessor, 98 | .hljs-pragma, 99 | .hljs-pi, 100 | .hljs-doctype, 101 | .hljs-shebang, 102 | .hljs-cdata { 103 | color: #999; 104 | font-weight: bold; 105 | } 106 | 107 | .hljs-deletion { 108 | background: #fdd; 109 | } 110 | 111 | .hljs-addition { 112 | background: #dfd; 113 | } 114 | 115 | .diff .hljs-change { 116 | background: #0086b3; 117 | } 118 | 119 | .hljs-chunk { 120 | color: #aaa; 121 | } 122 | -------------------------------------------------------------------------------- /docs/features.md: -------------------------------------------------------------------------------- 1 | # Features 2 | 3 | - Embed Youtube videos 4 | 5 | 6 | ## Embed Youtube videos 7 | 8 | Use `[ditto:youtube:]` to embed youtube videos: 9 | 10 | [ditto:youtube:https://www.youtube.com/watch?v=9CS7j5I6aOc] 11 | -------------------------------------------------------------------------------- /docs/how_do_i_run_ditto_locally.md: -------------------------------------------------------------------------------- 1 | # How do I run ditto locally? 2 | 3 | `ditto` requires a http server in-order to send GET requests to pull the markdown 4 | files. There are many ways to run ditto locally, perhaps the easiest is to use 5 | Python's `SimpleHTTPServer` like so: 6 | 7 | cd 8 | python -m SimpleHTTPServer 9 | 10 | Once the server is instaciated it should begin serving your documentation at 11 | address `127.0.0.1:8000`. 12 | 13 | 14 | 15 | ## Alternatives - LiveReload 16 | 17 | Personally I find it very convenient when editing markdown files in ditto 18 | whilst using a python tool called [LiveReload][livereload]. The tool 19 | automatically refreshes the page you are editing, giving you a dreamweaver like 20 | live-preview of the doc you are editing. 21 | 22 | pip install livereload 23 | cd livereload 24 | # serving on 127.0.0.1:35729 ... 25 | 26 | If you run livereload at the root of your repo, it detects any file changes 27 | and automatically refreshes the page. What I normally do is have browser and 28 | editor side by side, as I type and save, the content on the browser gets 29 | automatically refreshed. 30 | 31 | 32 | [livereload]: https://github.com/lepture/python-livereload 33 | -------------------------------------------------------------------------------- /docs/how_do_i_use_ditto.md: -------------------------------------------------------------------------------- 1 | # How do I use ditto? 2 | 3 | Contents: 4 | - File Structure 5 | - index.html 6 | - sidebar.md 7 | - README.md 8 | 9 | 10 | ## File Structure 11 | `ditto` expects the file structure of your documentation website to look 12 | something like this: 13 | 14 | index.html 15 | sidebar.md 16 | README.md 17 | docs/ # insert markdown files here! 18 | 19 | ## index.html 20 | **NOTE**: Before you create the `index.html` file, please know that `ditto` 21 | requires a http server for the documentation to be pulled down. If you're using 22 | `gh-pages` in your github, just push this `index.html` along with other files 23 | discussed in section `File Structure` to your `gh-pages` branch on github to 24 | host your files. 25 | 26 | [Download][index_file](<- right-click "Save as") or copy the following code 27 | snippet and save it as `index.html` 28 | 29 | 30 | 31 | 32 | TITLE 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 61 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 |
73 |
74 | 75 | 76 |
top
77 |
edit
78 |
Loading ...
79 |
80 | 81 | 82 | 101 | 102 | 103 | 104 | Edit: 105 | - `ditto.index` 106 | - `ditto.sidebar_file` 107 | - `ditto.github_username` 108 | - `ditto.github_repo` 109 | - `ditto.base_url` 110 | 111 | as you see fit. 112 | 113 | 114 | ## sidebar.md 115 | In the `sidebar.md` file you can create links to documentation you wish to list 116 | (just as you would in markdown). You have to list them in the form: 117 | 118 | #folder_containing_docs/file_name_without_extension 119 | 120 | For example: 121 | 122 | - [Documentation 1](#docs/document_1) 123 | - [Documentation 2](#docs/document_2) 124 | - [Documentation 3](#docs/document_3) 125 | 126 | If you want the GitHub search bar enter the following in the same file: 127 | 128 | [ditto:searchbar] 129 | 130 | **IMPORTANT NOTE**: 131 | - **This will only search markdown files in your repo's master branch.** 132 | - Add `#` infront of `docs`, where `docs` is the folder where `document_1.md` resides 133 | - Also ___DO NOT___ INCLUDE THE FILE EXTENSION AT THE END! 134 | 135 | ## README.md 136 | Do I really have to tell you what to put in here? 137 | 138 | [index_file]: http://raw.githubusercontent.com/chutsu/ditto/master/ver/latest/index.html 139 | -------------------------------------------------------------------------------- /docs/how_does_it_work.md: -------------------------------------------------------------------------------- 1 | # How does it work? 2 | 3 | **Contents**: 4 | 5 | - General 6 | - Other 7 | 8 | ## General 9 | When you open the `index.html` file, the javascript file `ditto.js` opens 10 | `sidebar.md` and `README.md` files converts the file using 11 | [marked][marked_github] and displays the rendered html (unless defined 12 | differently by you otherwise). 13 | 14 | ![layout](images/layout.png) 15 | 16 | Documentation defined in `sidebar.md` should be of the form: 17 | 18 | #folder_containing_docs/file_name_without_extension 19 | 20 | 21 | For example: 22 | 23 | - #docs/document_1 24 | - #docs/document_2 25 | - #docs/document_3 26 | 27 | When you click on the link, the hash is parsed and modified in such a way it 28 | converts it back to the file location where the documentation is: 29 | 30 | 31 | From: To: 32 | 33 | #docs/document_1 -----------> docs/document_1.md 34 | 35 | 36 | `jQuery` then launches a GET request to the server requesting the markdown file 37 | and uses `marked` up to render the file and display it in `#content`. 38 | 39 | 40 | ## Other 41 | `ditto` also performs other magick as well, such as : 42 | 43 | - Normalizing paths 44 | - Creating page anchors automatically 45 | 46 | 47 | ### Normalizing paths 48 | For example say you are editing the doc in `docs/some_doc.md` and you link the 49 | image in `docs/images/image_1.jpg`. Naturally when you edit the file you would 50 | write this in markdown: 51 | 52 | 53 | ![some image](images/image_1.jpg) 54 | 55 | 56 | However that doesn't work without magick, because the server root is `/` and it would look for 57 | `images/image_1.jpg`, which is the wrong place. 58 | 59 | To fix that issue, `ditto` simply gathers the `window.location` and 60 | `window.location.hash`, does some path normalizing, and performs a search and 61 | replace on the page to fix that issue. 62 | 63 | 64 | ### Creating page anchors automatically 65 | Using `jQuery` all the `li` tags are parsed, and if it matches any html headers 66 | (e.g. `h2`), an event listener is created on the `li` tag, such that if you 67 | click on the `li` element, the page would automatically scroll down to the 68 | relevant section, with the relevant section glowing red for a moment to attract 69 | attention. 70 | 71 | 72 | [marked_github]: https://github.com/markedjs/marked 73 | -------------------------------------------------------------------------------- /docs/images/layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chutsu/ditto/88480d2d43465c6c9316b5ac4d01ad5bdbcec3c3/docs/images/layout.png -------------------------------------------------------------------------------- /docs/maths_demo.md: -------------------------------------------------------------------------------- 1 | # Mathematical Equations Test 2 | 3 | This is an inline equation $f = ma$. The following are display maths: 4 | 5 | \begin{equation} 6 | \label{eq1} 7 | x = \alpha + \beta 8 | \end{equation} 9 | 10 | \begin{equation} 11 | \mathbf{V}_{1} \times \mathbf{V}_{2} = 12 | \begin{vmatrix} 13 | \mathbf{i} & \mathbf{j} & \mathbf{k} \\ 14 | \frac{\partial X}{\partial u} & \frac{\partial Y}{\partial u} & 0 \\ 15 | \frac{\partial X}{\partial v} & \frac{\partial Y}{\partial v} & 0 \\ 16 | \end{vmatrix} 17 | \end{equation} 18 | 19 | 20 | ## Maxwell's Equations: 21 | 22 | \begin{equation} 23 | \left \{ 24 | \begin{aligned} 25 | \nabla \times \vec{\mathbf{B}} - \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\\\ 26 | \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\\\ 27 | \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\\\ 28 | \nabla \cdot \vec{\mathbf{B}} & = 0 29 | \end{aligned} 30 | \right. 31 | \end{equation} 32 | 33 | 34 | 35 | ## Matricies 36 | 37 | \begin{equation} 38 | \begin{bmatrix} 39 | a & b \\ 40 | c & d 41 | \end{bmatrix} 42 | \end{equation} 43 | 44 | \begin{equation} 45 | \mathbf{I}_n = \left . \left( 46 | \vphantom{ 47 | \begin{array}{c} 1 \\ 1 \\ 1 \\ 1 \\ 1 \end{array} 48 | } 49 | \smash{\underbrace{ 50 | \begin{array}{ccccc} 51 | 1 & 0 & 0 & \cdots & 0 \\ 52 | 0 & 1 & 0 & \cdots & 0 \\ 53 | 0 & 0 & 1 & \cdots & 0 \\ 54 | \vdots&&&\ddots& \\ 55 | 0&0&0&\cdots &1 56 | \end{array} 57 | }_{n\text{ columns}}} 58 | \right)\right\} 59 | \,n\text{rows} 60 | \end{equation} 61 | 62 | 63 | 64 | ## Referencing Equations 65 | To refer to an equation you simply have to write the following: 66 | 67 | Eq $\ref{eq1}$ 68 | 69 | Where Eq $\ref{eq1}$ is defined as: 70 | 71 | \[ 72 | \label{eq1} 73 | x = \alpha + \beta 74 | \] 75 | 76 | As you would in latex. 77 | -------------------------------------------------------------------------------- /docs/why_use_ditto.md: -------------------------------------------------------------------------------- 1 | # Why use ditto? 2 | 3 | Docs are ugly and hard, period. We've all heard that too much comments is a bad 4 | thing, because your code should be simple and readable enough that I should be 5 | able to understand your design decisions with ease, and yet the most code 6 | documentation is in the code itself, this leads to huge comment blocks where 7 | the programmer probably spends more time scrolling then reading actual code. 8 | This has been discussed by Jeff Atwood's ["Coding Without Comments"][1], where 9 | his article opens with: 10 | 11 | > If peppering your code with lots of comments is good, then having zillions of 12 | > comments in your code must be great, right? Not quite. Excess is one way good 13 | > comments go bad: 14 | 15 | '************************************************* 16 | ' Name: CopyString 17 | ' 18 | ' Purpose: This routine copies a string from the source 19 | ' string (source) to the target string (target). 20 | ' 21 | ' Algorithm: It gets the length of "source" and then copies each 22 | ' character, one at a time, into "target". It uses 23 | ' the loop index as an array index into both "source" 24 | ' and "target" and increments the loop/array index 25 | ' after each character is copied. 26 | ' 27 | ' Inputs: input The string to be copied 28 | ' 29 | ' Outputs: output The string to receive the copy of "input" 30 | ' 31 | ' Interface Assumptions: None 32 | ' 33 | ' Modification History: None 34 | ' 35 | ' Author: Dwight K. Coder 36 | ' Date Created: 10/1/04 37 | ' Phone: (555) 222-2255 38 | ' SSN: 111-22-3333 39 | ' Eye Color: Green 40 | ' Maiden Name: None 41 | ' Blood Type: AB- 42 | ' Mother's Maiden Name: None 43 | ' Favorite Car: Pontiac Aztek 44 | ' Personalized License Plate: "Tek-ie" 45 | '************************************************* 46 | 47 | Other examples include: 48 | 49 | **Java - Javadoc** 50 | 51 | /** 52 | * Short one line description. (1) 53 | *

54 | * Longer description. If there were any, it would be [2] 55 | * here. 56 | *

57 | * And even more explanations to follow in consecutive 58 | * paragraphs separated by HTML paragraph breaks. 59 | * 60 | * @param variable Description text text text. (3) 61 | * @return Description text text text. 62 | */ 63 | public int methodName (...) { 64 | // method body with a return statement 65 | } 66 | 67 | **C++ - Doxygen** 68 | 69 | //! A test class. 70 | /*! 71 | A more elaborate class description. 72 | */ 73 | class Test 74 | { 75 | public: 76 | //! An enum. 77 | /*! More detailed enum description. */ 78 | enum TEnum { 79 | TVal1, /*!< Enum value TVal1. */ 80 | TVal2, /*!< Enum value TVal2. */ 81 | TVal3 /*!< Enum value TVal3. */ 82 | } 83 | //! Enum pointer. 84 | /*! Details. */ 85 | *enumPtr, 86 | //! Enum variable. 87 | /*! Details. */ 88 | enumVar; 89 | 90 | //! A constructor. 91 | /*! 92 | A more elaborate description of the constructor. 93 | */ 94 | Test(); 95 | //! A destructor. 96 | /*! 97 | A more elaborate description of the destructor. 98 | */ 99 | ~Test(); 100 | 101 | //! A normal member taking two arguments and returning an integer value. 102 | /*! 103 | \param a an integer argument. 104 | \param s a constant character pointer. 105 | \return The test results 106 | \sa Test(), ~Test(), testMeToo() and publicVar() 107 | */ 108 | int testMe(int a,const char *s); 109 | 110 | //! A pure virtual member. 111 | /*! 112 | \sa testMe() 113 | \param c1 the first argument. 114 | \param c2 the second argument. 115 | */ 116 | virtual void testMeToo(char c1,char c2) = 0; 117 | 118 | //! A public variable. 119 | /*! 120 | Details. 121 | */ 122 | int publicVar; 123 | 124 | //! A function variable. 125 | /*! 126 | Details. 127 | */ 128 | int (*handler)(int a,int b); 129 | }; 130 | 131 | **Python - Sphinx** 132 | 133 | def func(foo): 134 | 135 | """This function translates foo into bar 136 | 137 | :param foo: A string to be converted 138 | :returns: A bar formatted string 139 | """ 140 | 141 | And yet nothing much as changed in terms of documentation generation, worst yet 142 | it is being encouraged by the likes of [Docco][2]. That produce annotated 143 | sources like [this][3]. While it is beautiful on the rendered html, that is 144 | still not the answer to good documentation IMHO. I personally find that 145 | documentation in code just gets in the way of programming, it is an eye sore to 146 | look at needless comments, that it can actually slow down your productivity, 147 | because you have to scroll down to the relevant function. 148 | 149 | Instead of this: 150 | 151 | 152 | /** 153 | * Square root of n with Newton-Raphson approximation 154 | * 155 | * @param n some number 156 | */ 157 | private double SquareRootApproximation(n) { 158 | r = n / 2; 159 | 160 | // go though each abs(r - (n/r)) until its bigger than t 161 | while ( abs( r - (n/r) ) > t ) { 162 | r = 0.5 * ( r + (n/r) ); // calcuate a new r 163 | } 164 | } 165 | System.out.println( "r = " + r ); // print the final r value 166 | 167 | 168 | Would you not want to refactor the above code and work with this?: 169 | 170 | 171 | private double SquareRootApproximation(n) { 172 | r = n / 2; 173 | while ( abs( r - (n/r) ) > t ) { 174 | r = 0.5 * ( r + (n/r) ); 175 | } 176 | return r; 177 | } 178 | System.out.println( "r = " + SquareRootApproximation(r) ); 179 | 180 | This is the major reason why I've created `ditto`, I think markdown files are 181 | the easiest way to have both the source and documentation side by side, so that 182 | programmers can either focus on code or generate documentation or both without 183 | being slowed down, and I hope you like it :) 184 | 185 | 186 | [1]: http://blog.codinghorror.com/coding-without-comments/ 187 | [2]: http://jashkenas.github.io/docco/ 188 | [3]: http://backbonejs.org/docs/backbone.html 189 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ditto 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 33 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |

44 |
45 |
46 | 47 | 48 |
top
49 |
edit
50 |
Loading ...
51 |
52 | 53 | 54 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /js/ditto.js: -------------------------------------------------------------------------------- 1 | $(function($) { 2 | 3 | var ditto = { 4 | content_id: $("#content"), 5 | sidebar_id: $("#sidebar"), 6 | 7 | edit_id: $("#edit"), 8 | back_to_top_id: $("#back_to_top"), 9 | 10 | loading_id: $("#loading"), 11 | error_id: $("#error"), 12 | 13 | search_name: $("#search"), 14 | search_results_class: ".search_results", 15 | fragments_class: ".fragments", 16 | fragment_class: ".fragment", 17 | 18 | highlight_code: true, 19 | 20 | // display elements 21 | sidebar: true, 22 | edit_button: true, 23 | back_to_top_button: true, 24 | searchbar: true, 25 | 26 | // github specifics 27 | github_username: null, 28 | github_repo: null, 29 | 30 | // initialize function 31 | run: initialize 32 | }; 33 | 34 | function initialize() { 35 | // initialize sidebar and buttons 36 | if (ditto.sidebar) { 37 | init_sidebar_section(); 38 | } 39 | 40 | if (ditto.back_to_top_button) { 41 | init_back_to_top_button(); 42 | } 43 | 44 | if (ditto.edit_button) { 45 | init_edit_button(); 46 | } 47 | 48 | // intialize highligh.js 49 | if (ditto.highlight_code) { 50 | hljs.initHighlightingOnLoad(); 51 | } 52 | 53 | // page router 54 | router(); 55 | $(window).on('hashchange', router); 56 | } 57 | 58 | function init_sidebar_section() { 59 | $.get(ditto.sidebar_file, function(data) { 60 | ditto.sidebar_id.html(marked(data)); 61 | 62 | if (ditto.searchbar) { 63 | init_searchbar(); 64 | } 65 | 66 | }, "text").fail(function() { 67 | alert("Opps! can't find the sidebar file to display!"); 68 | }); 69 | 70 | } 71 | 72 | function init_back_to_top_button() { 73 | ditto.back_to_top_id.show(); 74 | ditto.back_to_top_id.on("click", function() { 75 | $("body, html").animate({ 76 | scrollTop: 0 77 | }, 200); 78 | }); 79 | } 80 | 81 | function init_edit_button() { 82 | if (ditto.base_url === null) { 83 | alert("Error! You didn't set 'base_url' when calling ditto.run()!"); 84 | 85 | } else { 86 | ditto.edit_id.show(); 87 | ditto.edit_id.on("click", function() { 88 | var hash = location.hash.replace("#", "/"); 89 | 90 | if (hash === "") { 91 | hash = "/" + ditto.index.replace(".md", ""); 92 | } 93 | 94 | window.open(ditto.base_url + hash + ".md"); 95 | // open is better than redirecting, as the previous page history 96 | // with redirect is a bit messed up 97 | }); 98 | } 99 | } 100 | 101 | function init_searchbar() { 102 | var sidebar = ditto.sidebar_id.html(); 103 | var match = "[ditto:searchbar]"; 104 | 105 | // html input searchbar 106 | var search = ""; 109 | 110 | // replace match code with a real html input search bar 111 | sidebar = sidebar.replace(match, search); 112 | ditto.sidebar_id.html(sidebar); 113 | 114 | // add search listener 115 | $("input[name=" + ditto.search_name.selector + "]").keydown(searchbar_listener); 116 | } 117 | 118 | function build_text_matches_html(fragments) { 119 | var html = ""; 120 | var class_name = ditto.fragments_class.replace(".", ""); 121 | 122 | html += "
    "; 123 | for (var i = 0; i < fragments.length; i++) { 124 | var fragment = fragments[i].fragment.replace("/[\uE000-\uF8FF]/g", ""); 125 | html += "
  • "; 126 | html += "
     ";
    127 |       fragment = $("#hide").text(fragment).html();
    128 |       html += fragment;
    129 |       html += " 
  • "; 130 | } 131 | html += "
"; 132 | 133 | return html; 134 | } 135 | 136 | function build_result_matches_html(matches) { 137 | var html = ""; 138 | var class_name = ditto.search_results_class.replace(".", ""); 139 | 140 | html += "
    "; 141 | for (var i = 0; i < matches.length; i++) { 142 | var url = matches[i].path; 143 | 144 | if (url !== ditto.sidebar_file) { 145 | var hash = "#" + url.replace(".md", ""); 146 | var path = window.location.origin+ "/" + hash; 147 | 148 | // html += "
  • "; 149 | html += "
  • "; 153 | 154 | var match = build_text_matches_html(matches[i].text_matches); 155 | html += match; 156 | } 157 | 158 | } 159 | html += "
"; 160 | 161 | return html; 162 | } 163 | 164 | function display_search_results(data) { 165 | var results_html = "

Search Results

"; 166 | 167 | if (data.items.length) { 168 | hide_errors(); 169 | results_html += build_result_matches_html(data.items); 170 | } else { 171 | show_error("Opps.. Found no matches!"); 172 | } 173 | 174 | ditto.content_id.html(results_html); 175 | $(ditto.search_results_class + " .link").click(function(){ 176 | var destination = "#" + $(this).html().replace(".md", ""); 177 | location.hash = destination; 178 | }); 179 | } 180 | 181 | function github_search(query) { 182 | if (ditto.github_username && ditto.github_repo) { 183 | // build github search api url string 184 | var github_api = "https://api.github.com/"; 185 | var search = "search/code?q="; 186 | var github_repo = ditto.github_username + "/" + ditto.github_repo; 187 | var search_details = "+in:file+language:markdown+repo:"; 188 | 189 | var url = github_api + search + query + search_details + github_repo; 190 | var accept_header = "application/vnd.github.v3.text-match+json"; 191 | 192 | $.ajax(url, {headers: {Accept: accept_header}}).done(function(data) { 193 | display_search_results(data); 194 | }); 195 | } 196 | 197 | if (ditto.github_username == null && ditto.github_repo == null) { 198 | alert("You have not set ditto.github_username and ditto.github_repo!"); 199 | } else if (ditto.github_username == null) { 200 | alert("You have not set ditto.github_username!"); 201 | } else if (ditto.github_repo == null) { 202 | alert("You have not set ditto.github_repo!"); 203 | } 204 | } 205 | 206 | function searchbar_listener(event) { 207 | if (event.which === 13) { // when user presses ENTER in search bar 208 | var q = $("input[name=" + ditto.search_name.selector + "]").val(); 209 | if (q !== "") { 210 | location.hash = "#search=" + q; 211 | } else { 212 | alert("Error! Empty search query!"); 213 | } 214 | } 215 | } 216 | 217 | function replace_symbols(text) { 218 | // replace symbols with underscore 219 | return text.replace(/[&\/\\#,+=()$~%.'":*?<>{}\ \]\[]/g, "_"); 220 | } 221 | 222 | function li_create_linkage(li_tag, header_level) { 223 | // add custom id and class attributes 224 | html_safe_tag = replace_symbols(li_tag.text()); 225 | li_tag.attr("id", html_safe_tag); 226 | li_tag.attr("class", "link"); 227 | 228 | // add click listener - on click scroll to relevant header section 229 | $(ditto.content_id.selector + " li#" + li_tag.attr("id")).click(function() { 230 | // scroll to relevant section 231 | var header = $("h" + header_level + "." + li_tag.attr("id")); 232 | $('html, body').animate({ 233 | scrollTop: header.offset().top 234 | }, 200); 235 | 236 | // highlight the relevant section 237 | original_color = header.css("color"); 238 | header.animate({ color: "#ED1C24", }, 500, function() { 239 | // revert back to orig color 240 | $(this).animate({color: original_color}, 2500); 241 | }); 242 | }); 243 | } 244 | 245 | function create_page_anchors() { 246 | // create page anchors by matching li's to headers 247 | // if there is a match, create click listeners 248 | // and scroll to relevant sections 249 | 250 | // go through header level 2 and 3 251 | for (var i = 2; i <= 4; i++) { 252 | // parse all headers 253 | var headers = []; 254 | $(ditto.content_id.selector + ' h' + i).map(function() { 255 | headers.push($(this).text()); 256 | $(this).addClass(replace_symbols($(this).text())); 257 | }); 258 | 259 | // parse and set links between li and h2 260 | $(ditto.content_id.selector + ' ul li').map(function() { 261 | for (var j = 0; j < headers.length; j++) { 262 | if (headers[j] === $(this).text()) { 263 | li_create_linkage($(this), i); 264 | } 265 | } 266 | }); 267 | } 268 | } 269 | 270 | function youtube_url_extract(data) { 271 | var yt_regex = /(https?\:\/\/)?(www\.youtube\.com|youtu\.?be)\/.+/g; 272 | var yt_url = String(data.match(yt_regex)); 273 | yt_url = yt_url.replace(/]/g, ""); 274 | return yt_url; 275 | } 276 | 277 | function youtube_url_to_embed(data) { 278 | return data = data.replace(/watch\?v\=/g, "embed/"); 279 | } 280 | 281 | function create_youtube_embeds(data) { 282 | // replaces [ditto:youtube:] 283 | // with a proper youtube embed iframe 284 | var token_regex = /\[ditto\:youtube:(https?\:\/\/)?(www\.youtube\.com|youtu\.?be)\/.+\]/g; 285 | var yt_url = youtube_url_extract(data); 286 | var yt_embed_url = youtube_url_to_embed(yt_url); 287 | 288 | // youtube embed html 289 | var embed_html = `
290 |
291 | 298 |
299 |
`; 300 | embed_html = embed_html.replace("", yt_embed_url); 301 | 302 | // replace match code with youtube video 303 | data = data.replace(token_regex, embed_html); 304 | return data; 305 | } 306 | 307 | function normalize_paths() { 308 | // images 309 | ditto.content_id.find("img").map(function() { 310 | var src = $(this).attr("src").replace(/^\.\//, ""); 311 | if ($(this).attr("src").slice(0, 5) !== "http") { 312 | var url = location.hash.replace("#", ""); 313 | 314 | // split and extract base dir 315 | url = url.split("/"); 316 | var base_dir = url.slice(0, url.length - 1).join("/"); 317 | 318 | // normalize the path (i.e. make it absolute) 319 | if (base_dir) { 320 | $(this).attr("src", base_dir + "/" + src); 321 | } else { 322 | $(this).attr("src", src); 323 | } 324 | } 325 | }); 326 | 327 | } 328 | 329 | function show_error(err_msg) { 330 | ditto.error_id.html(err_msg); 331 | ditto.error_id.show(); 332 | } 333 | 334 | function hide_errors() { 335 | ditto.error_id.hide(); 336 | } 337 | 338 | function show_loading() { 339 | ditto.loading_id.show(); 340 | ditto.content_id.html(""); // clear content 341 | 342 | // infinite loop until clearInterval() is called on loading 343 | ditto.loading_interval = setInterval(function() { 344 | ditto.loading_id.fadeIn(1000).fadeOut(1000); 345 | }, 2000); 346 | 347 | } 348 | 349 | function stop_loading() { 350 | clearInterval(ditto.loading_interval); 351 | ditto.loading_id.hide(); 352 | } 353 | 354 | function escape_github_badges(data) { 355 | $("img").map(function() { 356 | var ignore_list = [ 357 | "travis-ci.com", 358 | "travis-ci.org", 359 | "coveralls.io" 360 | ]; 361 | var src = $(this).attr("src"); 362 | 363 | var base_url = src.split("/"); 364 | var protocol = base_url[0]; 365 | var host = base_url[2]; 366 | 367 | if ($.inArray(host, ignore_list) >= 0) { 368 | $(this).attr("class", "github_badges"); 369 | } 370 | }); 371 | return data; 372 | } 373 | 374 | function page_getter() { 375 | window.scrollTo(0, 0); 376 | var path = location.hash.replace("#", "./"); 377 | 378 | // default page if hash is empty 379 | var current_page = location.pathname.split("/").pop(); 380 | if (current_page === "index.html") { 381 | path = location.pathname.replace("index.html", ditto.index); 382 | normalize_paths(); 383 | 384 | } else if (path === "") { 385 | path = window.location + ditto.index; 386 | normalize_paths(); 387 | 388 | } else { 389 | path = path + ".md"; 390 | 391 | } 392 | 393 | // otherwise get the markdown and render it 394 | show_loading(); 395 | $.get(path, function(data) { 396 | compile_into_dom(path, data, function() { 397 | // rerender mathjax and reset mathjax equation counter 398 | if (MathJax && MathJax.Extension["Tex/AMSmath"]) { 399 | MathJax.Extension["TeX/AMSmath"].startNumber = 0; 400 | MathJax.Extension["TeX/AMSmath"].labels = {}; 401 | 402 | var content = document.getElementById("content"); 403 | MathJax.Hub.Queue(["Typeset", MathJax.Hub, content]); 404 | } 405 | }); 406 | }).fail(function() { 407 | show_error("Opps! ... File not found!"); 408 | stop_loading(); 409 | }); 410 | } 411 | 412 | function escape_html(string) { 413 | return string 414 | .replace(/\\/g, "\") 415 | .replace(/\_/g, "_"); 416 | } 417 | 418 | function unescape_html(string) { 419 | return string 420 | .replace(/&#92;/g, "\\") 421 | .replace(/&#95;/g, "_"); 422 | } 423 | 424 | function compile_into_dom(path, data, cb) { 425 | hide_errors(); 426 | 427 | data = create_youtube_embeds(data); 428 | data = marked(escape_html(data)); 429 | data = unescape_html(data); 430 | ditto.content_id.html(data); 431 | 432 | stop_loading(); 433 | escape_github_badges(data); 434 | 435 | normalize_paths(); 436 | create_page_anchors(); 437 | 438 | if (ditto.highlight_code) { 439 | $('pre code').each(function(i, block) { 440 | hljs.highlightBlock(block); 441 | }); 442 | } 443 | 444 | if (cb) { 445 | cb(data); 446 | } 447 | } 448 | 449 | function router() { 450 | var hash = location.hash; 451 | 452 | if (hash.slice(1, 7) !== "search") { 453 | page_getter(); 454 | 455 | } else { 456 | if (ditto.searchbar) { 457 | github_search(hash.replace("#search=", "")); 458 | } 459 | 460 | } 461 | } 462 | 463 | window.ditto = ditto; 464 | }); 465 | -------------------------------------------------------------------------------- /scripts/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | generate_files() { 4 | echo ""; 5 | echo ""; 6 | echo "downloading / generating ditto files ... "; 7 | 8 | # download ditto index file 9 | curl -O http://chutsu.github.io/ditto/ver/latest/index.html 10 | 11 | # create sidebar file 12 | cat << EOF > sidebar.md 13 | # [Your Project Name](Your project link) 14 | 15 | - [FAQ](#docs/faq) 16 | - [API](#docs/api) 17 | 18 | ## REMOVE THE FOLLOWING COMMENT AFTER YOU READ IT 19 | In the above two links (FAQ and API) ditto will look for files in 20 | 'docs/faq.md' and 'docs/api.md'. (i.e. it automatically appends the '.md' to 21 | your links so you don't have to) 22 | EOF 23 | 24 | cat << EOF > docs/faq.md 25 | # FAQ 26 | FAQ content here!! 27 | EOF 28 | 29 | cat << EOF > docs/api.md 30 | # API 31 | API content here!! 32 | EOF 33 | 34 | echo ""; 35 | echo ""; 36 | } 37 | 38 | print_instructions() { 39 | echo "**IMPORTANT INSTRUCTIONS**:"; 40 | echo "STEP 1: Edit files"; 41 | echo "- index.html"; 42 | echo "- sidebar.md"; 43 | echo "instructions are inside those files"; 44 | echo ""; 45 | 46 | echo "STEP 2: Test your site"; 47 | echo "To test your site enter the following command:"; 48 | echo ""; 49 | echo " python -m SimpleHTTPServer"; 50 | echo ""; 51 | echo "when you run the server, go visit 'localhost:8000' with your browser."; 52 | echo "For more information visit: http://chutsu.github.io/ditto/"; 53 | echo ""; 54 | echo ""; 55 | } 56 | 57 | main() { 58 | clear; 59 | echo "This script will generate your ditto site by doing the following:" 60 | echo "- create a 'docs' folder (will **NOT** overwrite if it exists!)" 61 | echo "- download index.html" 62 | echo "- create sidebar.md" 63 | 64 | while true 65 | do 66 | read -r -p 'Do you want to continue? (y/n): ' choice 67 | case "$choice" in 68 | n|N) break;; 69 | y|Y) 70 | mkdir -p docs 71 | generate_files 72 | print_instructions 73 | break 74 | ;; 75 | *) echo 'Invalid input! Please answer y or n!';; 76 | esac 77 | done 78 | } 79 | 80 | 81 | # RUN MAIN 82 | main 83 | -------------------------------------------------------------------------------- /sidebar.md: -------------------------------------------------------------------------------- 1 | # [ditto]() 2 | version 0.15 3 | 4 | - [Github Repository](http://github.com/chutsu/ditto/) 5 | 6 | [ditto:searchbar] 7 | 8 | ## FAQ 9 | - [How do I use ditto?](#docs/how_do_i_use_ditto) 10 | - [How does it work?](#docs/how_does_it_work) 11 | - [Why use ditto?](#docs/why_use_ditto) 12 | - [How do I run ditto locally?](#docs/how_do_i_run_ditto_locally) 13 | - [How I write equations in ditto?](#docs/maths_demo) 14 | - [Features](#docs/features) 15 | 16 | ## Projects that use ditto 17 | - [playground](http://chutsu.github.io/playground) 18 | - [direnv](http://direnv.net) 19 | - [rover](http://wallarelvo.github.io/rover) 20 | - [zeromq-ros](http://wallarelvo.github.io/zeromq-ros) 21 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TITLE 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 33 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 |
46 | 47 | 48 |
top
49 |
edit
50 |
Loading ...
51 |
52 | 53 | 54 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /templates/sidebar.md: -------------------------------------------------------------------------------- 1 | # [Project]() 2 | version 0.1 3 | 4 | - [Github Repository](http://github.com//) 5 | 6 | [ditto:searchbar] 7 | 8 | ## Header 2 9 | - [Page1](#docs/page1) 10 | - [Page2](#docs/page2) 11 | -------------------------------------------------------------------------------- /ver/0.1/ditto.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #333; 3 | margin: 0; 4 | padding: 0; 5 | 6 | font-family: Verdana, Arial; 7 | font-size: 0.8em; 8 | } 9 | 10 | #sidebar { 11 | position: fixed; 12 | width: 220px; 13 | height: 100%; 14 | 15 | overflow-y: scroll; 16 | overflow: -moz-scrollbars-vertical; 17 | 18 | margin-right: 20px; 19 | margin-top: 0; 20 | padding-left: 25px; 21 | padding-top: 0; 22 | 23 | box-shadow: 0 0 40px #CCC; 24 | -webkit-box-shadow: 0 0 40px #CCC; 25 | -moz-box-shadow: 0 0 40px #CCC; 26 | border-right: 1px solid #BBB; 27 | } 28 | 29 | #sidebar h1 { 30 | font-size: 25px; 31 | margin-bottom: 0px; 32 | padding-bottom: 0px; 33 | } 34 | 35 | #sidebar h1 a:link, #sidebar h1 a:visited { 36 | color: #333; 37 | } 38 | 39 | #sidebar h2 { 40 | font-size: 15px; 41 | } 42 | 43 | #sidebar h5 { 44 | margin-top: 20px; 45 | margin-bottom: 0; 46 | } 47 | 48 | #sidebar a:visited, #sidebar a:link { 49 | color: #4682BE; 50 | text-decoration: none; 51 | } 52 | 53 | #sidebar ul { 54 | list-style-type: none; 55 | margin: 0; 56 | padding-left: 10px; 57 | padding-top: 0; 58 | } 59 | 60 | #sidebar ul li:before { /* a hack to have dashes as a list style */ 61 | content: "-"; 62 | position: relative; 63 | left: -5px; 64 | } 65 | 66 | #sidebar ul li { 67 | margin-top: 0; 68 | margin-bottom: 2px; 69 | margin-left: 10px; 70 | padding: 0; 71 | 72 | text-indent: -5px; /* to compensate for the padding for the dash */ 73 | font-size: 12px; 74 | } 75 | 76 | #content { 77 | width: 580px; 78 | 79 | margin-left: 300px; 80 | padding-top: 10px; 81 | padding-bottom: 150px; 82 | 83 | text-align: justify; 84 | font-size: 13px; 85 | 86 | /* border: 1px solid black; */ 87 | } 88 | 89 | #content pre { 90 | margin-left: auto; 91 | margin-right: auto; 92 | 93 | padding-top: 10px; 94 | padding-bottom: 10px; 95 | padding-left: 13px; 96 | padding-right: 13px; 97 | 98 | color: #FFF; 99 | white-space: pre-wrap; /* css-3 */ 100 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 101 | white-space: -pre-wrap; /* Opera 4-6 */ 102 | white-space: -o-pre-wrap; /* Opera 7 */ 103 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 104 | 105 | background: #444; 106 | border-radius: 5px; 107 | } 108 | 109 | #content pre code { 110 | padding-left: 0; 111 | } 112 | 113 | #content code { 114 | padding-left: 5px; 115 | padding-right: 5px; 116 | 117 | color: #FFF; 118 | font-size: 10px; 119 | font-weight: normal; 120 | font-family: Consolas, monospace; 121 | 122 | background: #444; 123 | border-radius: 2px; 124 | } 125 | 126 | #content h2 { 127 | margin-top: 50px; 128 | margin-bottom: 0px; 129 | 130 | padding-top: 20px; 131 | padding-bottom: 0px; 132 | 133 | font-size: 18px; 134 | text-align: left; 135 | 136 | border-top: 2px solid #666; 137 | } 138 | 139 | #content h3 { 140 | margin-top: 50px; 141 | margin-bottom: 0px; 142 | 143 | padding-top: 20px; 144 | padding-bottom: 0px; 145 | 146 | text-align: left; 147 | border-top: 1px dotted #777; 148 | } 149 | 150 | #content img { 151 | max-width: 90%; 152 | display: block; 153 | 154 | margin-left: auto; 155 | margin-right: auto; 156 | margin-top: 40px; 157 | margin-bottom: 40px; 158 | 159 | border-radius: 5px; 160 | } 161 | 162 | #content ul { 163 | display: block; 164 | list-style-type: none; 165 | } 166 | 167 | #content ul li:before { /* a hack to have dashes as a list style */ 168 | content: "-"; 169 | position: relative; 170 | left: -5px; 171 | } 172 | 173 | #content ul li { 174 | text-indent: -5px; /* to compensate for the padding for the dash */ 175 | font-size: 13px; 176 | } 177 | 178 | #content ul li.link { 179 | color: #4682BE; 180 | text-decoration: none; 181 | font-size: 13px; 182 | font-weight: bold; 183 | cursor: pointer; 184 | } 185 | 186 | #content a:link, #content a:visited { 187 | color: #4682BE; 188 | text-decoration: none; 189 | } 190 | 191 | #back_to_top { 192 | display: none; 193 | position: fixed; 194 | 195 | height: 20px; 196 | width: 70px; 197 | top: 20px; 198 | 199 | margin-left: 890px; 200 | margin-top: 0px; 201 | 202 | color: #FFF; 203 | line-height: 20px; 204 | text-align: center; 205 | font-size: 10px; 206 | 207 | 208 | border-radius: 5px; 209 | background-color: #AAA; 210 | } 211 | 212 | #back_to_top:hover { 213 | background-color: #444; 214 | cursor: pointer; 215 | } 216 | 217 | #edit { 218 | display: none; 219 | position: fixed; 220 | 221 | height: 17px; 222 | width: 70px; 223 | top: 45px; 224 | 225 | margin-left: 890px; 226 | margin-top: 0px; 227 | 228 | color: #FFF; 229 | line-height: 17px; 230 | text-align: center; 231 | font-size: 10px; 232 | 233 | 234 | border-radius: 5px; 235 | background-color: #AAA; 236 | } 237 | 238 | #edit:hover { 239 | background-color: #444; 240 | cursor: pointer; 241 | } 242 | 243 | #loading, #error { 244 | display: none; 245 | position: fixed; 246 | 247 | height: 17px; 248 | top: 45%; 249 | 250 | margin-left: 560px; 251 | 252 | font-size: 14px; 253 | font-weight: bold; 254 | } 255 | 256 | input[type=search] { 257 | display: block; 258 | width: 180px; 259 | 260 | text-align: left; 261 | } 262 | 263 | .search_results{ 264 | 265 | 266 | } 267 | 268 | .fragments { 269 | margin: 0; 270 | padding: 10px; 271 | /* border: 1px solid #777; */ 272 | /* border-radius: 5px; */ 273 | } 274 | 275 | .fragment { 276 | padding-left: 10px; 277 | padding-right: 10px; 278 | padding-top: 0px; 279 | padding-bottom: 0px; 280 | 281 | /* border: 1px solid #777; */ 282 | /* border-radius: 5px; */ 283 | } 284 | 285 | .search_results .link { 286 | margin-top: 35px; 287 | } 288 | 289 | #content ul li { 290 | text-align: left; 291 | } 292 | 293 | #content ul .fragments li:before { 294 | content: ""; 295 | position: relative; 296 | left: 0px; 297 | } 298 | 299 | #content ul li.fragment:before { 300 | content: ""; 301 | margin: 0; 302 | padding: 0; 303 | } 304 | 305 | #content img.github_badges { 306 | display: inline; 307 | margin-top: 0; 308 | margin-bottom: 0; 309 | } 310 | 311 | 312 | #hide { 313 | display: none; 314 | } 315 | -------------------------------------------------------------------------------- /ver/0.1/ditto.js: -------------------------------------------------------------------------------- 1 | var ditto = { 2 | // page elements 3 | content_id: "#content", 4 | sidebar_id: "#sidebar", 5 | 6 | edit_id: "#edit", 7 | back_to_top_id: "#back_to_top", 8 | 9 | loading_id: "#loading", 10 | error_id: "#error", 11 | 12 | search_name: "#search", 13 | search_results_class: ".search_results", 14 | fragments_class: ".fragments", 15 | fragment_class: ".fragment", 16 | 17 | // display elements 18 | sidebar: true, 19 | edit_button: true, 20 | back_to_top_button: true, 21 | searchbar: true, 22 | 23 | // github specifics 24 | github_username: null, 25 | github_repo: null, 26 | 27 | // initialize function 28 | run: initialize 29 | }; 30 | 31 | function initialize() { 32 | // initialize sidebar and buttons 33 | if (ditto.sidebar) { 34 | init_sidebar_section(); 35 | } 36 | 37 | if (ditto.back_to_top_button) { 38 | init_back_to_top_button(); 39 | } 40 | 41 | if (ditto.edit_button) { 42 | init_edit_button(); 43 | } 44 | 45 | // page router 46 | router(); 47 | $(window).on('hashchange', router); 48 | } 49 | 50 | function init_sidebar_section() { 51 | $.get(ditto.sidebar_file, function(data) { 52 | $(ditto.sidebar_id).html(marked(data)); 53 | 54 | if (ditto.searchbar) { 55 | init_searchbar(); 56 | } 57 | 58 | }, "text").fail(function() { 59 | alert("Opps! can't find the sidebar file to display!"); 60 | }); 61 | 62 | } 63 | 64 | function init_back_to_top_button() { 65 | $(ditto.back_to_top_id).show(); 66 | $(ditto.back_to_top_id).on("click", function() { 67 | $("html body").animate({ 68 | scrollTop: 0 69 | }, 200); 70 | }); 71 | } 72 | 73 | function init_edit_button() { 74 | if (ditto.base_url === null) { 75 | alert("Error! You didn't set 'base_url' when calling ditto.run()!"); 76 | 77 | } else { 78 | $(ditto.edit_id).show(); 79 | $(ditto.edit_id).on("click", function() { 80 | var hash = location.hash.replace("#", "/"); 81 | 82 | if (hash === "") { 83 | hash = "/" + ditto.index.replace(".md", ""); 84 | } 85 | 86 | window.open(ditto.base_url + hash + ".md"); 87 | // open is better than redirecting, as the previous page history 88 | // with redirect is a bit messed up 89 | }); 90 | } 91 | } 92 | 93 | function init_searchbar() { 94 | var sidebar = $(ditto.sidebar_id).html(); 95 | var match = "[ditto:searchbar]"; 96 | 97 | // html input searchbar 98 | var search = ""; 101 | 102 | // replace match code with a real html input search bar 103 | sidebar = sidebar.replace(match, search); 104 | $(ditto.sidebar_id).html(sidebar); 105 | 106 | // add search listener 107 | $("input[name=" + ditto.search_name + "]").keydown(searchbar_listener); 108 | } 109 | 110 | function build_text_matches_html(fragments) { 111 | var html = ""; 112 | var class_name = ditto.fragments_class.replace(".", ""); 113 | 114 | html += "
    "; 115 | for (var i = 0; i < fragments.length; i++) { 116 | var fragment = fragments[i].fragment.replace("/[\uE000-\uF8FF]/g", ""); 117 | html += "
  • "; 118 | html += "
     ";
    119 |         fragment = $("#hide").text(fragment).html();
    120 |         html += fragment;
    121 |         html += " 
  • "; 122 | } 123 | html += "
"; 124 | 125 | return html; 126 | } 127 | 128 | function build_result_matches_html(matches) { 129 | var html = ""; 130 | var class_name = ditto.search_results_class.replace(".", ""); 131 | 132 | html += "
    "; 133 | for (var i = 0; i < matches.length; i++) { 134 | var url = matches[i].path; 135 | 136 | if (url !== ditto.sidebar_file) { 137 | var hash = "#" + url.replace(".md", ""); 138 | var path = window.location.origin+ "/" + hash; 139 | 140 | // html += "
  • "; 141 | html += "
  • "; 145 | 146 | var match = build_text_matches_html(matches[i].text_matches); 147 | html += match; 148 | } 149 | 150 | } 151 | html += "
"; 152 | 153 | return html; 154 | } 155 | 156 | function display_search_results(data) { 157 | var results_html = "

Search Results

"; 158 | 159 | console.log(data); 160 | 161 | if (data.items.length) { 162 | $(ditto.error_id).hide(); 163 | results_html += build_result_matches_html(data.items); 164 | } else { 165 | show_error("Opps.. Found no matches!"); 166 | } 167 | 168 | $(ditto.content_id).html(results_html); 169 | $(ditto.search_results_class + " .link").click(function(){ 170 | var destination = "#" + $(this).html().replace(".md", ""); 171 | location.hash = destination; 172 | }); 173 | } 174 | 175 | function github_search(query) { 176 | if (ditto.github_username && ditto.github_repo) { 177 | // build github search api url string 178 | var github_api = "https://api.github.com/"; 179 | var search = "search/code?q="; 180 | var github_repo = ditto.github_username + "/" + ditto.github_repo; 181 | var search_details = "+in:file+language:markdown+repo:"; 182 | 183 | var url = github_api + search + query + search_details + github_repo; 184 | var accept_header = "application/vnd.github.v3.text-match+json"; 185 | 186 | $.ajax(url, {headers: {Accept: accept_header}}).done(function(data) { 187 | display_search_results(data); 188 | }); 189 | } 190 | 191 | if (ditto.github_username == null && ditto.github_repo == null) { 192 | alert("You have not set ditto.github_username and ditto.github_repo!"); 193 | } else if (ditto.github_username == null) { 194 | alert("You have not set ditto.github_username!"); 195 | } else if (ditto.github_repo == null) { 196 | alert("You have not set ditto.github_repo!"); 197 | } 198 | } 199 | 200 | function searchbar_listener(event) { 201 | if (event.which === 13) { // when user presses ENTER in search bar 202 | var q = $("input[name=" + ditto.search_name + "]").val(); 203 | if (q !== "") { 204 | location.hash = "#search=" + q; 205 | } else { 206 | alert("Error! Empty search query!"); 207 | } 208 | } 209 | } 210 | 211 | function replace_symbols(text) { 212 | // replace symbols with underscore 213 | return text.replace(/[&\/\\#,+=()$~%.'":*?<>{}\ \]\[]/g, "_"); 214 | } 215 | 216 | function li_create_linkage(li_tag, header_level) { 217 | // add custom id and class attributes 218 | html_safe_tag = replace_symbols(li_tag.text()); 219 | li_tag.attr("id", html_safe_tag); 220 | li_tag.attr("class", "link"); 221 | 222 | // add click listener - on click scroll to relevant header section 223 | $(ditto.content_id + " li#" + li_tag.attr("id")).click(function() { 224 | // scroll to relevant section 225 | var header = $( 226 | ditto.content_id + " h" + header_level + "." + li_tag.attr("id") 227 | ); 228 | $('html, body').animate({ 229 | scrollTop: header.offset().top 230 | }, 200); 231 | 232 | // highlight the relevant section 233 | original_color = header.css("color"); 234 | header.animate({ color: "#ED1C24", }, 500, function() { 235 | // revert back to orig color 236 | $(this).animate({color: original_color}, 2500); 237 | }); 238 | }); 239 | } 240 | 241 | function create_page_anchors() { 242 | // create page anchors by matching li's to headers 243 | // if there is a match, create click listeners 244 | // and scroll to relevant sections 245 | 246 | // go through header level 2 and 3 247 | for (var i = 2; i <= 4; i++) { 248 | // parse all headers 249 | var headers = []; 250 | $(ditto.content_id + ' h' + i).map(function() { 251 | headers.push($(this).text()); 252 | $(this).addClass(replace_symbols($(this).text())); 253 | }); 254 | 255 | // parse and set links between li and h2 256 | $(ditto.content_id + ' ul li').map(function() { 257 | for (var j = 0; j < headers.length; j++) { 258 | if (headers[j] === $(this).text()) { 259 | li_create_linkage($(this), i); 260 | } 261 | } 262 | }); 263 | } 264 | } 265 | 266 | function normalize_paths() { 267 | // images 268 | $(ditto.content_id + " img").map(function() { 269 | var src = $(this).attr("src").replace("./", ""); 270 | if ($(this).attr("src").slice(0, 5) !== "http") { 271 | var url = location.hash.replace("#", ""); 272 | 273 | // split and extract base dir 274 | url = url.split("/"); 275 | var base_dir = url.slice(0, url.length - 1).toString(); 276 | 277 | // normalize the path (i.e. make it absolute) 278 | if (base_dir) { 279 | $(this).attr("src", base_dir + "/" + src); 280 | } else { 281 | $(this).attr("src", src); 282 | } 283 | } 284 | }); 285 | 286 | } 287 | 288 | function show_error(err_msg) { 289 | $(ditto.error_id).html(err_msg); 290 | $(ditto.error_id).show(); 291 | } 292 | 293 | function show_loading() { 294 | $(ditto.loading_id).show(); 295 | $(ditto.content_id).html(""); // clear content 296 | 297 | // infinite loop until clearInterval() is called on loading 298 | var loading = setInterval(function() { 299 | $(ditto.loading_id).fadeIn(1000).fadeOut(1000); 300 | }, 2000); 301 | 302 | return loading; 303 | } 304 | 305 | function escape_github_badges(data) { 306 | $("img").map(function() { 307 | var ignore_list = [ 308 | "travis-ci.org", 309 | "coveralls.io" 310 | ]; 311 | var src = $(this).attr("src"); 312 | 313 | var base_url = src.split("/"); 314 | var protocol = base_url[0]; 315 | var host = base_url[2]; 316 | 317 | if ($.inArray(host, ignore_list) >= 0) { 318 | $(this).attr("class", "github_badges"); 319 | } 320 | }); 321 | return data; 322 | } 323 | 324 | function page_getter() { 325 | var path = location.hash.replace("#", "./"); 326 | 327 | // default page if hash is empty 328 | var current_page = location.pathname.split("/").pop(); 329 | if (current_page === "index.html") { 330 | path = location.pathname.replace("index.html", ditto.index); 331 | normalize_paths(); 332 | 333 | } else if (path === "") { 334 | path = window.location + ditto.index; 335 | normalize_paths(); 336 | 337 | } else { 338 | path = path + ".md"; 339 | 340 | } 341 | 342 | // otherwise get the markdown and render it 343 | var loading = show_loading(); 344 | $.get(path , function(data) { 345 | $(ditto.error_id).hide(); 346 | data = marked(data); 347 | $(ditto.content_id).html(data); 348 | escape_github_badges(data); 349 | 350 | normalize_paths(); 351 | create_page_anchors(); 352 | 353 | }).fail(function() { 354 | show_error("Opps! ... File not found!"); 355 | 356 | }).always(function() { 357 | clearInterval(loading); 358 | $(ditto.loading_id).hide(); 359 | 360 | }); 361 | } 362 | 363 | function router() { 364 | var hash = location.hash; 365 | console.log(hash); 366 | 367 | if (hash.slice(1, 7) !== "search") { 368 | page_getter(); 369 | 370 | } else { 371 | if (ditto.searchbar) { 372 | github_search(hash.replace("#search=", "")); 373 | } 374 | 375 | } 376 | } 377 | -------------------------------------------------------------------------------- /ver/0.1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 |
back to top
22 |
edit
23 |
Loading ...
24 |
25 | 26 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /ver/0.1/sidebar.md: -------------------------------------------------------------------------------- 1 | # [Project]() 2 | version 0.1 3 | 4 | - [Github Repository](http://github.com//) 5 | 6 | [ditto:searchbar] 7 | 8 | ## Header 2 9 | - [Page1](#docs/page1) 10 | - [Page2](#docs/page2) 11 | -------------------------------------------------------------------------------- /ver/0.11/ditto.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #333; 3 | margin: 0; 4 | padding: 0; 5 | 6 | font-family: Verdana, Arial; 7 | font-size: 0.8em; 8 | } 9 | 10 | #sidebar { 11 | position: fixed; 12 | width: 220px; 13 | height: 100%; 14 | 15 | overflow-y: scroll; 16 | overflow: -moz-scrollbars-vertical; 17 | 18 | margin-right: 20px; 19 | margin-top: 0; 20 | padding-left: 25px; 21 | padding-top: 0; 22 | 23 | box-shadow: 0 0 40px #CCC; 24 | -webkit-box-shadow: 0 0 40px #CCC; 25 | -moz-box-shadow: 0 0 40px #CCC; 26 | border-right: 1px solid #BBB; 27 | } 28 | 29 | #sidebar h1 { 30 | font-size: 25px; 31 | margin-bottom: 0px; 32 | padding-bottom: 0px; 33 | } 34 | 35 | #sidebar h1 a:link, #sidebar h1 a:visited { 36 | color: #333; 37 | } 38 | 39 | #sidebar h2 { 40 | font-size: 15px; 41 | } 42 | 43 | #sidebar h5 { 44 | margin-top: 20px; 45 | margin-bottom: 0; 46 | } 47 | 48 | #sidebar a:visited, #sidebar a:link { 49 | color: #4682BE; 50 | text-decoration: none; 51 | } 52 | 53 | #sidebar ul { 54 | list-style-type: none; 55 | margin: 0; 56 | padding-left: 10px; 57 | padding-top: 0; 58 | } 59 | 60 | #sidebar ul li:before { /* a hack to have dashes as a list style */ 61 | content: "-"; 62 | position: relative; 63 | left: -5px; 64 | } 65 | 66 | #sidebar ul li { 67 | margin-top: 0; 68 | margin-bottom: 2px; 69 | margin-left: 10px; 70 | padding: 0; 71 | 72 | text-indent: -5px; /* to compensate for the padding for the dash */ 73 | font-size: 12px; 74 | } 75 | 76 | #content { 77 | width: 580px; 78 | 79 | margin-left: 300px; 80 | padding-top: 10px; 81 | padding-bottom: 150px; 82 | 83 | text-align: justify; 84 | font-size: 1.0em; 85 | } 86 | 87 | #content pre { 88 | margin-left: auto; 89 | margin-right: auto; 90 | 91 | padding-top: 10px; 92 | padding-bottom: 10px; 93 | padding-left: 13px; 94 | padding-right: 13px; 95 | 96 | color: #FFF; 97 | white-space: pre-wrap; /* css-3 */ 98 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 99 | white-space: -pre-wrap; /* Opera 4-6 */ 100 | white-space: -o-pre-wrap; /* Opera 7 */ 101 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 102 | 103 | background: #F7FAFB; 104 | border-radius: 5px; 105 | } 106 | 107 | #content pre code { 108 | padding-left: 0; 109 | font-size: 1.1em; 110 | border: none; 111 | } 112 | 113 | #content code { 114 | padding-left: 5px; 115 | padding-right: 5px; 116 | padding-top: 1px; 117 | padding-bottom: 1px; 118 | 119 | color: #555; 120 | font-size: 10px; 121 | font-weight: normal; 122 | font-family: Consolas, monospace; 123 | 124 | background: #F7FAFB; 125 | border: 1px solid #E3EDF3; 126 | border-radius: 2px; 127 | } 128 | 129 | #content h2 { 130 | margin-top: 50px; 131 | margin-bottom: 0px; 132 | 133 | padding-top: 20px; 134 | padding-bottom: 0px; 135 | 136 | font-size: 18px; 137 | text-align: left; 138 | 139 | border-top: 2px solid #666; 140 | } 141 | 142 | #content h3 { 143 | margin-top: 50px; 144 | margin-bottom: 0px; 145 | 146 | padding-top: 20px; 147 | padding-bottom: 0px; 148 | 149 | text-align: left; 150 | border-top: 1px dotted #777; 151 | } 152 | 153 | #content hr { 154 | border: 0; 155 | height: 0; 156 | border-top: 1px solid rgba(0, 0, 0, 0.1); 157 | border-bottom: 1px solid rgba(255, 255, 255, 0.3); 158 | } 159 | 160 | #content img { 161 | max-width: 90%; 162 | display: block; 163 | 164 | margin-left: auto; 165 | margin-right: auto; 166 | margin-top: 40px; 167 | margin-bottom: 40px; 168 | 169 | border-radius: 5px; 170 | } 171 | 172 | #content ul { 173 | display: block; 174 | list-style-type: none; 175 | } 176 | 177 | #content ul li:before { /* a hack to have dashes as a list style */ 178 | content: "-"; 179 | position: relative; 180 | left: -5px; 181 | } 182 | 183 | #content ul li { 184 | text-indent: -5px; /* to compensate for the padding for the dash */ 185 | font-size: 13px; 186 | } 187 | 188 | #content ul li.link { 189 | color: #4682BE; 190 | text-decoration: none; 191 | font-size: 13px; 192 | font-weight: bold; 193 | cursor: pointer; 194 | } 195 | 196 | #content a:link, #content a:visited { 197 | color: #4682BE; 198 | text-decoration: none; 199 | } 200 | 201 | #back_to_top { 202 | display: none; 203 | position: fixed; 204 | 205 | height: 20px; 206 | line-height: 20px; 207 | width: 50px; 208 | top: 20px; 209 | 210 | margin-left: 890px; 211 | 212 | color: #FFF; 213 | vertical-align: middle; 214 | text-align: center; 215 | font-size: 10px; 216 | 217 | border-radius: 5px; 218 | background-color: #AAA; 219 | } 220 | 221 | #back_to_top:hover { 222 | background-color: #444; 223 | cursor: pointer; 224 | } 225 | 226 | #edit { 227 | display: none; 228 | position: fixed; 229 | 230 | height: 20px; 231 | line-height: 20px; 232 | width: 50px; 233 | top: 50px; 234 | 235 | margin-left: 890px; 236 | 237 | color: #FFF; 238 | vertical-align: middle; 239 | text-align: center; 240 | font-size: 10px; 241 | 242 | border-radius: 5px; 243 | background-color: #AAA; 244 | } 245 | 246 | #edit:hover { 247 | background-color: #444; 248 | cursor: pointer; 249 | } 250 | 251 | #loading, #error { 252 | display: none; 253 | position: fixed; 254 | 255 | height: 17px; 256 | top: 45%; 257 | 258 | margin-left: 560px; 259 | 260 | font-size: 14px; 261 | font-weight: bold; 262 | } 263 | 264 | input[type=search] { 265 | display: block; 266 | width: 180px; 267 | 268 | text-align: left; 269 | } 270 | 271 | .search_results{ 272 | 273 | 274 | } 275 | 276 | .fragments { 277 | margin: 0; 278 | padding: 10px; 279 | /* border: 1px solid #777; */ 280 | /* border-radius: 5px; */ 281 | } 282 | 283 | .fragment { 284 | padding-left: 10px; 285 | padding-right: 10px; 286 | padding-top: 0px; 287 | padding-bottom: 0px; 288 | 289 | /* border: 1px solid #777; */ 290 | /* border-radius: 5px; */ 291 | } 292 | 293 | .search_results .link { 294 | margin-top: 35px; 295 | } 296 | 297 | #content ul li { 298 | text-align: left; 299 | } 300 | 301 | #content ul .fragments li:before { 302 | content: ""; 303 | position: relative; 304 | left: 0px; 305 | } 306 | 307 | #content ul li.fragment:before { 308 | content: ""; 309 | margin: 0; 310 | padding: 0; 311 | } 312 | 313 | #content img.github_badges { 314 | display: inline; 315 | margin-top: 0; 316 | margin-bottom: 0; 317 | } 318 | 319 | 320 | #hide { 321 | display: none; 322 | } 323 | -------------------------------------------------------------------------------- /ver/0.11/ditto.js: -------------------------------------------------------------------------------- 1 | $(function($) { 2 | 3 | var ditto = { 4 | content_id: $("#content"), 5 | sidebar_id: $("#sidebar"), 6 | 7 | edit_id: $("#edit"), 8 | back_to_top_id: $("#back_to_top"), 9 | 10 | loading_id: $("#loading"), 11 | error_id: $("#error"), 12 | 13 | search_name: $("#search"), 14 | search_results_class: ".search_results", 15 | fragments_class: ".fragments", 16 | fragment_class: ".fragment", 17 | 18 | // display elements 19 | sidebar: true, 20 | edit_button: true, 21 | back_to_top_button: true, 22 | searchbar: true, 23 | 24 | // github specifics 25 | github_username: null, 26 | github_repo: null, 27 | 28 | // initialize function 29 | run: initialize 30 | }; 31 | 32 | function initialize() { 33 | // clear localStorage 34 | window.localStorage.clear(); 35 | 36 | // initialize sidebar and buttons 37 | if (ditto.sidebar) { 38 | init_sidebar_section(); 39 | } 40 | 41 | if (ditto.back_to_top_button) { 42 | init_back_to_top_button(); 43 | } 44 | 45 | if (ditto.edit_button) { 46 | init_edit_button(); 47 | } 48 | 49 | // page router 50 | router(); 51 | $(window).on('hashchange', router); 52 | } 53 | 54 | function init_sidebar_section() { 55 | $.get(ditto.sidebar_file, function(data) { 56 | ditto.sidebar_id.html(marked(data)); 57 | 58 | if (ditto.searchbar) { 59 | init_searchbar(); 60 | } 61 | 62 | }, "text").fail(function() { 63 | alert("Opps! can't find the sidebar file to display!"); 64 | }); 65 | 66 | } 67 | 68 | function init_back_to_top_button() { 69 | ditto.back_to_top_id.show(); 70 | ditto.back_to_top_id.on("click", function() { 71 | $("body, html").animate({ 72 | scrollTop: 0 73 | }, 200); 74 | }); 75 | } 76 | 77 | function init_edit_button() { 78 | if (ditto.base_url === null) { 79 | alert("Error! You didn't set 'base_url' when calling ditto.run()!"); 80 | 81 | } else { 82 | ditto.edit_id.show(); 83 | ditto.edit_id.on("click", function() { 84 | var hash = location.hash.replace("#", "/"); 85 | 86 | if (hash === "") { 87 | hash = "/" + ditto.index.replace(".md", ""); 88 | } 89 | 90 | window.open(ditto.base_url + hash + ".md"); 91 | // open is better than redirecting, as the previous page history 92 | // with redirect is a bit messed up 93 | }); 94 | } 95 | } 96 | 97 | function init_searchbar() { 98 | var sidebar = ditto.sidebar_id.html(); 99 | var match = "[ditto:searchbar]"; 100 | 101 | // html input searchbar 102 | var search = ""; 105 | 106 | // replace match code with a real html input search bar 107 | sidebar = sidebar.replace(match, search); 108 | ditto.sidebar_id.html(sidebar); 109 | 110 | // add search listener 111 | $("input[name=" + ditto.search_name.selector + "]").keydown(searchbar_listener); 112 | } 113 | 114 | function build_text_matches_html(fragments) { 115 | var html = ""; 116 | var class_name = ditto.fragments_class.replace(".", ""); 117 | 118 | html += "
    "; 119 | for (var i = 0; i < fragments.length; i++) { 120 | var fragment = fragments[i].fragment.replace("/[\uE000-\uF8FF]/g", ""); 121 | html += "
  • "; 122 | html += "
     ";
    123 |       fragment = $("#hide").text(fragment).html();
    124 |       html += fragment;
    125 |       html += " 
  • "; 126 | } 127 | html += "
"; 128 | 129 | return html; 130 | } 131 | 132 | function build_result_matches_html(matches) { 133 | var html = ""; 134 | var class_name = ditto.search_results_class.replace(".", ""); 135 | 136 | html += "
    "; 137 | for (var i = 0; i < matches.length; i++) { 138 | var url = matches[i].path; 139 | 140 | if (url !== ditto.sidebar_file) { 141 | var hash = "#" + url.replace(".md", ""); 142 | var path = window.location.origin+ "/" + hash; 143 | 144 | // html += "
  • "; 145 | html += "
  • "; 149 | 150 | var match = build_text_matches_html(matches[i].text_matches); 151 | html += match; 152 | } 153 | 154 | } 155 | html += "
"; 156 | 157 | return html; 158 | } 159 | 160 | function display_search_results(data) { 161 | var results_html = "

Search Results

"; 162 | 163 | if (data.items.length) { 164 | hide_errors(); 165 | results_html += build_result_matches_html(data.items); 166 | } else { 167 | show_error("Opps.. Found no matches!"); 168 | } 169 | 170 | ditto.content_id.html(results_html); 171 | $(ditto.search_results_class + " .link").click(function(){ 172 | var destination = "#" + $(this).html().replace(".md", ""); 173 | location.hash = destination; 174 | }); 175 | } 176 | 177 | function github_search(query) { 178 | if (ditto.github_username && ditto.github_repo) { 179 | // build github search api url string 180 | var github_api = "https://api.github.com/"; 181 | var search = "search/code?q="; 182 | var github_repo = ditto.github_username + "/" + ditto.github_repo; 183 | var search_details = "+in:file+language:markdown+repo:"; 184 | 185 | var url = github_api + search + query + search_details + github_repo; 186 | var accept_header = "application/vnd.github.v3.text-match+json"; 187 | 188 | $.ajax(url, {headers: {Accept: accept_header}}).done(function(data) { 189 | display_search_results(data); 190 | }); 191 | } 192 | 193 | if (ditto.github_username == null && ditto.github_repo == null) { 194 | alert("You have not set ditto.github_username and ditto.github_repo!"); 195 | } else if (ditto.github_username == null) { 196 | alert("You have not set ditto.github_username!"); 197 | } else if (ditto.github_repo == null) { 198 | alert("You have not set ditto.github_repo!"); 199 | } 200 | } 201 | 202 | function searchbar_listener(event) { 203 | if (event.which === 13) { // when user presses ENTER in search bar 204 | var q = $("input[name=" + ditto.search_name.selector + "]").val(); 205 | if (q !== "") { 206 | location.hash = "#search=" + q; 207 | } else { 208 | alert("Error! Empty search query!"); 209 | } 210 | } 211 | } 212 | 213 | function replace_symbols(text) { 214 | // replace symbols with underscore 215 | return text.replace(/[&\/\\#,+=()$~%.'":*?<>{}\ \]\[]/g, "_"); 216 | } 217 | 218 | function li_create_linkage(li_tag, header_level) { 219 | // add custom id and class attributes 220 | html_safe_tag = replace_symbols(li_tag.text()); 221 | li_tag.attr("id", html_safe_tag); 222 | li_tag.attr("class", "link"); 223 | 224 | // add click listener - on click scroll to relevant header section 225 | $(ditto.content_id.selector + " li#" + li_tag.attr("id")).click(function() { 226 | // scroll to relevant section 227 | var header = $( 228 | ditto.content_id + " h" + header_level + "." + li_tag.attr("id") 229 | ); 230 | $('html, body').animate({ 231 | scrollTop: header.offset().top 232 | }, 200); 233 | 234 | // highlight the relevant section 235 | original_color = header.css("color"); 236 | header.animate({ color: "#ED1C24", }, 500, function() { 237 | // revert back to orig color 238 | $(this).animate({color: original_color}, 2500); 239 | }); 240 | }); 241 | } 242 | 243 | function create_page_anchors() { 244 | // create page anchors by matching li's to headers 245 | // if there is a match, create click listeners 246 | // and scroll to relevant sections 247 | 248 | // go through header level 2 and 3 249 | for (var i = 2; i <= 4; i++) { 250 | // parse all headers 251 | var headers = []; 252 | $(ditto.content_id.selector + ' h' + i).map(function() { 253 | headers.push($(this).text()); 254 | $(this).addClass(replace_symbols($(this).text())); 255 | }); 256 | 257 | // parse and set links between li and h2 258 | $(ditto.content_id.selector + ' ul li').map(function() { 259 | for (var j = 0; j < headers.length; j++) { 260 | if (headers[j] === $(this).text()) { 261 | li_create_linkage($(this), i); 262 | } 263 | } 264 | }); 265 | } 266 | } 267 | 268 | function normalize_paths() { 269 | // images 270 | ditto.content_id.find("img").map(function() { 271 | var src = $(this).attr("src").replace("./", ""); 272 | if ($(this).attr("src").slice(0, 5) !== "http") { 273 | var url = location.hash.replace("#", ""); 274 | 275 | // split and extract base dir 276 | url = url.split("/"); 277 | var base_dir = url.slice(0, url.length - 1).join("/"); 278 | 279 | // normalize the path (i.e. make it absolute) 280 | if (base_dir) { 281 | $(this).attr("src", base_dir + "/" + src); 282 | } else { 283 | $(this).attr("src", src); 284 | } 285 | } 286 | }); 287 | 288 | } 289 | 290 | function show_error(err_msg) { 291 | ditto.error_id.html(err_msg); 292 | ditto.error_id.show(); 293 | } 294 | 295 | function hide_errors() { 296 | ditto.error_id.hide(); 297 | } 298 | 299 | function show_loading() { 300 | ditto.loading_id.show(); 301 | ditto.content_id.html(""); // clear content 302 | 303 | // infinite loop until clearInterval() is called on loading 304 | ditto.loading_interval = setInterval(function() { 305 | ditto.loading_id.fadeIn(1000).fadeOut(1000); 306 | }, 2000); 307 | 308 | } 309 | 310 | function stop_loading() { 311 | clearInterval(ditto.loading_interval); 312 | ditto.loading_id.hide(); 313 | } 314 | 315 | function escape_github_badges(data) { 316 | $("img").map(function() { 317 | var ignore_list = [ 318 | "travis-ci.org", 319 | "coveralls.io" 320 | ]; 321 | var src = $(this).attr("src"); 322 | 323 | var base_url = src.split("/"); 324 | var protocol = base_url[0]; 325 | var host = base_url[2]; 326 | 327 | if ($.inArray(host, ignore_list) >= 0) { 328 | $(this).attr("class", "github_badges"); 329 | } 330 | }); 331 | return data; 332 | } 333 | 334 | function page_getter() { 335 | window.scrollTo(0, 0); 336 | var path = location.hash.replace("#", "./"); 337 | 338 | // default page if hash is empty 339 | var current_page = location.pathname.split("/").pop(); 340 | if (current_page === "index.html") { 341 | path = location.pathname.replace("index.html", ditto.index); 342 | normalize_paths(); 343 | 344 | } else if (path === "") { 345 | path = window.location + ditto.index; 346 | normalize_paths(); 347 | 348 | } else { 349 | path = path + ".md"; 350 | 351 | } 352 | 353 | // otherwise get the markdown and render it 354 | show_loading(); 355 | $.get(path, function(data) { 356 | compile_into_dom(path, data); 357 | }).fail(function() { 358 | show_error("Opps! ... File not found!"); 359 | }) 360 | } 361 | 362 | function compile_into_dom(path, data) { 363 | hide_errors(); 364 | data = marked(data); 365 | ditto.content_id.html(data); 366 | stop_loading(); 367 | escape_github_badges(data); 368 | 369 | normalize_paths(); 370 | create_page_anchors(); 371 | } 372 | 373 | function router() { 374 | var hash = location.hash; 375 | 376 | if (hash.slice(1, 7) !== "search") { 377 | page_getter(); 378 | 379 | } else { 380 | if (ditto.searchbar) { 381 | github_search(hash.replace("#search=", "")); 382 | } 383 | 384 | } 385 | } 386 | 387 | window.ditto = ditto; 388 | }); 389 | -------------------------------------------------------------------------------- /ver/0.11/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TITLE 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 | 23 | 24 |
top
25 |
edit
26 |
Loading ...
27 |
28 | 29 | 30 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /ver/0.11/sidebar.md: -------------------------------------------------------------------------------- 1 | # [Project]() 2 | version 0.1 3 | 4 | - [Github Repository](http://github.com//) 5 | 6 | [ditto:searchbar] 7 | 8 | ## Header 2 9 | - [Page1](#docs/page1) 10 | - [Page2](#docs/page2) 11 | -------------------------------------------------------------------------------- /ver/0.12/ditto.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #333; 3 | margin: 0; 4 | padding: 0; 5 | 6 | font-family: Verdana, Arial; 7 | font-size: 0.8em; 8 | } 9 | 10 | #sidebar { 11 | position: fixed; 12 | width: 220px; 13 | height: 100%; 14 | 15 | overflow-y: scroll; 16 | overflow: -moz-scrollbars-vertical; 17 | 18 | margin-right: 20px; 19 | margin-top: 0; 20 | padding-left: 25px; 21 | padding-top: 0; 22 | 23 | box-shadow: 0 0 40px #CCC; 24 | -webkit-box-shadow: 0 0 40px #CCC; 25 | -moz-box-shadow: 0 0 40px #CCC; 26 | border-right: 1px solid #BBB; 27 | } 28 | 29 | #sidebar h1 { 30 | font-size: 25px; 31 | margin-bottom: 0px; 32 | padding-bottom: 0px; 33 | } 34 | 35 | #sidebar h1 a:link, #sidebar h1 a:visited { 36 | color: #333; 37 | } 38 | 39 | #sidebar h2 { 40 | font-size: 15px; 41 | } 42 | 43 | #sidebar h5 { 44 | margin-top: 20px; 45 | margin-bottom: 0; 46 | } 47 | 48 | #sidebar a:visited, #sidebar a:link { 49 | color: #4682BE; 50 | text-decoration: none; 51 | } 52 | 53 | #sidebar ul { 54 | list-style-type: none; 55 | margin: 0; 56 | padding-left: 10px; 57 | padding-top: 0; 58 | } 59 | 60 | #sidebar ul li:before { /* a hack to have dashes as a list style */ 61 | content: "-"; 62 | position: relative; 63 | left: -5px; 64 | } 65 | 66 | #sidebar ul li { 67 | margin-top: 0; 68 | margin-bottom: 2px; 69 | margin-left: 10px; 70 | padding: 0; 71 | 72 | text-indent: -5px; /* to compensate for the padding for the dash */ 73 | font-size: 12px; 74 | } 75 | 76 | #content { 77 | width: 580px; 78 | 79 | margin-left: 300px; 80 | padding-top: 10px; 81 | padding-bottom: 150px; 82 | 83 | text-align: justify; 84 | font-size: 1.0em; 85 | } 86 | 87 | #content pre { 88 | margin-left: auto; 89 | margin-right: auto; 90 | 91 | padding-top: 10px; 92 | padding-bottom: 10px; 93 | padding-left: 13px; 94 | padding-right: 13px; 95 | 96 | color: #FFF; 97 | white-space: pre-wrap; /* css-3 */ 98 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 99 | white-space: -pre-wrap; /* Opera 4-6 */ 100 | white-space: -o-pre-wrap; /* Opera 7 */ 101 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 102 | 103 | background: #F7FAFB; 104 | border-radius: 5px; 105 | } 106 | 107 | #content pre code { 108 | padding-left: 0; 109 | font-size: 1.1em; 110 | border: none; 111 | } 112 | 113 | #content code { 114 | padding-left: 5px; 115 | padding-right: 5px; 116 | padding-top: 1px; 117 | padding-bottom: 1px; 118 | 119 | color: #555; 120 | font-size: 10px; 121 | font-weight: normal; 122 | font-family: Consolas, monospace; 123 | 124 | background: #F7FAFB; 125 | border: 1px solid #E3EDF3; 126 | border-radius: 2px; 127 | } 128 | 129 | #content h2 { 130 | margin-top: 50px; 131 | margin-bottom: 0px; 132 | 133 | padding-top: 20px; 134 | padding-bottom: 0px; 135 | 136 | font-size: 18px; 137 | text-align: left; 138 | 139 | border-top: 2px solid #666; 140 | } 141 | 142 | #content h3 { 143 | margin-top: 50px; 144 | margin-bottom: 0px; 145 | 146 | padding-top: 20px; 147 | padding-bottom: 0px; 148 | 149 | text-align: left; 150 | border-top: 1px dotted #777; 151 | } 152 | 153 | #content hr { 154 | border: 0; 155 | height: 0; 156 | border-top: 1px solid rgba(0, 0, 0, 0.1); 157 | border-bottom: 1px solid rgba(255, 255, 255, 0.3); 158 | } 159 | 160 | #content img { 161 | max-width: 90%; 162 | display: block; 163 | 164 | margin-left: auto; 165 | margin-right: auto; 166 | margin-top: 40px; 167 | margin-bottom: 40px; 168 | 169 | border-radius: 5px; 170 | } 171 | 172 | #content ul { 173 | display: block; 174 | list-style-type: none; 175 | } 176 | 177 | #content ul li:before { /* a hack to have dashes as a list style */ 178 | content: "-"; 179 | position: relative; 180 | left: -5px; 181 | } 182 | 183 | #content ul li { 184 | text-indent: -5px; /* to compensate for the padding for the dash */ 185 | font-size: 13px; 186 | } 187 | 188 | #content ul li.link { 189 | color: #4682BE; 190 | text-decoration: none; 191 | font-size: 13px; 192 | font-weight: bold; 193 | cursor: pointer; 194 | } 195 | 196 | #content a:link, #content a:visited { 197 | color: #4682BE; 198 | text-decoration: none; 199 | } 200 | 201 | #back_to_top { 202 | display: none; 203 | position: fixed; 204 | 205 | height: 20px; 206 | line-height: 20px; 207 | width: 50px; 208 | top: 20px; 209 | 210 | margin-left: 890px; 211 | 212 | color: #FFF; 213 | vertical-align: middle; 214 | text-align: center; 215 | font-size: 10px; 216 | 217 | border-radius: 5px; 218 | background-color: #AAA; 219 | } 220 | 221 | #back_to_top:hover { 222 | background-color: #444; 223 | cursor: pointer; 224 | } 225 | 226 | #edit { 227 | display: none; 228 | position: fixed; 229 | 230 | height: 20px; 231 | line-height: 20px; 232 | width: 50px; 233 | top: 50px; 234 | 235 | margin-left: 890px; 236 | 237 | color: #FFF; 238 | vertical-align: middle; 239 | text-align: center; 240 | font-size: 10px; 241 | 242 | border-radius: 5px; 243 | background-color: #AAA; 244 | } 245 | 246 | #edit:hover { 247 | background-color: #444; 248 | cursor: pointer; 249 | } 250 | 251 | #loading, #error { 252 | display: none; 253 | position: fixed; 254 | 255 | height: 17px; 256 | top: 45%; 257 | 258 | margin-left: 560px; 259 | 260 | font-size: 14px; 261 | font-weight: bold; 262 | } 263 | 264 | input[type=search] { 265 | display: block; 266 | width: 180px; 267 | 268 | text-align: left; 269 | } 270 | 271 | .search_results{ 272 | 273 | 274 | } 275 | 276 | .fragments { 277 | margin: 0; 278 | padding: 10px; 279 | /* border: 1px solid #777; */ 280 | /* border-radius: 5px; */ 281 | } 282 | 283 | .fragment { 284 | padding-left: 10px; 285 | padding-right: 10px; 286 | padding-top: 0px; 287 | padding-bottom: 0px; 288 | 289 | /* border: 1px solid #777; */ 290 | /* border-radius: 5px; */ 291 | } 292 | 293 | .search_results .link { 294 | margin-top: 35px; 295 | } 296 | 297 | #content ul li { 298 | text-align: left; 299 | } 300 | 301 | #content ul .fragments li:before { 302 | content: ""; 303 | position: relative; 304 | left: 0px; 305 | } 306 | 307 | #content ul li.fragment:before { 308 | content: ""; 309 | margin: 0; 310 | padding: 0; 311 | } 312 | 313 | #content img.github_badges { 314 | display: inline; 315 | margin-top: 0; 316 | margin-bottom: 0; 317 | } 318 | 319 | 320 | #hide { 321 | display: none; 322 | } 323 | -------------------------------------------------------------------------------- /ver/0.12/ditto.js: -------------------------------------------------------------------------------- 1 | $(function($) { 2 | 3 | var ditto = { 4 | content_id: $("#content"), 5 | sidebar_id: $("#sidebar"), 6 | 7 | edit_id: $("#edit"), 8 | back_to_top_id: $("#back_to_top"), 9 | 10 | loading_id: $("#loading"), 11 | error_id: $("#error"), 12 | 13 | search_name: $("#search"), 14 | search_results_class: ".search_results", 15 | fragments_class: ".fragments", 16 | fragment_class: ".fragment", 17 | 18 | highlight_code: true, 19 | 20 | // display elements 21 | sidebar: true, 22 | edit_button: true, 23 | back_to_top_button: true, 24 | searchbar: true, 25 | 26 | // github specifics 27 | github_username: null, 28 | github_repo: null, 29 | 30 | // initialize function 31 | run: initialize 32 | }; 33 | 34 | function initialize() { 35 | // initialize sidebar and buttons 36 | if (ditto.sidebar) { 37 | init_sidebar_section(); 38 | } 39 | 40 | if (ditto.back_to_top_button) { 41 | init_back_to_top_button(); 42 | } 43 | 44 | if (ditto.edit_button) { 45 | init_edit_button(); 46 | } 47 | 48 | // intialize highligh.js 49 | if (ditto.highlight_code) { 50 | hljs.initHighlightingOnLoad(); 51 | } 52 | 53 | // page router 54 | router(); 55 | $(window).on('hashchange', router); 56 | } 57 | 58 | function init_sidebar_section() { 59 | $.get(ditto.sidebar_file, function(data) { 60 | ditto.sidebar_id.html(marked(data)); 61 | 62 | if (ditto.searchbar) { 63 | init_searchbar(); 64 | } 65 | 66 | }, "text").fail(function() { 67 | alert("Opps! can't find the sidebar file to display!"); 68 | }); 69 | 70 | } 71 | 72 | function init_back_to_top_button() { 73 | ditto.back_to_top_id.show(); 74 | ditto.back_to_top_id.on("click", function() { 75 | $("body, html").animate({ 76 | scrollTop: 0 77 | }, 200); 78 | }); 79 | } 80 | 81 | function init_edit_button() { 82 | if (ditto.base_url === null) { 83 | alert("Error! You didn't set 'base_url' when calling ditto.run()!"); 84 | 85 | } else { 86 | ditto.edit_id.show(); 87 | ditto.edit_id.on("click", function() { 88 | var hash = location.hash.replace("#", "/"); 89 | 90 | if (hash === "") { 91 | hash = "/" + ditto.index.replace(".md", ""); 92 | } 93 | 94 | window.open(ditto.base_url + hash + ".md"); 95 | // open is better than redirecting, as the previous page history 96 | // with redirect is a bit messed up 97 | }); 98 | } 99 | } 100 | 101 | function init_searchbar() { 102 | var sidebar = ditto.sidebar_id.html(); 103 | var match = "[ditto:searchbar]"; 104 | 105 | // html input searchbar 106 | var search = ""; 109 | 110 | // replace match code with a real html input search bar 111 | sidebar = sidebar.replace(match, search); 112 | ditto.sidebar_id.html(sidebar); 113 | 114 | // add search listener 115 | $("input[name=" + ditto.search_name.selector + "]").keydown(searchbar_listener); 116 | } 117 | 118 | function build_text_matches_html(fragments) { 119 | var html = ""; 120 | var class_name = ditto.fragments_class.replace(".", ""); 121 | 122 | html += "
    "; 123 | for (var i = 0; i < fragments.length; i++) { 124 | var fragment = fragments[i].fragment.replace("/[\uE000-\uF8FF]/g", ""); 125 | html += "
  • "; 126 | html += "
     ";
    127 |       fragment = $("#hide").text(fragment).html();
    128 |       html += fragment;
    129 |       html += " 
  • "; 130 | } 131 | html += "
"; 132 | 133 | return html; 134 | } 135 | 136 | function build_result_matches_html(matches) { 137 | var html = ""; 138 | var class_name = ditto.search_results_class.replace(".", ""); 139 | 140 | html += "
    "; 141 | for (var i = 0; i < matches.length; i++) { 142 | var url = matches[i].path; 143 | 144 | if (url !== ditto.sidebar_file) { 145 | var hash = "#" + url.replace(".md", ""); 146 | var path = window.location.origin+ "/" + hash; 147 | 148 | // html += "
  • "; 149 | html += "
  • "; 153 | 154 | var match = build_text_matches_html(matches[i].text_matches); 155 | html += match; 156 | } 157 | 158 | } 159 | html += "
"; 160 | 161 | return html; 162 | } 163 | 164 | function display_search_results(data) { 165 | var results_html = "

Search Results

"; 166 | 167 | if (data.items.length) { 168 | hide_errors(); 169 | results_html += build_result_matches_html(data.items); 170 | } else { 171 | show_error("Opps.. Found no matches!"); 172 | } 173 | 174 | ditto.content_id.html(results_html); 175 | $(ditto.search_results_class + " .link").click(function(){ 176 | var destination = "#" + $(this).html().replace(".md", ""); 177 | location.hash = destination; 178 | }); 179 | } 180 | 181 | function github_search(query) { 182 | if (ditto.github_username && ditto.github_repo) { 183 | // build github search api url string 184 | var github_api = "https://api.github.com/"; 185 | var search = "search/code?q="; 186 | var github_repo = ditto.github_username + "/" + ditto.github_repo; 187 | var search_details = "+in:file+language:markdown+repo:"; 188 | 189 | var url = github_api + search + query + search_details + github_repo; 190 | var accept_header = "application/vnd.github.v3.text-match+json"; 191 | 192 | $.ajax(url, {headers: {Accept: accept_header}}).done(function(data) { 193 | display_search_results(data); 194 | }); 195 | } 196 | 197 | if (ditto.github_username == null && ditto.github_repo == null) { 198 | alert("You have not set ditto.github_username and ditto.github_repo!"); 199 | } else if (ditto.github_username == null) { 200 | alert("You have not set ditto.github_username!"); 201 | } else if (ditto.github_repo == null) { 202 | alert("You have not set ditto.github_repo!"); 203 | } 204 | } 205 | 206 | function searchbar_listener(event) { 207 | if (event.which === 13) { // when user presses ENTER in search bar 208 | var q = $("input[name=" + ditto.search_name.selector + "]").val(); 209 | if (q !== "") { 210 | location.hash = "#search=" + q; 211 | } else { 212 | alert("Error! Empty search query!"); 213 | } 214 | } 215 | } 216 | 217 | function replace_symbols(text) { 218 | // replace symbols with underscore 219 | return text.replace(/[&\/\\#,+=()$~%.'":*?<>{}\ \]\[]/g, "_"); 220 | } 221 | 222 | function li_create_linkage(li_tag, header_level) { 223 | // add custom id and class attributes 224 | html_safe_tag = replace_symbols(li_tag.text()); 225 | li_tag.attr("id", html_safe_tag); 226 | li_tag.attr("class", "link"); 227 | 228 | // add click listener - on click scroll to relevant header section 229 | $(ditto.content_id.selector + " li#" + li_tag.attr("id")).click(function() { 230 | // scroll to relevant section 231 | var header = $("h" + header_level + "." + li_tag.attr("id")); 232 | $('html, body').animate({ 233 | scrollTop: header.offset().top 234 | }, 200); 235 | 236 | // highlight the relevant section 237 | original_color = header.css("color"); 238 | header.animate({ color: "#ED1C24", }, 500, function() { 239 | // revert back to orig color 240 | $(this).animate({color: original_color}, 2500); 241 | }); 242 | }); 243 | } 244 | 245 | function create_page_anchors() { 246 | // create page anchors by matching li's to headers 247 | // if there is a match, create click listeners 248 | // and scroll to relevant sections 249 | 250 | // go through header level 2 and 3 251 | for (var i = 2; i <= 4; i++) { 252 | // parse all headers 253 | var headers = []; 254 | $(ditto.content_id.selector + ' h' + i).map(function() { 255 | headers.push($(this).text()); 256 | $(this).addClass(replace_symbols($(this).text())); 257 | }); 258 | 259 | // parse and set links between li and h2 260 | $(ditto.content_id.selector + ' ul li').map(function() { 261 | for (var j = 0; j < headers.length; j++) { 262 | if (headers[j] === $(this).text()) { 263 | li_create_linkage($(this), i); 264 | } 265 | } 266 | }); 267 | } 268 | } 269 | 270 | function normalize_paths() { 271 | // images 272 | ditto.content_id.find("img").map(function() { 273 | var src = $(this).attr("src").replace("./", ""); 274 | if ($(this).attr("src").slice(0, 5) !== "http") { 275 | var url = location.hash.replace("#", ""); 276 | 277 | // split and extract base dir 278 | url = url.split("/"); 279 | var base_dir = url.slice(0, url.length - 1).join("/"); 280 | 281 | // normalize the path (i.e. make it absolute) 282 | if (base_dir) { 283 | $(this).attr("src", base_dir + "/" + src); 284 | } else { 285 | $(this).attr("src", src); 286 | } 287 | } 288 | }); 289 | 290 | } 291 | 292 | function show_error(err_msg) { 293 | ditto.error_id.html(err_msg); 294 | ditto.error_id.show(); 295 | } 296 | 297 | function hide_errors() { 298 | ditto.error_id.hide(); 299 | } 300 | 301 | function show_loading() { 302 | ditto.loading_id.show(); 303 | ditto.content_id.html(""); // clear content 304 | 305 | // infinite loop until clearInterval() is called on loading 306 | ditto.loading_interval = setInterval(function() { 307 | ditto.loading_id.fadeIn(1000).fadeOut(1000); 308 | }, 2000); 309 | 310 | } 311 | 312 | function stop_loading() { 313 | clearInterval(ditto.loading_interval); 314 | ditto.loading_id.hide(); 315 | } 316 | 317 | function escape_github_badges(data) { 318 | $("img").map(function() { 319 | var ignore_list = [ 320 | "travis-ci.org", 321 | "coveralls.io" 322 | ]; 323 | var src = $(this).attr("src"); 324 | 325 | var base_url = src.split("/"); 326 | var protocol = base_url[0]; 327 | var host = base_url[2]; 328 | 329 | if ($.inArray(host, ignore_list) >= 0) { 330 | $(this).attr("class", "github_badges"); 331 | } 332 | }); 333 | return data; 334 | } 335 | 336 | function page_getter() { 337 | window.scrollTo(0, 0); 338 | var path = location.hash.replace("#", "./"); 339 | 340 | // default page if hash is empty 341 | var current_page = location.pathname.split("/").pop(); 342 | if (current_page === "index.html") { 343 | path = location.pathname.replace("index.html", ditto.index); 344 | normalize_paths(); 345 | 346 | } else if (path === "") { 347 | path = window.location + ditto.index; 348 | normalize_paths(); 349 | 350 | } else { 351 | path = path + ".md"; 352 | 353 | } 354 | 355 | // otherwise get the markdown and render it 356 | show_loading(); 357 | $.get(path, function(data) { 358 | compile_into_dom(path, data); 359 | }).fail(function() { 360 | show_error("Opps! ... File not found!"); 361 | stop_loading(); 362 | }) 363 | } 364 | 365 | function compile_into_dom(path, data) { 366 | hide_errors(); 367 | data = marked(data); 368 | ditto.content_id.html(data); 369 | stop_loading(); 370 | escape_github_badges(data); 371 | 372 | normalize_paths(); 373 | create_page_anchors(); 374 | 375 | if (ditto.highlight_code) { 376 | $('pre code').each(function(i, block) { 377 | hljs.highlightBlock(block); 378 | }); 379 | } 380 | } 381 | 382 | function router() { 383 | var hash = location.hash; 384 | 385 | if (hash.slice(1, 7) !== "search") { 386 | page_getter(); 387 | 388 | } else { 389 | if (ditto.searchbar) { 390 | github_search(hash.replace("#search=", "")); 391 | } 392 | 393 | } 394 | } 395 | 396 | window.ditto = ditto; 397 | }); 398 | -------------------------------------------------------------------------------- /ver/0.12/github.css: -------------------------------------------------------------------------------- 1 | /* 2 | github.com style (c) Vasily Polovnyov 3 | */ 4 | 5 | .hljs { 6 | display: block; 7 | overflow-x: auto; 8 | padding: 0.5em; 9 | color: #333; 10 | background: #f8f8f8; 11 | -webkit-text-size-adjust: none; 12 | } 13 | 14 | .hljs-comment, 15 | .diff .hljs-header { 16 | color: #998; 17 | font-style: italic; 18 | } 19 | 20 | .hljs-keyword, 21 | .css .rule .hljs-keyword, 22 | .hljs-winutils, 23 | .nginx .hljs-title, 24 | .hljs-subst, 25 | .hljs-request, 26 | .hljs-status { 27 | color: #333; 28 | font-weight: bold; 29 | } 30 | 31 | .hljs-number, 32 | .hljs-hexcolor, 33 | .ruby .hljs-constant { 34 | color: #008080; 35 | } 36 | 37 | .hljs-string, 38 | .hljs-tag .hljs-value, 39 | .hljs-doctag, 40 | .tex .hljs-formula { 41 | color: #d14; 42 | } 43 | 44 | .hljs-title, 45 | .hljs-id, 46 | .scss .hljs-preprocessor { 47 | color: #900; 48 | font-weight: bold; 49 | } 50 | 51 | .hljs-list .hljs-keyword, 52 | .hljs-subst { 53 | font-weight: normal; 54 | } 55 | 56 | .hljs-class .hljs-title, 57 | .hljs-type, 58 | .vhdl .hljs-literal, 59 | .tex .hljs-command { 60 | color: #458; 61 | font-weight: bold; 62 | } 63 | 64 | .hljs-tag, 65 | .hljs-tag .hljs-title, 66 | .hljs-rule .hljs-property, 67 | .django .hljs-tag .hljs-keyword { 68 | color: #000080; 69 | font-weight: normal; 70 | } 71 | 72 | .hljs-attribute, 73 | .hljs-variable, 74 | .lisp .hljs-body, 75 | .hljs-name { 76 | color: #008080; 77 | } 78 | 79 | .hljs-regexp { 80 | color: #009926; 81 | } 82 | 83 | .hljs-symbol, 84 | .ruby .hljs-symbol .hljs-string, 85 | .lisp .hljs-keyword, 86 | .clojure .hljs-keyword, 87 | .scheme .hljs-keyword, 88 | .tex .hljs-special, 89 | .hljs-prompt { 90 | color: #990073; 91 | } 92 | 93 | .hljs-built_in { 94 | color: #0086b3; 95 | } 96 | 97 | .hljs-preprocessor, 98 | .hljs-pragma, 99 | .hljs-pi, 100 | .hljs-doctype, 101 | .hljs-shebang, 102 | .hljs-cdata { 103 | color: #999; 104 | font-weight: bold; 105 | } 106 | 107 | .hljs-deletion { 108 | background: #fdd; 109 | } 110 | 111 | .hljs-addition { 112 | background: #dfd; 113 | } 114 | 115 | .diff .hljs-change { 116 | background: #0086b3; 117 | } 118 | 119 | .hljs-chunk { 120 | color: #aaa; 121 | } 122 | -------------------------------------------------------------------------------- /ver/0.12/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TITLE 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 |
26 | 27 | 28 |
top
29 |
edit
30 |
Loading ...
31 |
32 | 33 | 34 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /ver/0.12/sidebar.md: -------------------------------------------------------------------------------- 1 | # [Project]() 2 | version 0.1 3 | 4 | - [Github Repository](http://github.com//) 5 | 6 | [ditto:searchbar] 7 | 8 | ## Header 2 9 | - [Page1](#docs/page1) 10 | - [Page2](#docs/page2) 11 | -------------------------------------------------------------------------------- /ver/0.13/ditto.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #333; 3 | margin: 0; 4 | padding: 0; 5 | 6 | font-family: Verdana, Arial; 7 | font-size: 0.8em; 8 | } 9 | 10 | #sidebar { 11 | position: fixed; 12 | width: 220px; 13 | height: 100%; 14 | 15 | overflow-y: scroll; 16 | overflow: -moz-scrollbars-vertical; 17 | 18 | margin-right: 20px; 19 | margin-top: 0; 20 | padding-left: 25px; 21 | padding-top: 0; 22 | 23 | box-shadow: 0 0 40px #CCC; 24 | -webkit-box-shadow: 0 0 40px #CCC; 25 | -moz-box-shadow: 0 0 40px #CCC; 26 | border-right: 1px solid #BBB; 27 | } 28 | 29 | #sidebar h1 { 30 | font-size: 25px; 31 | margin-bottom: 0px; 32 | padding-bottom: 0px; 33 | } 34 | 35 | #sidebar h1 a:link, #sidebar h1 a:visited { 36 | color: #333; 37 | } 38 | 39 | #sidebar h2 { 40 | font-size: 15px; 41 | } 42 | 43 | #sidebar h5 { 44 | margin-top: 20px; 45 | margin-bottom: 0; 46 | } 47 | 48 | #sidebar a:visited, #sidebar a:link { 49 | color: #4682BE; 50 | text-decoration: none; 51 | } 52 | 53 | #sidebar ul { 54 | list-style-type: none; 55 | margin: 0; 56 | padding-left: 10px; 57 | padding-top: 0; 58 | } 59 | 60 | #sidebar ul li:before { /* a hack to have dashes as a list style */ 61 | content: "-"; 62 | position: relative; 63 | left: -5px; 64 | } 65 | 66 | #sidebar ul li { 67 | margin-top: 0; 68 | margin-bottom: 2px; 69 | margin-left: 10px; 70 | padding: 0; 71 | 72 | text-indent: -5px; /* to compensate for the padding for the dash */ 73 | font-size: 12px; 74 | } 75 | 76 | #content { 77 | width: 580px; 78 | 79 | margin-left: 300px; 80 | padding-top: 10px; 81 | padding-bottom: 150px; 82 | 83 | text-align: justify; 84 | font-size: 1.0em; 85 | } 86 | 87 | #content pre { 88 | margin-left: auto; 89 | margin-right: auto; 90 | 91 | padding-top: 10px; 92 | padding-bottom: 10px; 93 | padding-left: 13px; 94 | padding-right: 13px; 95 | 96 | color: #FFF; 97 | white-space: pre-wrap; /* css-3 */ 98 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 99 | white-space: -pre-wrap; /* Opera 4-6 */ 100 | white-space: -o-pre-wrap; /* Opera 7 */ 101 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 102 | 103 | background: #F7FAFB; 104 | border-radius: 5px; 105 | } 106 | 107 | #content pre code { 108 | padding-left: 0; 109 | font-size: 1.1em; 110 | border: none; 111 | } 112 | 113 | #content code { 114 | padding-left: 5px; 115 | padding-right: 5px; 116 | padding-top: 1px; 117 | padding-bottom: 1px; 118 | 119 | color: #555; 120 | font-size: 10px; 121 | font-weight: normal; 122 | font-family: Consolas, monospace; 123 | 124 | background: #F7FAFB; 125 | border: 1px solid #E3EDF3; 126 | border-radius: 2px; 127 | } 128 | 129 | #content h2 { 130 | margin-top: 50px; 131 | margin-bottom: 0px; 132 | 133 | padding-top: 20px; 134 | padding-bottom: 0px; 135 | 136 | font-size: 18px; 137 | text-align: left; 138 | 139 | border-top: 2px solid #666; 140 | } 141 | 142 | #content h3 { 143 | margin-top: 50px; 144 | margin-bottom: 0px; 145 | 146 | padding-top: 20px; 147 | padding-bottom: 0px; 148 | 149 | text-align: left; 150 | border-top: 1px dotted #777; 151 | } 152 | 153 | #content hr { 154 | border: 0; 155 | height: 0; 156 | border-top: 1px solid rgba(0, 0, 0, 0.1); 157 | border-bottom: 1px solid rgba(255, 255, 255, 0.3); 158 | } 159 | 160 | #content img { 161 | max-width: 90%; 162 | display: block; 163 | 164 | margin-left: auto; 165 | margin-right: auto; 166 | margin-top: 40px; 167 | margin-bottom: 40px; 168 | 169 | border-radius: 5px; 170 | } 171 | 172 | #content ul { 173 | display: block; 174 | list-style-type: none; 175 | } 176 | 177 | #content ul li:before { /* a hack to have dashes as a list style */ 178 | content: "-"; 179 | position: relative; 180 | left: -5px; 181 | } 182 | 183 | #content ul li { 184 | text-indent: -5px; /* to compensate for the padding for the dash */ 185 | font-size: 13px; 186 | } 187 | 188 | #content ul li.link { 189 | color: #4682BE; 190 | text-decoration: none; 191 | font-size: 13px; 192 | font-weight: bold; 193 | cursor: pointer; 194 | } 195 | 196 | #content a:link, #content a:visited { 197 | color: #4682BE; 198 | text-decoration: none; 199 | } 200 | 201 | #back_to_top { 202 | display: none; 203 | position: fixed; 204 | 205 | height: 20px; 206 | line-height: 20px; 207 | width: 50px; 208 | top: 20px; 209 | 210 | margin-left: 890px; 211 | 212 | color: #FFF; 213 | vertical-align: middle; 214 | text-align: center; 215 | font-size: 10px; 216 | 217 | border-radius: 5px; 218 | background-color: #AAA; 219 | } 220 | 221 | #back_to_top:hover { 222 | background-color: #444; 223 | cursor: pointer; 224 | } 225 | 226 | #edit { 227 | display: none; 228 | position: fixed; 229 | 230 | height: 20px; 231 | line-height: 20px; 232 | width: 50px; 233 | top: 50px; 234 | 235 | margin-left: 890px; 236 | 237 | color: #FFF; 238 | vertical-align: middle; 239 | text-align: center; 240 | font-size: 10px; 241 | 242 | border-radius: 5px; 243 | background-color: #AAA; 244 | } 245 | 246 | #edit:hover { 247 | background-color: #444; 248 | cursor: pointer; 249 | } 250 | 251 | #loading, #error { 252 | display: none; 253 | position: fixed; 254 | 255 | height: 17px; 256 | top: 45%; 257 | 258 | margin-left: 560px; 259 | 260 | font-size: 14px; 261 | font-weight: bold; 262 | } 263 | 264 | input[type=search] { 265 | display: block; 266 | width: 180px; 267 | 268 | text-align: left; 269 | } 270 | 271 | .search_results{ 272 | 273 | 274 | } 275 | 276 | .fragments { 277 | margin: 0; 278 | padding: 10px; 279 | /* border: 1px solid #777; */ 280 | /* border-radius: 5px; */ 281 | } 282 | 283 | .fragment { 284 | padding-left: 10px; 285 | padding-right: 10px; 286 | padding-top: 0px; 287 | padding-bottom: 0px; 288 | 289 | /* border: 1px solid #777; */ 290 | /* border-radius: 5px; */ 291 | } 292 | 293 | .search_results .link { 294 | margin-top: 35px; 295 | } 296 | 297 | #content ul li { 298 | text-align: left; 299 | } 300 | 301 | #content ul .fragments li:before { 302 | content: ""; 303 | position: relative; 304 | left: 0px; 305 | } 306 | 307 | #content ul li.fragment:before { 308 | content: ""; 309 | margin: 0; 310 | padding: 0; 311 | } 312 | 313 | #content img.github_badges { 314 | display: inline; 315 | margin-top: 0; 316 | margin-bottom: 0; 317 | } 318 | 319 | 320 | #hide { 321 | display: none; 322 | } 323 | -------------------------------------------------------------------------------- /ver/0.13/ditto.js: -------------------------------------------------------------------------------- 1 | $(function($) { 2 | 3 | var ditto = { 4 | content_id: $("#content"), 5 | sidebar_id: $("#sidebar"), 6 | 7 | edit_id: $("#edit"), 8 | back_to_top_id: $("#back_to_top"), 9 | 10 | loading_id: $("#loading"), 11 | error_id: $("#error"), 12 | 13 | search_name: $("#search"), 14 | search_results_class: ".search_results", 15 | fragments_class: ".fragments", 16 | fragment_class: ".fragment", 17 | 18 | highlight_code: true, 19 | 20 | // display elements 21 | sidebar: true, 22 | edit_button: true, 23 | back_to_top_button: true, 24 | searchbar: true, 25 | 26 | // github specifics 27 | github_username: null, 28 | github_repo: null, 29 | 30 | // initialize function 31 | run: initialize 32 | }; 33 | 34 | function initialize() { 35 | // initialize sidebar and buttons 36 | if (ditto.sidebar) { 37 | init_sidebar_section(); 38 | } 39 | 40 | if (ditto.back_to_top_button) { 41 | init_back_to_top_button(); 42 | } 43 | 44 | if (ditto.edit_button) { 45 | init_edit_button(); 46 | } 47 | 48 | // intialize highligh.js 49 | if (ditto.highlight_code) { 50 | hljs.initHighlightingOnLoad(); 51 | } 52 | 53 | // page router 54 | router(); 55 | $(window).on('hashchange', router); 56 | } 57 | 58 | function init_sidebar_section() { 59 | $.get(ditto.sidebar_file, function(data) { 60 | ditto.sidebar_id.html(marked(data)); 61 | 62 | if (ditto.searchbar) { 63 | init_searchbar(); 64 | } 65 | 66 | }, "text").fail(function() { 67 | alert("Opps! can't find the sidebar file to display!"); 68 | }); 69 | 70 | } 71 | 72 | function init_back_to_top_button() { 73 | ditto.back_to_top_id.show(); 74 | ditto.back_to_top_id.on("click", function() { 75 | $("body, html").animate({ 76 | scrollTop: 0 77 | }, 200); 78 | }); 79 | } 80 | 81 | function init_edit_button() { 82 | if (ditto.base_url === null) { 83 | alert("Error! You didn't set 'base_url' when calling ditto.run()!"); 84 | 85 | } else { 86 | ditto.edit_id.show(); 87 | ditto.edit_id.on("click", function() { 88 | var hash = location.hash.replace("#", "/"); 89 | 90 | if (hash === "") { 91 | hash = "/" + ditto.index.replace(".md", ""); 92 | } 93 | 94 | window.open(ditto.base_url + hash + ".md"); 95 | // open is better than redirecting, as the previous page history 96 | // with redirect is a bit messed up 97 | }); 98 | } 99 | } 100 | 101 | function init_searchbar() { 102 | var sidebar = ditto.sidebar_id.html(); 103 | var match = "[ditto:searchbar]"; 104 | 105 | // html input searchbar 106 | var search = ""; 109 | 110 | // replace match code with a real html input search bar 111 | sidebar = sidebar.replace(match, search); 112 | ditto.sidebar_id.html(sidebar); 113 | 114 | // add search listener 115 | $("input[name=" + ditto.search_name.selector + "]").keydown(searchbar_listener); 116 | } 117 | 118 | function build_text_matches_html(fragments) { 119 | var html = ""; 120 | var class_name = ditto.fragments_class.replace(".", ""); 121 | 122 | html += "
    "; 123 | for (var i = 0; i < fragments.length; i++) { 124 | var fragment = fragments[i].fragment.replace("/[\uE000-\uF8FF]/g", ""); 125 | html += "
  • "; 126 | html += "
     ";
    127 |       fragment = $("#hide").text(fragment).html();
    128 |       html += fragment;
    129 |       html += " 
  • "; 130 | } 131 | html += "
"; 132 | 133 | return html; 134 | } 135 | 136 | function build_result_matches_html(matches) { 137 | var html = ""; 138 | var class_name = ditto.search_results_class.replace(".", ""); 139 | 140 | html += "
    "; 141 | for (var i = 0; i < matches.length; i++) { 142 | var url = matches[i].path; 143 | 144 | if (url !== ditto.sidebar_file) { 145 | var hash = "#" + url.replace(".md", ""); 146 | var path = window.location.origin+ "/" + hash; 147 | 148 | // html += "
  • "; 149 | html += "
  • "; 153 | 154 | var match = build_text_matches_html(matches[i].text_matches); 155 | html += match; 156 | } 157 | 158 | } 159 | html += "
"; 160 | 161 | return html; 162 | } 163 | 164 | function display_search_results(data) { 165 | var results_html = "

Search Results

"; 166 | 167 | if (data.items.length) { 168 | hide_errors(); 169 | results_html += build_result_matches_html(data.items); 170 | } else { 171 | show_error("Opps.. Found no matches!"); 172 | } 173 | 174 | ditto.content_id.html(results_html); 175 | $(ditto.search_results_class + " .link").click(function(){ 176 | var destination = "#" + $(this).html().replace(".md", ""); 177 | location.hash = destination; 178 | }); 179 | } 180 | 181 | function github_search(query) { 182 | if (ditto.github_username && ditto.github_repo) { 183 | // build github search api url string 184 | var github_api = "https://api.github.com/"; 185 | var search = "search/code?q="; 186 | var github_repo = ditto.github_username + "/" + ditto.github_repo; 187 | var search_details = "+in:file+language:markdown+repo:"; 188 | 189 | var url = github_api + search + query + search_details + github_repo; 190 | var accept_header = "application/vnd.github.v3.text-match+json"; 191 | 192 | $.ajax(url, {headers: {Accept: accept_header}}).done(function(data) { 193 | display_search_results(data); 194 | }); 195 | } 196 | 197 | if (ditto.github_username == null && ditto.github_repo == null) { 198 | alert("You have not set ditto.github_username and ditto.github_repo!"); 199 | } else if (ditto.github_username == null) { 200 | alert("You have not set ditto.github_username!"); 201 | } else if (ditto.github_repo == null) { 202 | alert("You have not set ditto.github_repo!"); 203 | } 204 | } 205 | 206 | function searchbar_listener(event) { 207 | if (event.which === 13) { // when user presses ENTER in search bar 208 | var q = $("input[name=" + ditto.search_name.selector + "]").val(); 209 | if (q !== "") { 210 | location.hash = "#search=" + q; 211 | } else { 212 | alert("Error! Empty search query!"); 213 | } 214 | } 215 | } 216 | 217 | function replace_symbols(text) { 218 | // replace symbols with underscore 219 | return text.replace(/[&\/\\#,+=()$~%.'":*?<>{}\ \]\[]/g, "_"); 220 | } 221 | 222 | function li_create_linkage(li_tag, header_level) { 223 | // add custom id and class attributes 224 | html_safe_tag = replace_symbols(li_tag.text()); 225 | li_tag.attr("id", html_safe_tag); 226 | li_tag.attr("class", "link"); 227 | 228 | // add click listener - on click scroll to relevant header section 229 | $(ditto.content_id.selector + " li#" + li_tag.attr("id")).click(function() { 230 | // scroll to relevant section 231 | var header = $("h" + header_level + "." + li_tag.attr("id")); 232 | $('html, body').animate({ 233 | scrollTop: header.offset().top 234 | }, 200); 235 | 236 | // highlight the relevant section 237 | original_color = header.css("color"); 238 | header.animate({ color: "#ED1C24", }, 500, function() { 239 | // revert back to orig color 240 | $(this).animate({color: original_color}, 2500); 241 | }); 242 | }); 243 | } 244 | 245 | function create_page_anchors() { 246 | // create page anchors by matching li's to headers 247 | // if there is a match, create click listeners 248 | // and scroll to relevant sections 249 | 250 | // go through header level 2 and 3 251 | for (var i = 2; i <= 4; i++) { 252 | // parse all headers 253 | var headers = []; 254 | $(ditto.content_id.selector + ' h' + i).map(function() { 255 | headers.push($(this).text()); 256 | $(this).addClass(replace_symbols($(this).text())); 257 | }); 258 | 259 | // parse and set links between li and h2 260 | $(ditto.content_id.selector + ' ul li').map(function() { 261 | for (var j = 0; j < headers.length; j++) { 262 | if (headers[j] === $(this).text()) { 263 | li_create_linkage($(this), i); 264 | } 265 | } 266 | }); 267 | } 268 | } 269 | 270 | function normalize_paths() { 271 | // images 272 | ditto.content_id.find("img").map(function() { 273 | var src = $(this).attr("src").replace("./", ""); 274 | if ($(this).attr("src").slice(0, 5) !== "http") { 275 | var url = location.hash.replace("#", ""); 276 | 277 | // split and extract base dir 278 | url = url.split("/"); 279 | var base_dir = url.slice(0, url.length - 1).join("/"); 280 | 281 | // normalize the path (i.e. make it absolute) 282 | if (base_dir) { 283 | $(this).attr("src", base_dir + "/" + src); 284 | } else { 285 | $(this).attr("src", src); 286 | } 287 | } 288 | }); 289 | 290 | } 291 | 292 | function show_error(err_msg) { 293 | ditto.error_id.html(err_msg); 294 | ditto.error_id.show(); 295 | } 296 | 297 | function hide_errors() { 298 | ditto.error_id.hide(); 299 | } 300 | 301 | function show_loading() { 302 | ditto.loading_id.show(); 303 | ditto.content_id.html(""); // clear content 304 | 305 | // infinite loop until clearInterval() is called on loading 306 | ditto.loading_interval = setInterval(function() { 307 | ditto.loading_id.fadeIn(1000).fadeOut(1000); 308 | }, 2000); 309 | 310 | } 311 | 312 | function stop_loading() { 313 | clearInterval(ditto.loading_interval); 314 | ditto.loading_id.hide(); 315 | } 316 | 317 | function escape_github_badges(data) { 318 | $("img").map(function() { 319 | var ignore_list = [ 320 | "travis-ci.org", 321 | "coveralls.io" 322 | ]; 323 | var src = $(this).attr("src"); 324 | 325 | var base_url = src.split("/"); 326 | var protocol = base_url[0]; 327 | var host = base_url[2]; 328 | 329 | if ($.inArray(host, ignore_list) >= 0) { 330 | $(this).attr("class", "github_badges"); 331 | } 332 | }); 333 | return data; 334 | } 335 | 336 | function page_getter() { 337 | window.scrollTo(0, 0); 338 | var path = location.hash.replace("#", "./"); 339 | 340 | // default page if hash is empty 341 | var current_page = location.pathname.split("/").pop(); 342 | if (current_page === "index.html") { 343 | path = location.pathname.replace("index.html", ditto.index); 344 | normalize_paths(); 345 | 346 | } else if (path === "") { 347 | path = window.location + ditto.index; 348 | normalize_paths(); 349 | 350 | } else { 351 | path = path + ".md"; 352 | 353 | } 354 | 355 | // otherwise get the markdown and render it 356 | show_loading(); 357 | $.get(path, function(data) { 358 | compile_into_dom(path, data, function() { 359 | // reset mathjax equation counter 360 | <<<<<<< HEAD 361 | MathJax.Extension["TeX/AMSmath"].startNumber = 0; 362 | MathJax.Extension["TeX/AMSmath"].labels = {}; 363 | ======= 364 | if (MathJax.Extension["Tex/AMSmath"]) { 365 | MathJax.Extension["TeX/AMSmath"].startNumber = 0; 366 | MathJax.Extension["TeX/AMSmath"].labels = {}; 367 | } 368 | >>>>>>> master 369 | 370 | // rerender mathjax 371 | var content = document.getElementById("content"); 372 | MathJax.Hub.Queue(["Typeset", MathJax.Hub, content]); 373 | <<<<<<< HEAD 374 | 375 | ======= 376 | >>>>>>> master 377 | }); 378 | }).fail(function() { 379 | show_error("Opps! ... File not found!"); 380 | stop_loading(); 381 | }); 382 | } 383 | 384 | function escape_html(string) { 385 | return string 386 | .replace(/\\/g, "\") 387 | .replace(/\_/g, "_"); 388 | } 389 | 390 | function unescape_html(string) { 391 | return string 392 | .replace(/&#92;/g, "\\") 393 | .replace(/&#95;/g, "_"); 394 | } 395 | 396 | function compile_into_dom(path, data, cb) { 397 | hide_errors(); 398 | 399 | data = marked(escape_html(data)); 400 | data = unescape_html(data); 401 | ditto.content_id.html(data); 402 | 403 | stop_loading(); 404 | escape_github_badges(data); 405 | 406 | normalize_paths(); 407 | create_page_anchors(); 408 | 409 | if (ditto.highlight_code) { 410 | $('pre code').each(function(i, block) { 411 | hljs.highlightBlock(block); 412 | }); 413 | } 414 | 415 | if (cb) { 416 | cb(data); 417 | } 418 | } 419 | 420 | function router() { 421 | var hash = location.hash; 422 | 423 | if (hash.slice(1, 7) !== "search") { 424 | page_getter(); 425 | 426 | } else { 427 | if (ditto.searchbar) { 428 | github_search(hash.replace("#search=", "")); 429 | } 430 | 431 | } 432 | } 433 | 434 | window.ditto = ditto; 435 | }); 436 | -------------------------------------------------------------------------------- /ver/0.13/github.css: -------------------------------------------------------------------------------- 1 | /* 2 | github.com style (c) Vasily Polovnyov 3 | */ 4 | 5 | .hljs { 6 | display: block; 7 | overflow-x: auto; 8 | padding: 0.5em; 9 | color: #333; 10 | background: #f8f8f8; 11 | -webkit-text-size-adjust: none; 12 | } 13 | 14 | .hljs-comment, 15 | .diff .hljs-header { 16 | color: #998; 17 | font-style: italic; 18 | } 19 | 20 | .hljs-keyword, 21 | .css .rule .hljs-keyword, 22 | .hljs-winutils, 23 | .nginx .hljs-title, 24 | .hljs-subst, 25 | .hljs-request, 26 | .hljs-status { 27 | color: #333; 28 | font-weight: bold; 29 | } 30 | 31 | .hljs-number, 32 | .hljs-hexcolor, 33 | .ruby .hljs-constant { 34 | color: #008080; 35 | } 36 | 37 | .hljs-string, 38 | .hljs-tag .hljs-value, 39 | .hljs-doctag, 40 | .tex .hljs-formula { 41 | color: #d14; 42 | } 43 | 44 | .hljs-title, 45 | .hljs-id, 46 | .scss .hljs-preprocessor { 47 | color: #900; 48 | font-weight: bold; 49 | } 50 | 51 | .hljs-list .hljs-keyword, 52 | .hljs-subst { 53 | font-weight: normal; 54 | } 55 | 56 | .hljs-class .hljs-title, 57 | .hljs-type, 58 | .vhdl .hljs-literal, 59 | .tex .hljs-command { 60 | color: #458; 61 | font-weight: bold; 62 | } 63 | 64 | .hljs-tag, 65 | .hljs-tag .hljs-title, 66 | .hljs-rule .hljs-property, 67 | .django .hljs-tag .hljs-keyword { 68 | color: #000080; 69 | font-weight: normal; 70 | } 71 | 72 | .hljs-attribute, 73 | .hljs-variable, 74 | .lisp .hljs-body, 75 | .hljs-name { 76 | color: #008080; 77 | } 78 | 79 | .hljs-regexp { 80 | color: #009926; 81 | } 82 | 83 | .hljs-symbol, 84 | .ruby .hljs-symbol .hljs-string, 85 | .lisp .hljs-keyword, 86 | .clojure .hljs-keyword, 87 | .scheme .hljs-keyword, 88 | .tex .hljs-special, 89 | .hljs-prompt { 90 | color: #990073; 91 | } 92 | 93 | .hljs-built_in { 94 | color: #0086b3; 95 | } 96 | 97 | .hljs-preprocessor, 98 | .hljs-pragma, 99 | .hljs-pi, 100 | .hljs-doctype, 101 | .hljs-shebang, 102 | .hljs-cdata { 103 | color: #999; 104 | font-weight: bold; 105 | } 106 | 107 | .hljs-deletion { 108 | background: #fdd; 109 | } 110 | 111 | .hljs-addition { 112 | background: #dfd; 113 | } 114 | 115 | .diff .hljs-change { 116 | background: #0086b3; 117 | } 118 | 119 | .hljs-chunk { 120 | color: #aaa; 121 | } 122 | -------------------------------------------------------------------------------- /ver/0.13/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TITLE 5 | 6 | 7 | 8 | 9 | 10 | 11 | <<<<<<< HEAD 12 | 13 | 14 | 15 | 16 | 17 | ======= 18 | 19 | 20 | 21 | 22 | 23 | >>>>>>> master 24 | 25 | 26 | 42 | 45 | 46 | 47 | <<<<<<< HEAD 48 | 49 | 50 | ======= 51 | 52 | 53 | >>>>>>> master 54 | 55 | 56 | 57 | 58 |
59 |
60 | 61 | 62 |
top
63 |
edit
64 |
Loading ...
65 |
66 | 67 | 68 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /ver/0.13/sidebar.md: -------------------------------------------------------------------------------- 1 | # [Project]() 2 | version 0.1 3 | 4 | - [Github Repository](http://github.com//) 5 | 6 | [ditto:searchbar] 7 | 8 | ## Header 2 9 | - [Page1](#docs/page1) 10 | - [Page2](#docs/page2) 11 | -------------------------------------------------------------------------------- /ver/0.14/ditto.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #333; 3 | margin: 0; 4 | padding: 0; 5 | 6 | font-family: Verdana, Arial; 7 | font-size: 0.8em; 8 | } 9 | 10 | #sidebar { 11 | position: fixed; 12 | width: 220px; 13 | height: 100%; 14 | 15 | overflow-y: scroll; 16 | overflow: -moz-scrollbars-vertical; 17 | 18 | margin-right: 20px; 19 | margin-top: 0; 20 | padding-left: 25px; 21 | padding-top: 0; 22 | 23 | box-shadow: 0 0 40px #CCC; 24 | -webkit-box-shadow: 0 0 40px #CCC; 25 | -moz-box-shadow: 0 0 40px #CCC; 26 | border-right: 1px solid #BBB; 27 | } 28 | 29 | #sidebar h1 { 30 | font-size: 25px; 31 | margin-bottom: 0px; 32 | padding-bottom: 0px; 33 | } 34 | 35 | #sidebar h1 a:link, #sidebar h1 a:visited { 36 | color: #333; 37 | } 38 | 39 | #sidebar h2 { 40 | font-size: 15px; 41 | } 42 | 43 | #sidebar h5 { 44 | margin-top: 20px; 45 | margin-bottom: 0; 46 | } 47 | 48 | #sidebar a:visited, #sidebar a:link { 49 | color: #4682BE; 50 | text-decoration: none; 51 | } 52 | 53 | #sidebar ul { 54 | list-style-type: none; 55 | margin: 0; 56 | padding-left: 10px; 57 | padding-top: 0; 58 | } 59 | 60 | #sidebar ul li:before { /* a hack to have dashes as a list style */ 61 | content: "-"; 62 | position: relative; 63 | left: -5px; 64 | } 65 | 66 | #sidebar ul li { 67 | margin-top: 0; 68 | margin-bottom: 2px; 69 | margin-left: 10px; 70 | padding: 0; 71 | 72 | text-indent: -5px; /* to compensate for the padding for the dash */ 73 | font-size: 12px; 74 | } 75 | 76 | #content { 77 | width: 580px; 78 | 79 | margin-left: 300px; 80 | padding-top: 10px; 81 | padding-bottom: 150px; 82 | 83 | text-align: justify; 84 | font-size: 1.0em; 85 | } 86 | 87 | #content pre { 88 | margin-left: auto; 89 | margin-right: auto; 90 | 91 | padding-top: 10px; 92 | padding-bottom: 10px; 93 | padding-left: 13px; 94 | padding-right: 13px; 95 | 96 | color: #FFF; 97 | white-space: pre-wrap; /* css-3 */ 98 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 99 | white-space: -pre-wrap; /* Opera 4-6 */ 100 | white-space: -o-pre-wrap; /* Opera 7 */ 101 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 102 | 103 | background: #F7FAFB; 104 | border-radius: 5px; 105 | } 106 | 107 | #content pre code { 108 | padding-left: 0; 109 | font-size: 1.1em; 110 | border: none; 111 | } 112 | 113 | #content code { 114 | padding-left: 5px; 115 | padding-right: 5px; 116 | padding-top: 1px; 117 | padding-bottom: 1px; 118 | 119 | color: #555; 120 | font-size: 10px; 121 | font-weight: normal; 122 | font-family: Consolas, monospace; 123 | 124 | background: #F7FAFB; 125 | border: 1px solid #E3EDF3; 126 | border-radius: 2px; 127 | } 128 | 129 | #content h2 { 130 | margin-top: 50px; 131 | margin-bottom: 0px; 132 | 133 | padding-top: 20px; 134 | padding-bottom: 0px; 135 | 136 | font-size: 18px; 137 | text-align: left; 138 | 139 | border-top: 2px solid #666; 140 | } 141 | 142 | #content h3 { 143 | margin-top: 50px; 144 | margin-bottom: 0px; 145 | 146 | padding-top: 20px; 147 | padding-bottom: 0px; 148 | 149 | text-align: left; 150 | border-top: 1px dotted #777; 151 | } 152 | 153 | #content hr { 154 | border: 0; 155 | height: 0; 156 | border-top: 1px solid rgba(0, 0, 0, 0.1); 157 | border-bottom: 1px solid rgba(255, 255, 255, 0.3); 158 | } 159 | 160 | #content img { 161 | max-width: 90%; 162 | display: block; 163 | 164 | margin-left: auto; 165 | margin-right: auto; 166 | margin-top: 40px; 167 | margin-bottom: 40px; 168 | 169 | border-radius: 5px; 170 | } 171 | 172 | #content ul { 173 | display: block; 174 | list-style-type: none; 175 | } 176 | 177 | #content ul li:before { /* a hack to have dashes as a list style */ 178 | content: "-"; 179 | position: relative; 180 | left: -5px; 181 | } 182 | 183 | #content ul li { 184 | text-indent: -5px; /* to compensate for the padding for the dash */ 185 | font-size: 13px; 186 | } 187 | 188 | #content ul li.link { 189 | color: #4682BE; 190 | text-decoration: none; 191 | font-size: 13px; 192 | font-weight: bold; 193 | cursor: pointer; 194 | } 195 | 196 | #content a:link, #content a:visited { 197 | color: #4682BE; 198 | text-decoration: none; 199 | } 200 | 201 | #back_to_top { 202 | display: none; 203 | position: fixed; 204 | 205 | height: 20px; 206 | line-height: 20px; 207 | width: 50px; 208 | top: 20px; 209 | 210 | margin-left: 890px; 211 | 212 | color: #FFF; 213 | vertical-align: middle; 214 | text-align: center; 215 | font-size: 10px; 216 | 217 | border-radius: 5px; 218 | background-color: #AAA; 219 | } 220 | 221 | #back_to_top:hover { 222 | background-color: #444; 223 | cursor: pointer; 224 | } 225 | 226 | #edit { 227 | display: none; 228 | position: fixed; 229 | 230 | height: 20px; 231 | line-height: 20px; 232 | width: 50px; 233 | top: 50px; 234 | 235 | margin-left: 890px; 236 | 237 | color: #FFF; 238 | vertical-align: middle; 239 | text-align: center; 240 | font-size: 10px; 241 | 242 | border-radius: 5px; 243 | background-color: #AAA; 244 | } 245 | 246 | #edit:hover { 247 | background-color: #444; 248 | cursor: pointer; 249 | } 250 | 251 | #loading, #error { 252 | display: none; 253 | position: fixed; 254 | 255 | height: 17px; 256 | top: 45%; 257 | 258 | margin-left: 560px; 259 | 260 | font-size: 14px; 261 | font-weight: bold; 262 | } 263 | 264 | input[type=search] { 265 | display: block; 266 | width: 180px; 267 | 268 | text-align: left; 269 | } 270 | 271 | .search_results{ 272 | 273 | 274 | } 275 | 276 | .fragments { 277 | margin: 0; 278 | padding: 10px; 279 | /* border: 1px solid #777; */ 280 | /* border-radius: 5px; */ 281 | } 282 | 283 | .fragment { 284 | padding-left: 10px; 285 | padding-right: 10px; 286 | padding-top: 0px; 287 | padding-bottom: 0px; 288 | 289 | /* border: 1px solid #777; */ 290 | /* border-radius: 5px; */ 291 | } 292 | 293 | .search_results .link { 294 | margin-top: 35px; 295 | } 296 | 297 | #content ul li { 298 | text-align: left; 299 | } 300 | 301 | #content ul .fragments li:before { 302 | content: ""; 303 | position: relative; 304 | left: 0px; 305 | } 306 | 307 | #content ul li.fragment:before { 308 | content: ""; 309 | margin: 0; 310 | padding: 0; 311 | } 312 | 313 | #content img.github_badges { 314 | display: inline; 315 | margin-top: 0; 316 | margin-bottom: 0; 317 | } 318 | 319 | 320 | #hide { 321 | display: none; 322 | } 323 | -------------------------------------------------------------------------------- /ver/0.14/ditto.js: -------------------------------------------------------------------------------- 1 | $(function($) { 2 | 3 | var ditto = { 4 | content_id: $("#content"), 5 | sidebar_id: $("#sidebar"), 6 | 7 | edit_id: $("#edit"), 8 | back_to_top_id: $("#back_to_top"), 9 | 10 | loading_id: $("#loading"), 11 | error_id: $("#error"), 12 | 13 | search_name: $("#search"), 14 | search_results_class: ".search_results", 15 | fragments_class: ".fragments", 16 | fragment_class: ".fragment", 17 | 18 | highlight_code: true, 19 | 20 | // display elements 21 | sidebar: true, 22 | edit_button: true, 23 | back_to_top_button: true, 24 | searchbar: true, 25 | 26 | // github specifics 27 | github_username: null, 28 | github_repo: null, 29 | 30 | // initialize function 31 | run: initialize 32 | }; 33 | 34 | function initialize() { 35 | // initialize sidebar and buttons 36 | if (ditto.sidebar) { 37 | init_sidebar_section(); 38 | } 39 | 40 | if (ditto.back_to_top_button) { 41 | init_back_to_top_button(); 42 | } 43 | 44 | if (ditto.edit_button) { 45 | init_edit_button(); 46 | } 47 | 48 | // intialize highligh.js 49 | if (ditto.highlight_code) { 50 | hljs.initHighlightingOnLoad(); 51 | } 52 | 53 | // page router 54 | router(); 55 | $(window).on('hashchange', router); 56 | } 57 | 58 | function init_sidebar_section() { 59 | $.get(ditto.sidebar_file, function(data) { 60 | ditto.sidebar_id.html(marked(data)); 61 | 62 | if (ditto.searchbar) { 63 | init_searchbar(); 64 | } 65 | 66 | }, "text").fail(function() { 67 | alert("Opps! can't find the sidebar file to display!"); 68 | }); 69 | 70 | } 71 | 72 | function init_back_to_top_button() { 73 | ditto.back_to_top_id.show(); 74 | ditto.back_to_top_id.on("click", function() { 75 | $("body, html").animate({ 76 | scrollTop: 0 77 | }, 200); 78 | }); 79 | } 80 | 81 | function init_edit_button() { 82 | if (ditto.base_url === null) { 83 | alert("Error! You didn't set 'base_url' when calling ditto.run()!"); 84 | 85 | } else { 86 | ditto.edit_id.show(); 87 | ditto.edit_id.on("click", function() { 88 | var hash = location.hash.replace("#", "/"); 89 | 90 | if (hash === "") { 91 | hash = "/" + ditto.index.replace(".md", ""); 92 | } 93 | 94 | window.open(ditto.base_url + hash + ".md"); 95 | // open is better than redirecting, as the previous page history 96 | // with redirect is a bit messed up 97 | }); 98 | } 99 | } 100 | 101 | function init_searchbar() { 102 | var sidebar = ditto.sidebar_id.html(); 103 | var match = "[ditto:searchbar]"; 104 | 105 | // html input searchbar 106 | var search = ""; 109 | 110 | // replace match code with a real html input search bar 111 | sidebar = sidebar.replace(match, search); 112 | ditto.sidebar_id.html(sidebar); 113 | 114 | // add search listener 115 | $("input[name=" + ditto.search_name.selector + "]").keydown(searchbar_listener); 116 | } 117 | 118 | function build_text_matches_html(fragments) { 119 | var html = ""; 120 | var class_name = ditto.fragments_class.replace(".", ""); 121 | 122 | html += "
    "; 123 | for (var i = 0; i < fragments.length; i++) { 124 | var fragment = fragments[i].fragment.replace("/[\uE000-\uF8FF]/g", ""); 125 | html += "
  • "; 126 | html += "
     ";
    127 |       fragment = $("#hide").text(fragment).html();
    128 |       html += fragment;
    129 |       html += " 
  • "; 130 | } 131 | html += "
"; 132 | 133 | return html; 134 | } 135 | 136 | function build_result_matches_html(matches) { 137 | var html = ""; 138 | var class_name = ditto.search_results_class.replace(".", ""); 139 | 140 | html += "
    "; 141 | for (var i = 0; i < matches.length; i++) { 142 | var url = matches[i].path; 143 | 144 | if (url !== ditto.sidebar_file) { 145 | var hash = "#" + url.replace(".md", ""); 146 | var path = window.location.origin+ "/" + hash; 147 | 148 | // html += "
  • "; 149 | html += "
  • "; 153 | 154 | var match = build_text_matches_html(matches[i].text_matches); 155 | html += match; 156 | } 157 | 158 | } 159 | html += "
"; 160 | 161 | return html; 162 | } 163 | 164 | function display_search_results(data) { 165 | var results_html = "

Search Results

"; 166 | 167 | if (data.items.length) { 168 | hide_errors(); 169 | results_html += build_result_matches_html(data.items); 170 | } else { 171 | show_error("Opps.. Found no matches!"); 172 | } 173 | 174 | ditto.content_id.html(results_html); 175 | $(ditto.search_results_class + " .link").click(function(){ 176 | var destination = "#" + $(this).html().replace(".md", ""); 177 | location.hash = destination; 178 | }); 179 | } 180 | 181 | function github_search(query) { 182 | if (ditto.github_username && ditto.github_repo) { 183 | // build github search api url string 184 | var github_api = "https://api.github.com/"; 185 | var search = "search/code?q="; 186 | var github_repo = ditto.github_username + "/" + ditto.github_repo; 187 | var search_details = "+in:file+language:markdown+repo:"; 188 | 189 | var url = github_api + search + query + search_details + github_repo; 190 | var accept_header = "application/vnd.github.v3.text-match+json"; 191 | 192 | $.ajax(url, {headers: {Accept: accept_header}}).done(function(data) { 193 | display_search_results(data); 194 | }); 195 | } 196 | 197 | if (ditto.github_username == null && ditto.github_repo == null) { 198 | alert("You have not set ditto.github_username and ditto.github_repo!"); 199 | } else if (ditto.github_username == null) { 200 | alert("You have not set ditto.github_username!"); 201 | } else if (ditto.github_repo == null) { 202 | alert("You have not set ditto.github_repo!"); 203 | } 204 | } 205 | 206 | function searchbar_listener(event) { 207 | if (event.which === 13) { // when user presses ENTER in search bar 208 | var q = $("input[name=" + ditto.search_name.selector + "]").val(); 209 | if (q !== "") { 210 | location.hash = "#search=" + q; 211 | } else { 212 | alert("Error! Empty search query!"); 213 | } 214 | } 215 | } 216 | 217 | function replace_symbols(text) { 218 | // replace symbols with underscore 219 | return text.replace(/[&\/\\#,+=()$~%.'":*?<>{}\ \]\[]/g, "_"); 220 | } 221 | 222 | function li_create_linkage(li_tag, header_level) { 223 | // add custom id and class attributes 224 | html_safe_tag = replace_symbols(li_tag.text()); 225 | li_tag.attr("id", html_safe_tag); 226 | li_tag.attr("class", "link"); 227 | 228 | // add click listener - on click scroll to relevant header section 229 | $(ditto.content_id.selector + " li#" + li_tag.attr("id")).click(function() { 230 | // scroll to relevant section 231 | var header = $("h" + header_level + "." + li_tag.attr("id")); 232 | $('html, body').animate({ 233 | scrollTop: header.offset().top 234 | }, 200); 235 | 236 | // highlight the relevant section 237 | original_color = header.css("color"); 238 | header.animate({ color: "#ED1C24", }, 500, function() { 239 | // revert back to orig color 240 | $(this).animate({color: original_color}, 2500); 241 | }); 242 | }); 243 | } 244 | 245 | function create_page_anchors() { 246 | // create page anchors by matching li's to headers 247 | // if there is a match, create click listeners 248 | // and scroll to relevant sections 249 | 250 | // go through header level 2 and 3 251 | for (var i = 2; i <= 4; i++) { 252 | // parse all headers 253 | var headers = []; 254 | $(ditto.content_id.selector + ' h' + i).map(function() { 255 | headers.push($(this).text()); 256 | $(this).addClass(replace_symbols($(this).text())); 257 | }); 258 | 259 | // parse and set links between li and h2 260 | $(ditto.content_id.selector + ' ul li').map(function() { 261 | for (var j = 0; j < headers.length; j++) { 262 | if (headers[j] === $(this).text()) { 263 | li_create_linkage($(this), i); 264 | } 265 | } 266 | }); 267 | } 268 | } 269 | 270 | function normalize_paths() { 271 | // images 272 | ditto.content_id.find("img").map(function() { 273 | var src = $(this).attr("src").replace(/^\.\//, ""); 274 | if ($(this).attr("src").slice(0, 5) !== "http") { 275 | var url = location.hash.replace("#", ""); 276 | 277 | // split and extract base dir 278 | url = url.split("/"); 279 | var base_dir = url.slice(0, url.length - 1).join("/"); 280 | 281 | // normalize the path (i.e. make it absolute) 282 | if (base_dir) { 283 | $(this).attr("src", base_dir + "/" + src); 284 | } else { 285 | $(this).attr("src", src); 286 | } 287 | } 288 | }); 289 | 290 | } 291 | 292 | function show_error(err_msg) { 293 | ditto.error_id.html(err_msg); 294 | ditto.error_id.show(); 295 | } 296 | 297 | function hide_errors() { 298 | ditto.error_id.hide(); 299 | } 300 | 301 | function show_loading() { 302 | ditto.loading_id.show(); 303 | ditto.content_id.html(""); // clear content 304 | 305 | // infinite loop until clearInterval() is called on loading 306 | ditto.loading_interval = setInterval(function() { 307 | ditto.loading_id.fadeIn(1000).fadeOut(1000); 308 | }, 2000); 309 | 310 | } 311 | 312 | function stop_loading() { 313 | clearInterval(ditto.loading_interval); 314 | ditto.loading_id.hide(); 315 | } 316 | 317 | function escape_github_badges(data) { 318 | $("img").map(function() { 319 | var ignore_list = [ 320 | "travis-ci.org", 321 | "coveralls.io" 322 | ]; 323 | var src = $(this).attr("src"); 324 | 325 | var base_url = src.split("/"); 326 | var protocol = base_url[0]; 327 | var host = base_url[2]; 328 | 329 | if ($.inArray(host, ignore_list) >= 0) { 330 | $(this).attr("class", "github_badges"); 331 | } 332 | }); 333 | return data; 334 | } 335 | 336 | function page_getter() { 337 | window.scrollTo(0, 0); 338 | var path = location.hash.replace("#", "./"); 339 | 340 | // default page if hash is empty 341 | var current_page = location.pathname.split("/").pop(); 342 | if (current_page === "index.html") { 343 | path = location.pathname.replace("index.html", ditto.index); 344 | normalize_paths(); 345 | 346 | } else if (path === "") { 347 | path = window.location + ditto.index; 348 | normalize_paths(); 349 | 350 | } else { 351 | path = path + ".md"; 352 | 353 | } 354 | 355 | // otherwise get the markdown and render it 356 | show_loading(); 357 | $.get(path, function(data) { 358 | compile_into_dom(path, data, function() { 359 | // reset mathjax equation counter 360 | if (MathJax.Extension["Tex/AMSmath"]) { 361 | MathJax.Extension["TeX/AMSmath"].startNumber = 0; 362 | MathJax.Extension["TeX/AMSmath"].labels = {}; 363 | } 364 | 365 | // rerender mathjax 366 | var content = document.getElementById("content"); 367 | MathJax.Hub.Queue(["Typeset", MathJax.Hub, content]); 368 | }); 369 | }).fail(function() { 370 | show_error("Opps! ... File not found!"); 371 | stop_loading(); 372 | }); 373 | } 374 | 375 | function escape_html(string) { 376 | return string 377 | .replace(/\\/g, "\") 378 | .replace(/\_/g, "_"); 379 | } 380 | 381 | function unescape_html(string) { 382 | return string 383 | .replace(/&#92;/g, "\\") 384 | .replace(/&#95;/g, "_"); 385 | } 386 | 387 | function compile_into_dom(path, data, cb) { 388 | hide_errors(); 389 | 390 | data = marked(escape_html(data)); 391 | data = unescape_html(data); 392 | ditto.content_id.html(data); 393 | 394 | stop_loading(); 395 | escape_github_badges(data); 396 | 397 | normalize_paths(); 398 | create_page_anchors(); 399 | 400 | if (ditto.highlight_code) { 401 | $('pre code').each(function(i, block) { 402 | hljs.highlightBlock(block); 403 | }); 404 | } 405 | 406 | if (cb) { 407 | cb(data); 408 | } 409 | } 410 | 411 | function router() { 412 | var hash = location.hash; 413 | 414 | if (hash.slice(1, 7) !== "search") { 415 | page_getter(); 416 | 417 | } else { 418 | if (ditto.searchbar) { 419 | github_search(hash.replace("#search=", "")); 420 | } 421 | 422 | } 423 | } 424 | 425 | window.ditto = ditto; 426 | }); 427 | -------------------------------------------------------------------------------- /ver/0.14/github.css: -------------------------------------------------------------------------------- 1 | /* 2 | github.com style (c) Vasily Polovnyov 3 | */ 4 | 5 | .hljs { 6 | display: block; 7 | overflow-x: auto; 8 | padding: 0.5em; 9 | color: #333; 10 | background: #f8f8f8; 11 | -webkit-text-size-adjust: none; 12 | } 13 | 14 | .hljs-comment, 15 | .diff .hljs-header { 16 | color: #998; 17 | font-style: italic; 18 | } 19 | 20 | .hljs-keyword, 21 | .css .rule .hljs-keyword, 22 | .hljs-winutils, 23 | .nginx .hljs-title, 24 | .hljs-subst, 25 | .hljs-request, 26 | .hljs-status { 27 | color: #333; 28 | font-weight: bold; 29 | } 30 | 31 | .hljs-number, 32 | .hljs-hexcolor, 33 | .ruby .hljs-constant { 34 | color: #008080; 35 | } 36 | 37 | .hljs-string, 38 | .hljs-tag .hljs-value, 39 | .hljs-doctag, 40 | .tex .hljs-formula { 41 | color: #d14; 42 | } 43 | 44 | .hljs-title, 45 | .hljs-id, 46 | .scss .hljs-preprocessor { 47 | color: #900; 48 | font-weight: bold; 49 | } 50 | 51 | .hljs-list .hljs-keyword, 52 | .hljs-subst { 53 | font-weight: normal; 54 | } 55 | 56 | .hljs-class .hljs-title, 57 | .hljs-type, 58 | .vhdl .hljs-literal, 59 | .tex .hljs-command { 60 | color: #458; 61 | font-weight: bold; 62 | } 63 | 64 | .hljs-tag, 65 | .hljs-tag .hljs-title, 66 | .hljs-rule .hljs-property, 67 | .django .hljs-tag .hljs-keyword { 68 | color: #000080; 69 | font-weight: normal; 70 | } 71 | 72 | .hljs-attribute, 73 | .hljs-variable, 74 | .lisp .hljs-body, 75 | .hljs-name { 76 | color: #008080; 77 | } 78 | 79 | .hljs-regexp { 80 | color: #009926; 81 | } 82 | 83 | .hljs-symbol, 84 | .ruby .hljs-symbol .hljs-string, 85 | .lisp .hljs-keyword, 86 | .clojure .hljs-keyword, 87 | .scheme .hljs-keyword, 88 | .tex .hljs-special, 89 | .hljs-prompt { 90 | color: #990073; 91 | } 92 | 93 | .hljs-built_in { 94 | color: #0086b3; 95 | } 96 | 97 | .hljs-preprocessor, 98 | .hljs-pragma, 99 | .hljs-pi, 100 | .hljs-doctype, 101 | .hljs-shebang, 102 | .hljs-cdata { 103 | color: #999; 104 | font-weight: bold; 105 | } 106 | 107 | .hljs-deletion { 108 | background: #fdd; 109 | } 110 | 111 | .hljs-addition { 112 | background: #dfd; 113 | } 114 | 115 | .diff .hljs-change { 116 | background: #0086b3; 117 | } 118 | 119 | .hljs-chunk { 120 | color: #aaa; 121 | } 122 | -------------------------------------------------------------------------------- /ver/0.14/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TITLE 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | 48 | 49 |
top
50 |
edit
51 |
Loading ...
52 |
53 | 54 | 55 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /ver/0.14/sidebar.md: -------------------------------------------------------------------------------- 1 | # [Project]() 2 | version 0.1 3 | 4 | - [Github Repository](http://github.com//) 5 | 6 | [ditto:searchbar] 7 | 8 | ## Header 2 9 | - [Page1](#docs/page1) 10 | - [Page2](#docs/page2) 11 | -------------------------------------------------------------------------------- /ver/0.15/ditto.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #333; 3 | margin: 0; 4 | padding: 0; 5 | 6 | font-family: Verdana, Arial; 7 | font-size: 0.8em; 8 | } 9 | 10 | #sidebar { 11 | position: fixed; 12 | width: 220px; 13 | height: 100%; 14 | 15 | overflow-y: scroll; 16 | overflow: -moz-scrollbars-vertical; 17 | 18 | margin-right: 20px; 19 | margin-top: 0; 20 | padding-left: 25px; 21 | padding-top: 0; 22 | 23 | box-shadow: 0 0 40px #CCC; 24 | -webkit-box-shadow: 0 0 40px #CCC; 25 | -moz-box-shadow: 0 0 40px #CCC; 26 | border-right: 1px solid #BBB; 27 | } 28 | 29 | #sidebar h1 { 30 | font-size: 25px; 31 | margin-bottom: 0px; 32 | padding-bottom: 0px; 33 | } 34 | 35 | #sidebar h1 a:link, #sidebar h1 a:visited { 36 | color: #333; 37 | } 38 | 39 | #sidebar h2 { 40 | font-size: 15px; 41 | } 42 | 43 | #sidebar h5 { 44 | margin-top: 20px; 45 | margin-bottom: 0; 46 | } 47 | 48 | #sidebar a:visited, #sidebar a:link { 49 | color: #4682BE; 50 | text-decoration: none; 51 | } 52 | 53 | #sidebar ul { 54 | list-style-type: none; 55 | margin: 0; 56 | padding-left: 10px; 57 | padding-top: 0; 58 | } 59 | 60 | #sidebar ul li:before { /* a hack to have dashes as a list style */ 61 | content: "-"; 62 | position: relative; 63 | left: -5px; 64 | } 65 | 66 | #sidebar ul li { 67 | margin-top: 0; 68 | margin-bottom: 2px; 69 | margin-left: 10px; 70 | padding: 0; 71 | 72 | text-indent: -5px; /* to compensate for the padding for the dash */ 73 | font-size: 12px; 74 | } 75 | 76 | #content { 77 | width: 580px; 78 | 79 | margin-left: 300px; 80 | padding-top: 10px; 81 | padding-bottom: 150px; 82 | 83 | text-align: justify; 84 | font-size: 1.0em; 85 | } 86 | 87 | #content pre { 88 | margin-left: auto; 89 | margin-right: auto; 90 | 91 | padding-top: 10px; 92 | padding-bottom: 10px; 93 | padding-left: 13px; 94 | padding-right: 13px; 95 | 96 | color: #FFF; 97 | white-space: pre-wrap; /* css-3 */ 98 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 99 | white-space: -pre-wrap; /* Opera 4-6 */ 100 | white-space: -o-pre-wrap; /* Opera 7 */ 101 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 102 | 103 | background: #F7FAFB; 104 | border-radius: 5px; 105 | } 106 | 107 | #content pre code { 108 | padding-top: 0px; 109 | padding-bottom: 0px; 110 | padding-left: 0; 111 | font-size: 1.1em; 112 | border: none; 113 | } 114 | 115 | #content code { 116 | padding-left: 5px; 117 | padding-right: 5px; 118 | padding-top: 1px; 119 | padding-bottom: 1px; 120 | 121 | color: #555; 122 | font-size: 10px; 123 | font-weight: normal; 124 | font-family: Consolas, monospace; 125 | 126 | background: #F7FAFB; 127 | border: 1px solid #E3EDF3; 128 | border-radius: 2px; 129 | } 130 | 131 | #content h2 { 132 | margin-top: 50px; 133 | margin-bottom: 0px; 134 | 135 | padding-top: 20px; 136 | padding-bottom: 0px; 137 | 138 | font-size: 18px; 139 | text-align: left; 140 | 141 | border-top: 2px solid #666; 142 | } 143 | 144 | #content h3 { 145 | margin-top: 50px; 146 | margin-bottom: 0px; 147 | 148 | padding-top: 20px; 149 | padding-bottom: 0px; 150 | 151 | text-align: left; 152 | border-top: 1px dotted #777; 153 | } 154 | 155 | #content hr { 156 | border: 0; 157 | height: 0; 158 | border-top: 1px solid rgba(0, 0, 0, 0.1); 159 | border-bottom: 1px solid rgba(255, 255, 255, 0.3); 160 | } 161 | 162 | #content img { 163 | max-width: 90%; 164 | display: block; 165 | 166 | margin-left: auto; 167 | margin-right: auto; 168 | margin-top: 40px; 169 | margin-bottom: 40px; 170 | 171 | border-radius: 5px; 172 | } 173 | 174 | #content ul { 175 | display: block; 176 | list-style-type: none; 177 | } 178 | 179 | #content ul li:before { /* a hack to have dashes as a list style */ 180 | content: "-"; 181 | position: relative; 182 | left: -5px; 183 | } 184 | 185 | #content ul li { 186 | text-indent: -5px; /* to compensate for the padding for the dash */ 187 | font-size: 13px; 188 | } 189 | 190 | #content ul li.link { 191 | color: #4682BE; 192 | text-decoration: none; 193 | font-size: 13px; 194 | font-weight: bold; 195 | cursor: pointer; 196 | } 197 | 198 | #content a:link, #content a:visited { 199 | color: #4682BE; 200 | text-decoration: none; 201 | } 202 | 203 | #back_to_top { 204 | display: none; 205 | position: fixed; 206 | 207 | height: 20px; 208 | line-height: 20px; 209 | width: 50px; 210 | top: 20px; 211 | 212 | margin-left: 890px; 213 | 214 | color: #FFF; 215 | vertical-align: middle; 216 | text-align: center; 217 | font-size: 10px; 218 | 219 | border-radius: 5px; 220 | background-color: #AAA; 221 | } 222 | 223 | #back_to_top:hover { 224 | background-color: #444; 225 | cursor: pointer; 226 | } 227 | 228 | #edit { 229 | display: none; 230 | position: fixed; 231 | 232 | height: 20px; 233 | line-height: 20px; 234 | width: 50px; 235 | top: 50px; 236 | 237 | margin-left: 890px; 238 | 239 | color: #FFF; 240 | vertical-align: middle; 241 | text-align: center; 242 | font-size: 10px; 243 | 244 | border-radius: 5px; 245 | background-color: #AAA; 246 | } 247 | 248 | #edit:hover { 249 | background-color: #444; 250 | cursor: pointer; 251 | } 252 | 253 | #loading, #error { 254 | display: none; 255 | position: fixed; 256 | 257 | height: 17px; 258 | top: 45%; 259 | 260 | margin-left: 560px; 261 | 262 | font-size: 14px; 263 | font-weight: bold; 264 | } 265 | 266 | input[type=search] { 267 | display: block; 268 | width: 180px; 269 | 270 | text-align: left; 271 | } 272 | 273 | .search_results{ 274 | 275 | 276 | } 277 | 278 | .fragments { 279 | margin: 0; 280 | padding: 10px; 281 | /* border: 1px solid #777; */ 282 | /* border-radius: 5px; */ 283 | } 284 | 285 | .fragment { 286 | padding-left: 10px; 287 | padding-right: 10px; 288 | padding-top: 0px; 289 | padding-bottom: 0px; 290 | 291 | /* border: 1px solid #777; */ 292 | /* border-radius: 5px; */ 293 | } 294 | 295 | .search_results .link { 296 | margin-top: 35px; 297 | } 298 | 299 | #content ul li { 300 | text-align: left; 301 | } 302 | 303 | #content ul .fragments li:before { 304 | content: ""; 305 | position: relative; 306 | left: 0px; 307 | } 308 | 309 | #content ul li.fragment:before { 310 | content: ""; 311 | margin: 0; 312 | padding: 0; 313 | } 314 | 315 | #content img.github_badges { 316 | display: inline; 317 | margin-top: 0; 318 | margin-bottom: 0; 319 | } 320 | 321 | #content .youtube_video { 322 | margin-top: 20px; 323 | } 324 | 325 | #hide { 326 | display: none; 327 | } 328 | -------------------------------------------------------------------------------- /ver/0.15/ditto.js: -------------------------------------------------------------------------------- 1 | $(function($) { 2 | 3 | var ditto = { 4 | content_id: $("#content"), 5 | sidebar_id: $("#sidebar"), 6 | 7 | edit_id: $("#edit"), 8 | back_to_top_id: $("#back_to_top"), 9 | 10 | loading_id: $("#loading"), 11 | error_id: $("#error"), 12 | 13 | search_name: $("#search"), 14 | search_results_class: ".search_results", 15 | fragments_class: ".fragments", 16 | fragment_class: ".fragment", 17 | 18 | highlight_code: true, 19 | 20 | // display elements 21 | sidebar: true, 22 | edit_button: true, 23 | back_to_top_button: true, 24 | searchbar: true, 25 | 26 | // github specifics 27 | github_username: null, 28 | github_repo: null, 29 | 30 | // initialize function 31 | run: initialize 32 | }; 33 | 34 | function initialize() { 35 | // initialize sidebar and buttons 36 | if (ditto.sidebar) { 37 | init_sidebar_section(); 38 | } 39 | 40 | if (ditto.back_to_top_button) { 41 | init_back_to_top_button(); 42 | } 43 | 44 | if (ditto.edit_button) { 45 | init_edit_button(); 46 | } 47 | 48 | // intialize highligh.js 49 | if (ditto.highlight_code) { 50 | hljs.initHighlightingOnLoad(); 51 | } 52 | 53 | // page router 54 | router(); 55 | $(window).on('hashchange', router); 56 | } 57 | 58 | function init_sidebar_section() { 59 | $.get(ditto.sidebar_file, function(data) { 60 | ditto.sidebar_id.html(marked(data)); 61 | 62 | if (ditto.searchbar) { 63 | init_searchbar(); 64 | } 65 | 66 | }, "text").fail(function() { 67 | alert("Opps! can't find the sidebar file to display!"); 68 | }); 69 | 70 | } 71 | 72 | function init_back_to_top_button() { 73 | ditto.back_to_top_id.show(); 74 | ditto.back_to_top_id.on("click", function() { 75 | $("body, html").animate({ 76 | scrollTop: 0 77 | }, 200); 78 | }); 79 | } 80 | 81 | function init_edit_button() { 82 | if (ditto.base_url === null) { 83 | alert("Error! You didn't set 'base_url' when calling ditto.run()!"); 84 | 85 | } else { 86 | ditto.edit_id.show(); 87 | ditto.edit_id.on("click", function() { 88 | var hash = location.hash.replace("#", "/"); 89 | 90 | if (hash === "") { 91 | hash = "/" + ditto.index.replace(".md", ""); 92 | } 93 | 94 | window.open(ditto.base_url + hash + ".md"); 95 | // open is better than redirecting, as the previous page history 96 | // with redirect is a bit messed up 97 | }); 98 | } 99 | } 100 | 101 | function init_searchbar() { 102 | var sidebar = ditto.sidebar_id.html(); 103 | var match = "[ditto:searchbar]"; 104 | 105 | // html input searchbar 106 | var search = ""; 109 | 110 | // replace match code with a real html input search bar 111 | sidebar = sidebar.replace(match, search); 112 | ditto.sidebar_id.html(sidebar); 113 | 114 | // add search listener 115 | $("input[name=" + ditto.search_name.selector + "]").keydown(searchbar_listener); 116 | } 117 | 118 | function build_text_matches_html(fragments) { 119 | var html = ""; 120 | var class_name = ditto.fragments_class.replace(".", ""); 121 | 122 | html += "
    "; 123 | for (var i = 0; i < fragments.length; i++) { 124 | var fragment = fragments[i].fragment.replace("/[\uE000-\uF8FF]/g", ""); 125 | html += "
  • "; 126 | html += "
     ";
    127 |       fragment = $("#hide").text(fragment).html();
    128 |       html += fragment;
    129 |       html += " 
  • "; 130 | } 131 | html += "
"; 132 | 133 | return html; 134 | } 135 | 136 | function build_result_matches_html(matches) { 137 | var html = ""; 138 | var class_name = ditto.search_results_class.replace(".", ""); 139 | 140 | html += "
    "; 141 | for (var i = 0; i < matches.length; i++) { 142 | var url = matches[i].path; 143 | 144 | if (url !== ditto.sidebar_file) { 145 | var hash = "#" + url.replace(".md", ""); 146 | var path = window.location.origin+ "/" + hash; 147 | 148 | // html += "
  • "; 149 | html += "
  • "; 153 | 154 | var match = build_text_matches_html(matches[i].text_matches); 155 | html += match; 156 | } 157 | 158 | } 159 | html += "
"; 160 | 161 | return html; 162 | } 163 | 164 | function display_search_results(data) { 165 | var results_html = "

Search Results

"; 166 | 167 | if (data.items.length) { 168 | hide_errors(); 169 | results_html += build_result_matches_html(data.items); 170 | } else { 171 | show_error("Opps.. Found no matches!"); 172 | } 173 | 174 | ditto.content_id.html(results_html); 175 | $(ditto.search_results_class + " .link").click(function(){ 176 | var destination = "#" + $(this).html().replace(".md", ""); 177 | location.hash = destination; 178 | }); 179 | } 180 | 181 | function github_search(query) { 182 | if (ditto.github_username && ditto.github_repo) { 183 | // build github search api url string 184 | var github_api = "https://api.github.com/"; 185 | var search = "search/code?q="; 186 | var github_repo = ditto.github_username + "/" + ditto.github_repo; 187 | var search_details = "+in:file+language:markdown+repo:"; 188 | 189 | var url = github_api + search + query + search_details + github_repo; 190 | var accept_header = "application/vnd.github.v3.text-match+json"; 191 | 192 | $.ajax(url, {headers: {Accept: accept_header}}).done(function(data) { 193 | display_search_results(data); 194 | }); 195 | } 196 | 197 | if (ditto.github_username == null && ditto.github_repo == null) { 198 | alert("You have not set ditto.github_username and ditto.github_repo!"); 199 | } else if (ditto.github_username == null) { 200 | alert("You have not set ditto.github_username!"); 201 | } else if (ditto.github_repo == null) { 202 | alert("You have not set ditto.github_repo!"); 203 | } 204 | } 205 | 206 | function searchbar_listener(event) { 207 | if (event.which === 13) { // when user presses ENTER in search bar 208 | var q = $("input[name=" + ditto.search_name.selector + "]").val(); 209 | if (q !== "") { 210 | location.hash = "#search=" + q; 211 | } else { 212 | alert("Error! Empty search query!"); 213 | } 214 | } 215 | } 216 | 217 | function replace_symbols(text) { 218 | // replace symbols with underscore 219 | return text.replace(/[&\/\\#,+=()$~%.'":*?<>{}\ \]\[]/g, "_"); 220 | } 221 | 222 | function li_create_linkage(li_tag, header_level) { 223 | // add custom id and class attributes 224 | html_safe_tag = replace_symbols(li_tag.text()); 225 | li_tag.attr("id", html_safe_tag); 226 | li_tag.attr("class", "link"); 227 | 228 | // add click listener - on click scroll to relevant header section 229 | $(ditto.content_id.selector + " li#" + li_tag.attr("id")).click(function() { 230 | // scroll to relevant section 231 | var header = $("h" + header_level + "." + li_tag.attr("id")); 232 | $('html, body').animate({ 233 | scrollTop: header.offset().top 234 | }, 200); 235 | 236 | // highlight the relevant section 237 | original_color = header.css("color"); 238 | header.animate({ color: "#ED1C24", }, 500, function() { 239 | // revert back to orig color 240 | $(this).animate({color: original_color}, 2500); 241 | }); 242 | }); 243 | } 244 | 245 | function create_page_anchors() { 246 | // create page anchors by matching li's to headers 247 | // if there is a match, create click listeners 248 | // and scroll to relevant sections 249 | 250 | // go through header level 2 and 3 251 | for (var i = 2; i <= 4; i++) { 252 | // parse all headers 253 | var headers = []; 254 | $(ditto.content_id.selector + ' h' + i).map(function() { 255 | headers.push($(this).text()); 256 | $(this).addClass(replace_symbols($(this).text())); 257 | }); 258 | 259 | // parse and set links between li and h2 260 | $(ditto.content_id.selector + ' ul li').map(function() { 261 | for (var j = 0; j < headers.length; j++) { 262 | if (headers[j] === $(this).text()) { 263 | li_create_linkage($(this), i); 264 | } 265 | } 266 | }); 267 | } 268 | } 269 | 270 | function youtube_url_extract(data) { 271 | var yt_regex = /(https?\:\/\/)?(www\.youtube\.com|youtu\.?be)\/.+/g; 272 | var yt_url = String(data.match(yt_regex)); 273 | yt_url = yt_url.replace(/]/g, ""); 274 | return yt_url; 275 | } 276 | 277 | function youtube_url_to_embed(data) { 278 | return data = data.replace(/watch\?v\=/g, "embed/"); 279 | } 280 | 281 | function create_youtube_embeds(data) { 282 | // replaces [ditto:youtube:] 283 | // with a proper youtube embed iframe 284 | var token_regex = /\[ditto\:youtube:(https?\:\/\/)?(www\.youtube\.com|youtu\.?be)\/.+\]/g; 285 | var yt_url = youtube_url_extract(data); 286 | var yt_embed_url = youtube_url_to_embed(yt_url); 287 | 288 | // youtube embed html 289 | var embed_html = `
290 |
291 | 298 |
299 |
`; 300 | embed_html = embed_html.replace("", yt_embed_url); 301 | 302 | // replace match code with youtube video 303 | data = data.replace(token_regex, embed_html); 304 | return data; 305 | } 306 | 307 | function normalize_paths() { 308 | // images 309 | ditto.content_id.find("img").map(function() { 310 | var src = $(this).attr("src").replace(/^\.\//, ""); 311 | if ($(this).attr("src").slice(0, 5) !== "http") { 312 | var url = location.hash.replace("#", ""); 313 | 314 | // split and extract base dir 315 | url = url.split("/"); 316 | var base_dir = url.slice(0, url.length - 1).join("/"); 317 | 318 | // normalize the path (i.e. make it absolute) 319 | if (base_dir) { 320 | $(this).attr("src", base_dir + "/" + src); 321 | } else { 322 | $(this).attr("src", src); 323 | } 324 | } 325 | }); 326 | 327 | } 328 | 329 | function show_error(err_msg) { 330 | ditto.error_id.html(err_msg); 331 | ditto.error_id.show(); 332 | } 333 | 334 | function hide_errors() { 335 | ditto.error_id.hide(); 336 | } 337 | 338 | function show_loading() { 339 | ditto.loading_id.show(); 340 | ditto.content_id.html(""); // clear content 341 | 342 | // infinite loop until clearInterval() is called on loading 343 | ditto.loading_interval = setInterval(function() { 344 | ditto.loading_id.fadeIn(1000).fadeOut(1000); 345 | }, 2000); 346 | 347 | } 348 | 349 | function stop_loading() { 350 | clearInterval(ditto.loading_interval); 351 | ditto.loading_id.hide(); 352 | } 353 | 354 | function escape_github_badges(data) { 355 | $("img").map(function() { 356 | var ignore_list = [ 357 | "travis-ci.com", 358 | "travis-ci.org", 359 | "coveralls.io" 360 | ]; 361 | var src = $(this).attr("src"); 362 | 363 | var base_url = src.split("/"); 364 | var protocol = base_url[0]; 365 | var host = base_url[2]; 366 | 367 | if ($.inArray(host, ignore_list) >= 0) { 368 | $(this).attr("class", "github_badges"); 369 | } 370 | }); 371 | return data; 372 | } 373 | 374 | function page_getter() { 375 | window.scrollTo(0, 0); 376 | var path = location.hash.replace("#", "./"); 377 | 378 | // default page if hash is empty 379 | var current_page = location.pathname.split("/").pop(); 380 | if (current_page === "index.html") { 381 | path = location.pathname.replace("index.html", ditto.index); 382 | normalize_paths(); 383 | 384 | } else if (path === "") { 385 | path = window.location + ditto.index; 386 | normalize_paths(); 387 | 388 | } else { 389 | path = path + ".md"; 390 | 391 | } 392 | 393 | // otherwise get the markdown and render it 394 | show_loading(); 395 | $.get(path, function(data) { 396 | compile_into_dom(path, data, function() { 397 | // rerender mathjax and reset mathjax equation counter 398 | if (MathJax) { 399 | MathJax.Extension["TeX/AMSmath"].startNumber = 0; 400 | MathJax.Extension["TeX/AMSmath"].labels = {}; 401 | 402 | var content = document.getElementById("content"); 403 | MathJax.Hub.Queue(["Typeset", MathJax.Hub, content]); 404 | } 405 | }); 406 | }).fail(function() { 407 | show_error("Opps! ... File not found!"); 408 | stop_loading(); 409 | }); 410 | } 411 | 412 | function escape_html(string) { 413 | return string 414 | .replace(/\\/g, "\") 415 | .replace(/\_/g, "_"); 416 | } 417 | 418 | function unescape_html(string) { 419 | return string 420 | .replace(/&#92;/g, "\\") 421 | .replace(/&#95;/g, "_"); 422 | } 423 | 424 | function compile_into_dom(path, data, cb) { 425 | hide_errors(); 426 | 427 | data = create_youtube_embeds(data); 428 | data = marked(escape_html(data)); 429 | data = unescape_html(data); 430 | ditto.content_id.html(data); 431 | 432 | stop_loading(); 433 | escape_github_badges(data); 434 | 435 | normalize_paths(); 436 | create_page_anchors(); 437 | 438 | if (ditto.highlight_code) { 439 | $('pre code').each(function(i, block) { 440 | hljs.highlightBlock(block); 441 | }); 442 | } 443 | 444 | if (cb) { 445 | cb(data); 446 | } 447 | } 448 | 449 | function router() { 450 | var hash = location.hash; 451 | 452 | if (hash.slice(1, 7) !== "search") { 453 | page_getter(); 454 | 455 | } else { 456 | if (ditto.searchbar) { 457 | github_search(hash.replace("#search=", "")); 458 | } 459 | 460 | } 461 | } 462 | 463 | window.ditto = ditto; 464 | }); 465 | -------------------------------------------------------------------------------- /ver/0.15/github.css: -------------------------------------------------------------------------------- 1 | /* 2 | github.com style (c) Vasily Polovnyov 3 | */ 4 | 5 | .hljs { 6 | display: block; 7 | overflow-x: auto; 8 | padding: 0.5em; 9 | color: #333; 10 | background: #f8f8f8; 11 | -webkit-text-size-adjust: none; 12 | } 13 | 14 | .hljs-comment, 15 | .diff .hljs-header { 16 | color: #998; 17 | font-style: italic; 18 | } 19 | 20 | .hljs-keyword, 21 | .css .rule .hljs-keyword, 22 | .hljs-winutils, 23 | .nginx .hljs-title, 24 | .hljs-subst, 25 | .hljs-request, 26 | .hljs-status { 27 | color: #333; 28 | font-weight: bold; 29 | } 30 | 31 | .hljs-number, 32 | .hljs-hexcolor, 33 | .ruby .hljs-constant { 34 | color: #008080; 35 | } 36 | 37 | .hljs-string, 38 | .hljs-tag .hljs-value, 39 | .hljs-doctag, 40 | .tex .hljs-formula { 41 | color: #d14; 42 | } 43 | 44 | .hljs-title, 45 | .hljs-id, 46 | .scss .hljs-preprocessor { 47 | color: #900; 48 | font-weight: bold; 49 | } 50 | 51 | .hljs-list .hljs-keyword, 52 | .hljs-subst { 53 | font-weight: normal; 54 | } 55 | 56 | .hljs-class .hljs-title, 57 | .hljs-type, 58 | .vhdl .hljs-literal, 59 | .tex .hljs-command { 60 | color: #458; 61 | font-weight: bold; 62 | } 63 | 64 | .hljs-tag, 65 | .hljs-tag .hljs-title, 66 | .hljs-rule .hljs-property, 67 | .django .hljs-tag .hljs-keyword { 68 | color: #000080; 69 | font-weight: normal; 70 | } 71 | 72 | .hljs-attribute, 73 | .hljs-variable, 74 | .lisp .hljs-body, 75 | .hljs-name { 76 | color: #008080; 77 | } 78 | 79 | .hljs-regexp { 80 | color: #009926; 81 | } 82 | 83 | .hljs-symbol, 84 | .ruby .hljs-symbol .hljs-string, 85 | .lisp .hljs-keyword, 86 | .clojure .hljs-keyword, 87 | .scheme .hljs-keyword, 88 | .tex .hljs-special, 89 | .hljs-prompt { 90 | color: #990073; 91 | } 92 | 93 | .hljs-built_in { 94 | color: #0086b3; 95 | } 96 | 97 | .hljs-preprocessor, 98 | .hljs-pragma, 99 | .hljs-pi, 100 | .hljs-doctype, 101 | .hljs-shebang, 102 | .hljs-cdata { 103 | color: #999; 104 | font-weight: bold; 105 | } 106 | 107 | .hljs-deletion { 108 | background: #fdd; 109 | } 110 | 111 | .hljs-addition { 112 | background: #dfd; 113 | } 114 | 115 | .diff .hljs-change { 116 | background: #0086b3; 117 | } 118 | 119 | .hljs-chunk { 120 | color: #aaa; 121 | } 122 | -------------------------------------------------------------------------------- /ver/0.15/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TITLE 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 33 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 |
46 | 47 | 48 |
top
49 |
edit
50 |
Loading ...
51 |
52 | 53 | 54 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /ver/0.15/sidebar.md: -------------------------------------------------------------------------------- 1 | # [Project]() 2 | version 0.1 3 | 4 | - [Github Repository](http://github.com//) 5 | 6 | [ditto:searchbar] 7 | 8 | ## Header 2 9 | - [Page1](#docs/page1) 10 | - [Page2](#docs/page2) 11 | -------------------------------------------------------------------------------- /ver/latest/ditto.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #333; 3 | margin: 0; 4 | padding: 0; 5 | 6 | font-family: Verdana, Arial; 7 | font-size: 0.8em; 8 | } 9 | 10 | #sidebar { 11 | position: fixed; 12 | width: 220px; 13 | height: 100%; 14 | 15 | overflow-y: scroll; 16 | overflow: -moz-scrollbars-vertical; 17 | 18 | margin-right: 20px; 19 | margin-top: 0; 20 | padding-left: 25px; 21 | padding-top: 0; 22 | 23 | box-shadow: 0 0 40px #CCC; 24 | -webkit-box-shadow: 0 0 40px #CCC; 25 | -moz-box-shadow: 0 0 40px #CCC; 26 | border-right: 1px solid #BBB; 27 | } 28 | 29 | #sidebar h1 { 30 | font-size: 25px; 31 | margin-bottom: 0px; 32 | padding-bottom: 0px; 33 | } 34 | 35 | #sidebar h1 a:link, #sidebar h1 a:visited { 36 | color: #333; 37 | } 38 | 39 | #sidebar h2 { 40 | font-size: 15px; 41 | } 42 | 43 | #sidebar h5 { 44 | margin-top: 20px; 45 | margin-bottom: 0; 46 | } 47 | 48 | #sidebar a:visited, #sidebar a:link { 49 | color: #4682BE; 50 | text-decoration: none; 51 | } 52 | 53 | #sidebar ul { 54 | list-style-type: none; 55 | margin: 0; 56 | padding-left: 10px; 57 | padding-top: 0; 58 | } 59 | 60 | #sidebar ul li:before { /* a hack to have dashes as a list style */ 61 | content: "-"; 62 | position: relative; 63 | left: -5px; 64 | } 65 | 66 | #sidebar ul li { 67 | margin-top: 0; 68 | margin-bottom: 2px; 69 | margin-left: 10px; 70 | padding: 0; 71 | 72 | text-indent: -5px; /* to compensate for the padding for the dash */ 73 | font-size: 12px; 74 | } 75 | 76 | #content { 77 | width: 580px; 78 | 79 | margin-left: 300px; 80 | padding-top: 10px; 81 | padding-bottom: 150px; 82 | 83 | text-align: justify; 84 | font-size: 1.0em; 85 | } 86 | 87 | #content pre { 88 | margin-left: auto; 89 | margin-right: auto; 90 | 91 | padding-top: 10px; 92 | padding-bottom: 10px; 93 | padding-left: 13px; 94 | padding-right: 13px; 95 | 96 | color: #FFF; 97 | white-space: pre-wrap; /* css-3 */ 98 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 99 | white-space: -pre-wrap; /* Opera 4-6 */ 100 | white-space: -o-pre-wrap; /* Opera 7 */ 101 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 102 | 103 | background: #F7FAFB; 104 | border-radius: 5px; 105 | } 106 | 107 | #content pre code { 108 | padding-top: 0px; 109 | padding-bottom: 0px; 110 | padding-left: 0; 111 | font-size: 1.1em; 112 | border: none; 113 | } 114 | 115 | #content code { 116 | padding-left: 5px; 117 | padding-right: 5px; 118 | padding-top: 1px; 119 | padding-bottom: 1px; 120 | 121 | color: #555; 122 | font-size: 10px; 123 | font-weight: normal; 124 | font-family: Consolas, monospace; 125 | 126 | background: #F7FAFB; 127 | border: 1px solid #E3EDF3; 128 | border-radius: 2px; 129 | } 130 | 131 | #content h2 { 132 | margin-top: 50px; 133 | margin-bottom: 0px; 134 | 135 | padding-top: 20px; 136 | padding-bottom: 0px; 137 | 138 | font-size: 18px; 139 | text-align: left; 140 | 141 | border-top: 2px solid #666; 142 | } 143 | 144 | #content h3 { 145 | margin-top: 50px; 146 | margin-bottom: 0px; 147 | 148 | padding-top: 20px; 149 | padding-bottom: 0px; 150 | 151 | text-align: left; 152 | border-top: 1px dotted #777; 153 | } 154 | 155 | #content hr { 156 | border: 0; 157 | height: 0; 158 | border-top: 1px solid rgba(0, 0, 0, 0.1); 159 | border-bottom: 1px solid rgba(255, 255, 255, 0.3); 160 | } 161 | 162 | #content img { 163 | max-width: 90%; 164 | display: block; 165 | 166 | margin-left: auto; 167 | margin-right: auto; 168 | margin-top: 40px; 169 | margin-bottom: 40px; 170 | 171 | border-radius: 5px; 172 | } 173 | 174 | #content ul { 175 | display: block; 176 | list-style-type: none; 177 | } 178 | 179 | #content ul li:before { /* a hack to have dashes as a list style */ 180 | content: "-"; 181 | position: relative; 182 | left: -5px; 183 | } 184 | 185 | #content ul li { 186 | text-indent: -5px; /* to compensate for the padding for the dash */ 187 | font-size: 13px; 188 | } 189 | 190 | #content ul li.link { 191 | color: #4682BE; 192 | text-decoration: none; 193 | font-size: 13px; 194 | font-weight: bold; 195 | cursor: pointer; 196 | } 197 | 198 | #content a:link, #content a:visited { 199 | color: #4682BE; 200 | text-decoration: none; 201 | } 202 | 203 | #back_to_top { 204 | display: none; 205 | position: fixed; 206 | 207 | height: 20px; 208 | line-height: 20px; 209 | width: 50px; 210 | top: 20px; 211 | 212 | margin-left: 890px; 213 | 214 | color: #FFF; 215 | vertical-align: middle; 216 | text-align: center; 217 | font-size: 10px; 218 | 219 | border-radius: 5px; 220 | background-color: #AAA; 221 | } 222 | 223 | #back_to_top:hover { 224 | background-color: #444; 225 | cursor: pointer; 226 | } 227 | 228 | #edit { 229 | display: none; 230 | position: fixed; 231 | 232 | height: 20px; 233 | line-height: 20px; 234 | width: 50px; 235 | top: 50px; 236 | 237 | margin-left: 890px; 238 | 239 | color: #FFF; 240 | vertical-align: middle; 241 | text-align: center; 242 | font-size: 10px; 243 | 244 | border-radius: 5px; 245 | background-color: #AAA; 246 | } 247 | 248 | #edit:hover { 249 | background-color: #444; 250 | cursor: pointer; 251 | } 252 | 253 | #loading, #error { 254 | display: none; 255 | position: fixed; 256 | 257 | height: 17px; 258 | top: 45%; 259 | 260 | margin-left: 560px; 261 | 262 | font-size: 14px; 263 | font-weight: bold; 264 | } 265 | 266 | input[type=search] { 267 | display: block; 268 | width: 180px; 269 | 270 | text-align: left; 271 | } 272 | 273 | .search_results{ 274 | 275 | 276 | } 277 | 278 | .fragments { 279 | margin: 0; 280 | padding: 10px; 281 | /* border: 1px solid #777; */ 282 | /* border-radius: 5px; */ 283 | } 284 | 285 | .fragment { 286 | padding-left: 10px; 287 | padding-right: 10px; 288 | padding-top: 0px; 289 | padding-bottom: 0px; 290 | 291 | /* border: 1px solid #777; */ 292 | /* border-radius: 5px; */ 293 | } 294 | 295 | .search_results .link { 296 | margin-top: 35px; 297 | } 298 | 299 | #content ul li { 300 | text-align: left; 301 | } 302 | 303 | #content ul .fragments li:before { 304 | content: ""; 305 | position: relative; 306 | left: 0px; 307 | } 308 | 309 | #content ul li.fragment:before { 310 | content: ""; 311 | margin: 0; 312 | padding: 0; 313 | } 314 | 315 | #content img.github_badges { 316 | display: inline; 317 | margin-top: 0; 318 | margin-bottom: 0; 319 | } 320 | 321 | #content .youtube_video { 322 | margin-top: 20px; 323 | } 324 | 325 | #hide { 326 | display: none; 327 | } 328 | -------------------------------------------------------------------------------- /ver/latest/ditto.js: -------------------------------------------------------------------------------- 1 | $(function($) { 2 | 3 | var ditto = { 4 | content_id: $("#content"), 5 | sidebar_id: $("#sidebar"), 6 | 7 | edit_id: $("#edit"), 8 | back_to_top_id: $("#back_to_top"), 9 | 10 | loading_id: $("#loading"), 11 | error_id: $("#error"), 12 | 13 | search_name: $("#search"), 14 | search_results_class: ".search_results", 15 | fragments_class: ".fragments", 16 | fragment_class: ".fragment", 17 | 18 | highlight_code: true, 19 | 20 | // display elements 21 | sidebar: true, 22 | edit_button: true, 23 | back_to_top_button: true, 24 | searchbar: true, 25 | 26 | // github specifics 27 | github_username: null, 28 | github_repo: null, 29 | 30 | // initialize function 31 | run: initialize 32 | }; 33 | 34 | function initialize() { 35 | // initialize sidebar and buttons 36 | if (ditto.sidebar) { 37 | init_sidebar_section(); 38 | } 39 | 40 | if (ditto.back_to_top_button) { 41 | init_back_to_top_button(); 42 | } 43 | 44 | if (ditto.edit_button) { 45 | init_edit_button(); 46 | } 47 | 48 | // intialize highligh.js 49 | if (ditto.highlight_code) { 50 | hljs.initHighlightingOnLoad(); 51 | } 52 | 53 | // page router 54 | router(); 55 | $(window).on('hashchange', router); 56 | } 57 | 58 | function init_sidebar_section() { 59 | $.get(ditto.sidebar_file, function(data) { 60 | ditto.sidebar_id.html(marked(data)); 61 | 62 | if (ditto.searchbar) { 63 | init_searchbar(); 64 | } 65 | 66 | }, "text").fail(function() { 67 | alert("Opps! can't find the sidebar file to display!"); 68 | }); 69 | 70 | } 71 | 72 | function init_back_to_top_button() { 73 | ditto.back_to_top_id.show(); 74 | ditto.back_to_top_id.on("click", function() { 75 | $("body, html").animate({ 76 | scrollTop: 0 77 | }, 200); 78 | }); 79 | } 80 | 81 | function init_edit_button() { 82 | if (ditto.base_url === null) { 83 | alert("Error! You didn't set 'base_url' when calling ditto.run()!"); 84 | 85 | } else { 86 | ditto.edit_id.show(); 87 | ditto.edit_id.on("click", function() { 88 | var hash = location.hash.replace("#", "/"); 89 | 90 | if (hash === "") { 91 | hash = "/" + ditto.index.replace(".md", ""); 92 | } 93 | 94 | window.open(ditto.base_url + hash + ".md"); 95 | // open is better than redirecting, as the previous page history 96 | // with redirect is a bit messed up 97 | }); 98 | } 99 | } 100 | 101 | function init_searchbar() { 102 | var sidebar = ditto.sidebar_id.html(); 103 | var match = "[ditto:searchbar]"; 104 | 105 | // html input searchbar 106 | var search = ""; 109 | 110 | // replace match code with a real html input search bar 111 | sidebar = sidebar.replace(match, search); 112 | ditto.sidebar_id.html(sidebar); 113 | 114 | // add search listener 115 | $("input[name=" + ditto.search_name.selector + "]").keydown(searchbar_listener); 116 | } 117 | 118 | function build_text_matches_html(fragments) { 119 | var html = ""; 120 | var class_name = ditto.fragments_class.replace(".", ""); 121 | 122 | html += "
    "; 123 | for (var i = 0; i < fragments.length; i++) { 124 | var fragment = fragments[i].fragment.replace("/[\uE000-\uF8FF]/g", ""); 125 | html += "
  • "; 126 | html += "
     ";
    127 |       fragment = $("#hide").text(fragment).html();
    128 |       html += fragment;
    129 |       html += " 
  • "; 130 | } 131 | html += "
"; 132 | 133 | return html; 134 | } 135 | 136 | function build_result_matches_html(matches) { 137 | var html = ""; 138 | var class_name = ditto.search_results_class.replace(".", ""); 139 | 140 | html += "
    "; 141 | for (var i = 0; i < matches.length; i++) { 142 | var url = matches[i].path; 143 | 144 | if (url !== ditto.sidebar_file) { 145 | var hash = "#" + url.replace(".md", ""); 146 | var path = window.location.origin+ "/" + hash; 147 | 148 | // html += "
  • "; 149 | html += "
  • "; 153 | 154 | var match = build_text_matches_html(matches[i].text_matches); 155 | html += match; 156 | } 157 | 158 | } 159 | html += "
"; 160 | 161 | return html; 162 | } 163 | 164 | function display_search_results(data) { 165 | var results_html = "

Search Results

"; 166 | 167 | if (data.items.length) { 168 | hide_errors(); 169 | results_html += build_result_matches_html(data.items); 170 | } else { 171 | show_error("Opps.. Found no matches!"); 172 | } 173 | 174 | ditto.content_id.html(results_html); 175 | $(ditto.search_results_class + " .link").click(function(){ 176 | var destination = "#" + $(this).html().replace(".md", ""); 177 | location.hash = destination; 178 | }); 179 | } 180 | 181 | function github_search(query) { 182 | if (ditto.github_username && ditto.github_repo) { 183 | // build github search api url string 184 | var github_api = "https://api.github.com/"; 185 | var search = "search/code?q="; 186 | var github_repo = ditto.github_username + "/" + ditto.github_repo; 187 | var search_details = "+in:file+language:markdown+repo:"; 188 | 189 | var url = github_api + search + query + search_details + github_repo; 190 | var accept_header = "application/vnd.github.v3.text-match+json"; 191 | 192 | $.ajax(url, {headers: {Accept: accept_header}}).done(function(data) { 193 | display_search_results(data); 194 | }); 195 | } 196 | 197 | if (ditto.github_username == null && ditto.github_repo == null) { 198 | alert("You have not set ditto.github_username and ditto.github_repo!"); 199 | } else if (ditto.github_username == null) { 200 | alert("You have not set ditto.github_username!"); 201 | } else if (ditto.github_repo == null) { 202 | alert("You have not set ditto.github_repo!"); 203 | } 204 | } 205 | 206 | function searchbar_listener(event) { 207 | if (event.which === 13) { // when user presses ENTER in search bar 208 | var q = $("input[name=" + ditto.search_name.selector + "]").val(); 209 | if (q !== "") { 210 | location.hash = "#search=" + q; 211 | } else { 212 | alert("Error! Empty search query!"); 213 | } 214 | } 215 | } 216 | 217 | function replace_symbols(text) { 218 | // replace symbols with underscore 219 | return text.replace(/[&\/\\#,+=()$~%.'":*?<>{}\ \]\[]/g, "_"); 220 | } 221 | 222 | function li_create_linkage(li_tag, header_level) { 223 | // add custom id and class attributes 224 | html_safe_tag = replace_symbols(li_tag.text()); 225 | li_tag.attr("id", html_safe_tag); 226 | li_tag.attr("class", "link"); 227 | 228 | // add click listener - on click scroll to relevant header section 229 | $(ditto.content_id.selector + " li#" + li_tag.attr("id")).click(function() { 230 | // scroll to relevant section 231 | var header = $("h" + header_level + "." + li_tag.attr("id")); 232 | $('html, body').animate({ 233 | scrollTop: header.offset().top 234 | }, 200); 235 | 236 | // highlight the relevant section 237 | original_color = header.css("color"); 238 | header.animate({ color: "#ED1C24", }, 500, function() { 239 | // revert back to orig color 240 | $(this).animate({color: original_color}, 2500); 241 | }); 242 | }); 243 | } 244 | 245 | function create_page_anchors() { 246 | // create page anchors by matching li's to headers 247 | // if there is a match, create click listeners 248 | // and scroll to relevant sections 249 | 250 | // go through header level 2 and 3 251 | for (var i = 2; i <= 4; i++) { 252 | // parse all headers 253 | var headers = []; 254 | $(ditto.content_id.selector + ' h' + i).map(function() { 255 | headers.push($(this).text()); 256 | $(this).addClass(replace_symbols($(this).text())); 257 | }); 258 | 259 | // parse and set links between li and h2 260 | $(ditto.content_id.selector + ' ul li').map(function() { 261 | for (var j = 0; j < headers.length; j++) { 262 | if (headers[j] === $(this).text()) { 263 | li_create_linkage($(this), i); 264 | } 265 | } 266 | }); 267 | } 268 | } 269 | 270 | function youtube_url_extract(data) { 271 | var yt_regex = /(https?\:\/\/)?(www\.youtube\.com|youtu\.?be)\/.+/g; 272 | var yt_url = String(data.match(yt_regex)); 273 | yt_url = yt_url.replace(/]/g, ""); 274 | return yt_url; 275 | } 276 | 277 | function youtube_url_to_embed(data) { 278 | return data = data.replace(/watch\?v\=/g, "embed/"); 279 | } 280 | 281 | function create_youtube_embeds(data) { 282 | // replaces [ditto:youtube:] 283 | // with a proper youtube embed iframe 284 | var token_regex = /\[ditto\:youtube:(https?\:\/\/)?(www\.youtube\.com|youtu\.?be)\/.+\]/g; 285 | var yt_url = youtube_url_extract(data); 286 | var yt_embed_url = youtube_url_to_embed(yt_url); 287 | 288 | // youtube embed html 289 | var embed_html = `
290 |
291 | 298 |
299 |
`; 300 | embed_html = embed_html.replace("", yt_embed_url); 301 | 302 | // replace match code with youtube video 303 | data = data.replace(token_regex, embed_html); 304 | return data; 305 | } 306 | 307 | function normalize_paths() { 308 | // images 309 | ditto.content_id.find("img").map(function() { 310 | var src = $(this).attr("src").replace(/^\.\//, ""); 311 | if ($(this).attr("src").slice(0, 5) !== "http") { 312 | var url = location.hash.replace("#", ""); 313 | 314 | // split and extract base dir 315 | url = url.split("/"); 316 | var base_dir = url.slice(0, url.length - 1).join("/"); 317 | 318 | // normalize the path (i.e. make it absolute) 319 | if (base_dir) { 320 | $(this).attr("src", base_dir + "/" + src); 321 | } else { 322 | $(this).attr("src", src); 323 | } 324 | } 325 | }); 326 | 327 | } 328 | 329 | function show_error(err_msg) { 330 | ditto.error_id.html(err_msg); 331 | ditto.error_id.show(); 332 | } 333 | 334 | function hide_errors() { 335 | ditto.error_id.hide(); 336 | } 337 | 338 | function show_loading() { 339 | ditto.loading_id.show(); 340 | ditto.content_id.html(""); // clear content 341 | 342 | // infinite loop until clearInterval() is called on loading 343 | ditto.loading_interval = setInterval(function() { 344 | ditto.loading_id.fadeIn(1000).fadeOut(1000); 345 | }, 2000); 346 | 347 | } 348 | 349 | function stop_loading() { 350 | clearInterval(ditto.loading_interval); 351 | ditto.loading_id.hide(); 352 | } 353 | 354 | function escape_github_badges(data) { 355 | $("img").map(function() { 356 | var ignore_list = [ 357 | "travis-ci.com", 358 | "travis-ci.org", 359 | "coveralls.io" 360 | ]; 361 | var src = $(this).attr("src"); 362 | 363 | var base_url = src.split("/"); 364 | var protocol = base_url[0]; 365 | var host = base_url[2]; 366 | 367 | if ($.inArray(host, ignore_list) >= 0) { 368 | $(this).attr("class", "github_badges"); 369 | } 370 | }); 371 | return data; 372 | } 373 | 374 | function page_getter() { 375 | window.scrollTo(0, 0); 376 | var path = location.hash.replace("#", "./"); 377 | 378 | // default page if hash is empty 379 | var current_page = location.pathname.split("/").pop(); 380 | if (current_page === "index.html") { 381 | path = location.pathname.replace("index.html", ditto.index); 382 | normalize_paths(); 383 | 384 | } else if (path === "") { 385 | path = window.location + ditto.index; 386 | normalize_paths(); 387 | 388 | } else { 389 | path = path + ".md"; 390 | 391 | } 392 | 393 | // otherwise get the markdown and render it 394 | show_loading(); 395 | $.get(path, function(data) { 396 | compile_into_dom(path, data, function() { 397 | // rerender mathjax and reset mathjax equation counter 398 | if (MathJax) { 399 | if (MathJax.Extension["Tex/AMSmath"]) { 400 | MathJax.Extension["TeX/AMSmath"].startNumber = 0; 401 | MathJax.Extension["TeX/AMSmath"].labels = {}; 402 | } 403 | 404 | var content = document.getElementById("content"); 405 | MathJax.Hub.Queue(["Typeset", MathJax.Hub, content]); 406 | } 407 | }); 408 | }).fail(function() { 409 | show_error("Opps! ... File not found!"); 410 | stop_loading(); 411 | }); 412 | } 413 | 414 | function escape_html(string) { 415 | return string 416 | .replace(/\\/g, "\") 417 | .replace(/\_/g, "_"); 418 | } 419 | 420 | function unescape_html(string) { 421 | return string 422 | .replace(/&#92;/g, "\\") 423 | .replace(/&#95;/g, "_"); 424 | } 425 | 426 | function compile_into_dom(path, data, cb) { 427 | hide_errors(); 428 | 429 | data = create_youtube_embeds(data); 430 | data = marked(escape_html(data)); 431 | data = unescape_html(data); 432 | ditto.content_id.html(data); 433 | 434 | stop_loading(); 435 | escape_github_badges(data); 436 | 437 | normalize_paths(); 438 | create_page_anchors(); 439 | 440 | if (ditto.highlight_code) { 441 | $('pre code').each(function(i, block) { 442 | hljs.highlightBlock(block); 443 | }); 444 | } 445 | 446 | if (cb) { 447 | cb(data); 448 | } 449 | } 450 | 451 | function router() { 452 | var hash = location.hash; 453 | 454 | if (hash.slice(1, 7) !== "search") { 455 | page_getter(); 456 | 457 | } else { 458 | if (ditto.searchbar) { 459 | github_search(hash.replace("#search=", "")); 460 | } 461 | 462 | } 463 | } 464 | 465 | window.ditto = ditto; 466 | }); 467 | -------------------------------------------------------------------------------- /ver/latest/github.css: -------------------------------------------------------------------------------- 1 | /* 2 | github.com style (c) Vasily Polovnyov 3 | */ 4 | 5 | .hljs { 6 | display: block; 7 | overflow-x: auto; 8 | padding: 0.5em; 9 | color: #333; 10 | background: #f8f8f8; 11 | -webkit-text-size-adjust: none; 12 | } 13 | 14 | .hljs-comment, 15 | .diff .hljs-header { 16 | color: #998; 17 | font-style: italic; 18 | } 19 | 20 | .hljs-keyword, 21 | .css .rule .hljs-keyword, 22 | .hljs-winutils, 23 | .nginx .hljs-title, 24 | .hljs-subst, 25 | .hljs-request, 26 | .hljs-status { 27 | color: #333; 28 | font-weight: bold; 29 | } 30 | 31 | .hljs-number, 32 | .hljs-hexcolor, 33 | .ruby .hljs-constant { 34 | color: #008080; 35 | } 36 | 37 | .hljs-string, 38 | .hljs-tag .hljs-value, 39 | .hljs-doctag, 40 | .tex .hljs-formula { 41 | color: #d14; 42 | } 43 | 44 | .hljs-title, 45 | .hljs-id, 46 | .scss .hljs-preprocessor { 47 | color: #900; 48 | font-weight: bold; 49 | } 50 | 51 | .hljs-list .hljs-keyword, 52 | .hljs-subst { 53 | font-weight: normal; 54 | } 55 | 56 | .hljs-class .hljs-title, 57 | .hljs-type, 58 | .vhdl .hljs-literal, 59 | .tex .hljs-command { 60 | color: #458; 61 | font-weight: bold; 62 | } 63 | 64 | .hljs-tag, 65 | .hljs-tag .hljs-title, 66 | .hljs-rule .hljs-property, 67 | .django .hljs-tag .hljs-keyword { 68 | color: #000080; 69 | font-weight: normal; 70 | } 71 | 72 | .hljs-attribute, 73 | .hljs-variable, 74 | .lisp .hljs-body, 75 | .hljs-name { 76 | color: #008080; 77 | } 78 | 79 | .hljs-regexp { 80 | color: #009926; 81 | } 82 | 83 | .hljs-symbol, 84 | .ruby .hljs-symbol .hljs-string, 85 | .lisp .hljs-keyword, 86 | .clojure .hljs-keyword, 87 | .scheme .hljs-keyword, 88 | .tex .hljs-special, 89 | .hljs-prompt { 90 | color: #990073; 91 | } 92 | 93 | .hljs-built_in { 94 | color: #0086b3; 95 | } 96 | 97 | .hljs-preprocessor, 98 | .hljs-pragma, 99 | .hljs-pi, 100 | .hljs-doctype, 101 | .hljs-shebang, 102 | .hljs-cdata { 103 | color: #999; 104 | font-weight: bold; 105 | } 106 | 107 | .hljs-deletion { 108 | background: #fdd; 109 | } 110 | 111 | .hljs-addition { 112 | background: #dfd; 113 | } 114 | 115 | .diff .hljs-change { 116 | background: #0086b3; 117 | } 118 | 119 | .hljs-chunk { 120 | color: #aaa; 121 | } 122 | -------------------------------------------------------------------------------- /ver/latest/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TITLE 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 33 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 |
46 | 47 | 48 |
top
49 |
edit
50 |
Loading ...
51 |
52 | 53 | 54 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /ver/latest/sidebar.md: -------------------------------------------------------------------------------- 1 | # [Project]() 2 | version 0.1 3 | 4 | - [Github Repository](http://github.com//) 5 | 6 | [ditto:searchbar] 7 | 8 | ## Header 2 9 | - [Page1](#docs/page1) 10 | - [Page2](#docs/page2) 11 | --------------------------------------------------------------------------------