newport 1.0.2 → 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -7
- data/exe/newport +1 -1
- data/lib/newport.rb +35 -0
- data/lib/newport/build.rb +87 -0
- data/lib/newport/help.rb +13 -0
- data/lib/newport/logger.rb +8 -0
- data/lib/newport/new.rb +69 -0
- data/lib/newport/version.rb +5 -0
- data/lib/site_template/config.yml +8 -0
- data/lib/site_template/javascript/js.cookie.min.js +2 -0
- data/lib/site_template/layouts/footer.html +10 -0
- data/lib/site_template/layouts/head.html +9 -0
- data/lib/site_template/layouts/main.html +16 -0
- data/lib/site_template/layouts/nav.html +4 -0
- data/lib/site_template/layouts/style.css +37 -0
- data/lib/site_template/plugins/changefont.js +83 -0
- data/lib/site_template/plugins/darkmode.js +42 -0
- data/lib/site_template/plugins/expander.js +29 -0
- data/lib/site_template/plugins/pagination.js +30 -0
- data/lib/site_template/plugins/permalink.js +42 -0
- data/lib/site_template/posts/202107211703_digital-ocean-static-site-hosting.md +14 -0
- metadata +21 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff47fb76e4cf88c9843d48f1b435d2fd0ce938bef6ce7f74db9ffa26ca05173a
|
4
|
+
data.tar.gz: a8e78af5182b81b2cd27d8b39bca804940a873f1084c68ec47a88e12a3c6c4c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd4c6743ef16d99548496ef16e7acefe08a97bc2566ed6e0cde29b0e64e5a789a290acf6b87601e0470ab6851c889430735694da937310a42cdcca0174356a1f
|
7
|
+
data.tar.gz: 637c43e5b8cbff4ddca8001d37b634f1b5577f1dbed2cf25cdae70af0b61fd304779efa8df06bdede63563de93b9547fa204397323b2c599245f0345e7e0a40b
|
data/README.md
CHANGED
@@ -1,16 +1,25 @@
|
|
1
|
+
[https://richard.fisher.cymru](https://richard.fisher.cymru)
|
2
|
+
|
1
3
|
# Newport
|
2
|
-
Newport is a
|
4
|
+
Newport is a Ruby Gem for building a single file blog/static site.
|
3
5
|
|
4
6
|
## Getting Started
|
5
|
-
-
|
6
|
-
-
|
7
|
-
-
|
8
|
-
-
|
9
|
-
- Modify the layouts and add some posts
|
10
|
-
- Run `bundle exec ruby build.rb`
|
7
|
+
- `gem install newport`
|
8
|
+
- `newport new <path>`
|
9
|
+
- `cd <path>`
|
10
|
+
- `newport build`
|
11
11
|
|
12
12
|
## Plugins
|
13
13
|
Plugins are available in the plugins directory and are pure javascript. Plugins are run after the page loads and can modify the contents.
|
14
14
|
|
15
15
|
### Expander
|
16
16
|
For example the expander plugin will loop through your posts and show n number of paragraphs for each one and hide the rest, adding a down arrow to click to expand and show the full post.
|
17
|
+
|
18
|
+
### Pagination
|
19
|
+
Set the variable show in pagination.js to the number of posts you want to display per page. The plugin will automatically add an arrow to click to show more.
|
20
|
+
|
21
|
+
### Permalinks
|
22
|
+
Add a hash to the end of each post that links to the permanent location for that post.
|
23
|
+
|
24
|
+
### Dark Mode
|
25
|
+
Shows a light/dark toggle to toggle between light mode and dark mode. It uses cookies to remember your selection. There are some css variables that you can change for light/dark mode in style.css
|
data/exe/newport
CHANGED
data/lib/newport.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift __dir__ # For use/testing when no gem is installed
|
4
|
+
|
5
|
+
def require_all(path)
|
6
|
+
glob = File.join(__dir__, path, '*.rb')
|
7
|
+
Dir[glob].each do |f|
|
8
|
+
require f
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'rubygems'
|
13
|
+
require 'fileutils'
|
14
|
+
require 'time'
|
15
|
+
require 'logger'
|
16
|
+
require 'colorator'
|
17
|
+
require 'kramdown'
|
18
|
+
require 'rss'
|
19
|
+
|
20
|
+
module Newport
|
21
|
+
autoload :VERSION, 'newport/version'
|
22
|
+
autoload :Help, 'newport/help'
|
23
|
+
autoload :New, 'newport/new'
|
24
|
+
autoload :Build, 'newport/build'
|
25
|
+
|
26
|
+
require 'newport/logger'
|
27
|
+
|
28
|
+
class << self
|
29
|
+
def logger
|
30
|
+
@logger ||= Logger.new($stdout)
|
31
|
+
@logger.formatter = proc { |_severity, _datetime, _progname, msg| "#{msg}\n" }
|
32
|
+
@logger
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Newport
|
4
|
+
class Build
|
5
|
+
class << self
|
6
|
+
def process(args)
|
7
|
+
show_help if args[1] == 'help'
|
8
|
+
build_blog
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def show_help
|
14
|
+
Newport.logger.info "Newport #{Newport::VERSION}"
|
15
|
+
Newport.logger.info 'usage: newport build'
|
16
|
+
abort
|
17
|
+
end
|
18
|
+
|
19
|
+
def build_blog
|
20
|
+
html = content_from_layouts
|
21
|
+
html = add_javascript html
|
22
|
+
html = add_plugins html
|
23
|
+
html = add_posts(html, build_posts)
|
24
|
+
html = replcae_tags html
|
25
|
+
write_html html
|
26
|
+
end
|
27
|
+
|
28
|
+
def config
|
29
|
+
@config ||= YAML.load_file('config.yml')
|
30
|
+
end
|
31
|
+
|
32
|
+
def content_from_layouts
|
33
|
+
head = File.read('layouts/head.html')
|
34
|
+
style = File.read('layouts/style.css')
|
35
|
+
head = head.gsub('<!-- style -->', "<style>#{style}</style>")
|
36
|
+
nav = File.read('layouts/nav.html')
|
37
|
+
main = File.read('layouts/main.html')
|
38
|
+
footer = File.read('layouts/footer.html')
|
39
|
+
main.gsub('<!-- head -->', head).gsub('<!-- nav -->', nav).gsub('<!-- footer -->', footer)
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_javascript(html)
|
43
|
+
jss = []
|
44
|
+
Dir.glob('javascript/*.js') { |filename| jss << File.open(filename).read }
|
45
|
+
html.gsub('<!-- javascript -->', "<script>#{jss.join}</script>")
|
46
|
+
end
|
47
|
+
|
48
|
+
def add_plugins(html)
|
49
|
+
plugins = []
|
50
|
+
config['plugins'].each do |p|
|
51
|
+
plugin = File.open("plugins/#{p}.js").read
|
52
|
+
plugins << plugin
|
53
|
+
end
|
54
|
+
html.gsub('<!-- plugins -->', "<script>#{plugins.join}</script>")
|
55
|
+
end
|
56
|
+
|
57
|
+
def build_posts
|
58
|
+
files = []
|
59
|
+
posts = []
|
60
|
+
|
61
|
+
Dir.glob('posts/*.md') { |filename| files << filename.split('/').last }
|
62
|
+
|
63
|
+
files.reverse.each do |filename|
|
64
|
+
post = '<article>' + Kramdown::Document.new(File.open("posts/#{filename}").read).to_html + '</article>'
|
65
|
+
posts << post
|
66
|
+
end
|
67
|
+
posts
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_posts(html, posts)
|
71
|
+
html.gsub('<!-- posts -->', posts.join)
|
72
|
+
end
|
73
|
+
|
74
|
+
def replcae_tags(html)
|
75
|
+
html = html.gsub('<!-- email -->', config['email'])
|
76
|
+
html.gsub('<!-- title -->', config['title'])
|
77
|
+
end
|
78
|
+
|
79
|
+
def write_html(html)
|
80
|
+
FileUtils.mkdir_p 'production/images'
|
81
|
+
File.open('production/index.html', 'w') do |f|
|
82
|
+
f.write html
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/newport/help.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Newport
|
4
|
+
class Help
|
5
|
+
class << self
|
6
|
+
def show
|
7
|
+
Newport.logger.info "Newport #{Newport::VERSION}"
|
8
|
+
Newport.logger.info 'usage: newport [command] [options]'
|
9
|
+
Newport.logger.info 'commands: new, build, help'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/newport/new.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Newport
|
4
|
+
class New
|
5
|
+
class << self
|
6
|
+
def process(args)
|
7
|
+
Newport.logger.abort_with 'fatal: please specify path.'.red unless args[1]
|
8
|
+
show_help if args[1] == 'help'
|
9
|
+
create_blog args[1]
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def show_help
|
15
|
+
Newport.logger.info "Newport #{Newport::VERSION}"
|
16
|
+
Newport.logger.info 'usage: newport new [path]'
|
17
|
+
abort
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_blog(path)
|
21
|
+
blog_path = File.expand_path(path, Dir.pwd)
|
22
|
+
FileUtils.mkdir_p blog_path
|
23
|
+
FileUtils.cp_r "#{template}/.", path
|
24
|
+
FileUtils.chmod_R 'u+w', path
|
25
|
+
File.open(File.expand_path('Gemfile', path), 'w') do |f|
|
26
|
+
f.write(gemfile_contents)
|
27
|
+
end
|
28
|
+
after_install path
|
29
|
+
end
|
30
|
+
|
31
|
+
def template
|
32
|
+
File.expand_path('../site_template', __dir__)
|
33
|
+
end
|
34
|
+
|
35
|
+
def gemfile_contents
|
36
|
+
<<~RUBY
|
37
|
+
source "https://rubygems.org"
|
38
|
+
|
39
|
+
gem "newport", "~> #{Newport::VERSION}"
|
40
|
+
|
41
|
+
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
|
42
|
+
# and associated library.
|
43
|
+
platforms :mingw, :x64_mingw, :mswin, :jruby do
|
44
|
+
gem "tzinfo", "~> 1.2"
|
45
|
+
gem "tzinfo-data"
|
46
|
+
end
|
47
|
+
RUBY
|
48
|
+
end
|
49
|
+
|
50
|
+
def after_install(path)
|
51
|
+
begin
|
52
|
+
require 'bundler'
|
53
|
+
bundle_install path
|
54
|
+
rescue LoadError
|
55
|
+
Newport.logger.info 'Could not load Bundler. Bundle install skipped.'
|
56
|
+
end
|
57
|
+
|
58
|
+
Newport.logger.info "New Newport site installed in #{path.cyan}."
|
59
|
+
end
|
60
|
+
|
61
|
+
def bundle_install(path)
|
62
|
+
Newport.logger.info "Running bundle install in #{path.cyan}..."
|
63
|
+
Dir.chdir(path) do
|
64
|
+
system('bundle')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,2 @@
|
|
1
|
+
/*! js-cookie v3.0.0-rc.1 | MIT */
|
2
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self,function(){var n=e.Cookies,r=e.Cookies=t();r.noConflict=function(){return e.Cookies=n,r}}())}(this,function(){"use strict";function e(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)e[r]=n[r]}return e}var t={read:function(e){return e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent)},write:function(e){return encodeURIComponent(e).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,decodeURIComponent)}};return function n(r,o){function i(t,n,i){if("undefined"!=typeof document){"number"==typeof(i=e({},o,i)).expires&&(i.expires=new Date(Date.now()+864e5*i.expires)),i.expires&&(i.expires=i.expires.toUTCString()),t=encodeURIComponent(t).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape),n=r.write(n,t);var c="";for(var u in i)i[u]&&(c+="; "+u,!0!==i[u]&&(c+="="+i[u].split(";")[0]));return document.cookie=t+"="+n+c}}return Object.create({set:i,get:function(e){if("undefined"!=typeof document&&(!arguments.length||e)){for(var n=document.cookie?document.cookie.split("; "):[],o={},i=0;i<n.length;i++){var c=n[i].split("="),u=c.slice(1).join("=");'"'===u[0]&&(u=u.slice(1,-1));try{var f=t.read(c[0]);if(o[f]=r.read(u,f),e===f)break}catch(e){}}return e?o[e]:o}},remove:function(t,n){i(t,"",e({},n,{expires:-1}))},withAttributes:function(t){return n(this.converter,e({},this.attributes,t))},withConverter:function(t){return n(e({},this.converter,t),this.attributes)}},{attributes:{value:Object.freeze(o)},converter:{value:Object.freeze(r)}})}(t,{path:"/"})});
|
@@ -0,0 +1,37 @@
|
|
1
|
+
html{height:100%}
|
2
|
+
body{margin:0;padding:0 0.5em;background-color: var(--background-color);color: var(--text-color);height:100%}
|
3
|
+
.container{max-width:768px;margin:auto;padding-left:5px;padding-right:5px}
|
4
|
+
body{font-family:monospace;font-size:1.1rem;line-height:1.2rem;}
|
5
|
+
a,a:active,a:visited{color:#1FC5FF;text-decoration:none}
|
6
|
+
article h1 {margin-bottom:3px;color:var(--h1-color)}
|
7
|
+
article h2 {margin-top:-1em;color:#EA4D89;font-weight:normal;font-size:0.85rem;margin: 0}
|
8
|
+
pre{white-space: pre-wrap}
|
9
|
+
article{margin-bottom:3em}
|
10
|
+
nav{text-align:right;padding-top:0.5rem}
|
11
|
+
article img{margin: auto;display: block}
|
12
|
+
article blockquote{margin-left:25px;border-left:10px #ddd solid;padding-left:15px;white-space: pre-wrap}
|
13
|
+
img{max-width: 100%;}
|
14
|
+
h1 a,h1 a:active,h1 a:visited{color:var(--h1-color)}
|
15
|
+
.title{float:left;padding-top:0.5rem}
|
16
|
+
section{margin-top:2rem}
|
17
|
+
#darkmode,#changefont{display:inline}
|
18
|
+
.expander-arrow, .more-arrow, .more-arrow:active, .more-arrow:visited { color: var(--text-color); fill: var(--text-color) }
|
19
|
+
footer {border-top: 1px var(--footer-border-color) solid;min-height: 80px;padding-top: 10px;padding-bottom:15px}
|
20
|
+
.main {min-height: calc(100% - 40px)}
|
21
|
+
code{background:var(--code-background-color);padding-left:2px;padding-right:2px}
|
22
|
+
|
23
|
+
:root {
|
24
|
+
--background-color: #fafafa;
|
25
|
+
--text-color: #111;
|
26
|
+
--code-background-color: #ccc;
|
27
|
+
--footer-border-color: #ccc;
|
28
|
+
--h1-color: #111;
|
29
|
+
}
|
30
|
+
|
31
|
+
[data-theme="dark"] {
|
32
|
+
--background-color: #0D1117;
|
33
|
+
--text-color: #8B949E;
|
34
|
+
--code-background-color: #888;
|
35
|
+
--footer-border-color: #555;
|
36
|
+
--h1-color: #ddd;
|
37
|
+
}
|
@@ -0,0 +1,83 @@
|
|
1
|
+
function setFontFromCookies() {
|
2
|
+
var fontSize = Cookies.get('font-size');
|
3
|
+
if (fontSize == undefined) {
|
4
|
+
var fontSize = 0.9;
|
5
|
+
}
|
6
|
+
|
7
|
+
var fontFamily = Cookies.get('font-family');
|
8
|
+
if (fontFamily == undefined) {
|
9
|
+
var fontFamily = 'monospace';
|
10
|
+
}
|
11
|
+
|
12
|
+
if (fontFamily == 'monospace') {
|
13
|
+
var lineHeight = Number(fontSize) + 0.4;
|
14
|
+
} else {
|
15
|
+
var lineHeight = Number(fontSize) + 1;
|
16
|
+
}
|
17
|
+
|
18
|
+
console.log(fontFamily);
|
19
|
+
console.log(fontSize + 'rem');
|
20
|
+
console.log(lineHeight + 'rem');
|
21
|
+
|
22
|
+
let body = document.getElementsByClassName("posts")[0];
|
23
|
+
body.style.fontSize = fontSize + 'rem';
|
24
|
+
body.style.fontFamily = fontFamily;
|
25
|
+
body.style.lineHeight = lineHeight + 'rem';
|
26
|
+
}
|
27
|
+
|
28
|
+
function showDropDown() {
|
29
|
+
document.getElementById("dropdown").classList.toggle("show");
|
30
|
+
}
|
31
|
+
|
32
|
+
function setFontSize(size) {
|
33
|
+
switch (size) {
|
34
|
+
case 'small':
|
35
|
+
Cookies.set('font-size', 0.8);
|
36
|
+
setFontFromCookies();
|
37
|
+
break;
|
38
|
+
case 'medium':
|
39
|
+
Cookies.set('font-size', 0.9);
|
40
|
+
setFontFromCookies();
|
41
|
+
break;
|
42
|
+
case 'large':
|
43
|
+
Cookies.set('font-size', 1.0);
|
44
|
+
setFontFromCookies();
|
45
|
+
break;
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
function setFont(font) {
|
50
|
+
switch (font) {
|
51
|
+
case 'mono':
|
52
|
+
Cookies.set('font-family', 'monospace');
|
53
|
+
setFontFromCookies();
|
54
|
+
break;
|
55
|
+
case 'sans':
|
56
|
+
Cookies.set('font-family', 'sans-serif');
|
57
|
+
setFontFromCookies();
|
58
|
+
break;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
// Close the dropdown menu if the user clicks outside of it
|
63
|
+
window.onclick = function (event) {
|
64
|
+
if (!event.target.matches('.dropbtn')) {
|
65
|
+
var dropdowns = document.getElementsByClassName("dropdown-content");
|
66
|
+
var i;
|
67
|
+
for (i = 0; i < dropdowns.length; i++) {
|
68
|
+
var openDropdown = dropdowns[i];
|
69
|
+
if (openDropdown.classList.contains('show')) {
|
70
|
+
openDropdown.classList.remove('show');
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
setFontFromCookies();
|
77
|
+
document.getElementById("changefont").innerHTML = '<div class="dropdown"><button onclick="showDropDown()" class="dropbtn">☰</button><div id="dropdown" class="dropdown-content"><span>Font Size<br /><button onclick="setFontSize(\x27small\x27)" class="font-size-small">A</button><button onclick="setFontSize(\x27medium\x27)" class="font-size-medium">A</button><button onclick="setFontSize(\x27large\x27)" class="font-size-large">A</button></span><span>Font<br /><button onclick="setFont(\x27mono\x27)" class="font-mono">mono</button><button onclick="setFont(\x27sans\x27)" class="font-sans">sans-serif</button></span></div></div>';
|
78
|
+
var css = '.font-size-small{font-size:.9rem;border:none;background:#ddd;cursor:pointer}.font-size-medium{font-size:1rem;border:none;background:#ddd;cursor:pointer}.font-size-large{font-size:1.1rem;border:none;background:#ddd;cursor:pointer}.font-mono{font-family:monospace;border:none;cursor:pointer}.font-sans{font-family:sans-serif;border:none;cursor:pointer}.dropbtn{padding:0;font-size:16px;border:none;cursor:pointer;background:0 0;color:var(--text-color)}.dropdown{position:relative;display:inline-block}.dropdown-content{text-align:center;display:none;position:absolute;background-color:#eee;min-width:180px;z-index:1;margin-left:-160px}.dropdown-content span{color:#000;padding:12px 16px;text-decoration:none;display:block}.show{display:block}';
|
79
|
+
var head = document.getElementsByTagName('head')[0];
|
80
|
+
var s = document.createElement('style');
|
81
|
+
s.setAttribute('type', 'text/css');
|
82
|
+
s.appendChild(document.createTextNode(css));
|
83
|
+
head.appendChild(s);
|
@@ -0,0 +1,42 @@
|
|
1
|
+
// Place an empty div with the id darkmode where you want to toggle to appear in your html
|
2
|
+
// ie. <div id="darkmode"></div>
|
3
|
+
|
4
|
+
(function () {
|
5
|
+
|
6
|
+
function showDark() {
|
7
|
+
document.documentElement.setAttribute("data-theme", "dark");
|
8
|
+
Cookies.set('appearance', 'dark');
|
9
|
+
}
|
10
|
+
|
11
|
+
function showLight() {
|
12
|
+
document.documentElement.setAttribute("data-theme", "light");
|
13
|
+
Cookies.set('appearance', 'light');
|
14
|
+
}
|
15
|
+
|
16
|
+
var appearance = Cookies.get('appearance')
|
17
|
+
document.getElementById("darkmode").innerHTML = '<span style="color: orangered">☼</span>/<span style="color: #888">☽</span><label class="switch"><input type="checkbox" name="darkmode" id="darkmode-checkbox"/><span class="slider round"></span></label>';
|
18
|
+
|
19
|
+
if (appearance == 'dark') {
|
20
|
+
document.getElementById('darkmode-checkbox').checked = true;
|
21
|
+
showDark();
|
22
|
+
} else if (appearance == 'light') {
|
23
|
+
document.getElementById('darkmode-checkbox').checked = false;
|
24
|
+
showLight();
|
25
|
+
}
|
26
|
+
|
27
|
+
document.getElementById("darkmode-checkbox").onchange = function () {
|
28
|
+
if (document.getElementById('darkmode-checkbox').checked) {
|
29
|
+
showDark();
|
30
|
+
} else {
|
31
|
+
showLight();
|
32
|
+
}
|
33
|
+
};
|
34
|
+
|
35
|
+
})();
|
36
|
+
|
37
|
+
var css = ' .switch {position: relative;display: inline-block;width: 30px;height: 17px;}.switch input {opacity: 0;width: 0;height: 0;}.slider {position: absolute;cursor: pointer;top: 0;left: 0;right: 0;bottom: 0;background-color: #ccc;-webkit-transition: .4s;transition: .4s;}.slider:before {position: absolute;content: "";height: 13px;width: 13px;left: 2px;bottom: 2px;background-color: white;-webkit-transition: .4s;transition: .4s;color: #000;}input:checked + .slider {background-color: #333;}input:focus + .slider {box-shadow: 0 0 1px #333;}input:checked + .slider:before {-webkit-transform: translateX(13px);-ms-transform: translateX(13px);transform: translateX(13px);}.slider.round {border-radius: 17px;}.slider.round:before {border-radius: 50%;}';
|
38
|
+
var head = document.getElementsByTagName('head')[0];
|
39
|
+
var s = document.createElement('style');
|
40
|
+
s.setAttribute('type', 'text/css');
|
41
|
+
s.appendChild(document.createTextNode(css));
|
42
|
+
head.appendChild(s);
|
@@ -0,0 +1,29 @@
|
|
1
|
+
(function() {
|
2
|
+
const show = 1; // The number of paragraphs to show for each article/post
|
3
|
+
|
4
|
+
var articles = document.getElementsByTagName("article");
|
5
|
+
for(var i = 0; i < articles.length; i++){
|
6
|
+
var paras = articles[i].getElementsByTagName("p");
|
7
|
+
if (paras.length > show) {
|
8
|
+
// We have more paragraphs than we want to show
|
9
|
+
var r = Math.random().toString(36).substring(7);
|
10
|
+
// Now loop through the paragraphs
|
11
|
+
for(var j = 0; j < paras.length; j++){
|
12
|
+
if (j >= show) {
|
13
|
+
paras[j].setAttribute("style", 'display:none');
|
14
|
+
paras[j].setAttribute("class", r);
|
15
|
+
}
|
16
|
+
}
|
17
|
+
let expander = document.createElement('a');
|
18
|
+
expander.innerHTML = '<svg style="height: 10px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg>';
|
19
|
+
var expand_function = 'var elms = document.getElementsByClassName("'+r+'"); for(var k = 0; k < elms.length; k++) { elms[k].setAttribute("style", "display:block") } document.getElementById("link_'+r+'").setAttribute("style", "display:none"); return false;';
|
20
|
+
expander.setAttribute('onclick', expand_function);
|
21
|
+
expander.setAttribute('href', "#");
|
22
|
+
expander.setAttribute("id", 'link_'+r);
|
23
|
+
expander.setAttribute("style", 'color: #000');
|
24
|
+
expander.setAttribute("class", 'expander-arrow');
|
25
|
+
expander.setAttribute("title", 'Click to expand text');
|
26
|
+
paras[show].parentNode.insertBefore(expander, paras[show]);
|
27
|
+
}
|
28
|
+
}
|
29
|
+
})();
|
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
const show = 10; // The number of posts to show per page
|
3
|
+
|
4
|
+
function showPage(offset) {
|
5
|
+
// Avoid conflicts with permalink plugin
|
6
|
+
const link = window.location.href.split('#')[1];
|
7
|
+
if (link !== undefined) {
|
8
|
+
return;
|
9
|
+
}
|
10
|
+
let articles = document.getElementsByTagName("article");
|
11
|
+
for(let i = 0; i < articles.length; i++){
|
12
|
+
if (i < show+offset) {
|
13
|
+
articles[i].setAttribute("style", 'display:block');
|
14
|
+
} else {
|
15
|
+
articles[i].setAttribute("style", 'display:none');
|
16
|
+
}
|
17
|
+
}
|
18
|
+
if (articles.length > show+offset) {
|
19
|
+
let more = document.createElement('a');
|
20
|
+
more.innerHTML = 'more <svg style="width: 10px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"/></svg>';
|
21
|
+
let more_function = 'var elms = document.getElementsByClassName("more-arrow"); for(var k = 0; k < elms.length; k++) { elms[k].remove() }; showPage('+(offset+show)+'); return false;';
|
22
|
+
more.setAttribute('onclick', more_function);
|
23
|
+
more.setAttribute('href', "#");
|
24
|
+
more.setAttribute("class", 'more-arrow');
|
25
|
+
more.setAttribute("title", 'Click to show more posts');
|
26
|
+
articles[show+offset-1].parentNode.insertBefore(more, articles[show+offset-1].nextSibling);
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
showPage(0);
|
@@ -0,0 +1,42 @@
|
|
1
|
+
(function () {
|
2
|
+
window.addEventListener('hashchange', function () {
|
3
|
+
window.location.reload(true);
|
4
|
+
}, false);
|
5
|
+
// Add id and permailink to every article
|
6
|
+
var articles = document.getElementsByTagName("article");
|
7
|
+
for (var i = 0; i < articles.length; i++) {
|
8
|
+
let id = articles[i].getElementsByTagName("h1")[0].id;
|
9
|
+
articles[i].id = id;
|
10
|
+
var paras = articles[i].getElementsByTagName("p");
|
11
|
+
var pos = paras.length - 1;
|
12
|
+
paras[pos].innerHTML = paras[pos].innerHTML + ' <a href="#' + id + '" title="Permanent link to post" onclick="window.location.reload(true);">#</a>';
|
13
|
+
}
|
14
|
+
// Check if url contains link to article
|
15
|
+
const link = window.location.href.split('#')[1];
|
16
|
+
if (link !== undefined) {
|
17
|
+
var articles = document.getElementsByTagName("article");
|
18
|
+
var found = false;
|
19
|
+
for (var i = 0; i < articles.length; i++) {
|
20
|
+
var id = articles[i].id;
|
21
|
+
if (link == id) {
|
22
|
+
found = true;
|
23
|
+
articles[i].setAttribute("style", 'display:block');
|
24
|
+
var paras = articles[i].getElementsByTagName("p");
|
25
|
+
for (var j = 0; j < paras.length; j++) {
|
26
|
+
paras[j].setAttribute("style", 'display:block');
|
27
|
+
}
|
28
|
+
var arrows = articles[i].getElementsByClassName("expander-arrow");
|
29
|
+
for (var k = 0; k < arrows.length; k++) {
|
30
|
+
arrows[k].setAttribute("style", 'display:none');
|
31
|
+
}
|
32
|
+
} else {
|
33
|
+
articles[i].setAttribute("style", 'display:none');
|
34
|
+
}
|
35
|
+
}
|
36
|
+
if (found == false) {
|
37
|
+
let p = document.createElement('p');
|
38
|
+
p.innerHTML = 'Post ' + link + ' not found :(';
|
39
|
+
document.getElementsByTagName("section")[0].appendChild(p);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
})();
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Welcome to Newport
|
2
|
+
|
3
|
+
## 21 Jul, 2021
|
4
|
+
|
5
|
+
Welcome to your new blog powered by Newport. Start writing your blog posts in this directory, using markdown, and then run `newport build`. Your static blog will be written to a folder called production and you just need to upload the contents of that folder somewhere that is capable of hosting a static site for you. Some free options are:
|
6
|
+
|
7
|
+
1. [GitHub Pages](https://pages.github.com)
|
8
|
+
2. [DigitalOcean App Platform](https://www.digitalocean.com/products/app-platform/)
|
9
|
+
|
10
|
+
Don't forget to update your email address and site title in the config.yml
|
11
|
+
|
12
|
+
You'll find plugins in the javascript directory. If you develop any useful plugins for your own use please consider submitting a pull request to the [Newport GitHub](https://github.com/richard-fisher/newport)
|
13
|
+
|
14
|
+
Happy blogging!
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: newport
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Fisher
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-07-
|
11
|
+
date: 2021-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorator
|
@@ -44,26 +44,6 @@ dependencies:
|
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 2.3.1
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: mercenary
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
requirements:
|
51
|
-
- - ">="
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: 0.3.6
|
54
|
-
- - "<"
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
version: '0.5'
|
57
|
-
type: :runtime
|
58
|
-
prerelease: false
|
59
|
-
version_requirements: !ruby/object:Gem::Requirement
|
60
|
-
requirements:
|
61
|
-
- - ">="
|
62
|
-
- !ruby/object:Gem::Version
|
63
|
-
version: 0.3.6
|
64
|
-
- - "<"
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
version: '0.5'
|
67
47
|
- !ruby/object:Gem::Dependency
|
68
48
|
name: rss
|
69
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -97,6 +77,25 @@ files:
|
|
97
77
|
- LICENSE
|
98
78
|
- README.md
|
99
79
|
- exe/newport
|
80
|
+
- lib/newport.rb
|
81
|
+
- lib/newport/build.rb
|
82
|
+
- lib/newport/help.rb
|
83
|
+
- lib/newport/logger.rb
|
84
|
+
- lib/newport/new.rb
|
85
|
+
- lib/newport/version.rb
|
86
|
+
- lib/site_template/config.yml
|
87
|
+
- lib/site_template/javascript/js.cookie.min.js
|
88
|
+
- lib/site_template/layouts/footer.html
|
89
|
+
- lib/site_template/layouts/head.html
|
90
|
+
- lib/site_template/layouts/main.html
|
91
|
+
- lib/site_template/layouts/nav.html
|
92
|
+
- lib/site_template/layouts/style.css
|
93
|
+
- lib/site_template/plugins/changefont.js
|
94
|
+
- lib/site_template/plugins/darkmode.js
|
95
|
+
- lib/site_template/plugins/expander.js
|
96
|
+
- lib/site_template/plugins/pagination.js
|
97
|
+
- lib/site_template/plugins/permalink.js
|
98
|
+
- lib/site_template/posts/202107211703_digital-ocean-static-site-hosting.md
|
100
99
|
homepage: https://github.com/richard-fisher/newport
|
101
100
|
licenses:
|
102
101
|
- MIT
|