jmv 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CODE_OF_CONDUCT.md +102 -0
- data/LICENSE +21 -0
- data/README.md +56 -0
- data/exe/jmv +44 -0
- data/jmv.gemspec +25 -0
- data/lib/jmv/template.html.liquid +233 -0
- data/lib/jmv/version.rb +5 -0
- data/lib/jmv.rb +82 -0
- metadata +67 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2bf45f987619f45bdcc50440f4e044c7d57fa2661e923a15a4e0d8581ac388a9
|
4
|
+
data.tar.gz: 3052a76fa4a0861e966729ecf2c63b1e8f6d663e6280b7d62643939f275000c9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ed354bb8caa1a439bb59a0624b50eeecef4f5cc37e302851c31ba1038d220ca79dd8ec70dd51c7ab78ce1d55d3c367dc6268dbbdafee35b289f164e441a9bfc6
|
7
|
+
data.tar.gz: e51a567437aaf09eddeef2a2c590507da79b4abe331107d2d9eb26044cdebc6f9287345db27ba33a7a4050a8d100da705334262007e669651035198a36bda8a1
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for
|
6
|
+
everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity
|
7
|
+
and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion,
|
8
|
+
or sexual identity and orientation.
|
9
|
+
|
10
|
+
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to a positive environment for our community include:
|
15
|
+
|
16
|
+
* Demonstrating empathy and kindness toward other people
|
17
|
+
* Being respectful of differing opinions, viewpoints, and experiences
|
18
|
+
* Giving and gracefully accepting constructive feedback
|
19
|
+
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
20
|
+
* Focusing on what is best not just for us as individuals, but for the overall community
|
21
|
+
|
22
|
+
Examples of unacceptable behavior include:
|
23
|
+
|
24
|
+
* The use of sexualized language or imagery, and sexual attention or
|
25
|
+
advances of any kind
|
26
|
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
27
|
+
* Public or private harassment
|
28
|
+
* Publishing others' private information, such as a physical or email
|
29
|
+
address, without their explicit permission
|
30
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
31
|
+
professional setting
|
32
|
+
|
33
|
+
## Enforcement Responsibilities
|
34
|
+
|
35
|
+
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take
|
36
|
+
appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive,
|
37
|
+
or harmful.
|
38
|
+
|
39
|
+
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits,
|
40
|
+
issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for
|
41
|
+
moderation decisions when appropriate.
|
42
|
+
|
43
|
+
## Scope
|
44
|
+
|
45
|
+
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing
|
46
|
+
the community in public spaces. Examples of representing our community include using an official e-mail address, posting
|
47
|
+
via an official social media account, or acting as an appointed representative at an online or offline event.
|
48
|
+
|
49
|
+
## Enforcement
|
50
|
+
|
51
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible
|
52
|
+
for enforcement at ashmaroli@gmail.com. All complaints will be reviewed and investigated promptly and fairly.
|
53
|
+
|
54
|
+
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
|
55
|
+
|
56
|
+
## Enforcement Guidelines
|
57
|
+
|
58
|
+
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem
|
59
|
+
in violation of this Code of Conduct:
|
60
|
+
|
61
|
+
### 1. Correction
|
62
|
+
|
63
|
+
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
|
64
|
+
|
65
|
+
**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation
|
66
|
+
and an explanation of why the behavior was inappropriate. A public apology may be requested.
|
67
|
+
|
68
|
+
### 2. Warning
|
69
|
+
|
70
|
+
**Community Impact**: A violation through a single incident or series of actions.
|
71
|
+
|
72
|
+
**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including
|
73
|
+
unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding
|
74
|
+
interactions in community spaces as well as external channels like social media. Violating these terms may lead to
|
75
|
+
a temporary or permanent ban.
|
76
|
+
|
77
|
+
### 3. Temporary Ban
|
78
|
+
|
79
|
+
**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
|
80
|
+
|
81
|
+
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified
|
82
|
+
period of time. No public or private interaction with the people involved, including unsolicited interaction with those
|
83
|
+
enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
|
84
|
+
|
85
|
+
### 4. Permanent Ban
|
86
|
+
|
87
|
+
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate
|
88
|
+
behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
|
89
|
+
|
90
|
+
**Consequence**: A permanent ban from any sort of public interaction within the community.
|
91
|
+
|
92
|
+
## Attribution
|
93
|
+
|
94
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
|
95
|
+
available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
96
|
+
|
97
|
+
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
|
98
|
+
|
99
|
+
[homepage]: https://www.contributor-covenant.org
|
100
|
+
|
101
|
+
For answers to common questions about this code of conduct, see the FAQ at
|
102
|
+
https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2021 Ashwin Maroli
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# JMV
|
2
|
+
|
3
|
+
Jekyll Metadata file Viewer (JMV) is a simple tool to enable viewing contents of the `.jekyll-metadata` file generated
|
4
|
+
by Jekyll when a site is built or served under _incremental_ mode.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your Jekyll site's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'jmv', '~> 0.1'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle install
|
17
|
+
|
18
|
+
Or install it directly via:
|
19
|
+
|
20
|
+
$ gem install jmv
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
JMV installs as a command-line program that serves a local webpage generated and rendered using the contents of
|
25
|
+
the metadata file, provided that a `.jekyll-metadata` file exists at the root of the given directory.
|
26
|
+
|
27
|
+
1. `cd` into a Jekyll project directory containing the `.jekyll-metadata` file.
|
28
|
+
|
29
|
+
2. Run `jmv` or `bundle exec jmv` if the gem is to be used via a `Gemfile`.
|
30
|
+
|
31
|
+
The above two steps can be executed in a single step by utilizing the `--source` (or `-s`) option:
|
32
|
+
|
33
|
+
$ jmv --source path/to/dir
|
34
|
+
|
35
|
+
Once the server is up and running, point your web browser to `http://localhost:3000` to view the metadata file contents.
|
36
|
+
If you wish to use a different port for the server, you may do so by utilizing the `--port` (or `-p`) option before
|
37
|
+
starting the server:
|
38
|
+
|
39
|
+
$ jmv --port 8080
|
40
|
+
|
41
|
+
The server will then start mounted at `http://localhost:8080`.
|
42
|
+
|
43
|
+
## Contributing
|
44
|
+
|
45
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ashmaroli/jmv. This project is intended to be
|
46
|
+
a safe, welcoming space for collaboration, and contributors are expected to adhere to
|
47
|
+
the [code of conduct](https://github.com/ashmaroli/jmv/blob/master/CODE_OF_CONDUCT.md).
|
48
|
+
|
49
|
+
## License
|
50
|
+
|
51
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
52
|
+
|
53
|
+
## Code of Conduct
|
54
|
+
|
55
|
+
Everyone interacting in the JMV project's codebases, issue trackers, chat rooms and mailing lists is expected to follow
|
56
|
+
the [code of conduct](https://github.com/ashmaroli/jmv/blob/master/CODE_OF_CONDUCT.md).
|
data/exe/jmv
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative '../lib/jmv'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
options = {}
|
8
|
+
option_parser = OptionParser.new do |opts|
|
9
|
+
opts.banner = <<~TEXT
|
10
|
+
|
11
|
+
Jekyll Metadata file Viewer (JMV) - v#{JMV::VERSION}
|
12
|
+
------------------------------------------
|
13
|
+
|
14
|
+
Serves contents of the metadata file as a local webpage
|
15
|
+
|
16
|
+
Usage:
|
17
|
+
jmv [<options>]
|
18
|
+
|
19
|
+
TEXT
|
20
|
+
|
21
|
+
opts.on('-s', '--source DIR', 'Configure metadata file location. Default: current dir') do |source|
|
22
|
+
options[:source] = source
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on('-p', '--port PORT', 'Configure server port. Default: 3000') do |port|
|
26
|
+
options[:port] = port
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on('-h', '--help', 'Show this message') do |help|
|
30
|
+
puts opts
|
31
|
+
exit
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
begin
|
36
|
+
option_parser.parse!
|
37
|
+
rescue OptionParser::InvalidOption => e
|
38
|
+
puts ''
|
39
|
+
puts " Error! #{e}"
|
40
|
+
puts ' Please run `jmv --help` to view available options.'
|
41
|
+
exit
|
42
|
+
end
|
43
|
+
|
44
|
+
JMV.start(options)
|
data/jmv.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/jmv/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "jmv"
|
7
|
+
spec.version = JMV::VERSION
|
8
|
+
spec.authors = ["Ashwin Maroli"]
|
9
|
+
spec.email = ["ashmaroli@gmail.com"]
|
10
|
+
spec.homepage = "https://github.com/ashmaroli/jmv"
|
11
|
+
|
12
|
+
spec.summary = "Simple tool to enable viewing contents of '.jekyll-metadata' file."
|
13
|
+
spec.description = "Jekyll Metadata file Viewer (JMV) is a simple tool to enable viewing " \
|
14
|
+
"contents of the '.jekyll-metadata' file generated by Jekyll."
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| File.basename(f).start_with?(".") }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = ["jmv"]
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.required_ruby_version = ">= 2.5.0"
|
23
|
+
|
24
|
+
spec.add_dependency "webrick", "~> 1.7"
|
25
|
+
end
|
@@ -0,0 +1,233 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="UTF-8">
|
5
|
+
<title>{{ app.name }}</title>
|
6
|
+
<style>
|
7
|
+
:root {
|
8
|
+
--dark-gray: #454545;
|
9
|
+
--gray: #757575;
|
10
|
+
--light-gray: #eeeeee;
|
11
|
+
--off-white: #fcfcfc;
|
12
|
+
--white: #ffffff;
|
13
|
+
--red: #b30404;
|
14
|
+
--light-red: #ecd7d7;
|
15
|
+
--pale-red: #fbf9f9;
|
16
|
+
}
|
17
|
+
|
18
|
+
* { box-sizing: border-box }
|
19
|
+
body {
|
20
|
+
margin: 0;
|
21
|
+
font-family: Roboto, sans-serif;
|
22
|
+
line-height: 1.25;
|
23
|
+
color: var(--red);
|
24
|
+
background: var(--pale-red);
|
25
|
+
}
|
26
|
+
header {
|
27
|
+
margin-bottom: 30px;
|
28
|
+
padding: 15px;
|
29
|
+
background: var(--off-white);
|
30
|
+
border-bottom: 1px solid var(--light-gray);
|
31
|
+
}
|
32
|
+
h2 {
|
33
|
+
margin: 0;
|
34
|
+
font-size: 1.125em;
|
35
|
+
color: var(--red);
|
36
|
+
text-align: center;
|
37
|
+
}
|
38
|
+
main {
|
39
|
+
height: calc(100vh - 195px);
|
40
|
+
overflow-y: auto;
|
41
|
+
overflow-x: hidden;
|
42
|
+
|
43
|
+
}
|
44
|
+
ul {
|
45
|
+
margin: 0;
|
46
|
+
padding-left: 0.5em ;
|
47
|
+
list-style: none;
|
48
|
+
}
|
49
|
+
footer {
|
50
|
+
margin-top: 30px;
|
51
|
+
padding: 15px;
|
52
|
+
color: var(--red);;
|
53
|
+
font-size: 0.8em;
|
54
|
+
text-align: center;
|
55
|
+
background: var(--off-white);
|
56
|
+
border-top: 1px solid var(--light-gray);
|
57
|
+
}
|
58
|
+
footer a { color: var(--red) }
|
59
|
+
.toggles {
|
60
|
+
margin-left: 30px;
|
61
|
+
position: fixed;
|
62
|
+
}
|
63
|
+
.toggle-btn {
|
64
|
+
margin: 8px 15px;
|
65
|
+
padding: 8px 15px;
|
66
|
+
font-size: 0.8em;
|
67
|
+
cursor: pointer;
|
68
|
+
border: 1px solid var(--light-red);
|
69
|
+
border-radius: 15px 5px;
|
70
|
+
}
|
71
|
+
#toggle-collapse:after { content: 'Collapse All' }
|
72
|
+
#toggle-collapse.collapsed:after { content: 'Expand All' }
|
73
|
+
#toggle-json:after { content: 'View JSON' }
|
74
|
+
#toggle-json.active:after { content: 'Hide JSON' }
|
75
|
+
.container {
|
76
|
+
max-width: 960px;
|
77
|
+
width: calc(100% - 400px);
|
78
|
+
margin: 0 auto;
|
79
|
+
}
|
80
|
+
.wrapper {
|
81
|
+
width: calc(100% - 30px);
|
82
|
+
height: calc(100vh - 200px);
|
83
|
+
overflow: auto;
|
84
|
+
}
|
85
|
+
.entry {
|
86
|
+
margin-bottom: 3px;
|
87
|
+
padding: 10px 15px;
|
88
|
+
background: var(--off-white);
|
89
|
+
transition: all 0.5s;
|
90
|
+
}
|
91
|
+
.entry, .entry.togglable.collapsed {
|
92
|
+
border: 1px solid var(--light-gray);
|
93
|
+
}
|
94
|
+
.entry.togglable {
|
95
|
+
background: var(--white);
|
96
|
+
border-color: var(--light-red);
|
97
|
+
}
|
98
|
+
.entry.togglable:hover .name { color: var(--red) }
|
99
|
+
.deps {
|
100
|
+
width: calc(100% - 25px);
|
101
|
+
padding-top: 2px;
|
102
|
+
color: var(--dark-gray);
|
103
|
+
overflow: hidden;
|
104
|
+
}
|
105
|
+
.deps li {
|
106
|
+
padding-left: 15px;
|
107
|
+
border-left: 1px dotted var(--light-red);
|
108
|
+
}
|
109
|
+
.chevron {
|
110
|
+
width: 25px;
|
111
|
+
max-height: 20px;
|
112
|
+
vertical-align: middle;
|
113
|
+
text-align: center;
|
114
|
+
}
|
115
|
+
.hidden { display: none }
|
116
|
+
.path { display: flex }
|
117
|
+
.name { width: calc(100% - 25px); color: var(--gray) }
|
118
|
+
.togglable .name { color: var(--red) }
|
119
|
+
.togglable { cursor: pointer }
|
120
|
+
.chevron:after { content: '\25B4'; font-size: 1.5em }
|
121
|
+
.collapsed .name, .json { color: var(--gray) }
|
122
|
+
.collapsed .deps { height: 0 }
|
123
|
+
.collapsed .chevron:after { content: '\25BD'; font-size: 1em }
|
124
|
+
.app-meta, .oss {
|
125
|
+
display: inline-block;
|
126
|
+
padding: 10px 15px;
|
127
|
+
}
|
128
|
+
.oss {
|
129
|
+
width: 58px;
|
130
|
+
border-left: 1px solid var(--light-red);
|
131
|
+
}
|
132
|
+
|
133
|
+
::-webkit-scrollbar {
|
134
|
+
width: 15px;
|
135
|
+
}
|
136
|
+
::-webkit-scrollbar-track {
|
137
|
+
background: #fbf9f9;
|
138
|
+
box-shadow: inset 0 0 8px #eac8c8;
|
139
|
+
border-radius: 8px;
|
140
|
+
}
|
141
|
+
::-webkit-scrollbar-thumb {
|
142
|
+
background: #bb1b1b;
|
143
|
+
background-clip: content-box;
|
144
|
+
border: 3px solid transparent;
|
145
|
+
border-radius: 10px;
|
146
|
+
}
|
147
|
+
</style>
|
148
|
+
</head>
|
149
|
+
<body>
|
150
|
+
<header>
|
151
|
+
<h2>{{ data.path }}</h2>
|
152
|
+
</header>
|
153
|
+
<main>
|
154
|
+
<aside class="toggles">
|
155
|
+
<div id="toggle-collapse" class="toggle-btn"></div>
|
156
|
+
<div id="toggle-json" class="toggle-btn"></div>
|
157
|
+
</aside>
|
158
|
+
<div class="wrapper">
|
159
|
+
<div class="slabs container">
|
160
|
+
{%- for entry in data.data -%}
|
161
|
+
{% assign mtime = entry[1]['mtime'] -%}
|
162
|
+
{% assign deps = entry[1]['deps'] -%}
|
163
|
+
{%- if deps.size != 0 %}
|
164
|
+
<div class="entry togglable">
|
165
|
+
<div class="path" title="last modified at: {{ mtime }}; {{ deps.size }} dependencies">
|
166
|
+
<div class="name">{{ entry[0] }}</div>
|
167
|
+
<span class="chevron"></span>
|
168
|
+
</div>
|
169
|
+
<div class="deps">
|
170
|
+
<ul>
|
171
|
+
{%- for dependency in deps %}
|
172
|
+
<li>{{ dependency }}</li>
|
173
|
+
{%- endfor %}
|
174
|
+
</ul>
|
175
|
+
</div>
|
176
|
+
</div>
|
177
|
+
{%- else %}
|
178
|
+
<div class="entry">
|
179
|
+
<div class="path" title="last modified at: {{ mtime }}; no dependencies">
|
180
|
+
<div class="name">{{ entry[0] }}</div>
|
181
|
+
</div>
|
182
|
+
</div>
|
183
|
+
{%- endif -%}
|
184
|
+
{%- endfor %}
|
185
|
+
</div>
|
186
|
+
<div class="json container hidden">
|
187
|
+
<pre>{{ data.json }}</pre>
|
188
|
+
</div>
|
189
|
+
</div>
|
190
|
+
</main>
|
191
|
+
<footer>
|
192
|
+
<div class="footer-contents">
|
193
|
+
<div class="app-meta">
|
194
|
+
<div>{{ app.name }}</div>
|
195
|
+
<div>v{{ app.version }}</div>
|
196
|
+
</div>
|
197
|
+
<div class="oss">
|
198
|
+
<a href="https://github.com/ashmaroli/jmv" title="Source code at GitHub">
|
199
|
+
<svg viewBox="0 0 16 16">
|
200
|
+
<path fill="currentcolor" d="M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z"/>
|
201
|
+
</svg>
|
202
|
+
</a>
|
203
|
+
</div>
|
204
|
+
</div>
|
205
|
+
</footer>
|
206
|
+
<script>
|
207
|
+
const togglables = document.getElementsByClassName('togglable');
|
208
|
+
const toggleClassName = 'collapsed';
|
209
|
+
for (entry of togglables) {
|
210
|
+
entry.addEventListener('click', function() {
|
211
|
+
this.classList.toggle(toggleClassName);
|
212
|
+
});
|
213
|
+
}
|
214
|
+
document.getElementById('toggle-collapse').addEventListener(
|
215
|
+
'click', function() {
|
216
|
+
this.classList.toggle(toggleClassName);
|
217
|
+
if (this.classList.contains(toggleClassName)) {
|
218
|
+
for (entry of togglables) { entry.classList.add(toggleClassName); }
|
219
|
+
} else {
|
220
|
+
for (entry of togglables) { entry.classList.remove(toggleClassName); }
|
221
|
+
}
|
222
|
+
}
|
223
|
+
);
|
224
|
+
document.getElementById('toggle-json').addEventListener(
|
225
|
+
'click', function() {
|
226
|
+
this.classList.toggle('active');
|
227
|
+
document.getElementsByClassName('slabs')[0].classList.toggle('hidden');
|
228
|
+
document.getElementsByClassName('json')[0].classList.toggle('hidden');
|
229
|
+
}
|
230
|
+
);
|
231
|
+
</script>
|
232
|
+
</body>
|
233
|
+
</html>
|
data/lib/jmv/version.rb
ADDED
data/lib/jmv.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'jmv/version'
|
4
|
+
|
5
|
+
require 'json'
|
6
|
+
require 'liquid'
|
7
|
+
require 'webrick'
|
8
|
+
|
9
|
+
module JMV
|
10
|
+
class Servlet < WEBrick::HTTPServlet::AbstractServlet
|
11
|
+
TEMPLATE_PATH = File.join(__dir__, 'jmv', 'template.html.liquid').freeze
|
12
|
+
private_constant :TEMPLATE_PATH
|
13
|
+
|
14
|
+
def do_GET(_request, response)
|
15
|
+
metadata_file = @server.config[:ResourcePath]
|
16
|
+
metadata = read metadata_file
|
17
|
+
|
18
|
+
context = {
|
19
|
+
'app' => {
|
20
|
+
'name' => 'Jekyll Metadata file Viewer',
|
21
|
+
'version' => JMV::VERSION,
|
22
|
+
},
|
23
|
+
'data' => {
|
24
|
+
'path' => metadata_file,
|
25
|
+
'data' => metadata,
|
26
|
+
'json' => JSON.pretty_generate(metadata),
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
# Repeat on every browser window refresh
|
31
|
+
template_contents = File.binread(TEMPLATE_PATH)
|
32
|
+
rendered_contents = Liquid::Template.parse(template_contents).render(context)
|
33
|
+
|
34
|
+
response.status = 200
|
35
|
+
response['Content-Type'] = 'text/html'
|
36
|
+
response.body = rendered_contents
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def read(file)
|
42
|
+
Marshal.load(File.binread(file))
|
43
|
+
rescue StandardError => e
|
44
|
+
puts " Error loading #{file}: #{e}"
|
45
|
+
raise e
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.start(options)
|
50
|
+
source = File.expand_path(options[:source] || '')
|
51
|
+
puts "\n Source: #{source}"
|
52
|
+
metadata_file = File.join(source, '.jekyll-metadata')
|
53
|
+
|
54
|
+
if File.exist?(metadata_file) && !File.directory?(metadata_file)
|
55
|
+
puts " Metadata file: #{metadata_file}"
|
56
|
+
puts ''
|
57
|
+
puts ' Processing..'
|
58
|
+
else
|
59
|
+
puts " Error: Could not find the '.jekyll-metadata' file at source. Aborting.."
|
60
|
+
puts ' Build or serve a Jekyll source either with `--incremental` CLI option or'
|
61
|
+
puts ' with `incremental: true` config setting to generate the metadata file.'
|
62
|
+
return
|
63
|
+
end
|
64
|
+
|
65
|
+
server = WEBrick::HTTPServer.new(
|
66
|
+
:Port => options[:port] || 3000,
|
67
|
+
:Logger => WEBrick::Log.new($stdout, WEBrick::Log::WARN),
|
68
|
+
:AccessLog => [],
|
69
|
+
:ResourcePath => metadata_file
|
70
|
+
)
|
71
|
+
server.mount('/', Servlet)
|
72
|
+
trap('INT') do
|
73
|
+
puts ' Shutting down server..'
|
74
|
+
puts ''
|
75
|
+
server.shutdown
|
76
|
+
end
|
77
|
+
puts ' Starting server..'
|
78
|
+
puts " Server mounted at http://localhost:#{server.config[:Port]}."
|
79
|
+
puts ''
|
80
|
+
server.start
|
81
|
+
end
|
82
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jmv
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ashwin Maroli
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-09-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: webrick
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
description: Jekyll Metadata file Viewer (JMV) is a simple tool to enable viewing
|
28
|
+
contents of the '.jekyll-metadata' file generated by Jekyll.
|
29
|
+
email:
|
30
|
+
- ashmaroli@gmail.com
|
31
|
+
executables:
|
32
|
+
- jmv
|
33
|
+
extensions: []
|
34
|
+
extra_rdoc_files: []
|
35
|
+
files:
|
36
|
+
- CODE_OF_CONDUCT.md
|
37
|
+
- LICENSE
|
38
|
+
- README.md
|
39
|
+
- exe/jmv
|
40
|
+
- jmv.gemspec
|
41
|
+
- lib/jmv.rb
|
42
|
+
- lib/jmv/template.html.liquid
|
43
|
+
- lib/jmv/version.rb
|
44
|
+
homepage: https://github.com/ashmaroli/jmv
|
45
|
+
licenses:
|
46
|
+
- MIT
|
47
|
+
metadata: {}
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 2.5.0
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirements: []
|
63
|
+
rubygems_version: 3.1.6
|
64
|
+
signing_key:
|
65
|
+
specification_version: 4
|
66
|
+
summary: Simple tool to enable viewing contents of '.jekyll-metadata' file.
|
67
|
+
test_files: []
|