├── .gitignore ├── README.md ├── assets ├── css │ ├── font-awesome.min.css │ └── style.css ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ └── fontawesome-webfont.woff └── js │ └── default.js ├── favicon.ico ├── favicon.png ├── index.html ├── lib ├── jquery-1.11.1.min.js └── markdown │ ├── Markdown.Converter.js │ ├── Markdown.Editor.js │ ├── Markdown.Extra.js │ ├── Markdown.Sanitizer.js │ └── prettify.js └── preview.png /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Markdown online editor 2 | ====================== 3 | This is a simple markdown editor. You can type in one of the page boxes and on the other side you will see the respective markdown translation to our normal perspective. 4 | 5 | ## Demo 6 |  7 | 8 | ## Contributing 9 | This is a simple project that I built some time ago to learn more about markdown parsers in javascript. 10 | At this point, there is no active development on this project. 11 | But, if you feel like you can add/contribute something, feel free: Create an Issue and we will work together on the PullRequest. 12 | 13 | ## Acknowledgements 14 | This project would not be possible without some libraries as: 15 | 16 | + [jmcmanus/pagedown-extra](https://github.com/jmcmanus/pagedown-extra) 17 | + [FortAwesome/Font-Awesome](https://github.com/FortAwesome/Font-Awesome) 18 | -------------------------------------------------------------------------------- /assets/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.1.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-square:before,.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"} -------------------------------------------------------------------------------- /assets/css/style.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Open+Sans|Special+Elite|Raleway); 2 | 3 | body, html {border: 0px; margin: 0px; padding: 0px; 4 | height:100%; position:relative; width:100%;} 5 | 6 | a, a:link { 7 | text-decoration: none; 8 | color: inherit; 9 | } 10 | 11 | a:hover { 12 | color: #787878; 13 | } 14 | 15 | .options { 16 | color: rgb(0,0,0,1); 17 | cursor: pointer; 18 | } 19 | 20 | .options i { 21 | margin-left: 10px; 22 | } 23 | 24 | .options i:hover { 25 | color: #787878; 26 | } 27 | 28 | .left{ 29 | float: left; 30 | } 31 | 32 | .right{ 33 | float: right; 34 | } 35 | 36 | .container { 37 | width: 95%; 38 | height: 90%; 39 | margin: 10px auto; 40 | } 41 | 42 | .container #text-holder { 43 | width: 47%; 44 | height: 100%; 45 | } 46 | 47 | .container #text { 48 | width: 100%; 49 | height: 85%; 50 | border: none; 51 | overflow: auto; 52 | outline: none; 53 | resize:none; 54 | 55 | -webkit-box-shadow: none; 56 | -moz-box-shadow: none; 57 | box-shadow: none; 58 | 59 | color: inherit; 60 | background-color: inherit; 61 | 62 | padding: 22px 5px 0 5px; 63 | font-family: 'Raleway', sans-serif; 64 | 65 | font-size: 18px; 66 | line-height: 30px; 67 | font-weight: 300; 68 | text-align: left; 69 | } 70 | 71 | .container #preview { 72 | width: 47%; 73 | height: 85%; 74 | float: right; 75 | display: inline-block; 76 | overflow-y: auto; 77 | overflow-x: hidden; 78 | word-wrap: break-word; 79 | 80 | 81 | font-family: 'Open Sans', sans-serif; 82 | font-size: 18px; 83 | line-height: 30px; 84 | font-weight: 300; 85 | text-align: left; 86 | } 87 | 88 | .help-wrapper { 89 | position: absolute; 90 | bottom: 5px; 91 | left: 0; 92 | width: 100%; 93 | text-align: center; 94 | } 95 | 96 | .help-wrapper .hellper{ 97 | position: relative; 98 | width: 80%; 99 | margin:0 auto; 100 | background-color: rgba(0,0,0,0.1); 101 | border-radius: 5px; 102 | padding: 3px 5px 3px 5px; 103 | font-family: 'Open Sans', sans-serif; 104 | text-align: right; 105 | } 106 | 107 | .help-wrapper .hellper table { 108 | width: 100%; 109 | font-size: 12px; 110 | text-align: left; 111 | border: 0; 112 | } 113 | 114 | .help-wrapper .hellper table .symbol { 115 | display: inline-block; 116 | text-align: right; 117 | width: 100px; 118 | overflow: hidden; 119 | margin-right: 15px; 120 | } 121 | 122 | .help-wrapper .hellper table .info { 123 | display: inline-block; 124 | text-align: left; 125 | margin-left: 15px; 126 | } 127 | 128 | .help-wrapper .hellper table .symbol {font-family: 'Open Sans', sans-serif;} 129 | .help-wrapper .hellper table .info {font-family: 'Special Elite', cursive;} 130 | 131 | .help-wrapper .hellper .close { 132 | position: absolute; 133 | right: 7px; 134 | cursor: pointer; 135 | } 136 | 137 | .help-wrapper .hellper .close:hover {color: #787878;} 138 | 139 | @media (max-width: 1080px) { 140 | .help-wrapper .hellper table .symbol {margin-right: 0;} 141 | .help-wrapper .hellper table .info {margin-left: 0;} 142 | } 143 | 144 | @media (max-width: 920px) { 145 | .help-wrapper .hellper {width: 97%} 146 | } 147 | 148 | @media (max-width: 750px) { 149 | .help-wrapper .hellper {display: none;} 150 | .options .fa-info-circle {display: none;} 151 | .container #text, .container #preview {float: none;width: 100%;height: 40%;} 152 | } 153 | -------------------------------------------------------------------------------- /assets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mariogarridopt/markdown-editor-html/b7091169514e97a1db1b7797dba63462435018c0/assets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mariogarridopt/markdown-editor-html/b7091169514e97a1db1b7797dba63462435018c0/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mariogarridopt/markdown-editor-html/b7091169514e97a1db1b7797dba63462435018c0/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mariogarridopt/markdown-editor-html/b7091169514e97a1db1b7797dba63462435018c0/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /assets/js/default.js: -------------------------------------------------------------------------------- 1 | var colorStatus = true, 2 | infoStatus = true; 3 | 4 | $(function() { 5 | // When using more than one `textarea` on your page, change the following line to match the one you’re after 6 | var $textarea = $('textarea'), 7 | $preview = $('
').insertAfter('#text-holder'), 8 | converter = new Markdown.getSanitizingConverter(); 9 | Markdown.Extra.init(converter); 10 | convert = converter.makeHtml; 11 | 12 | var text = sessionStorage.getItem("mkdowninfo"); 13 | if(text == null || text == "null" || text == "") 14 | text = "";//"Hi\n==\nYou can type your text **here**."; 15 | 16 | // instead of `keyup`, consider using `input` using this plugin: http://mathiasbynens.be/notes/oninput#comment-1 17 | $textarea.keyup(function() { 18 | if(text == null){ 19 | $preview.html(convert($textarea.val())); 20 | sessionStorage.setItem("mkdowninfo", $textarea.val()); 21 | }else{ 22 | $textarea.val(text); 23 | $preview.html(convert(text)); 24 | text = null; 25 | } 26 | }).trigger('keyup'); 27 | }); 28 | 29 | function toggleInfo() { 30 | if(infoStatus == false) { 31 | var height = $(document.body).height() - 150; 32 | $( ".help-wrapper" ).fadeIn( "fast" ); 33 | $('textarea').css("height", height + "px"); 34 | $('#preview').css("height", height + "px"); 35 | } else { 36 | $( ".help-wrapper" ).fadeOut( "fast" ); 37 | $('textarea').css("height", "100%"); 38 | $('#preview').css("height", "100%"); 39 | } 40 | infoStatus = !infoStatus; 41 | } 42 | 43 | function toggleColor(){ 44 | if(colorStatus == false) { 45 | $('body').css("background-color", "white"); 46 | $('body').css("color", "black"); 47 | $('.help-wrapper .hellper').css("background-color", "rgba(0,0,0,0.1)"); 48 | $('textarea').css("background-color", "white"); 49 | $('textarea').css("color", "black"); 50 | $('#preview').css("background-color", "white"); 51 | $('#preview').css("color", "black"); 52 | } else { 53 | $('body').css("background-color", "black"); 54 | $('body').css("color", "white"); 55 | $('.help-wrapper .hellper').css("background-color", "rgba(255,255,255,0.1)"); 56 | $('textarea').css("background-color", "black"); 57 | $('textarea').css("color", "white"); 58 | $('#preview').css("background-color", "black"); 59 | $('#preview').css("color", "white"); 60 | } 61 | colorStatus = !colorStatus; 62 | } 63 | 64 | function clearPage() { 65 | $('textarea').val(""); 66 | $('#preview').html(""); 67 | sessionStorage.setItem("mkdowninfo", ""); 68 | } 69 | 70 | function copyToClipboard() { 71 | window.prompt("Copy to clipboard: Ctrl+C, Enter", $('textarea').val()); 72 | } 73 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mariogarridopt/markdown-editor-html/b7091169514e97a1db1b7797dba63462435018c0/favicon.ico -------------------------------------------------------------------------------- /favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mariogarridopt/markdown-editor-html/b7091169514e97a1db1b7797dba63462435018c0/favicon.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |44 | # ## ...> 45 | h1 h2 ... 46 | | 47 |48 | *text*> 49 | Italic 50 | | 51 |52 | 1. text 2. text> 53 | List 54 | | 55 |56 | `code`> 57 | In-line code 58 | | 59 |
62 | [text](https://link)> 63 | Link 64 | | 65 |66 | **text**> 67 | Bold 68 | | 69 |70 | + bla + bla> 71 | List 72 | | 73 |74 | ***> 75 | Horizontal Rule 76 | | 77 |
81 | > 82 | Image 83 | | 84 |85 | ~~text~~> 86 | Strikethrough 87 | | 88 |89 | > text> 90 | Text quote 91 | | 92 |93 | more... 94 | | 95 |
s around 276 | // "paragraphs" that are wrapped in non-block-level tags, such as anchors, 277 | // phrase emphasis, and spans. The list of tags we're looking for is 278 | // hard-coded: 279 | var block_tags_a = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del" 280 | var block_tags_b = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math" 281 | 282 | // First, look for nested blocks, e.g.: 283 | //
tags around block-level tags.
435 | text = _HashHTMLBlocks(text);
436 | text = _FormParagraphs(text, doNotUnhash);
437 |
438 | return text;
439 | }
440 |
441 | function _RunSpanGamut(text) {
442 | //
443 | // These are all the transformations that occur *within* block-level
444 | // tags like paragraphs, headers, and list items.
445 | //
446 |
447 | text = pluginHooks.preSpanGamut(text);
448 |
449 | text = _DoCodeSpans(text);
450 | text = _EscapeSpecialCharsWithinTagAttributes(text);
451 | text = _EncodeBackslashEscapes(text);
452 |
453 | // Process anchor and image tags. Images must come first,
454 | // because ![foo][f] looks like an anchor.
455 | text = _DoImages(text);
456 | text = _DoAnchors(text);
457 |
458 | // Make links out of things like ` Just type tags
1151 | //
1152 |
1153 | // Strip leading and trailing lines:
1154 | text = text.replace(/^\n+/g, "");
1155 | text = text.replace(/\n+$/g, "");
1156 |
1157 | var grafs = text.split(/\n{2,}/g);
1158 | var grafsOut = [];
1159 |
1160 | var markerRe = /~K(\d+)K/;
1161 |
1162 | //
1163 | // Wrap tags.
1164 | //
1165 | var end = grafs.length;
1166 | for (var i = 0; i < end; i++) {
1167 | var str = grafs[i];
1168 |
1169 | // if this is an HTML marker, copy it
1170 | if (markerRe.test(str)) {
1171 | grafsOut.push(str);
1172 | }
1173 | else if (/\S/.test(str)) {
1174 | str = _RunSpanGamut(str);
1175 | str = str.replace(/^([ \t]*)/g, " ");
1176 | str += " tag here so Pagedown won't.
265 | Markdown.Extra.prototype.hashExtraBlock = function(block) {
266 | return '\n ~X' + (this.hashBlocks.push(block) - 1) + 'X )?~X(\d+)X(?:<\/p>)?/g, function(wholeMatch, m1) {
279 | hasHash = true;
280 | var key = parseInt(m1, 10);
281 | return self.hashBlocks[key];
282 | });
283 | if(hasHash === true) {
284 | recursiveUnHash();
285 | }
286 | }
287 | recursiveUnHash();
288 | return text;
289 | };
290 |
291 | // Wrap headers to make sure they won't be in def lists
292 | Markdown.Extra.prototype.wrapHeaders = function(text) {
293 | function wrap(text) {
294 | return '\n' + text + '\n';
295 | }
296 | text = text.replace(/^.+[ \t]*\n=+[ \t]*\n+/gm, wrap);
297 | text = text.replace(/^.+[ \t]*\n-+[ \t]*\n+/gm, wrap);
298 | text = text.replace(/^\#{1,6}[ \t]*.+?[ \t]*\#*\n+/gm, wrap);
299 | return text;
300 | };
301 |
302 |
303 | /******************************************************************
304 | * Attribute Blocks *
305 | *****************************************************************/
306 |
307 | // TODO: use sentinels. Should we just add/remove them in doConversion?
308 | // TODO: better matches for id / class attributes
309 | var attrBlock = "\\{[ \\t]*((?:[#.][-_:a-zA-Z0-9]+[ \\t]*)+)\\}";
310 | var hdrAttributesA = new RegExp("^(#{1,6}.*#{0,6})[ \\t]+" + attrBlock + "[ \\t]*(?:\\n|0x03)", "gm");
311 | var hdrAttributesB = new RegExp("^(.*)[ \\t]+" + attrBlock + "[ \\t]*\\n" +
312 | "(?=[\\-|=]+\\s*(?:\\n|0x03))", "gm"); // underline lookahead
313 | var fcbAttributes = new RegExp("^(```[ \\t]*[^{\\s]*)[ \\t]+" + attrBlock + "[ \\t]*\\n" +
314 | "(?=([\\s\\S]*?)\\n```[ \\t]*(\\n|0x03))", "gm");
315 |
316 | // Extract headers attribute blocks, move them above the element they will be
317 | // applied to, and hash them for later.
318 | Markdown.Extra.prototype.hashHeaderAttributeBlocks = function(text) {
319 |
320 | var self = this;
321 | function attributeCallback(wholeMatch, pre, attr) {
322 | return ' ~XX' + (self.hashBlocks.push(attr) - 1) + 'XX ~XX' + (self.hashBlocks.push(attr) - 1) + 'XX ~XX(\\d+)XX He said, "'Quoted' words in a larger quote."
\n");
470 |
471 | text = pluginHooks.postSpanGamut(text);
472 |
473 | return text;
474 | }
475 |
476 | function _EscapeSpecialCharsWithinTagAttributes(text) {
477 | //
478 | // Within tags -- meaning between < and > -- encode [\ ` * _] so they
479 | // don't conflict with their use in Markdown for code, italics and strong.
480 | //
481 |
482 | // Build a regex to find HTML tags and comments. See Friedl's
483 | // "Mastering Regular Expressions", 2nd Ed., pp. 200-201.
484 |
485 | // SE: changed the comment part of the regex
486 |
487 | var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|-]|-[^>])(?:[^-]|-[^-])*)--)>)/gi;
488 |
489 | text = text.replace(regex, function (wholeMatch) {
490 | var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g, "$1`");
491 | tag = escapeCharacters(tag, wholeMatch.charAt(1) == "!" ? "\\`*_/" : "\\`*_"); // also escape slashes in comments to prevent autolinking there -- http://meta.stackoverflow.com/questions/95987
492 | return tag;
493 | });
494 |
495 | return text;
496 | }
497 |
498 | function _DoAnchors(text) {
499 | //
500 | // Turn Markdown link shortcuts into XHTML tags.
501 | //
502 | //
503 | // First, handle reference-style links: [link text] [id]
504 | //
505 |
506 | /*
507 | text = text.replace(/
508 | ( // wrap whole match in $1
509 | \[
510 | (
511 | (?:
512 | \[[^\]]*\] // allow brackets nested one level
513 | |
514 | [^\[] // or anything else
515 | )*
516 | )
517 | \]
518 |
519 | [ ]? // one optional space
520 | (?:\n[ ]*)? // one optional newline followed by spaces
521 |
522 | \[
523 | (.*?) // id = $3
524 | \]
525 | )
526 | ()()()() // pad remaining backreferences
527 | /g, writeAnchorTag);
528 | */
529 | text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, writeAnchorTag);
530 |
531 | //
532 | // Next, inline-style links: [link text](url "optional title")
533 | //
534 |
535 | /*
536 | text = text.replace(/
537 | ( // wrap whole match in $1
538 | \[
539 | (
540 | (?:
541 | \[[^\]]*\] // allow brackets nested one level
542 | |
543 | [^\[\]] // or anything else
544 | )*
545 | )
546 | \]
547 | \( // literal paren
548 | [ \t]*
549 | () // no id, so leave $3 empty
550 | ( // href = $4
551 | (?:
552 | \([^)]*\) // allow one level of (correctly nested) parens (think MSDN)
553 | |
554 | [^()\s]
555 | )*?
556 | )>?
557 | [ \t]*
558 | ( // $5
559 | (['"]) // quote char = $6
560 | (.*?) // Title = $7
561 | \6 // matching quote
562 | [ \t]* // ignore any spaces/tabs between closing quote and )
563 | )? // title is optional
564 | \)
565 | )
566 | /g, writeAnchorTag);
567 | */
568 |
569 | text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()((?:\([^)]*\)|[^()\s])*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, writeAnchorTag);
570 |
571 | //
572 | // Last, handle reference-style shortcuts: [link text]
573 | // These must come last in case you've also got [link test][1]
574 | // or [link test](/foo)
575 | //
576 |
577 | /*
578 | text = text.replace(/
579 | ( // wrap whole match in $1
580 | \[
581 | ([^\[\]]+) // link text = $2; can't contain '[' or ']'
582 | \]
583 | )
584 | ()()()()() // pad rest of backreferences
585 | /g, writeAnchorTag);
586 | */
587 | text = text.replace(/(\[([^\[\]]+)\])()()()()()/g, writeAnchorTag);
588 |
589 | return text;
590 | }
591 |
592 | function writeAnchorTag(wholeMatch, m1, m2, m3, m4, m5, m6, m7) {
593 | if (m7 == undefined) m7 = "";
594 | var whole_match = m1;
595 | var link_text = m2.replace(/:\/\//g, "~P"); // to prevent auto-linking withing the link. will be converted back after the auto-linker runs
596 | var link_id = m3.toLowerCase();
597 | var url = m4;
598 | var title = m7;
599 |
600 | if (url == "") {
601 | if (link_id == "") {
602 | // lower-case and turn embedded newlines into spaces
603 | link_id = link_text.toLowerCase().replace(/ ?\n/g, " ");
604 | }
605 | url = "#" + link_id;
606 |
607 | if (g_urls.get(link_id) != undefined) {
608 | url = g_urls.get(link_id);
609 | if (g_titles.get(link_id) != undefined) {
610 | title = g_titles.get(link_id);
611 | }
612 | }
613 | else {
614 | if (whole_match.search(/\(\s*\)$/m) > -1) {
615 | // Special case for explicit empty url
616 | url = "";
617 | } else {
618 | return whole_match;
619 | }
620 | }
621 | }
622 | url = encodeProblemUrlChars(url);
623 | url = escapeCharacters(url, "*_");
624 | var result = "" + link_text + "";
633 |
634 | return result;
635 | }
636 |
637 | function _DoImages(text) {
638 | //
639 | // Turn Markdown image shortcuts into tags.
640 | //
641 |
642 | //
643 | // First, handle reference-style labeled images: ![alt text][id]
644 | //
645 |
646 | /*
647 | text = text.replace(/
648 | ( // wrap whole match in $1
649 | !\[
650 | (.*?) // alt text = $2
651 | \]
652 |
653 | [ ]? // one optional space
654 | (?:\n[ ]*)? // one optional newline followed by spaces
655 |
656 | \[
657 | (.*?) // id = $3
658 | \]
659 | )
660 | ()()()() // pad rest of backreferences
661 | /g, writeImageTag);
662 | */
663 | text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, writeImageTag);
664 |
665 | //
666 | // Next, handle inline images: 
667 | // Don't forget: encode * and _
668 |
669 | /*
670 | text = text.replace(/
671 | ( // wrap whole match in $1
672 | !\[
673 | (.*?) // alt text = $2
674 | \]
675 | \s? // One optional whitespace character
676 | \( // literal paren
677 | [ \t]*
678 | () // no id, so leave $3 empty
679 | (\S+?)>? // src url = $4
680 | [ \t]*
681 | ( // $5
682 | (['"]) // quote char = $6
683 | (.*?) // title = $7
684 | \6 // matching quote
685 | [ \t]*
686 | )? // title is optional
687 | \)
688 | )
689 | /g, writeImageTag);
690 | */
691 | text = text.replace(/(!\[(.*?)\]\s?\([ \t]*()(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, writeImageTag);
692 |
693 | return text;
694 | }
695 |
696 | function attributeEncode(text) {
697 | // unconditionally replace angle brackets here -- what ends up in an attribute (e.g. alt or title)
698 | // never makes sense to have verbatim HTML in it (and the sanitizer would totally break it)
699 | return text.replace(/>/g, ">").replace(/";
743 |
744 | return result;
745 | }
746 |
747 | function _DoHeaders(text) {
748 |
749 | // Setext-style headers:
750 | // Header 1
751 | // ========
752 | //
753 | // Header 2
754 | // --------
755 | //
756 | text = text.replace(/^(.+)[ \t]*\n=+[ \t]*\n+/gm,
757 | function (wholeMatch, m1) { return "
" + _RunSpanGamut(m1) + "
\n\n"; }
758 | );
759 |
760 | text = text.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm,
761 | function (matchFound, m1) { return "" + _RunSpanGamut(m1) + "
\n\n"; }
762 | );
763 |
764 | // atx-style headers:
765 | // # Header 1
766 | // ## Header 2
767 | // ## Header 2 with closing hashes ##
768 | // ...
769 | // ###### Header 6
770 | //
771 |
772 | /*
773 | text = text.replace(/
774 | ^(\#{1,6}) // $1 = string of #'s
775 | [ \t]*
776 | (.+?) // $2 = Header text
777 | [ \t]*
778 | \#* // optional closing #'s (not counted)
779 | \n+
780 | /gm, function() {...});
781 | */
782 |
783 | text = text.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm,
784 | function (wholeMatch, m1, m2) {
785 | var h_level = m1.length;
786 | return "` blocks.
959 | //
960 |
961 | /*
962 | text = text.replace(/
963 | (?:\n\n|^)
964 | ( // $1 = the code block -- one or more lines, starting with a space/tab
965 | (?:
966 | (?:[ ]{4}|\t) // Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
967 | .*\n+
968 | )+
969 | )
970 | (\n*[ ]{0,3}[^ \t\n]|(?=~0)) // attacklab: g_tab_width
971 | /g ,function(){...});
972 | */
973 |
974 | // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
975 | text += "~0";
976 |
977 | text = text.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,
978 | function (wholeMatch, m1, m2) {
979 | var codeblock = m1;
980 | var nextChar = m2;
981 |
982 | codeblock = _EncodeCode(_Outdent(codeblock));
983 | codeblock = _Detab(codeblock);
984 | codeblock = codeblock.replace(/^\n+/g, ""); // trim leading newlines
985 | codeblock = codeblock.replace(/\n+$/g, ""); // trim trailing whitespace
986 |
987 | codeblock = "
";
988 |
989 | return "\n\n" + codeblock + "\n\n" + nextChar;
990 | }
991 | );
992 |
993 | // attacklab: strip sentinel
994 | text = text.replace(/~0/, "");
995 |
996 | return text;
997 | }
998 |
999 | function hashBlock(text) {
1000 | text = text.replace(/(^\n+|\n+$)/g, "");
1001 | return "\n\n~K" + (g_html_blocks.push(text) - 1) + "K\n\n";
1002 | }
1003 |
1004 | function _DoCodeSpans(text) {
1005 | //
1006 | // * Backtick quotes are used for " + codeblock + "\n
spans.
1007 | //
1008 | // * You can use multiple backticks as the delimiters if you want to
1009 | // include literal backticks in the code span. So, this input:
1010 | //
1011 | // Just type ``foo `bar` baz`` at the prompt.
1012 | //
1013 | // Will translate to:
1014 | //
1015 | //
foo `bar` baz
at the prompt.`bar`
...
1028 | //
1029 |
1030 | /*
1031 | text = text.replace(/
1032 | (^|[^\\]) // Character before opening ` can't be a backslash
1033 | (`+) // $2 = Opening run of `
1034 | ( // $3 = The code block
1035 | [^\r]*?
1036 | [^`] // attacklab: work around lack of lookbehind
1037 | )
1038 | \2 // Matching closer
1039 | (?!`)
1040 | /gm, function(){...});
1041 | */
1042 |
1043 | text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
1044 | function (wholeMatch, m1, m2, m3, m4) {
1045 | var c = m3;
1046 | c = c.replace(/^([ \t]*)/g, ""); // leading whitespace
1047 | c = c.replace(/[ \t]*$/g, ""); // trailing whitespace
1048 | c = _EncodeCode(c);
1049 | c = c.replace(/:\/\//g, "~P"); // to prevent auto-linking. Not necessary in code *blocks*, but in code spans. Will be converted back after the auto-linker runs.
1050 | return m1 + "" + c + "
";
1051 | }
1052 | );
1053 |
1054 | return text;
1055 | }
1056 |
1057 | function _EncodeCode(text) {
1058 | //
1059 | // Encode/escape certain characters inside Markdown code runs.
1060 | // The point is that in code, these characters are literals,
1061 | // and lose their special Markdown meanings.
1062 | //
1063 | // Encode all ampersands; HTML entities are not
1064 | // entities within a Markdown code span.
1065 | text = text.replace(/&/g, "&");
1066 |
1067 | // Do the angle bracket song and dance:
1068 | text = text.replace(//g, ">");
1070 |
1071 | // Now, escape characters that are magic in Markdown:
1072 | text = escapeCharacters(text, "\*_{}[]\\", false);
1073 |
1074 | // jj the line above breaks this:
1075 | //---
1076 |
1077 | //* Item
1078 |
1079 | // 1. Subitem
1080 |
1081 | // special char: *
1082 | //---
1083 |
1084 | return text;
1085 | }
1086 |
1087 | function _DoItalicsAndBold(text) {
1088 |
1089 | // must go first:
1090 | text = text.replace(/([\W_]|^)(\*\*|__)(?=\S)([^\r]*?\S[\*_]*)\2([\W_]|$)/g,
1091 | "$1$3$4");
1092 |
1093 | text = text.replace(/([\W_]|^)(\*|_)(?=\S)([^\r\*_]*?\S)\2([\W_]|$)/g,
1094 | "$1$3$4");
1095 |
1096 | return text;
1097 | }
1098 |
1099 | function _DoBlockQuotes(text) {
1100 |
1101 | /*
1102 | text = text.replace(/
1103 | ( // Wrap whole match in $1
1104 | (
1105 | ^[ \t]*>[ \t]? // '>' at the start of a line
1106 | .+\n // rest of the first line
1107 | (.+\n)* // subsequent consecutive lines
1108 | \n* // blanks
1109 | )+
1110 | )
1111 | /gm, function(){...});
1112 | */
1113 |
1114 | text = text.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm,
1115 | function (wholeMatch, m1) {
1116 | var bq = m1;
1117 |
1118 | // attacklab: hack around Konqueror 3.5.4 bug:
1119 | // "----------bug".replace(/^-/g,"") == "bug"
1120 |
1121 | bq = bq.replace(/^[ \t]*>[ \t]?/gm, "~0"); // trim one level of quoting
1122 |
1123 | // attacklab: clean up hack
1124 | bq = bq.replace(/~0/g, "");
1125 |
1126 | bq = bq.replace(/^[ \t]+$/gm, ""); // trim whitespace-only lines
1127 | bq = _RunBlockGamut(bq); // recurse
1128 |
1129 | bq = bq.replace(/(^|\n)/g, "$1 ");
1130 | // These leading spaces screw with content, so we need to fix that:
1131 | bq = bq.replace(
1132 | /(\s*
[^\r]+?<\/pre>)/gm,
1133 | function (wholeMatch, m1) {
1134 | var pre = m1;
1135 | // attacklab: hack around Konqueror 3.5.4 bug:
1136 | pre = pre.replace(/^ /mg, "~0");
1137 | pre = pre.replace(/~0/g, "");
1138 | return pre;
1139 | });
1140 |
1141 | return hashBlock("
\n" + bq + "\n
");
1142 | }
1143 | );
1144 | return text;
1145 | }
1146 |
1147 | function _FormParagraphs(text, doNotUnhash) {
1148 | //
1149 | // Params:
1150 | // $text - string to process with html \n', '\n', '
\n";
485 |
486 | // replace html with placeholder until postConversion step
487 | return self.hashExtraBlock(html);
488 | }
489 |
490 | return text;
491 | };
492 |
493 |
494 | /******************************************************************
495 | * Footnotes *
496 | *****************************************************************/
497 |
498 | // Strip footnote, store in hashes.
499 | Markdown.Extra.prototype.stripFootnoteDefinitions = function(text) {
500 | var self = this;
501 |
502 | text = text.replace(
503 | /\n[ ]{0,3}\[\^(.+?)\]\:[ \t]*\n?([\s\S]*?)\n{1,2}((?=\n[ ]{0,3}\S)|$)/g,
504 | function(wholeMatch, m1, m2) {
505 | m1 = slugify(m1);
506 | m2 += "\n";
507 | m2 = m2.replace(/^[ ]{0,3}/g, "");
508 | self.footnotes[m1] = m2;
509 | return "\n";
510 | });
511 |
512 | return text;
513 | };
514 |
515 |
516 | // Find and convert footnotes references.
517 | Markdown.Extra.prototype.doFootnotes = function(text) {
518 | var self = this;
519 | if(self.isConvertingFootnote === true) {
520 | return text;
521 | }
522 |
523 | var footnoteCounter = 0;
524 | text = text.replace(/\[\^(.+?)\]/g, function(wholeMatch, m1) {
525 | var id = slugify(m1);
526 | var footnote = self.footnotes[id];
527 | if (footnote === undefined) {
528 | return wholeMatch;
529 | }
530 | footnoteCounter++;
531 | self.usedFootnotes.push(id);
532 | var html = '' + footnoteCounter
534 | + '';
535 | return self.hashExtraInline(html);
536 | });
537 |
538 | return text;
539 | };
540 |
541 | // Print footnotes at the end of the document
542 | Markdown.Extra.prototype.printFootnotes = function(text) {
543 | var self = this;
544 |
545 | if (self.usedFootnotes.length === 0) {
546 | return text;
547 | }
548 |
549 | text += '\n\n\n'].join('');
456 |
457 | // build column headers.
458 | for (i = 0; i < colCount; i++) {
459 | var headerHtml = convertSpans(trim(headers[i]), self);
460 | html += [" \n\n";
463 |
464 | // build rows
465 | var rows = body.split('\n');
466 | for (i = 0; i < rows.length; i++) {
467 | if (rows[i].match(/^\s*$/)) // can apply to final row
468 | continue;
469 |
470 | // ensure number of rowCells matches colCount
471 | var rowCells = rows[i].split(/ *[|] */);
472 | var lenDiff = colCount - rowCells.length;
473 | for (var j = 0; j < lenDiff; j++)
474 | rowCells.push('');
475 |
476 | html += "", headerHtml, " \n"].join('');
461 | }
462 | html += "\n";
477 | for (j = 0; j < colCount; j++) {
478 | var colHtml = convertSpans(trim(rowCells[j]), self);
479 | html += [" \n";
482 | }
483 |
484 | html += "", colHtml, " \n"].join('');
480 | }
481 | html += "
\n\n\n';
550 | for(var i=0; i
\n
'].join('');
603 |
604 | // replace codeblock with placeholder until postConversion step
605 | return self.hashExtraBlock(html);
606 | });
607 |
608 | return text;
609 | };
610 |
611 |
612 | /******************************************************************
613 | * SmartyPants *
614 | ******************************************************************/
615 |
616 | Markdown.Extra.prototype.educatePants = function(text) {
617 | var self = this;
618 | var result = '';
619 | var blockOffset = 0;
620 | // Here we parse HTML in a very bad manner
621 | text.replace(/(?:)|(<)([a-zA-Z1-6]+)([^\n]*?>)([\s\S]*?)(<\/\2>)/g, function(wholeMatch, m1, m2, m3, m4, m5, offset) {
622 | var token = text.substring(blockOffset, offset);
623 | result += self.applyPants(token);
624 | self.smartyPantsLastChar = result.substring(result.length - 1);
625 | blockOffset = offset + wholeMatch.length;
626 | if(!m1) {
627 | // Skip commentary
628 | result += wholeMatch;
629 | return;
630 | }
631 | // Skip special tags
632 | if(!/code|kbd|pre|script|noscript|iframe|math|ins|del|pre/i.test(m2)) {
633 | m4 = self.educatePants(m4);
634 | }
635 | else {
636 | self.smartyPantsLastChar = m4.substring(m4.length - 1);
637 | }
638 | result += m1 + m2 + m3 + m4 + m5;
639 | });
640 | var lastToken = text.substring(blockOffset);
641 | result += self.applyPants(lastToken);
642 | self.smartyPantsLastChar = result.substring(result.length - 1);
643 | return result;
644 | };
645 |
646 | function revertPants(wholeMatch, m1) {
647 | var blockText = m1;
648 | blockText = blockText.replace(/&\#8220;/g, "\"");
649 | blockText = blockText.replace(/&\#8221;/g, "\"");
650 | blockText = blockText.replace(/&\#8216;/g, "'");
651 | blockText = blockText.replace(/&\#8217;/g, "'");
652 | blockText = blockText.replace(/&\#8212;/g, "---");
653 | blockText = blockText.replace(/&\#8211;/g, "--");
654 | blockText = blockText.replace(/&\#8230;/g, "...");
655 | return blockText;
656 | }
657 |
658 | Markdown.Extra.prototype.applyPants = function(text) {
659 | // Dashes
660 | text = text.replace(/---/g, "—").replace(/--/g, "–");
661 | // Ellipses
662 | text = text.replace(/\.\.\./g, "…").replace(/\.\s\.\s\./g, "…");
663 | // Backticks
664 | text = text.replace(/``/g, "“").replace (/''/g, "”");
665 |
666 | if(/^'$/.test(text)) {
667 | // Special case: single-character ' token
668 | if(/\S/.test(this.smartyPantsLastChar)) {
669 | return "’";
670 | }
671 | return "‘";
672 | }
673 | if(/^"$/.test(text)) {
674 | // Special case: single-character " token
675 | if(/\S/.test(this.smartyPantsLastChar)) {
676 | return "”";
677 | }
678 | return "“";
679 | }
680 |
681 | // Special case if the very first character is a quote
682 | // followed by punctuation at a non-word-break. Close the quotes by brute force:
683 | text = text.replace (/^'(?=[!"#\$\%'()*+,\-.\/:;<=>?\@\[\\]\^_`{|}~]\B)/, "’");
684 | text = text.replace (/^"(?=[!"#\$\%'()*+,\-.\/:;<=>?\@\[\\]\^_`{|}~]\B)/, "”");
685 |
686 | // Special case for double sets of quotes, e.g.:
687 | // ',
602 | encodeCode(codeblock), '
\n" + result + "\n
";
771 | return pre + self.hashExtraBlock(result) + "\n\n";
772 | });
773 |
774 | return removeAnchors(text);
775 | };
776 |
777 | // Process the contents of a single definition list, splitting it
778 | // into individual term and definition list items.
779 | Markdown.Extra.prototype.processDefListItems = function(listStr) {
780 | var self = this;
781 |
782 | var dt = new RegExp(
783 | ['(\\x02\\n?|\\n\\n+)' , // leading line
784 | '(' , // definition terms = $1
785 | '[ ]{0,3}' , // leading whitespace
786 | '(?![:][ ]|[ ])' , // negative lookahead for a definition
787 | // mark (colon) or more whitespace
788 | '(?:\\S.*\\n)+?' , // actual term (not whitespace)
789 | ')' ,
790 | '(?=\\n?[ ]{0,3}:[ ])' // lookahead for following line feed
791 | ].join(''), // with a definition mark
792 | 'gm'
793 | );
794 |
795 | var dd = new RegExp(
796 | ['\\n(\\n+)?' , // leading line = $1
797 | '(' , // marker space = $2
798 | '[ ]{0,3}' , // whitespace before colon
799 | '[:][ ]+' , // definition mark (colon)
800 | ')' ,
801 | '([\\s\\S]+?)' , // definition text = $3
802 | '(?=\\n*' , // stop at next definition mark,
803 | '(?:' , // next term or end of text
804 | '\\n[ ]{0,3}[:][ ]|' ,
805 | '$2$3");
859 | };
860 |
861 |
862 | /***********************************************************
863 | * New lines *
864 | ************************************************************/
865 |
866 | Markdown.Extra.prototype.newlines = function(text) {
867 | // We have to ignore already converted newlines and line breaks in sub-list items
868 | return text.replace(/(<(?:br|\/li)>)?\n/g, function(wholeMatch, previousTag) {
869 | return previousTag ? wholeMatch : "
\n";
870 | });
871 | };
872 |
873 | })();
874 |
875 |
--------------------------------------------------------------------------------
/lib/markdown/Markdown.Sanitizer.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | var output, Converter;
3 | if (typeof exports === "object" && typeof require === "function") { // we're in a CommonJS (e.g. Node.js) module
4 | output = exports;
5 | Converter = require("./Markdown.Converter").Converter;
6 | } else {
7 | output = window.Markdown;
8 | Converter = output.Converter;
9 | }
10 |
11 | output.getSanitizingConverter = function () {
12 | var converter = new Converter();
13 | converter.hooks.chain("postConversion", sanitizeHtml);
14 | converter.hooks.chain("postConversion", balanceTags);
15 | return converter;
16 | }
17 |
18 | function sanitizeHtml(html) {
19 | return html.replace(/<[^>]*>?/gi, sanitizeTag);
20 | }
21 |
22 | // (tags that can be opened/closed) | (tags that stand alone)
23 | var basic_tag_whitelist = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|i|kbd|li|ol|p|pre|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i;
24 | // |
25 | var a_white = /^(]+")?\s?>|<\/a>)$/i;
26 |
27 | // ]*")?(\stitle="[^"<>]*")?\s?\/?>)$/i;
29 |
30 | function sanitizeTag(tag) {
31 | if (tag.match(basic_tag_whitelist) || tag.match(a_white) || tag.match(img_white))
32 | return tag;
33 | else
34 | return "";
35 | }
36 |
37 | ///
";
62 | var match;
63 | var tagpaired = [];
64 | var tagremove = [];
65 | var needsRemoval = false;
66 |
67 | // loop through matched tags in forward order
68 | for (var ctag = 0; ctag < tagcount; ctag++) {
69 | tagname = tags[ctag].replace(/<\/?(\w+).*/, "$1");
70 | // skip any already paired tags
71 | // and skip tags in our ignore list; assume they're self-closed
72 | if (tagpaired[ctag] || ignoredtags.search("<" + tagname + ">") > -1)
73 | continue;
74 |
75 | tag = tags[ctag];
76 | match = -1;
77 |
78 | if (!/^<\//.test(tag)) {
79 | // this is an opening tag
80 | // search forwards (next tags), look for closing tags
81 | for (var ntag = ctag + 1; ntag < tagcount; ntag++) {
82 | if (!tagpaired[ntag] && tags[ntag] == "" + tagname + ">") {
83 | match = ntag;
84 | break;
85 | }
86 | }
87 | }
88 |
89 | if (match == -1)
90 | needsRemoval = tagremove[ctag] = true; // mark for removal
91 | else
92 | tagpaired[match] = true; // mark paired
93 | }
94 |
95 | if (!needsRemoval)
96 | return html;
97 |
98 | // delete all orphaned tags from the string
99 |
100 | var ctag = 0;
101 | html = html.replace(re, function (match) {
102 | var res = tagremove[ctag] ? "" : match;
103 | ctag++;
104 | return res;
105 | });
106 | return html;
107 | }
108 | })();
109 |
--------------------------------------------------------------------------------
/lib/markdown/prettify.js:
--------------------------------------------------------------------------------
1 | var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
2 | (function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
3 | [],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c