reloadlive 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/.rvmrc +52 -0
- data/Gemfile +4 -0
- data/Guardfile +15 -0
- data/LICENSE.txt +22 -0
- data/README.md +76 -0
- data/Rakefile +1 -0
- data/bin/reloadlive +10 -0
- data/demo.gif +0 -0
- data/lib/reloadlive/config.rb +64 -0
- data/lib/reloadlive/frontend.rb +38 -0
- data/lib/reloadlive/options.rb +54 -0
- data/lib/reloadlive/render.rb +150 -0
- data/lib/reloadlive/static/client.js +2194 -0
- data/lib/reloadlive/static/index.erb +21 -0
- data/lib/reloadlive/static/style.css +249 -0
- data/lib/reloadlive/version.rb +3 -0
- data/lib/reloadlive.rb +2 -0
- data/reloadlive.gemspec +35 -0
- data/spec/lib/reloadlive/render_spec.rb +74 -0
- data/spec/spec_helper.rb +27 -0
- metadata +286 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
+
# development environment upon cd'ing into the directory
|
5
|
+
|
6
|
+
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
|
7
|
+
# Only full ruby name is supported here, for short names use:
|
8
|
+
# echo "rvm use 1.9.3" > .rvmrc
|
9
|
+
environment_id="ruby-1.9.3-p392@reloadlive"
|
10
|
+
|
11
|
+
# Uncomment the following lines if you want to verify rvm version per project
|
12
|
+
# rvmrc_rvm_version="1.18.16 (stable)" # 1.10.1 seams as a safe start
|
13
|
+
# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
|
14
|
+
# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
|
15
|
+
# return 1
|
16
|
+
# }
|
17
|
+
|
18
|
+
# First we attempt to load the desired environment directly from the environment
|
19
|
+
# file. This is very fast and efficient compared to running through the entire
|
20
|
+
# CLI and selector. If you want feedback on which environment was used then
|
21
|
+
# insert the word 'use' after --create as this triggers verbose mode.
|
22
|
+
if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
|
23
|
+
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
24
|
+
then
|
25
|
+
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
26
|
+
[[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
|
27
|
+
\. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
|
28
|
+
if [[ $- == *i* ]] # check for interactive shells
|
29
|
+
then echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
|
30
|
+
else echo "Using: $GEM_HOME" # don't use colors in non-interactive shells
|
31
|
+
fi
|
32
|
+
else
|
33
|
+
# If the environment file has not yet been created, use the RVM CLI to select.
|
34
|
+
rvm --create use "$environment_id" || {
|
35
|
+
echo "Failed to create RVM environment '${environment_id}'."
|
36
|
+
return 1
|
37
|
+
}
|
38
|
+
fi
|
39
|
+
|
40
|
+
# If you use bundler, this might be useful to you:
|
41
|
+
# if [[ -s Gemfile ]] && {
|
42
|
+
# ! builtin command -v bundle >/dev/null ||
|
43
|
+
# builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null
|
44
|
+
# }
|
45
|
+
# then
|
46
|
+
# printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
|
47
|
+
# gem install bundler
|
48
|
+
# fi
|
49
|
+
# if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
|
50
|
+
# then
|
51
|
+
# bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete'
|
52
|
+
# fi
|
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec' do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
10
|
+
|
11
|
+
# Turnip features and steps
|
12
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
13
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
14
|
+
end
|
15
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Alberto Miorin
|
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,76 @@
|
|
1
|
+
# Reloadlive
|
2
|
+
Reloadlive is a command line tool that renders your markup files in your
|
3
|
+
browser without hitting the reload button.
|
4
|
+
|
5
|
+
You need only to save them. The last saved file will be rendered.
|
6
|
+
|
7
|
+
If the extension of the file is unknown, the content will be rendered in the
|
8
|
+
browser without modification.
|
9
|
+
|
10
|
+

|
11
|
+
|
12
|
+
## Markups
|
13
|
+
|
14
|
+
The following markups are supported. The dependencies listed are required if
|
15
|
+
you wish to run the library.
|
16
|
+
|
17
|
+
* [.markdown, .mdown, .md](http://daringfireball.net/projects/markdown/) -- `gem install redcarpet` (https://github.com/vmg/redcarpet)
|
18
|
+
* [.textile](http://www.textism.com/tools/textile/) -- `gem install RedCloth`
|
19
|
+
* [.rdoc](http://rdoc.sourceforge.net/) -- `gem install rdoc -v 3.6.1`
|
20
|
+
* [.org](http://orgmode.org/) -- `gem install org-ruby`
|
21
|
+
* [.creole](http://wikicreole.org/) -- `gem install creole`
|
22
|
+
* [.mediawiki](http://www.mediawiki.org/wiki/Help:Formatting) -- `gem install wikicloth`
|
23
|
+
* [.rst](http://docutils.sourceforge.net/rst.html) -- `easy_install docutils`
|
24
|
+
* [.asciidoc](http://www.methods.co.nz/asciidoc/) -- `brew install asciidoc`
|
25
|
+
* [.pod](http://search.cpan.org/dist/perl/pod/perlpod.pod) -- `Pod::Simple::HTML`
|
26
|
+
comes with Perl >= 5.10. Lower versions should install Pod::Simple from CPAN.
|
27
|
+
|
28
|
+
## Installation
|
29
|
+
|
30
|
+
$ gem install reloadlive
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
In the directory containings your files run:
|
34
|
+
|
35
|
+
$ reloadlive
|
36
|
+
|
37
|
+
and open ``http://localhost:4567`` in your browser.
|
38
|
+
|
39
|
+
$ reloadlive --help
|
40
|
+
|
41
|
+
prints the help
|
42
|
+
|
43
|
+
## Notes
|
44
|
+
* Reloadlive can be used instead of ``gollum`` or ``jekyll --auto``
|
45
|
+
* Internal wiki links don't work yet (to be done).
|
46
|
+
* The user cannot use his own layout (to be done).
|
47
|
+
* The current layout is not responsive (to be fixed).
|
48
|
+
|
49
|
+
## Credits
|
50
|
+
* [Gollum][0]
|
51
|
+
* [Github markup][1]
|
52
|
+
* [Faye][2]
|
53
|
+
* [Thin][3]
|
54
|
+
* [Rack][4]
|
55
|
+
* [Sinatra][5]
|
56
|
+
* [Listen][6]
|
57
|
+
* [instant-markdonw-d][7]
|
58
|
+
* [LiveReload][8]
|
59
|
+
|
60
|
+
## Contributing
|
61
|
+
|
62
|
+
1. Fork it
|
63
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
64
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
65
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
66
|
+
5. Create new Pull Request
|
67
|
+
|
68
|
+
[0]: https://github.com/gollum/gollum
|
69
|
+
[1]: https://github.com/github/markup
|
70
|
+
[2]: http://faye.jcoglan.com/
|
71
|
+
[3]: http://code.macournoyer.com/thin/
|
72
|
+
[4]: http://rack.github.com/
|
73
|
+
[5]: http://www.sinatrarb.com/
|
74
|
+
[6]: https://github.com/guard/listen
|
75
|
+
[7]: https://github.com/suan/instant-markdown-d
|
76
|
+
[8]: http://livereload.com/
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/reloadlive
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
|
4
|
+
|
5
|
+
require "reloadlive/options"
|
6
|
+
require 'reloadlive'
|
7
|
+
|
8
|
+
include Reloadlive
|
9
|
+
|
10
|
+
Rack::Handler::Thin.run builder(options['port']), :Port => options['port'], :Host => options['bind']
|
data/demo.gif
ADDED
Binary file
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require "faye"
|
2
|
+
require "listen"
|
3
|
+
require "reloadlive/frontend"
|
4
|
+
require "reloadlive/render"
|
5
|
+
|
6
|
+
module Reloadlive
|
7
|
+
def builder port
|
8
|
+
thread
|
9
|
+
Rack::Builder.new do
|
10
|
+
map "/" do
|
11
|
+
run Frontend
|
12
|
+
end
|
13
|
+
Faye::WebSocket.load_adapter('thin')
|
14
|
+
faye = Faye::RackAdapter.new :mount => '/', :timeout => 45
|
15
|
+
map "/faye" do
|
16
|
+
run faye
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def binary? file
|
22
|
+
s = (File.read(file, File.stat(file).blksize) || "").split(//)
|
23
|
+
((s.size - s.grep(" ".."~").size) / s.size.to_f) > 0.30
|
24
|
+
end
|
25
|
+
|
26
|
+
def dirs(stars=false)
|
27
|
+
dirs = options['watch'].dup
|
28
|
+
dirs.map! do |dir|
|
29
|
+
File.absolute_path(dir) + (stars ? "/**/*" : "")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def last_file_changed
|
34
|
+
timestamp = 0
|
35
|
+
last_file_changed = nil
|
36
|
+
Dir.glob(dirs(true)).each do |file|
|
37
|
+
next unless File.file? file
|
38
|
+
next if binary? file
|
39
|
+
ts = File.stat(file).mtime.to_i
|
40
|
+
if ts > timestamp
|
41
|
+
last_file_changed = file
|
42
|
+
timestamp = ts
|
43
|
+
end
|
44
|
+
end
|
45
|
+
last_file_changed
|
46
|
+
end
|
47
|
+
|
48
|
+
def thread
|
49
|
+
t = Thread.new do
|
50
|
+
client = Faye::Client.new("http://localhost:#{options['port']}/faye")
|
51
|
+
listener = Listen::MultiListener.new(*dirs) do |modified, added, removed|
|
52
|
+
filename = modified.first ? modified.first :
|
53
|
+
added.first ? added.first :
|
54
|
+
last_file_changed
|
55
|
+
return if binary? filename
|
56
|
+
render = Render.new(File.basename(filename), File.read(filename))
|
57
|
+
client.publish('/message', {'body' => render.formatted_data, 'title' => render.title })
|
58
|
+
puts "PUSH " + File.basename(filename)
|
59
|
+
end
|
60
|
+
listener.start
|
61
|
+
end
|
62
|
+
t.abort_on_exception = true
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "sinatra/base"
|
2
|
+
|
3
|
+
module Reloadlive
|
4
|
+
class Frontend < Sinatra::Base
|
5
|
+
STATIC = File.dirname(__FILE__) + "/static/"
|
6
|
+
|
7
|
+
enable :static
|
8
|
+
set :views, STATIC
|
9
|
+
set :public_folder, Reloadlive.options['static']
|
10
|
+
|
11
|
+
get '/' do
|
12
|
+
@last = last
|
13
|
+
@port = Reloadlive.options['port']
|
14
|
+
erb :index
|
15
|
+
end
|
16
|
+
|
17
|
+
get '/_reloadlive/style.css' do
|
18
|
+
send_file STATIC + 'style.css'
|
19
|
+
end
|
20
|
+
|
21
|
+
get '/_reloadlive/client.js' do
|
22
|
+
send_file STATIC + 'client.js'
|
23
|
+
end
|
24
|
+
|
25
|
+
def last
|
26
|
+
last_file_changed = Reloadlive.last_file_changed
|
27
|
+
body = "Save your document"
|
28
|
+
title = "Reloadlive"
|
29
|
+
if last_file_changed
|
30
|
+
render = Reloadlive::Render.new(File.basename(last_file_changed), File.read(last_file_changed))
|
31
|
+
body = render.formatted_data
|
32
|
+
title = render.title
|
33
|
+
end
|
34
|
+
puts "PUSH " + File.basename(last_file_changed)
|
35
|
+
{ body: body, title: title}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Reloadlive
|
4
|
+
help = <<HELP
|
5
|
+
Reloadlive is command line tool to easily preview your github-markup files
|
6
|
+
|
7
|
+
Basic Command Line Usage:
|
8
|
+
reloadlive [OPTIONS] [DIRS]
|
9
|
+
HELP
|
10
|
+
@@options = { 'port' => 4567, 'host' => '0.0.0.0', 'static' => Dir.pwd }
|
11
|
+
options_parser = OptionParser.new do |opts|
|
12
|
+
opts.banner = help
|
13
|
+
|
14
|
+
opts.on("--port [PORT]", "Bind port (default 4567).") do |port|
|
15
|
+
@@options['port'] = port.to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
opts.on("--host [HOST]", "Hostname or IP address to listen on (default 0.0.0.0).") do |host|
|
19
|
+
@@options['bind'] = host
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on("--static [PATH]", "Specify the static path.") do |path|
|
23
|
+
@@options['static'] = path
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.on("--version", "Display current version.") do
|
27
|
+
puts "Reloadlive " + Reloadlive::VERSION
|
28
|
+
exit 0
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
options_parser.parse!
|
34
|
+
rescue OptionParser::InvalidOption
|
35
|
+
puts "reloadlive: #{$!.message}"
|
36
|
+
puts "reloadlive: try 'reloadlive --help' for more information"
|
37
|
+
exit
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
if ARGV.empty?
|
42
|
+
@@options['watch'] = [Dir.pwd]
|
43
|
+
else
|
44
|
+
@@options['watch'] = ARGV.dup
|
45
|
+
end
|
46
|
+
|
47
|
+
def options
|
48
|
+
@@options
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.options
|
52
|
+
@@options
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'github/markup'
|
2
|
+
require 'pygments'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
# initialize Pygments
|
6
|
+
Pygments.start
|
7
|
+
|
8
|
+
module Reloadlive
|
9
|
+
class Render
|
10
|
+
include Rack::Utils
|
11
|
+
alias_method :h, :escape_html
|
12
|
+
attr_accessor :filename, :data, :title
|
13
|
+
|
14
|
+
def initialize filename, data
|
15
|
+
@filename = filename
|
16
|
+
@data = data
|
17
|
+
@codemap = {}
|
18
|
+
@title = filename
|
19
|
+
end
|
20
|
+
|
21
|
+
def formatted_data encoding=nil
|
22
|
+
data = @data.dup
|
23
|
+
data = extract_yaml data
|
24
|
+
data = extract_code data
|
25
|
+
begin
|
26
|
+
data = GitHub::Markup.render(@filename, data)
|
27
|
+
rescue => e
|
28
|
+
puts "Exception rendering #{@filename}: #{e.message}"
|
29
|
+
end
|
30
|
+
data = process_code(data, encoding)
|
31
|
+
if data == @data
|
32
|
+
p_lexer = Pygments::Lexer.find_by_extname(File.extname(@filename))
|
33
|
+
lexer = p_lexer ? p_lexer.aliases.first : nil
|
34
|
+
data = Pygments.highlight(data, :lexer => lexer, :options => {:encoding => encoding.to_s, :startinline => true})
|
35
|
+
end
|
36
|
+
data
|
37
|
+
end
|
38
|
+
|
39
|
+
def extract_yaml(data)
|
40
|
+
if data =~ /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
41
|
+
@title = YAML.load($1)['title']
|
42
|
+
data = $'
|
43
|
+
end
|
44
|
+
data
|
45
|
+
rescue => e
|
46
|
+
puts "YAML Exception reading #{@filename}: #{e.message}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def extract_code(data)
|
50
|
+
data.gsub!(/^([ \t]*)(~~~+) ?([^\r\n]+)?\r?\n(.+?)\r?\n\1(~~~+)[ \t\r]*$/m) do
|
51
|
+
m_indent = $1
|
52
|
+
m_start = $2 # ~~~
|
53
|
+
m_lang = $3
|
54
|
+
m_code = $4
|
55
|
+
m_end = $5 # ~~~
|
56
|
+
|
57
|
+
# start and finish tilde fence must be the same length
|
58
|
+
return '' if m_start.length != m_end.length
|
59
|
+
|
60
|
+
lang = m_lang ? m_lang.strip : nil
|
61
|
+
id = Digest::SHA1.hexdigest("#{lang}.#{m_code}")
|
62
|
+
cached = check_cache(:code, id)
|
63
|
+
|
64
|
+
# extract lang from { .ruby } or { #stuff .ruby .indent }
|
65
|
+
# see http://johnmacfarlane.net/pandoc/README.html#delimited-code-blocks
|
66
|
+
|
67
|
+
if lang
|
68
|
+
lang = lang.match(/\.([^}\s]+)/)
|
69
|
+
lang = lang[1] unless lang.nil?
|
70
|
+
end
|
71
|
+
|
72
|
+
@codemap[id] = cached ?
|
73
|
+
{ :output => cached } :
|
74
|
+
{ :lang => lang, :code => m_code, :indent => m_indent }
|
75
|
+
|
76
|
+
"#{m_indent}#{id}" # print the SHA1 ID with the proper indentation
|
77
|
+
end
|
78
|
+
|
79
|
+
data.gsub!(/^([ \t]*)``` ?([^\r\n]+)?\r?\n(.+?)\r?\n\1```[ \t]*\r?$/m) do
|
80
|
+
lang = $2 ? $2.strip : nil
|
81
|
+
id = Digest::SHA1.hexdigest("#{lang}.#{$3}")
|
82
|
+
cached = check_cache(:code, id)
|
83
|
+
@codemap[id] = cached ?
|
84
|
+
{ :output => cached } :
|
85
|
+
{ :lang => lang, :code => $3, :indent => $1 }
|
86
|
+
"#{$1}#{id}" # print the SHA1 ID with the proper indentation
|
87
|
+
end
|
88
|
+
data
|
89
|
+
end
|
90
|
+
|
91
|
+
def process_code(data, encoding = nil)
|
92
|
+
return data if data.nil? || data.size.zero? || @codemap.size.zero?
|
93
|
+
|
94
|
+
blocks = []
|
95
|
+
@codemap.each do |id, spec|
|
96
|
+
next if spec[:output] # cached
|
97
|
+
|
98
|
+
code = spec[:code]
|
99
|
+
|
100
|
+
remove_leading_space(code, /^#{spec[:indent]}/m)
|
101
|
+
remove_leading_space(code, /^( |\t)/m)
|
102
|
+
|
103
|
+
blocks << [spec[:lang], code]
|
104
|
+
end
|
105
|
+
|
106
|
+
highlighted = []
|
107
|
+
blocks.each do |lang, code|
|
108
|
+
encoding ||= 'utf-8'
|
109
|
+
begin
|
110
|
+
# must set startinline to true for php to be highlighted without <?
|
111
|
+
# http://pygments.org/docs/lexers/
|
112
|
+
hl_code = Pygments.highlight(code, :lexer => lang, :options => {:encoding => encoding.to_s, :startinline => true})
|
113
|
+
rescue
|
114
|
+
hl_code = code
|
115
|
+
end
|
116
|
+
highlighted << hl_code
|
117
|
+
end
|
118
|
+
|
119
|
+
@codemap.each do |id, spec|
|
120
|
+
body = spec[:output] || begin
|
121
|
+
if (body = highlighted.shift.to_s).size > 0
|
122
|
+
update_cache(:code, id, body)
|
123
|
+
body
|
124
|
+
else
|
125
|
+
"<pre><code>#{CGI.escapeHTML(spec[:code])}</code></pre>"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
data.gsub!(id) do
|
129
|
+
body
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
data
|
134
|
+
end
|
135
|
+
|
136
|
+
def remove_leading_space(code, regex)
|
137
|
+
if code.lines.all? { |line| line =~ /\A\r?\n\Z/ || line =~ regex }
|
138
|
+
code.gsub!(regex) do
|
139
|
+
''
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def check_cache(type, id)
|
145
|
+
end
|
146
|
+
|
147
|
+
def update_cache(type, id, data)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|