jekyll-viewsource 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cfe5b3a8492efe8b96f105d0fae4520e30a61c6d
4
+ data.tar.gz: d7706594cecfbcdce75868c3bba4fb05f9338aac
5
+ SHA512:
6
+ metadata.gz: eeabd3bc6482ef6c6799f36a13b350a49e0fd035a872ac0523219ae18acf15bd50b0569b4315eecd3fed4b2915d29db608a2c47da783e33f0d0c2b808c7c3034
7
+ data.tar.gz: 6c5b099a1edf932c4157d5f5fc7e61349b3158c2b9467e3523178a2d8fbe5493697492790f4d90da5267cbe13f14c68184609800169a0b25015e23eb6b396861
@@ -0,0 +1,21 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ # Swap
14
+ [._]*.s[a-v][a-z]
15
+ [._]*.sw[a-p]
16
+ [._]s[a-v][a-z]
17
+ [._]sw[a-p]
18
+ Session.vim
19
+
20
+ Gemfile.lock
21
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.16.0
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at jekyll@ibrado.org. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in jekyll-viewsource.gemspec
6
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 TODO: Write your name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,163 @@
1
+ # Jekyll::ViewSource
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/jekyll-viewsource.svg)](https://badge.fury.io/rb/jekyll-viewsource)
4
+
5
+ *Jekyll:ViewSource* is a plugin for [Jekyll](https://jekyllrb.com/) that generates plain or pretty Markdown and HTML source code pages from your content.
6
+
7
+ ## Installation
8
+
9
+ Add the gem to your application's Gemfile:
10
+
11
+ ```ruby
12
+ group :jekyll_plugins do
13
+ # other plugins here
14
+ gem 'jekyll-viewsource'
15
+ end
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself:
23
+
24
+ $ gem install jekyll-viewsource
25
+
26
+ ## Configuration
27
+
28
+ No configuration is required to run *Jekyll::ViewSource*. If you want to tweak its behavior, you may set the following options in `_config.yml`:
29
+
30
+ ```yaml
31
+ viewsource:
32
+ #enabled: false # Default: true
33
+ debug: true # Show additional messages during run; default: false
34
+ #collection: pages, "articles" # Which collections to paginate; default: pages and posts
35
+ collections: # Ditto, just a different way of writing it
36
+ - pages # Quotes are optional if collection names are obviously strings
37
+ - posts
38
+ - articles
39
+ options: pretty # Options that normally go in a doc's front matter
40
+ ```
41
+
42
+ ## Usage
43
+
44
+ Just add a `viewsource: true` entry to the front-matter of the content for you want to create source files:
45
+
46
+ ### Plain Markdown
47
+
48
+ ```yaml
49
+ ---
50
+ viewsource: true
51
+ ---
52
+ ```
53
+
54
+ (or `viewsource: md` or `viewsource: markdown`)
55
+
56
+ ### Plain HTML
57
+
58
+ ```yaml
59
+ viewsource: html
60
+ ```
61
+
62
+ ### Plain Markdown and HTML
63
+
64
+ ```yaml
65
+ viewsource: markdown, html
66
+ ```
67
+
68
+ ### Prettified
69
+
70
+ Add <code>pretty[="<rouge_template|css_path>"]</code>, e.g.
71
+
72
+ ```yaml
73
+ viewsource: markdown, html, pretty
74
+ ```
75
+
76
+ ```yaml
77
+ viewsource: markdown, html, pretty="thankful_eyes"
78
+ ```
79
+
80
+ ```yaml
81
+ viewsource: markdown, html, pretty="/url/path/to/syntax.css"
82
+ ```
83
+
84
+ You may show the themes currently supported by Rouge via the command line:
85
+
86
+ $ rougify help style
87
+
88
+ As of this writing, these are:
89
+
90
+ * base16, base16.dark, base16.light
91
+ * base16.monokai, base16.monokai.dark, base16.monokai.light
92
+ * base16.solarized, base16.solarized.dark, base16.solarized.light
93
+ * colorful
94
+ * github
95
+ * gruvbox, gruvbox.dark, gruvbox.light
96
+ * igorpro
97
+ * molokai
98
+ * monokai, monokai.sublime
99
+ * thankful_eyes
100
+ * tulip
101
+
102
+ The default is `github`
103
+
104
+ ### Source file links
105
+
106
+ To link to your source files, use the following:
107
+
108
+ `{{ page.source_url }}`
109
+ : The plain or pretty Markdown source URL
110
+
111
+ `{{ page.html_source_url }}`
112
+ : The plain or pretty HTML source URL
113
+
114
+ e.g.
115
+
116
+ ```liquid
117
+ [View Markdown source]({{ page.source_url }})
118
+ [View HTML source]({{ page.html_source_url }})
119
+ ```
120
+
121
+ ### Demo
122
+
123
+ [View Markdown source](https://ibrado.org/jvs.md-src.html)
124
+
125
+ [View HTML source](https://ibrado.org/jvs/index.html-src.html)
126
+
127
+ ## Cache
128
+
129
+ *ViewSource* maintains a cache in a hidden folder inside your site source: `.plugins/jekyll-viewsource`. If you encounter problems that you think may be related to the cache, you may remove this.
130
+
131
+ ## Contributing
132
+
133
+ 1. Fork this project: [https://github.com/ibrado/jekyll-viewsource/fork](https://github.com/ibrado/jekyll-viewsource/fork)
134
+ 1. Clone it (`git clone git://github.com/your_user_name/jekyll-viewsource.git`)
135
+ 1. `cd jekyll-viewsource`
136
+ 1. Create a new branch (e.g. `git checkout -b my-bug-fix`)
137
+ 1. Make your changes
138
+ 1. Commit your changes (`git commit -m "Bug fix"`)
139
+ 1. Build it (`gem build jekyll-viewsource.gemspec`)
140
+ 1. Install and test it (`gem install ./jekyll-viewsource-*.gem`)
141
+ 1. Repeat from step 5 as necessary
142
+ 1. Push the branch (`git push -u origin my-bug-fix`)
143
+ 1. Create a Pull Request, making sure to select the proper branch, e.g. `my-bug-fix` (via https://github.com/your_user_name/jekyll-viewsource)
144
+
145
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/ibrado/jekyll-viewsource](https://github.com/ibrado/jekyll-viewsource). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
146
+
147
+
148
+ ## License
149
+
150
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
151
+
152
+ ## Code of Conduct
153
+
154
+ Everyone interacting in the Jekyll::ViewSource project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/jekyll-viewsource/blob/master/CODE_OF_CONDUCT.md).
155
+
156
+ ## Also by the Author
157
+
158
+ [Jekyll Stickyposts Plugin](https://github.com/ibrado/jekyll-stickyposts) - Move/pin posts tagged `sticky: true` before all others. Sorting on custom fields supported; collection and paginator friendly.
159
+
160
+ [Jekyll Tweetsert Plugin](https://github.com/ibrado/jekyll-tweetsert) - Turn tweets into Jekyll posts. Multiple timelines, filters, hashtags, automatic category/tags, and more!
161
+
162
+ [Jekyll::Paginate::Content](https://github.com/ibrado/jekyll-tweetsert) - Split your Jekyll pages, posts, etc. into multiple pages automatically. Single-page view, pager, SEO support, self-adjusting links, multipage-aware Table Of Contents.
163
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "jekyll/viewsource"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,32 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "jekyll/viewsource/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jekyll-viewsource"
8
+ spec.version = Jekyll::ViewSource::VERSION
9
+ spec.required_ruby_version = '>= 2.1.0'
10
+ spec.authors = ["Alex Ibrado"]
11
+ spec.email = ["alex@ibrado.org"]
12
+
13
+ spec.summary = %q{View plain or pretty Markdown and/or HTML source code}
14
+ spec.description = %q{This Jekyll plugin generates pretty or plain Markdown and/or HTML source code pages for your Markdown docs, which you can easily link to for viewing.}
15
+ spec.homepage = "https://github.com/ibrado/jekyll-viewsource"
16
+ spec.license = "MIT"
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
+ f.match(%r{^(test|spec|features)/})
20
+ end
21
+ spec.bindir = "exe"
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_runtime_dependency "jekyll", "~> 3.0"
26
+ spec.add_runtime_dependency "htmlbeautifier", "~> 1.3"
27
+ rouge_versions = ENV["ROUGE_VERSION"] ? ["~> #{ENV["ROUGE_VERSION"]}"] : [">= 1.7", "< 3"]
28
+ spec.add_runtime_dependency("rouge", *rouge_versions)
29
+ spec.add_development_dependency "bundler", "~> 2.16"
30
+ spec.add_development_dependency "rake", "~> 10.0"
31
+ spec.add_development_dependency "rspec", "~> 3.0"
32
+ end
@@ -0,0 +1,117 @@
1
+ require 'jekyll/viewsource/constants'
2
+ require 'jekyll/viewsource/cache'
3
+ require 'jekyll/viewsource/renderer'
4
+
5
+ module Jekyll
6
+ module ViewSource
7
+
8
+ def self.debug_state(debug)
9
+ @debug ||= debug
10
+ end
11
+
12
+ def self.warn(msg)
13
+ Jekyll.logger.warn VIEWSOURCE_LOG, msg
14
+ end
15
+
16
+ def self.debug(item, msg)
17
+ if @debug
18
+ info = item ?
19
+ (item.respond_to?(:path) ? File.basename(item.path) :
20
+ item)
21
+ : 'main'.freeze
22
+
23
+ msg = "[#{info}] #{msg}"
24
+
25
+ Jekyll.logger.warn VIEWSOURCE_LOG, msg
26
+ end
27
+ end
28
+
29
+ def self.site(s = nil)
30
+ @site ||= s
31
+ end
32
+
33
+ class Generator < Jekyll::Generator
34
+ priority :low
35
+
36
+ def generate(site)
37
+ ViewSource.site(site)
38
+
39
+ config = site.config[VIEWSOURCE] || {}
40
+ return unless config["enabled"].nil? || config["enabled"]
41
+
42
+ config['options'] ||= ''
43
+
44
+ @debug = config["debug"]
45
+ ViewSource.debug_state @debug
46
+ Cache.setup(site, config['cache'].nil? || config['cache'])
47
+
48
+ config['collection'] = config['collection'].split(/,\s*/) if config['collection'].is_a?(String)
49
+
50
+ collections = [ config['collection'], config["collections"] ].flatten.compact.uniq
51
+
52
+ collections = [ "posts", "pages" ] if collections.empty?
53
+
54
+ collections.each do |collection|
55
+ if collection == "pages"
56
+ items = site.pages
57
+ else
58
+ next if !site.collections.has_key?(collection)
59
+ items = site.collections[collection].docs
60
+ end
61
+
62
+ process = items.select { |item| item.data[VIEWSOURCE]}
63
+
64
+ process.each do |item|
65
+ vs_opts = item.data[VIEWSOURCE].to_s + ' ' + config['options']
66
+
67
+ if m = /pretty\s*=?\s*(['"](.*?)['"]|)/.match(vs_opts)
68
+ pretty = m[2] || DEFAULT_CSS
69
+ end
70
+
71
+ if m = /linkback\s*=?\s*(['"](.*?)['"]|)/.match(vs_opts)
72
+ linkback = m[2] || 'Back'
73
+ end
74
+
75
+ view_md = (vs_opts =~ /\b(md|markdown)\b/i)
76
+ view_pr = (vs_opts =~ /\b(prerender)\b/i)
77
+ view_html = (vs_opts =~ /\bhtml\b/i)
78
+
79
+ view_md ||= !view_html
80
+
81
+ suffix = (pretty ? INFIXED_HTML : INFIXED_TXT)
82
+
83
+ # Enqueue for post site render
84
+ if view_md || view_pr
85
+ dest_folder = Pathname(item.url).dirname
86
+ dest_folder = '' if dest_folder.to_s == '/'
87
+ filename = File.basename(item.path)
88
+ item.data[MD_FILE_PROP] = "#{dest_folder}/#{filename}"
89
+ if view_md
90
+ item.data[MD_SOURCE_URL] = item.data[MD_FILE_PROP] + suffix
91
+ end
92
+
93
+ if view_pr
94
+ item.data[PR_SOURCE_URL] = item.data[MD_FILE_PROP] + suffix
95
+ end
96
+ end
97
+
98
+ if view_html
99
+ item.data[HTML_FILE_PROP] = "#{item.destination('')}".sub!(site.dest, '')
100
+ item.data[HTML_SOURCE_URL] = item.data[HTML_FILE_PROP] + suffix
101
+ end
102
+
103
+ item.data[PRETTY_PROP] = pretty
104
+ item.data[LINKBACK_PROP] = "#{item.url}|$|#{linkback}" if linkback
105
+ if view_md || view_html
106
+ Renderer.enqueue(item)
107
+ elsif view_pr
108
+ Renderer.enqueue(item, PR)
109
+ end
110
+
111
+ end
112
+ end
113
+
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,67 @@
1
+ require 'jekyll/viewsource/renderer'
2
+
3
+ module Jekyll
4
+ module ViewSource
5
+
6
+ class Cache
7
+ DEFAULT_CACHE = ".plugins/jekyll-viewsource/cache".freeze
8
+
9
+ def self.setup(site, cache)
10
+ @site = site
11
+
12
+ if cache
13
+ @cache_dir = File.join(@site.source,
14
+ (cache.is_a?(String) ? cache : DEFAULT_CACHE))
15
+
16
+ ViewSource.debug 'startup', "Setting up cache at #{@cache_dir}" if Renderer.first_run
17
+
18
+ FileUtils.mkdir_p File.join(@cache_dir)
19
+ end
20
+ end
21
+
22
+ def self.location(uri, dest)
23
+ return if !@cache_dir
24
+
25
+ subdir = Digest::SHA256.hexdigest(uri)
26
+
27
+ filename = File.basename(dest)
28
+ #filepath = Pathname(uri).dirname
29
+
30
+ #File.join(cache_path, subdir, filepath, filename)
31
+ File.join(@cache_dir, subdir, filename)
32
+ end
33
+
34
+ def self.contents(uri, dest, content = nil)
35
+ filepath = self.location(uri, dest)
36
+ return if !filepath
37
+
38
+ if content
39
+ FileUtils.mkdir_p Pathname(filepath).dirname
40
+ File.write(filepath, content)
41
+ else
42
+ if File.exist?(filepath)
43
+ content = File.read filepath
44
+ end
45
+ end
46
+
47
+ content
48
+ end
49
+
50
+ def self.modified?(source, dest, expiry = nil)
51
+ cache_path = self.location(source, dest)
52
+ if source =~ %r[://]
53
+ mod = Utils.modified?(nil, cache_path, expiry)
54
+ else
55
+ mod = Utils.modified?(source, cache_path, expiry)
56
+ end
57
+ mod
58
+ end
59
+
60
+ def self.valid?(source, dest, expiry = nil)
61
+ ! self.modified?(source, dest, expiry)
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,32 @@
1
+ module Jekyll
2
+ module ViewSource
3
+
4
+ VIEWSOURCE = 'viewsource'.freeze
5
+ VIEWSOURCE_LOG = 'ViewSource:'.freeze
6
+
7
+ HTML = 'html'.freeze
8
+ TXT = 'txt'.freeze
9
+ MARKDOWN = 'markdown'.freeze
10
+ MD = 'md'.freeze
11
+
12
+ PR = 'pr'.freeze
13
+
14
+ INFIX = '-src'.freeze
15
+ INFIXED_HTML = "#{INFIX}.#{HTML}".freeze
16
+ INFIXED_TXT = "#{INFIX}.#{TXT}".freeze
17
+
18
+ MD_SOURCE_URL = 'source_url'.freeze
19
+ PR_SOURCE_URL = 'prerender_source_url'.freeze
20
+ HTML_SOURCE_URL = 'html_source_url'.freeze
21
+
22
+ MD_FILE_PROP = "#{VIEWSOURCE}_file_md".freeze
23
+ HTML_FILE_PROP = "#{VIEWSOURCE}_file_html".freeze
24
+
25
+ PRETTY_PROP = "#{VIEWSOURCE}_pretty".freeze
26
+ LINKBACK_PROP = "#{VIEWSOURCE}_linkback".freeze
27
+
28
+ DEFAULT_CSS = 'github'.freeze
29
+ CSS_SCOPE = '.highlight'.freeze
30
+
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ require 'rouge'
2
+
3
+ module Rouge
4
+ module Lexers
5
+ class ViewSource < Markdown
6
+ tag 'viewsource'
7
+
8
+ def liquid
9
+ @liquid ||= Liquid.new(options)
10
+ end
11
+
12
+ def javascript
13
+ @javascript ||= Javascript.new(options)
14
+ end
15
+
16
+ def html
17
+ @html ||= HTML.new(options)
18
+ end
19
+
20
+ prepend :root do
21
+ rule(%r[\s*(?<!:)//.*?$]) { delegate javascript }
22
+ rule(%r(\s*/[*].*?[*]/\s*)m) { delegate javascript }
23
+
24
+ rule(%r(.*?%}.?)) { delegate liquid }
25
+ rule(%r(.*{{.*?}}.?)) { delegate liquid }
26
+
27
+ rule(%r(\s*<!--.*?-->\s*)m) { delegate html }
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,165 @@
1
+ require 'htmlbeautifier'
2
+
3
+ module Jekyll
4
+ module ViewSource
5
+
6
+ module Renderer
7
+ require_relative 'constants'
8
+ require_relative 'utils'
9
+ require_relative 'lexer'
10
+
11
+ # We have to run this after the site is written
12
+ # i.e. the HTML files exist
13
+ Jekyll::Hooks.register :site, :post_write do |site|
14
+ render_items(site)
15
+ end
16
+
17
+ @render_queue = []
18
+ @first_run = true
19
+
20
+ PRETTY = 'Pretty'.freeze
21
+ PLAIN = 'Plain'.freeze
22
+
23
+ DEFAULT_BG = '#808080'.freeze
24
+
25
+ CACHED = ' (cached)'.freeze
26
+
27
+ def self.first_run
28
+ @first_run
29
+ end
30
+
31
+ def self.enqueue(item)
32
+ @render_queue << item
33
+ end
34
+
35
+ def self.render_items(site)
36
+ @render_queue.each do |item|
37
+ pretty = item.data.delete(PRETTY_PROP)
38
+ linkback = item.data.delete(LINKBACK_PROP)
39
+
40
+ if md_file = item.data.delete(MD_FILE_PROP)
41
+ render_source(site, item, md_file, MD, pretty, linkback)
42
+ end
43
+
44
+ if html_file = item.data.delete(HTML_FILE_PROP)
45
+ render_source(site, item, html_file, HTML, pretty, linkback)
46
+ end
47
+
48
+ if @first_run
49
+ ViewSource.debug item, "Set CSS to #{pretty}" if pretty
50
+ ViewSource.debug item, "Set linkback text to #{linkback}" if linkback
51
+ end
52
+ end
53
+
54
+ @render_queue.clear
55
+ @first_run = false
56
+ end
57
+
58
+ def self.render_source(site, item, file_url, ext, pretty = nil, linkback = nil)
59
+ return unless file_url
60
+
61
+ source_link = file_url +
62
+ ( pretty ? INFIXED_HTML : INFIXED_TXT)
63
+
64
+ dest_file = File.join(site.dest, source_link)
65
+ source_md = Utils.source_file(item)
66
+
67
+ source_file = (ext == MD ? source_md :
68
+ File.join(site.dest, file_url))
69
+
70
+ if Cache.modified?(source_md, dest_file)
71
+ FileUtils.mkdir_p Pathname(dest_file).dirname
72
+
73
+ if pretty
74
+ File.write(dest_file, prettify(source_file, ext, pretty, linkback))
75
+ else
76
+ if ext == MD
77
+ FileUtils.cp source_file, dest_file
78
+ else
79
+ # Prettify it as text a bit, anyway
80
+ source_code = HtmlBeautifier.beautify File.read(source_file)
81
+ File.write(dest_file, source_code)
82
+ end
83
+ end
84
+
85
+ Cache.contents(source_md, dest_file, File.read(dest_file))
86
+
87
+ else
88
+ cached = CACHED
89
+ File.write(dest_file, Cache.contents(source_md, dest_file))
90
+ end
91
+
92
+ if @first_run || !cached
93
+ ViewSource.debug item, (pretty ? PRETTY : PLAIN) +
94
+ " #{ext}: #{source_link}#{cached}"
95
+ end
96
+
97
+ end
98
+
99
+ def self.prettify(source_file, type, user_css, linkback = nil)
100
+ source_code = File.read(source_file)
101
+ title = File.basename(source_file)
102
+
103
+ if type == HTML
104
+ source_code = HtmlBeautifier.beautify source_code
105
+ end
106
+
107
+ formatter = Rouge::Formatters::HTML.new
108
+ if type == MD
109
+ lexer = Rouge::Lexers::ViewSource.new
110
+ else
111
+ lexer = Rouge::Lexers::HTML.new
112
+ end
113
+
114
+ formatted = formatter.format(lexer.lex(source_code))
115
+
116
+ body = "<pre>#{formatted}</pre>"
117
+
118
+ if user_css
119
+ if user_css =~ /^\//
120
+ source_css = File.join(site.dest, user_css)
121
+ css = File.read(source_css) if File.exist?(source_css)
122
+ else
123
+ unless theme = Rouge::Theme.find(user_css)
124
+ theme = Rouge::Theme.find(DEFAULT_CSS)
125
+ end
126
+ css = theme.render(scope: CSS_SCOPE)
127
+ end
128
+ end
129
+
130
+ if m = css.match(/^\.highlight {.*?background-color:\s*(.*?);/m)
131
+ body_bg = m[1];
132
+ else
133
+ body_bg = DEFAULT_BG
134
+ end
135
+
136
+ if linkback
137
+ (lb_url, lb_text) = linkback.split('|$|', 2)
138
+ linkback = %Q(<div style="background-color: #fff; color: #000; padding: 5px;" class="viewsource-linkback">&laquo; <a href=").freeze + %Q(#{lb_url}">#{lb_text}) + '</a></div>'.freeze
139
+
140
+ end
141
+
142
+ # TODO: External template file
143
+ <<-HTML
144
+ <!DOCTYPE html>
145
+ <html>
146
+ <head>
147
+ <title>#{title}</title>
148
+ <style>
149
+ #{css}
150
+ </style>
151
+ </head>
152
+ <body style="background-color: #{body_bg};" class="viewsource-body">
153
+ <div class="highlight">
154
+ #{body}
155
+ #{linkback}
156
+ </div>
157
+ </body>
158
+ </html>
159
+ HTML
160
+
161
+ end
162
+
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,28 @@
1
+ require 'net/http'
2
+
3
+ module Jekyll
4
+ module ViewSource
5
+
6
+ module Utils
7
+ @touched = {}
8
+ @cache = {}
9
+
10
+ CACHE_EXPIRY = 600 # seconds
11
+
12
+ def self.source_file(item)
13
+ source_prefix = item.is_a?(Jekyll::Page) ? ViewSource.site.source : ''
14
+ File.join(source_prefix, item.path)
15
+ end
16
+
17
+ def self.modified?(source, dest, expiry = nil)
18
+ dest && !dest.empty? &&
19
+ (!File.exist?(dest) ||
20
+ (source && (File.mtime(source) > File.mtime(dest))) ||
21
+ (expiry && ((File.mtime(dest) + expiry) <= Time.now ))
22
+ )
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,5 @@
1
+ module Jekyll
2
+ module ViewSource
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-viewsource
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Alex Ibrado
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-01-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: htmlbeautifier
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rouge
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '1.7'
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: '3'
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '1.7'
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: '3'
61
+ - !ruby/object:Gem::Dependency
62
+ name: bundler
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '2.16'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '2.16'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rake
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '10.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '10.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rspec
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '3.0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '3.0'
103
+ description: This Jekyll plugin generates pretty or plain Markdown and/or HTML source
104
+ code pages for your Markdown docs, which you can easily link to for viewing.
105
+ email:
106
+ - alex@ibrado.org
107
+ executables: []
108
+ extensions: []
109
+ extra_rdoc_files: []
110
+ files:
111
+ - ".gitignore"
112
+ - ".rspec"
113
+ - ".travis.yml"
114
+ - CODE_OF_CONDUCT.md
115
+ - Gemfile
116
+ - LICENSE.txt
117
+ - README.md
118
+ - Rakefile
119
+ - bin/console
120
+ - bin/setup
121
+ - jekyll-viewsource.gemspec
122
+ - lib/jekyll/viewsource.rb
123
+ - lib/jekyll/viewsource/cache.rb
124
+ - lib/jekyll/viewsource/constants.rb
125
+ - lib/jekyll/viewsource/lexer.rb
126
+ - lib/jekyll/viewsource/renderer.rb
127
+ - lib/jekyll/viewsource/utils.rb
128
+ - lib/jekyll/viewsource/version.rb
129
+ homepage: https://github.com/ibrado/jekyll-viewsource
130
+ licenses:
131
+ - MIT
132
+ metadata: {}
133
+ post_install_message:
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: 2.1.0
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubyforge_project:
149
+ rubygems_version: 2.5.1
150
+ signing_key:
151
+ specification_version: 4
152
+ summary: View plain or pretty Markdown and/or HTML source code
153
+ test_files: []