kevorkian 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/.DS_Store +0 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +9 -0
  5. data/Guardfile +39 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +29 -0
  8. data/Rakefile +20 -0
  9. data/kevorkian.gemspec +23 -0
  10. data/lib/kevorkian/engine.rb +6 -0
  11. data/lib/kevorkian/version.rb +3 -0
  12. data/lib/kevorkian.rb +6 -0
  13. data/vendor/assets/javascripts/.DS_Store +0 -0
  14. data/vendor/assets/javascripts/button.js.coffee +42 -0
  15. data/vendor/assets/javascripts/buttons/block_quotes.js.coffee +19 -0
  16. data/vendor/assets/javascripts/buttons/bold.js.coffee +15 -0
  17. data/vendor/assets/javascripts/buttons/code_block.js.coffee +19 -0
  18. data/vendor/assets/javascripts/buttons/code_line.js.coffee +15 -0
  19. data/vendor/assets/javascripts/buttons/h1.js.coffee +13 -0
  20. data/vendor/assets/javascripts/buttons/h2.js.coffee +13 -0
  21. data/vendor/assets/javascripts/buttons/h3.js.coffee +13 -0
  22. data/vendor/assets/javascripts/buttons/hr.js.coffee +13 -0
  23. data/vendor/assets/javascripts/buttons/href.js.coffee +58 -0
  24. data/vendor/assets/javascripts/buttons/italics.js.coffee +15 -0
  25. data/vendor/assets/javascripts/buttons/ordered_list.js.coffee +19 -0
  26. data/vendor/assets/javascripts/buttons/unordered_list.js.coffee +19 -0
  27. data/vendor/assets/javascripts/default_row.js.coffee +17 -0
  28. data/vendor/assets/javascripts/editor.js.coffee +41 -0
  29. data/vendor/assets/javascripts/kevorkian.js.coffee +11 -0
  30. data/vendor/assets/javascripts/row.js.coffee +14 -0
  31. data/vendor/assets/javascripts/seperator.js.coffee +4 -0
  32. data/vendor/assets/javascripts/utils/carat.js.coffee +15 -0
  33. data/vendor/assets/javascripts/utils/manipulation.js.coffee +21 -0
  34. data/vendor/assets/javascripts/utils/slice.js.coffee +6 -0
  35. data/vendor/assets/stylesheets/kevorkian.css +18 -0
  36. metadata +113 -0
data/.DS_Store ADDED
Binary file
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jquery-bootstrap-pagination.gemspec
4
+ gemspec
5
+
6
+
7
+ gem "guard"
8
+ gem 'rb-fsevent'
9
+ gem 'sprockets'
data/Guardfile ADDED
@@ -0,0 +1,39 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ # guard 'bundler' do
5
+ # watch('Gemfile')
6
+ # # Uncomment next line if Gemfile contain `gemspec' command
7
+ # # watch(/^.+\.gemspec/)
8
+ # end
9
+
10
+ # guard 'coffeescript', :input => 'app/assets/javascripts'
11
+
12
+ # guard 'rspec' do
13
+ # watch(%r{^spec/.+_spec\.rb$})
14
+ # watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
15
+ # watch('spec/spec_helper.rb') { "spec" }
16
+
17
+ # # Rails example
18
+ # watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
19
+ # watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
20
+ # watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
21
+ # watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
22
+ # watch('config/routes.rb') { "spec/routing" }
23
+ # watch('app/controllers/application_controller.rb') { "spec/controllers" }
24
+
25
+ # # Capybara features specs
26
+ # watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
27
+
28
+ # # Turnip features and steps
29
+ # watch(%r{^spec/acceptance/(.+)\.feature$})
30
+ # watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
31
+ # end
32
+
33
+
34
+ # Add files and commands to this file, like the example:
35
+ # watch(%r{file/path}) { `command(s)` }
36
+ #
37
+ # guard 'shell' do
38
+ # watch(/(.*).txt/) {|m| `tail #{m[0]}` }
39
+ # end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Mark Bates
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Kevorkian
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'kevorkian'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install kevorkian
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ # task :compile do
4
+ # require 'fileutils'
5
+ # include FileUtils
6
+
7
+ # src = File.join(File.dirname(__FILE__), "src")
8
+ # tmp = File.join(File.dirname(__FILE__), "tmp")
9
+ # vendorJs = File.join(File.dirname(__FILE__), "vendor", "assets", "javascripts")
10
+
11
+ # system `sprockets --include=#{src} --output #{tmp}`
12
+ # Dir[File.join(tmp, "**", "*.*")].each do |file|
13
+ # # File.join(File.dirname(__FILE__), "vendor", "assets", "javascripts", "**", "*.*")
14
+ # if file.match(/kevorkian(-.+)\.js/)
15
+ # js = File.read(file)
16
+ # puts js
17
+ # else
18
+ # end
19
+ # end
20
+ # end
data/kevorkian.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kevorkian/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "kevorkian"
8
+ gem.version = Kevorkian::VERSION
9
+ gem.authors = ["Mark Bates"]
10
+ gem.email = ["mark@markbates.com"]
11
+ gem.description = %q{Easy, extensible MarkDown editor.}
12
+ gem.summary = %q{Easy, extensible MarkDown editor.}
13
+ gem.homepage = ""
14
+ gem.license = "MIT"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.add_development_dependency "rake"
22
+ gem.add_development_dependency "rspec"
23
+ end
@@ -0,0 +1,6 @@
1
+ if defined? Rails
2
+ module Kevorkian
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module Kevorkian
2
+ VERSION = "1.0.0"
3
+ end
data/lib/kevorkian.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "kevorkian/version"
2
+ require "kevorkian/engine"
3
+
4
+ module Kevorkian
5
+ # Your code goes here...
6
+ end
Binary file
@@ -0,0 +1,42 @@
1
+ class MD.Button
2
+
3
+ constructor: (name, attributes = {}) ->
4
+ @name = name
5
+ @attributes = attributes
6
+ @attributes["onClick"] ?= @buttonClick
7
+ @attributes["html"] ?= @html
8
+
9
+ buttonClick: (button, range) =>
10
+
11
+ html: =>
12
+ @name.toUpperCase()
13
+
14
+ onClick: (e) =>
15
+ e?.preventDefault()
16
+ if @attributes.onClick
17
+ @attributes.onClick(@, MD.Utils.Carat.getRange(@editor.target_name))
18
+
19
+ render: =>
20
+ button = $("<button class='btn'></button>").append(@attributes.html())
21
+ button.click(@onClick)
22
+ if @tooltip?
23
+ button.attr("title", @tooltip())
24
+ button.tooltip()
25
+ return button
26
+
27
+ perform: (range, callback) =>
28
+ @editor.trigger("before.perform", range, @)
29
+ results = MD.Utils.Manipulation.replaceRange(@editor.target_name, range, callback)
30
+ @editor.trigger("after.perform", range, @, results)
31
+ @editor.trigger("change", results.finalText)
32
+ return results
33
+
34
+ performAndSelect: (range, callback) =>
35
+ results = @perform(range, callback)
36
+ @setCaratRange(results.finalRange)
37
+ return results
38
+
39
+ setCaratRange: (range) =>
40
+ @editor.trigger("before.setCarat", range, @)
41
+ MD.Utils.Carat.setRange(@editor.target_name, range.start, range.end)
42
+ @editor.trigger("after.setCarat", range, @)
@@ -0,0 +1,19 @@
1
+ class MD.Button.BlockQuotes extends MD.Button
2
+
3
+ constructor: (@attributes = {}) ->
4
+ @name = "blockquotes"
5
+ super(@name, @attributes)
6
+
7
+ html: ->
8
+ "BQ"
9
+
10
+ tooltip: ->
11
+ "Block Quotes"
12
+
13
+ buttonClick: (button, range) =>
14
+ button.performAndSelect range, (text) ->
15
+ lines = text.split("\n")
16
+ nlines = []
17
+ for line in lines
18
+ nlines.push "> #{line}"
19
+ nlines.join("\n")
@@ -0,0 +1,15 @@
1
+ class MD.Button.Bold extends MD.Button
2
+
3
+ constructor: (@attributes = {}) ->
4
+ @name = "bold"
5
+ super(@name, @attributes)
6
+
7
+ html: =>
8
+ "<strong>B</strong>"
9
+
10
+ tooltip: ->
11
+ "Bold"
12
+
13
+ buttonClick: (button, range) =>
14
+ button.performAndSelect range, (text) ->
15
+ "**#{text}**"
@@ -0,0 +1,19 @@
1
+ class MD.Button.CodeBlock extends MD.Button
2
+
3
+ constructor: (@attributes = {}) ->
4
+ @name = "codeblock"
5
+ super(@name, @attributes)
6
+
7
+ html: ->
8
+ "CO"
9
+
10
+ tooltip: ->
11
+ "Code Block"
12
+
13
+ buttonClick: (button, range) =>
14
+ button.performAndSelect range, (text) ->
15
+ lines = text.split("\n")
16
+ nlines = []
17
+ for line in lines
18
+ nlines.push " #{line}"
19
+ nlines.join("\n")
@@ -0,0 +1,15 @@
1
+ class MD.Button.CodeLine extends MD.Button
2
+
3
+ constructor: (@attributes = {}) ->
4
+ @name = "codeline"
5
+ super(@name, @attributes)
6
+
7
+ html: ->
8
+ "CL"
9
+
10
+ tooltip: ->
11
+ "Code Line"
12
+
13
+ buttonClick: (button, range) =>
14
+ button.performAndSelect range, (text) ->
15
+ "`#{text}`"
@@ -0,0 +1,13 @@
1
+ class MD.Button.H1 extends MD.Button
2
+
3
+ constructor: (@attributes = {}) ->
4
+ @name = "h1"
5
+ super(@name, @attributes)
6
+
7
+ tooltip: ->
8
+ "H1"
9
+
10
+ buttonClick: (button, range) =>
11
+ results = button.perform range, (text) ->
12
+ "# #{text}\n\n"
13
+ button.setCaratRange(start: results.finalRange.end - 2)
@@ -0,0 +1,13 @@
1
+ class MD.Button.H2 extends MD.Button
2
+
3
+ constructor: (@attributes = {}) ->
4
+ @name = "h2"
5
+ super(@name, @attributes)
6
+
7
+ tooltip: ->
8
+ "H2"
9
+
10
+ buttonClick: (button, range) =>
11
+ results = button.perform range, (text) ->
12
+ "## #{text}\n\n"
13
+ button.setCaratRange(start: results.finalRange.end - 2)
@@ -0,0 +1,13 @@
1
+ class MD.Button.H3 extends MD.Button
2
+
3
+ constructor: (@attributes = {}) ->
4
+ @name = "h3"
5
+ super(@name, @attributes)
6
+
7
+ tooltip: ->
8
+ "H3"
9
+
10
+ buttonClick: (button, range) =>
11
+ results = button.perform range, (text) ->
12
+ "### #{text}\n\n"
13
+ button.setCaratRange(start: results.finalRange.end - 2)
@@ -0,0 +1,13 @@
1
+ class MD.Button.Hr extends MD.Button
2
+
3
+ constructor: (@attributes = {}) ->
4
+ @name = "hr"
5
+ super(@name, @attributes)
6
+
7
+ tooltip: ->
8
+ "Horizontal Rule"
9
+
10
+ buttonClick: (button, range) =>
11
+ results = button.perform range, (text) ->
12
+ "---\n\n"
13
+ button.setCaratRange(start: results.finalRange.end)
@@ -0,0 +1,58 @@
1
+ class MD.Button.Href extends MD.Button
2
+
3
+ constructor: (@attributes = {}) ->
4
+ @name = "href"
5
+ super(@name, @attributes)
6
+
7
+ tooltip: ->
8
+ "Insert an href link tag."
9
+
10
+ html: =>
11
+ "A"
12
+
13
+ modalWindow: =>
14
+ $("""
15
+ <div class="modal hide fade">
16
+ <div class="modal-header">
17
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
18
+ <h3>Build Link</h3>
19
+ </div>
20
+ <div class="modal-body">
21
+ <div class="control-group">
22
+ <label class="control-label" for="href_text">Text</label>
23
+ <div class="controls">
24
+ <input type="text" id="href_text" placeholder="Text">
25
+ </div>
26
+ </div>
27
+ <div class="control-group">
28
+ <label class="control-label" for="href_link">Link</label>
29
+ <div class="controls">
30
+ <input type="text" id="href_link" placeholder="Link">
31
+ </div>
32
+ </div>
33
+ </div>
34
+ <div class="modal-footer">
35
+ <a href="#" class="btn" data-dismiss="modal">Close</a>
36
+ <a href="#" class="btn btn-primary">Save</a>
37
+ </div>
38
+ </div>
39
+ """)
40
+
41
+ buttonClick: (button, range) =>
42
+ el = $(button.editor.target_name)
43
+ slice = new MD.Utils.Slice(el.val(), range)
44
+ html = @modalWindow()
45
+ $("#href_text", html).val(slice.textAtRange)
46
+ html.modal()
47
+ html.keyup (e) =>
48
+ e?.preventDefault()
49
+ if e.keyCode is 13
50
+ $(".btn-primary", html).click()
51
+ $(".btn-primary", html).click (e) =>
52
+ e?.preventDefault()
53
+ html.modal("hide")
54
+ hrefText = $("#href_text", html).val()
55
+ hrefLink = $("#href_link", html).val()
56
+ results = button.perform range, (text) =>
57
+ "[#{hrefText}](#{hrefLink})"
58
+ button.setCaratRange(start: results.finalRange.end - 1)
@@ -0,0 +1,15 @@
1
+ class MD.Button.Italics extends MD.Button
2
+
3
+ constructor: (@attributes = {}) ->
4
+ @name = "italics"
5
+ super(@name, @attributes)
6
+
7
+ tooltip: ->
8
+ "Italics"
9
+
10
+ html: ->
11
+ "<em>I</em>"
12
+
13
+ buttonClick: (button, range) =>
14
+ button.performAndSelect range, (text) ->
15
+ "_#{text}_"
@@ -0,0 +1,19 @@
1
+ class MD.Button.OrderedList extends MD.Button
2
+
3
+ constructor: (@attributes = {}) ->
4
+ @name = "orderedlist"
5
+ super(@name, @attributes)
6
+
7
+ html: ->
8
+ "OL"
9
+
10
+ tooltip: ->
11
+ "Ordered List"
12
+
13
+ buttonClick: (button, range) =>
14
+ button.performAndSelect range, (text) ->
15
+ lines = text.split("\n")
16
+ nlines = []
17
+ for line, i in lines
18
+ nlines.push "#{i + 1}. #{line}"
19
+ nlines.join("\n")
@@ -0,0 +1,19 @@
1
+ class MD.Button.UnorderedList extends MD.Button
2
+
3
+ constructor: (@attributes = {}) ->
4
+ @name = "unorderedlist"
5
+ super(@name, @attributes)
6
+
7
+ html: ->
8
+ "UL"
9
+
10
+ tooltip: ->
11
+ "Unordered List"
12
+
13
+ buttonClick: (button, range) =>
14
+ button.performAndSelect range, (text) ->
15
+ lines = text.split("\n")
16
+ nlines = []
17
+ for line in lines
18
+ nlines.push "* #{line}"
19
+ nlines.join("\n")
@@ -0,0 +1,17 @@
1
+ MD.Row.defaultRow = new MD.Row([
2
+ new MD.Button.H1(),
3
+ new MD.Button.H2(),
4
+ new MD.Button.H3(),
5
+ new MD.Button.Seperator(),
6
+ new MD.Button.Bold(),
7
+ new MD.Button.Italics(),
8
+ new MD.Button.Seperator(),
9
+ new MD.Button.BlockQuotes(),
10
+ new MD.Button.OrderedList(),
11
+ new MD.Button.UnorderedList(),
12
+ new MD.Button.CodeBlock(),
13
+ new MD.Button.CodeLine(),
14
+ new MD.Button.Seperator(),
15
+ new MD.Button.Href(),
16
+ new MD.Button.Hr()
17
+ ])
@@ -0,0 +1,41 @@
1
+ class @MD.Editor
2
+
3
+ constructor: (@target_name) ->
4
+ @clearRows()
5
+ @addRow(MD.Row.defaultRow)
6
+ @events = {}
7
+
8
+ on: (event, callback) ->
9
+ @events[event] ?= []
10
+ @events[event].push callback
11
+
12
+ trigger: (event, etc...) ->
13
+ for callback in (@events[event] || [])
14
+ callback(@, etc...)
15
+
16
+ clearRows: =>
17
+ @rows = []
18
+
19
+ addRow: (row) =>
20
+ row.setEditor(@)
21
+ @rows.push(row)
22
+
23
+ render: =>
24
+ el = $(@target_name)
25
+ inner = el.clone()
26
+ html = $("""
27
+ <div id='#{@target_name.replace('#', '')}_md_editor' class='markdown_editor'>
28
+ <div class='markdown_editor_toolbar' style="width: #{el.outerWidth(true)}px">
29
+ </div>
30
+ </div>
31
+ """)
32
+ for row in @rows
33
+ $(".markdown_editor_toolbar", html).append(row.render())
34
+ inner.appendTo(html)
35
+ el.replaceWith(html)
36
+ $(@target_name).keyup (e) =>
37
+ @trigger("change", $(e.target).val())
38
+ $(@target_name).change (e) =>
39
+ @trigger("change", $(e.target).val())
40
+ return @
41
+
@@ -0,0 +1,11 @@
1
+ #= require_self
2
+ #= require ./editor
3
+ #= require_tree ./utils
4
+ #= require ./row
5
+ #= require ./button
6
+ #= require_tree ./buttons
7
+ #= require ./seperator
8
+ #= require ./default_row
9
+
10
+ @MD =
11
+ Utils: {}
@@ -0,0 +1,14 @@
1
+ class MD.Row
2
+
3
+ constructor: (@buttons) ->
4
+
5
+ setEditor: (@editor) =>
6
+ for button in @buttons
7
+ button.row = @
8
+ button.editor = @editor
9
+
10
+ render: =>
11
+ html = $("<div class='markdown_editor_row navbar-inner'></div>")
12
+ for button in @buttons
13
+ html.append(button.render())
14
+ return html
@@ -0,0 +1,4 @@
1
+ class MD.Button.Seperator
2
+
3
+ render: =>
4
+ return $("<button class='btn markdown_editor_seperator' disabled='true'></button>")
@@ -0,0 +1,15 @@
1
+ class MD.Utils.Carat
2
+
3
+ @getRange: (target_name) ->
4
+ pos = [0,0]
5
+ ctrl = $(target_name)[0]
6
+ if ctrl.selectionStart or ctrl.selectionStart is '0'
7
+ pos[0] = ctrl.selectionStart
8
+ if ctrl.selectionEnd or ctrl.selectionEnd is '0'
9
+ pos[1] = ctrl.selectionEnd
10
+ return {start: pos[0], end: pos[1]}
11
+
12
+ @setRange: (target_name, start, end = start) =>
13
+ ctrl = $(target_name)[0]
14
+ ctrl.focus()
15
+ ctrl.setSelectionRange(start, end)
@@ -0,0 +1,21 @@
1
+ class MD.Utils.Manipulation
2
+
3
+ @replaceRange: (target_name, range, func) ->
4
+ el = $(target_name)
5
+ val = el.val()
6
+ slice = new MD.Utils.Slice(val, range)
7
+ replacement = func(slice.textAtRange)
8
+ final = "#{slice.first}#{replacement}#{slice.last}"
9
+ el.val(final)
10
+ return {
11
+ slice: slice
12
+ originalText: val
13
+ finalText: final
14
+ replacementText: replacement
15
+ textAtRange: slice.textAtRange
16
+ originalRange: range
17
+ el: el
18
+ finalRange:
19
+ start: range.start
20
+ end: range.start + replacement.length
21
+ }
@@ -0,0 +1,6 @@
1
+ class MD.Utils.Slice
2
+
3
+ constructor: (@value, @range) ->
4
+ @first = @value.slice(0, @range.start)
5
+ @last = @value.slice(@range.end)
6
+ @textAtRange = @value.substr(@range.start, @range.end - @range.start)
@@ -0,0 +1,18 @@
1
+ .markdown_editor {
2
+
3
+ }
4
+
5
+ .markdown_editor_row {
6
+ // border: 1px solid black;
7
+ margin-bottom: 5px;
8
+ }
9
+
10
+ .markdown_editor_row button {
11
+ margin-top: 5px;
12
+ margin-right: 5px;
13
+ }
14
+
15
+ .markdown_editor_seperator {
16
+ width: 2px;
17
+ padding: 0px;
18
+ }
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kevorkian
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mark Bates
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Easy, extensible MarkDown editor.
47
+ email:
48
+ - mark@markbates.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .DS_Store
54
+ - .gitignore
55
+ - .rspec
56
+ - Gemfile
57
+ - Guardfile
58
+ - LICENSE.txt
59
+ - README.md
60
+ - Rakefile
61
+ - kevorkian.gemspec
62
+ - lib/kevorkian.rb
63
+ - lib/kevorkian/engine.rb
64
+ - lib/kevorkian/version.rb
65
+ - vendor/assets/javascripts/.DS_Store
66
+ - vendor/assets/javascripts/button.js.coffee
67
+ - vendor/assets/javascripts/buttons/block_quotes.js.coffee
68
+ - vendor/assets/javascripts/buttons/bold.js.coffee
69
+ - vendor/assets/javascripts/buttons/code_block.js.coffee
70
+ - vendor/assets/javascripts/buttons/code_line.js.coffee
71
+ - vendor/assets/javascripts/buttons/h1.js.coffee
72
+ - vendor/assets/javascripts/buttons/h2.js.coffee
73
+ - vendor/assets/javascripts/buttons/h3.js.coffee
74
+ - vendor/assets/javascripts/buttons/hr.js.coffee
75
+ - vendor/assets/javascripts/buttons/href.js.coffee
76
+ - vendor/assets/javascripts/buttons/italics.js.coffee
77
+ - vendor/assets/javascripts/buttons/ordered_list.js.coffee
78
+ - vendor/assets/javascripts/buttons/unordered_list.js.coffee
79
+ - vendor/assets/javascripts/default_row.js.coffee
80
+ - vendor/assets/javascripts/editor.js.coffee
81
+ - vendor/assets/javascripts/kevorkian.js.coffee
82
+ - vendor/assets/javascripts/row.js.coffee
83
+ - vendor/assets/javascripts/seperator.js.coffee
84
+ - vendor/assets/javascripts/utils/carat.js.coffee
85
+ - vendor/assets/javascripts/utils/manipulation.js.coffee
86
+ - vendor/assets/javascripts/utils/slice.js.coffee
87
+ - vendor/assets/stylesheets/kevorkian.css
88
+ homepage: ''
89
+ licenses:
90
+ - MIT
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 1.8.24
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: Easy, extensible MarkDown editor.
113
+ test_files: []