├── LICENSE.md ├── README.md ├── kramdown-service ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── HISTORY.md ├── Manifest.txt ├── NOTES.md ├── README.md ├── Rakefile ├── TODOS.md ├── bin │ └── kramup ├── boot.rb ├── config.ru ├── lib │ └── kramdown │ │ ├── service.rb │ │ └── service │ │ ├── docs │ │ └── welcome.md │ │ ├── public │ │ ├── css │ │ │ └── markdown │ │ │ │ ├── note.css │ │ │ │ └── themes │ │ │ │ └── basic.css │ │ ├── i │ │ │ └── dots-white.gif │ │ ├── js │ │ │ ├── kramdown.js │ │ │ ├── lib3rd │ │ │ │ └── jquery-2.0.1.min.js │ │ │ └── markdown.note.js │ │ └── style.css │ │ ├── version.rb │ │ └── views │ │ ├── _debug.erb │ │ ├── _editor.erb │ │ ├── _editor_head.erb │ │ ├── _editor_setup.erb │ │ ├── _service.erb │ │ ├── _version.erb │ │ ├── debug.erb │ │ ├── editor.erb │ │ ├── index.erb │ │ ├── layout.erb │ │ └── service.erb └── test │ ├── helper.rb │ ├── test_babelmark.rb │ ├── test_kramdown.rb │ └── test_markdown.rb ├── markdown-service ├── .gitignore ├── Gemfile ├── HISTORY.md ├── Manifest.txt ├── README.md ├── Rakefile ├── boot.rb ├── config.ru └── lib │ └── markdown │ ├── service.rb │ └── service │ ├── docs │ └── welcome.md │ ├── public │ ├── css │ │ └── markdown │ │ │ ├── note.css │ │ │ └── themes │ │ │ └── basic.css │ ├── i │ │ └── dots-white.gif │ ├── js │ │ ├── lib3rd │ │ │ ├── jquery-2.0.1.min.js │ │ │ ├── pagedown.js │ │ │ └── showdown.min.js │ │ ├── markdown.api.js │ │ ├── markdown.lib.js │ │ └── markdown.note.js │ ├── note.html │ └── style.css │ ├── version.rb │ └── views │ ├── _about.erb │ ├── _debug.erb │ ├── _editor.erb │ ├── _editor_head.erb │ ├── _editor_setup.erb │ ├── _libs.erb │ ├── _libs_service.erb │ ├── _service.erb │ ├── _version.erb │ ├── debug.erb │ ├── editor.erb │ ├── index.erb │ ├── layout.erb │ └── service.erb ├── markdown-tools ├── .gitignore ├── HISTORY.md ├── Manifest.txt ├── README.md ├── Rakefile ├── bin │ └── markdown └── lib │ └── markdown │ ├── cli │ ├── gen.rb │ ├── opts.rb │ ├── runner.rb │ └── version.rb │ └── tools.rb ├── markdown.api.js ├── README.md └── markdown.api.js ├── markdown.lib.js ├── README.md └── markdown.lib.js ├── markdown.note.starter ├── .gitignore ├── README.md ├── css │ ├── markdown.note.css │ └── markdown.themes.basic.css ├── js │ ├── markdown.note.js │ └── showdown.min.js └── note.html ├── markdown.note ├── .gitignore ├── README.md ├── css │ └── markdown │ │ ├── note.css │ │ └── themes │ │ └── basic.css ├── i │ └── dots-white.gif ├── js │ ├── lib3rd │ │ ├── jquery-2.0.1.min.js │ │ ├── pagedown.js │ │ └── showdown.min.js │ ├── markdown.api.js │ ├── markdown.lib.js │ └── markdown.note.js └── note.html ├── markdown.themes ├── README.md └── basic.css └── markdown ├── .gitignore ├── HISTORY.md ├── Manifest.txt ├── README.md ├── Rakefile ├── TODO.md ├── lib ├── markdown.rb └── markdown │ ├── config.rb │ ├── engines │ ├── bluecloth.rb │ ├── kramdown.rb │ ├── maruku.rb │ ├── pandoc_ruby.rb │ ├── rdiscount.rb │ ├── redcarpet.rb │ └── rpeg_markdown.rb │ ├── version.rb │ └── wrapper.rb ├── sandbox ├── bench.rb ├── rest.text └── test.text └── test ├── helper.rb ├── test_kramdown.rb └── test_redcarpet.rb /LICENSE.md: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | 117 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # markdown tools, libraries & scripts 2 | 3 | Gems: 4 | 5 | - [markdown](markdown) - markdown engine wrapper - use your markdown library of choice 6 | - [markdown-service](markdown-service) - markdown HTTP JSON API service 7 | - [markdown-tools](markdown-tools) - markdown command line tools 8 | 9 | 10 | 11 | - [kramdown-service](kramdown-service) - kramdown HTTP JSON API service (convert markdown to HTML or LaTeX) 12 | 13 | 14 | - [markdown.note](markdown.note) - another simple single-page, server-less markdown editor in javascript & hypertext 15 | - [markdown.note.starter](markdown.note.starter) - another simple single-page, server-less markdown editor in javaScript & hypertext (started edition) 16 | - [markdown.api.js](markdown.api.js) - markdown HTTP JSON API (also known as dingus) 17 | - [markdown.lib.js](markdown.lib.js) - markdown (wrapper) for libraries in JavaScript 18 | 19 | 20 | - [markdown.themes](markdown.themes) - markdown themes (styles) 21 | 22 | 23 | 24 | ## License 25 | 26 | The scripts are dedicated to the public domain. 27 | Use it as you please with no restrictions whatsoever. 28 | 29 | -------------------------------------------------------------------------------- /kramdown-service/.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | coverage 6 | InstalledFiles 7 | lib/bundler/man 8 | pkg 9 | rdoc 10 | spec/reports 11 | test/tmp 12 | test/version_tmp 13 | tmp 14 | 15 | # YARD artifacts 16 | .yardoc 17 | _yardoc 18 | doc/ 19 | 20 | -------------------------------------------------------------------------------- /kramdown-service/Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | gem 'sinatra', :require => 'sinatra/base' 4 | 5 | 6 | gem 'kramdown' 7 | gem 'kramdown-service' ## :path => '.' ## try to use local (in-place) version 8 | 9 | 10 | ################### 11 | # more libs 12 | 13 | gem 'rouge' # syntax highlighter 14 | 15 | 16 | -------------------------------------------------------------------------------- /kramdown-service/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | kramdown (1.10.0) 5 | kramdown-service (0.3.0) 6 | kramdown 7 | rouge 8 | sinatra 9 | rack (1.6.4) 10 | rack-protection (1.5.3) 11 | rack 12 | rouge (1.10.1) 13 | sinatra (1.4.7) 14 | rack (~> 1.5) 15 | rack-protection (~> 1.4) 16 | tilt (>= 1.3, < 3) 17 | tilt (2.0.2) 18 | 19 | PLATFORMS 20 | x86-mingw32 21 | 22 | DEPENDENCIES 23 | kramdown 24 | kramdown-service 25 | rouge 26 | sinatra 27 | -------------------------------------------------------------------------------- /kramdown-service/HISTORY.md: -------------------------------------------------------------------------------- 1 | ### 0.0.1 / 2016-04-15 2 | 3 | * Everything is new. First release 4 | -------------------------------------------------------------------------------- /kramdown-service/Manifest.txt: -------------------------------------------------------------------------------- 1 | HISTORY.md 2 | Manifest.txt 3 | README.md 4 | Rakefile 5 | bin/kramup 6 | lib/kramdown/service.rb 7 | lib/kramdown/service/docs/welcome.md 8 | lib/kramdown/service/public/css/markdown/note.css 9 | lib/kramdown/service/public/css/markdown/themes/basic.css 10 | lib/kramdown/service/public/i/dots-white.gif 11 | lib/kramdown/service/public/js/kramdown.js 12 | lib/kramdown/service/public/js/lib3rd/jquery-2.0.1.min.js 13 | lib/kramdown/service/public/js/markdown.note.js 14 | lib/kramdown/service/public/style.css 15 | lib/kramdown/service/version.rb 16 | lib/kramdown/service/views/_debug.erb 17 | lib/kramdown/service/views/_editor.erb 18 | lib/kramdown/service/views/_editor_head.erb 19 | lib/kramdown/service/views/_editor_setup.erb 20 | lib/kramdown/service/views/_service.erb 21 | lib/kramdown/service/views/_version.erb 22 | lib/kramdown/service/views/debug.erb 23 | lib/kramdown/service/views/editor.erb 24 | lib/kramdown/service/views/index.erb 25 | lib/kramdown/service/views/layout.erb 26 | lib/kramdown/service/views/service.erb 27 | test/helper.rb 28 | test/test_babelmark.rb 29 | test/test_kramdown.rb 30 | test/test_markdown.rb 31 | -------------------------------------------------------------------------------- /kramdown-service/NOTES.md: -------------------------------------------------------------------------------- 1 | # Notes 2 | 3 | ## Alternatives 4 | 5 | Online Kramdown Editor by Daniel Perez Alvarez (aka unindented) 6 | 7 | - Live @ Heroku [kramdown.herokuapp.com](http://kramdown.herokuapp.com) 8 | - Source @ GitHub [unindented/online-kramdown-sinatra](https://github.com/unindented/online-kramdown-sinatra) 9 | 10 | 11 | 12 | ## kramdown Options 13 | 14 | doc = Kramdown::Document.new( '' ) 15 | pp doc.options 16 | 17 | ``` 18 | {:template=>"", 19 | :auto_ids=>true, 20 | :auto_id_stripping=>false, 21 | :auto_id_prefix=>"", 22 | :transliterated_header_ids=>false, 23 | :parse_block_html=>false, 24 | :parse_span_html=>true, 25 | :html_to_native=>false, 26 | :link_defs=>{}, 27 | :footnote_nr=>1, 28 | :enable_coderay=>true, 29 | :coderay_wrap=>:div, 30 | :coderay_line_numbers=>:inline, 31 | :coderay_line_number_start=>1, 32 | :coderay_tab_width=>8, 33 | :coderay_bold_every=>10, 34 | :coderay_css=>:style, 35 | :coderay_default_lang=>nil, 36 | :entity_output=>:as_char, 37 | :toc_levels=>[1, 2, 3, 4, 5, 6], 38 | :line_width=>72, 39 | :latex_headers=> 40 | ["section", 41 | "subsection", 42 | "subsubsection", 43 | "paragraph", 44 | "subparagraph", 45 | "subparagraph"], 46 | :smart_quotes=>["lsquo", "rsquo", "ldquo", "rdquo"], 47 | :remove_block_html_tags=>true, 48 | :remove_span_html_tags=>false, 49 | :header_offset=>0, 50 | :hard_wrap=>true, 51 | :syntax_highlighter=>:coderay, 52 | :syntax_highlighter_opts=>{}, 53 | :math_engine=>:mathjax, 54 | :math_engine_opts=>{}, 55 | :footnote_backlink=>"↩"} 56 | ``` 57 | 58 | doc = Kramdown::Document.new( '', input: 'GFM', hard_wrap: false, syntax_highlighter: 'rouge' ) 59 | pp doc.options 60 | 61 | ``` 62 | {:template=>"", 63 | :auto_ids=>true, 64 | :auto_id_stripping=>false, 65 | :auto_id_prefix=>"", 66 | :transliterated_header_ids=>false, 67 | :parse_block_html=>false, 68 | :parse_span_html=>true, 69 | :html_to_native=>false, 70 | :link_defs=>{}, 71 | :footnote_nr=>1, 72 | :enable_coderay=>true, 73 | :coderay_wrap=>:div, 74 | :coderay_line_numbers=>:inline, 75 | :coderay_line_number_start=>1, 76 | :coderay_tab_width=>8, 77 | :coderay_bold_every=>10, 78 | :coderay_css=>:style, 79 | :coderay_default_lang=>nil, 80 | :entity_output=>:as_char, 81 | :toc_levels=>[1, 2, 3, 4, 5, 6], 82 | :line_width=>72, 83 | :latex_headers=> 84 | ["section", 85 | "subsection", 86 | "subsubsection", 87 | "paragraph", 88 | "subparagraph", 89 | "subparagraph"], 90 | :smart_quotes=>["lsquo", "rsquo", "ldquo", "rdquo"], 91 | :remove_block_html_tags=>true, 92 | :remove_span_html_tags=>false, 93 | :header_offset=>0, 94 | :hard_wrap=>false, 95 | :syntax_highlighter=>:rouge, 96 | :syntax_highlighter_opts=>{}, 97 | :math_engine=>:mathjax, 98 | :math_engine_opts=>{}, 99 | :footnote_backlink=>"↩", 100 | :input=>"GFM"} 101 | ``` 102 | -------------------------------------------------------------------------------- /kramdown-service/README.md: -------------------------------------------------------------------------------- 1 | # kramdown-service gem - kramdown HTTP JSON API service (convert markdown to HTML or LaTeX) 2 | 3 | * home :: [github.com/writekit/kramdown-service](https://github.com/writekit/kramdown-service) 4 | * bugs :: [github.com/writekit/kramdown-service/issues](https://github.com/writekit/kramdown-service/issues) 5 | * gem :: [rubygems.org/gems/kramdown-service](https://rubygems.org/gems/kramdown-service) 6 | * rdoc :: [rubydoc.info/gems/kramdown-service](http://rubydoc.info/gems/kramdown-service) 7 | 8 | 9 | ## Live Version 10 | 11 | Try the `markdown` HTTP (JSON) API running 12 | on Heroku [`trykramdown.herokuapp.com`](http://trykramdown.herokuapp.com). 13 | 14 | Note: If you see an Application Error on Heroku. Sorry. It means "**Free app running time quota exhausted**". 15 | Please, check back and retry on the first day of the next upcoming month (that starts a new dyna hours quota) or use `$ kramup` to run the service on your local machine). Thanks. 16 | 17 | 18 | 19 | 20 | ## Start Your Own Local Version / Service 21 | 22 | To start your own local version on your own machine use the bundled command line tool called `kramup`. 23 | 24 | Step 0 - Install the gem e.g. 25 | 26 | $ gem install kramdown-service 27 | 28 | Step 1 - Start the server / service e.g. 29 | 30 | $ kramup 31 | 32 | Step 2 - Open up the editor page in your browser e.g. use `http://localhost:4567`. 33 | 34 | That's it. 35 | 36 | 37 | ## Usage - Web Service / HTTP (JSON) API - `GET /markdown` 38 | 39 | 40 | Example 1 - Converting to Hypertext (HTML): 41 | 42 | GET /markdown?text=Hello+World! 43 | 44 |

Hello World!

45 | 46 | 47 | Example 2 - Converting to LaTeX: 48 | 49 | GET /markdown?text=Hello+World!&to=latex 50 | 51 | Hello World! 52 | 53 | 54 | 55 | 56 | ## License 57 | 58 | The `kramdown-service` scripts are dedicated to the public domain. 59 | Use it as you please with no restrictions whatsoever. 60 | 61 | 62 | ## Questions? Comments? 63 | 64 | Send them along to the 65 | [wwwmake forum/mailing list](http://groups.google.com/group/wwwmake). 66 | Thanks! 67 | -------------------------------------------------------------------------------- /kramdown-service/Rakefile: -------------------------------------------------------------------------------- 1 | require 'hoe' 2 | require './lib/kramdown/service/version.rb' 3 | 4 | Hoe.spec 'kramdown-service' do 5 | 6 | self.version = KramdownService::VERSION 7 | 8 | self.summary = 'kramdown-service gem - kramdown HTTP JSON API service (convert markdown to HTML or LaTeX)' 9 | self.description = summary 10 | 11 | self.urls = ['https://github.com/writekit/kramdown-service'] 12 | 13 | self.author = 'Gerald Bauer' 14 | self.email = 'wwwmake@googlegroups.com' 15 | 16 | self.extra_deps = [ 17 | ['kramdown', '>=1.17.0'], ## markdown converter 18 | ['rouge'], ## syntax highlighter 19 | ['sinatra', '>=2.0.4'], 20 | ] 21 | 22 | # switch extension to .markdown for gihub formatting 23 | self.readme_file = 'README.md' 24 | self.history_file = 'HISTORY.md' 25 | 26 | self.licenses = ['Public Domain'] 27 | 28 | self.spec_extras = { 29 | required_ruby_version: '>= 2.2.2' 30 | } 31 | 32 | end 33 | -------------------------------------------------------------------------------- /kramdown-service/TODOS.md: -------------------------------------------------------------------------------- 1 | # TODOs 2 | 3 | - [ ] remove view-source: from sample links in service docu 4 | 5 | - [ ] check GFM if hard breaks are enforced by defaut? if yes, always add hard_breaks: false or something 6 | 7 | - [ ] add kramup bin in /bin to startup server 8 | - [ ] add rouge syntax highlighter 9 | - [ ] add some tests for the service use rack-test ?? 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /kramdown-service/bin/kramup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | ## for testing use: 4 | ## $ ruby -I ./lib bin/kramup 5 | 6 | ## note: use chmod a+x kramup to add execute flag 7 | 8 | 9 | require 'kramdown/service' 10 | 11 | 12 | Kramdown::Service.run! 13 | -------------------------------------------------------------------------------- /kramdown-service/boot.rb: -------------------------------------------------------------------------------- 1 | 2 | 3 | ENV['RACK_ENV'] ||= 'development' 4 | 5 | puts "ENV['RACK_ENV'] = #{ENV['RACK_ENV']}" 6 | 7 | ## NB: no DB required/in use for now; just simple service calls 8 | 9 | ## add lib to load path 10 | 11 | $LOAD_PATH << "./lib" 12 | 13 | require './lib/kramdown/service.rb' 14 | 15 | -------------------------------------------------------------------------------- /kramdown-service/config.ru: -------------------------------------------------------------------------------- 1 | require './boot' 2 | 3 | run Kramdown::Service 4 | 5 | -------------------------------------------------------------------------------- /kramdown-service/lib/kramdown/service.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | ###### 4 | # NB: use rackup to startup Sinatra service (see config.ru) 5 | # 6 | # e.g. config.ru: 7 | # require './boot' 8 | # run Kramdown::Service 9 | 10 | 11 | require 'pp' 12 | require 'json' 13 | 14 | 15 | # 3rd party libs/gems 16 | 17 | require 'sinatra/base' 18 | 19 | require 'kramdown' 20 | 21 | # our own code 22 | 23 | require 'kramdown/service/version' # let version always go first 24 | 25 | 26 | 27 | module Kramdown 28 | 29 | class Service < Sinatra::Base 30 | 31 | PUBLIC_FOLDER = "#{KramdownService.root}/lib/kramdown/service/public" 32 | VIEWS_FOLDER = "#{KramdownService.root}/lib/kramdown/service/views" 33 | 34 | puts "[boot] kramdown-service - setting public folder to: #{PUBLIC_FOLDER}" 35 | puts "[boot] kramdown-service - setting views folder to: #{VIEWS_FOLDER}" 36 | 37 | set :public_folder, PUBLIC_FOLDER # set up the static dir (with images/js/css inside) 38 | set :views, VIEWS_FOLDER # set up the views dir 39 | 40 | set :static, true # set up static file routing 41 | 42 | 43 | ############################################## 44 | # Controllers / Routing / Request Handlers 45 | 46 | 47 | get %r{/(service|services|srv|s)} do 48 | ## just a "live" docu page 49 | erb :service 50 | end 51 | 52 | get %r{/(editor|edit|ed|e)} do 53 | # note: allow optional params e.g. text and opts 54 | ## note: for now only html supported on get form/url params 55 | text = params.delete('text') || welcome_markdown 56 | to = params.delete('to') || 'html' ## optional - default to html 57 | opts = params_to_opts( params ) 58 | 59 | @welcome_markdown = text 60 | @welcome_html = text_to_html( text, opts ) 61 | 62 | erb :editor 63 | end 64 | 65 | get '/' do 66 | # note: allow optional params e.g. text and opts 67 | ## note: for now only html supported on get form/url params 68 | text = params.delete('text') || welcome_markdown 69 | to = params.delete('to') || 'html' ## optional - default to html 70 | opts = params_to_opts( params ) 71 | 72 | @welcome_markdown = text 73 | @welcome_html = text_to_html( text, opts ) 74 | 75 | erb :index 76 | end 77 | 78 | # return hypertext (html) ## allow /markdown or /m 79 | get %r{/(markdown|m)} do 80 | 81 | text = params.delete('text') || '' ## if no text param supplied, use empty/blank string 82 | to = params.delete('to') || 'html' ## optional - default to html 83 | opts = params_to_opts( params ) 84 | 85 | if ['latex','l','tex'].include?( to.downcase ) 86 | content_type 'text/latex' ### todo: check if latex content_type exists? 87 | text_to_latex( text, opts ) 88 | else ## assume html (default) 89 | content_type 'text/html' 90 | text_to_html( text, opts ) 91 | end 92 | 93 | end 94 | 95 | 96 | # return babelmark2/dingus-style json 97 | # return html wrapped in json (follows babelmark2 dingus service api) 98 | # note: defaults (uses) GFM - github-flavored markdown mode/input 99 | # note: only supports html for now (e.g. does NOT support to=html|latex option etc.) 100 | get '/babelmark' do 101 | text = params.delete('text') || '' ## if no text param supplied, use empty/blank string 102 | 103 | data = { 104 | name: 'kramdown', 105 | html: Kramdown::Document.new( text, input: 'GFM' ).to_html, 106 | version: Kramdown::VERSION 107 | } 108 | 109 | json_or_jsonp( data.to_json ) 110 | end 111 | 112 | 113 | get %r{/(options|opts|o)} do ## for debugging/testing "dump" options 114 | content_type 'text/plain' 115 | 116 | opts = preprocess_opts( params_to_opts( params )) 117 | doc = Kramdown::Document.new( '', opts ) 118 | doc.options.inspect 119 | end 120 | 121 | 122 | get '/d*' do 123 | erb :debug 124 | end 125 | 126 | 127 | private 128 | 129 | def welcome_markdown 130 | ## todo: rotate welcome / use random number for index 131 | # place markdown docs in server/docs 132 | text = File.read( "#{KramdownService.root}/lib/kramdown/service/docs/welcome.md" ) 133 | text 134 | end 135 | 136 | def params_to_opts( params ) 137 | ## convert (web form) params to kramdown (ruby) opts 138 | 139 | puts "params : #{params.class.name}:" 140 | pp params 141 | 142 | opts = {} 143 | 144 | ## map true/false strings to boolean 145 | params.each do |k,v| 146 | puts " k: >#{k}< : #{k.class.name}, v: >#{v}< : #{v.class.name}" 147 | 148 | ## skip "built-in" sinatra "internal" params 149 | ## - todo - use splice and whitelist instead - why? why not? 150 | next if ['splat', 'captures'].include?( k ) 151 | 152 | if v.is_a?( String ) && ['t', 'true'].include?( v.downcase ) 153 | opts[ k ] = true 154 | elsif v.is_a?( String ) && ['f', 'false'].include?( v.downcase ) 155 | opts[ k ] = false 156 | else 157 | opts[ k ] = v 158 | end 159 | end 160 | 161 | opts 162 | end 163 | 164 | 165 | def preprocess_opts( opts ) 166 | ### special case for input opt 167 | ## always default to gfm (github-flavored markdown) for now 168 | 169 | input = opts.delete( 'input' ) || 'GFM' 170 | 171 | if ['classic', 'std', 'standard', 'kramdown' ].include?( input.downcase ) 172 | ## skip; "pseudo" input options map to no (zero) standard/classic input 173 | elsif ['gfm'].include?( input.downcase ) 174 | ## note: GFM **MUST** be uppercase (gets converted to a matching ruby parser class) 175 | opts[ 'input' ] = 'GFM' 176 | ## in gfm mode (auto-)add hard_wrap = false unless set 177 | opts['hard_wrap'] = false if opts['hard_wrap'].nil? 178 | else 179 | opts[ 'input' ] = input 180 | end 181 | 182 | puts "opts (preprocessed/effective):" 183 | pp opts 184 | 185 | opts 186 | end 187 | 188 | def text_to_html( text, opts={} ) 189 | puts "text_to_html:" 190 | pp text 191 | pp opts 192 | 193 | opts = preprocess_opts( opts ) ## defaults to GFM input etc. 194 | 195 | Kramdown::Document.new( text, opts ).to_html 196 | end 197 | 198 | def text_to_latex( text, opts={} ) 199 | puts "text_to_latex:" 200 | pp text 201 | pp opts 202 | 203 | opts = preprocess_opts( opts ) ## defaults to GFM input etc. 204 | 205 | Kramdown::Document.new( text, opts ).to_latex 206 | end 207 | 208 | 209 | ### helper for json or jsonp response (depending on callback para) 210 | 211 | def json_or_jsonp( json ) 212 | callback = params.delete('callback') 213 | response = '' 214 | 215 | if callback 216 | content_type :js 217 | response = "#{callback}(#{json})" 218 | else 219 | content_type :json 220 | response = json 221 | end 222 | 223 | response 224 | end 225 | 226 | 227 | end # class Service 228 | end # module Kramdown 229 | 230 | 231 | # say hello 232 | puts KramdownService.banner 233 | -------------------------------------------------------------------------------- /kramdown-service/lib/kramdown/service/docs/welcome.md: -------------------------------------------------------------------------------- 1 | # Heading 1 2 | 3 | ## Heading 2 4 | 5 | ### Heading 3 6 | 7 | Welcome to the [kramdown Online Editor](/). We hope you **really** enjoy using this. 8 | 9 | Just type some [markdown](http://en.wikipedia.org/wiki/Markdown) 10 | on the left and see it on the right. *Simple as that.* 11 | 12 | > Quote goes here. 13 | 14 | A list: 15 | 16 | - One 17 | - Two 18 | - Three 19 | 20 | Some inline code `to_html` and a preformatted code block: 21 | 22 | ``` 23 | Kramdown::Document.new( 'Hello Markdown!' ).to_html 24 | ``` 25 | -------------------------------------------------------------------------------- /kramdown-service/lib/kramdown/service/public/css/markdown/note.css: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 4 | background-color: #EEEEEC; 5 | } 6 | 7 | /*********** 8 | * fix: use scss or less; cleanup css 9 | * 10 | ****/ 11 | 12 | a#output-toggle, a#output-toggle:visited, a#output-toggle:hover, 13 | a#output-update, a#output-update:visited, a#output-update:hover, 14 | a#input-toggle, a#input-toggle:visited, a#input-toggle:hover { 15 | color: black; 16 | text-decoration: none; } 17 | 18 | 19 | 20 | #input #note { 21 | width: 100%; min-height: 600px; 22 | 23 | -moz-box-sizing: border-box; 24 | -webkit-box-sizing: border-box; 25 | box-sizing: border-box; 26 | } 27 | 28 | 29 | .black { 30 | background-color: #2E3436; 31 | border: medium none; 32 | border-radius: 4px 4px 4px 4px; 33 | padding: 6px; 34 | color: #FFFFFF; 35 | font-weight: bold; 36 | } 37 | 38 | 39 | #output { 40 | width: 100%; 41 | /* padding-left: 10px; */ 42 | background-color: white; 43 | border-radius: 4px 4px 4px 4px; 44 | padding: 6px; 45 | 46 | -moz-box-sizing: border-box; 47 | -webkit-box-sizing: border-box; 48 | box-sizing: border-box; 49 | } 50 | 51 | 52 | #output-source { 53 | display: none; 54 | width: 100%; min-height: 600px; 55 | background-color: #EEEEEC; 56 | border: none; 57 | 58 | -moz-box-sizing: border-box; 59 | -webkit-box-sizing: border-box; 60 | box-sizing: border-box; 61 | } 62 | 63 | 64 | #output-loading { 65 | display: none; 66 | width: 21px; 67 | height: 5px; 68 | background: url('../../i/dots-white.gif') no-repeat; 69 | /* -webkit-transition: all 0.1s linear; */ 70 | } -------------------------------------------------------------------------------- /kramdown-service/lib/kramdown/service/public/css/markdown/themes/basic.css: -------------------------------------------------------------------------------- 1 | 2 | /*********** 3 | * fix: use scss or less; cleanup css 4 | * 5 | ****/ 6 | 7 | 8 | .markdown a, 9 | .markdown a:visited { 10 | color: #2e80d3; 11 | text-decoration: underline; 12 | } 13 | 14 | .markdown a:hover { 15 | background-color: gold; 16 | } 17 | 18 | 19 | .markdown em { 20 | background-color: #fffeca; 21 | padding: 0 0.08em; 22 | } 23 | 24 | .markdown abbr { 25 | border-bottom: 1px dashed; 26 | cursor: help; 27 | } 28 | 29 | .markdown blockquote { 30 | border-left: 5px solid #ddd; 31 | color: #555; 32 | margin: 0 0 1em; 33 | padding-left: 0.6em; 34 | } 35 | 36 | .markdown pre { 37 | background-color: #f8f8ff; 38 | border: 1px solid #dedede; 39 | color: #444; 40 | font-family: "Bitstream Vera Sans Mono", Courier, monospace; 41 | font-size: 0.8em; 42 | line-height: 1.5em; 43 | margin: 0 0 2em; 44 | overflow: auto; 45 | padding: 0.5em; 46 | } 47 | 48 | .markdown pre code { 49 | background-color: #f8f8ff; 50 | border: medium none; 51 | font-size: 1em; 52 | padding: 0; 53 | } 54 | 55 | .markdown code { 56 | background-color: #f8f8ff; 57 | border: 1px solid #dedede; 58 | color: #444; 59 | padding: 0 0.2em; 60 | font-family: "Bitstream Vera Sans Mono", Courier, monospace; 61 | font-size: 0.8em; 62 | } 63 | -------------------------------------------------------------------------------- /kramdown-service/lib/kramdown/service/public/i/dots-white.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubycocos/markdown/09b38ef4039d2750c1faaf6ec79817c4e48e985e/kramdown-service/lib/kramdown/service/public/i/dots-white.gif -------------------------------------------------------------------------------- /kramdown-service/lib/kramdown/service/public/js/kramdown.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var kramdown_new = function( opts ) { 4 | 5 | var settings; // NB: defaults + opts merged => settings 6 | 7 | var defaults = { 8 | api_url: 'http://trykramdown.herokuapp.com/markdown' 9 | } 10 | 11 | 12 | function _debug( msg ) 13 | { 14 | if(window.console && window.console.log ) 15 | window.console.log( "[debug] " + msg ); 16 | } 17 | 18 | 19 | function _init( opts ) { 20 | settings = $.extend( {}, defaults, opts ); 21 | } 22 | 23 | _init( opts ); 24 | 25 | 26 | function _convert( text, more_params, handler ) 27 | { 28 | var params = $.extend( { text: text }, more_params ); // merge in more params; use text for required param 29 | 30 | $.get( settings.api_url, params, function( data ) { 31 | handler( data ); 32 | }); 33 | } 34 | 35 | function convert_to_html( text, handler ) { 36 | // note: make gfm (github-flavored markdown) the default parser 37 | _convert( text, { to: 'html' }, handler ); 38 | } 39 | 40 | function convert_to_html_with_syntax_highlighter( text, handler ) { 41 | // note: make gfm (github-flavored markdown) the default parser 42 | _convert( text, { to: 'html', syntax_highlighter: 'rouge' }, handler ); 43 | } 44 | 45 | function convert_to_html_with_classic( text, handler ) { 46 | // note: use "classic" "standard" kramdown parser/reader 47 | _convert( text, { to: 'html', input: 'classic' }, handler ); 48 | } 49 | 50 | 51 | 52 | function convert_to_latex( text, handler ) { 53 | _convert( text, { to: 'latex' }, handler ); 54 | } 55 | 56 | return { 57 | convert_to_html: convert_to_html, 58 | convert_to_html_with_syntax_highlighter: convert_to_html_with_syntax_highlighter, 59 | convert_to_html_with_classic: convert_to_html_with_classic, 60 | convert_to_latex: convert_to_latex 61 | } 62 | 63 | } // fn kramdown_new 64 | 65 | -------------------------------------------------------------------------------- /kramdown-service/lib/kramdown/service/public/js/markdown.note.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var markdown_note_new = function( opts ) { 4 | 5 | // use module pattern (see JavaScript - The Good Parts) 6 | 7 | 8 | var getUrl = window.location; 9 | // note: host includes hostname + port; yes! 10 | var baseUrl = getUrl.protocol + "//" + getUrl.host; 11 | 12 | console.log( window.location ); 13 | console.log( baseUrl ); 14 | 15 | 16 | var kramdown = kramdown_new( { api_url: baseUrl + '/markdown' } ); 17 | // e.g. http://localhost:9292/markdown or http://trykramdown.herokuapp.com/markdown 18 | // kramdown api service / engine (see kramdown.js) 19 | 20 | var engines = [ 21 | { name: 'kramdown in GitHub-Flavored Markdown (GFM) Mode', format: 'HTML', 22 | markdown: kramdown.convert_to_html }, 23 | { name: 'kramdown in GitHub-Flavored Markdown (GFM) Mode w/ Syntax Highlighter (rouge)', format: 'HTML', 24 | markdown: kramdown.convert_to_html_with_syntax_highlighter }, 25 | { name: 'kramdown in "Classic" Mode', format: 'HTML', 26 | markdown: kramdown.convert_to_html_with_classic }, 27 | { name: 'kramdown in GitHub-Flavored Markdown (GFM) Mode', format: 'LaTeX', 28 | markdown: kramdown.convert_to_latex } 29 | ]; 30 | 31 | var welcome = { 32 | markdown: "Welcome to Markdown. We hope you **really** enjoy using this."+ 33 | "\n\n"+ 34 | "Just type some [markdown](http://daringfireball.net/projects/markdown) on the left and see it on the right. *Simple as that.*", 35 | html: "

Welcome to Markdown. We hope you really enjoy using this.

" + 36 | "

Just type some markdown on the left and see it on the right. Simple as that.

" 37 | } 38 | 39 | 40 | var settings; // NB: defaults + opts merged => settings 41 | 42 | var defaults = { 43 | output: '#output', 44 | output_source: '#output-source', 45 | output_toggle: { 46 | id: '#output-toggle', 47 | label_show: '[ Show HTML ]', 48 | label_hide: '[ Hide HTML ]' }, 49 | output_update: '#output-update', // a/link for update action 50 | output_loading: '#output-loading', // div for loading gif anim 51 | 52 | input: '#note', // textarea for markdown source 53 | input_lib: '#note-lib', // select inputbox for markdown libs/engines 54 | 55 | input_toggle: { 56 | id: '#input-toggle', 57 | label_black: '[ Use Black Color Theme]', 58 | label_white: '[ Use White Color Theme]' 59 | }, 60 | 61 | engines: engines, 62 | 63 | welcome: welcome 64 | } 65 | 66 | 67 | function _debug( msg ) 68 | { 69 | if(window.console && window.console.log ) 70 | window.console.log( "[debug] " + msg ); 71 | } 72 | 73 | var $output, 74 | $output_source, 75 | $output_toggle, 76 | $output_update, 77 | $output_loading, 78 | $input, 79 | $input_lib, 80 | $input_toggle; 81 | 82 | 83 | var show_html = false; 84 | var use_white_color_theme = false; 85 | var show_latex = false; 86 | 87 | function show_latex_output() { 88 | show_latex = true; 89 | 90 | $output.hide(); 91 | $output_toggle.hide(); // hide toggle show html button 92 | $output_source.show(); 93 | } 94 | 95 | function restore_html_output() { 96 | // restore output view to before entering "latex" mode 97 | if (show_latex == true) { 98 | show_latex = false; 99 | 100 | $output_toggle.show(); 101 | if( !show_html ) { // switch back in "preview" mode ? 102 | $output_source.hide(); 103 | $output.show(); 104 | } 105 | } 106 | } 107 | 108 | function toggle_output() 109 | { 110 | show_html = !show_html; 111 | 112 | if( show_html ) { 113 | $output_toggle.html( settings.output_toggle.label_hide ); 114 | $output.hide(); 115 | $output_source.show(); 116 | } 117 | else { 118 | $output_toggle.html( settings.output_toggle.label_show ); 119 | $output.show(); 120 | $output_source.hide(); 121 | } 122 | } 123 | 124 | 125 | function _toggle_color_theme() 126 | { 127 | /** 128 | * todo: move to addon?? out of "core" 129 | */ 130 | 131 | use_white_color_theme = !use_white_color_theme; 132 | if( use_white_color_theme ) { 133 | $input.removeClass( 'black' ); 134 | $input_toggle.html( settings.input_toggle.label_black ); 135 | } 136 | else { 137 | $input.addClass( 'black' ); 138 | $input_toggle.html( settings.input_toggle.label_white ); 139 | } 140 | } 141 | 142 | 143 | function update_output() 144 | { 145 | var text = $input.val(); // get markdown text 146 | var engine_index = parseInt( $input_lib.val(), 10); 147 | 148 | var engine = settings.engines[engine_index]; 149 | 150 | $output_loading.show(); // show progress bar/spinner 151 | 152 | engine.markdown( text, function( html ) { 153 | $output.html( html ); 154 | $output_source.html( html ); 155 | $output_loading.hide(); 156 | 157 | if( engine.format == 'LaTeX' ) // for latex always show source (only) 158 | show_latex_output(); 159 | else 160 | restore_html_output(); 161 | }); 162 | } 163 | 164 | 165 | function _init( opts ) 166 | { 167 | settings = $.extend( {}, defaults, opts ); 168 | 169 | $output = $( settings.output ); 170 | $output_source = $( settings.output_source ); 171 | $output_update = $( settings.output_update ); 172 | $output_toggle = $( settings.output_toggle.id ); 173 | $output_loading = $( settings.output_loading ); 174 | 175 | $input = $( settings.input ); 176 | $input_lib = $( settings.input_lib ); 177 | 178 | $input_toggle = $( settings.input_toggle.id ); 179 | 180 | $input.val( settings.welcome.markdown ); 181 | 182 | $output.html( settings.welcome.html ); 183 | $output_source.html( settings.welcome.html ); 184 | 185 | 186 | $output_update.click( function() { update_output(); } ); 187 | $output_toggle.click( function() { toggle_output(); } ); 188 | 189 | $input_toggle.click( function() { _toggle_color_theme(); } ); 190 | 191 | // add markdown engine/lib options 192 | var markdown_opts = ''; 193 | $.each( engines, function(index, engine) { 194 | markdown_opts += '