markdownr 0.5.17 → 0.5.18
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.
- checksums.yaml +4 -4
- data/bin/markdownr +5 -0
- data/lib/markdown_server/app.rb +17 -0
- data/lib/markdown_server/version.rb +1 -1
- data/views/layout.erb +8 -15
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1186498f524f4e5d50aa1d9ddb93f4d48e3dcfb327b6d4e10bb530be747179a3
|
|
4
|
+
data.tar.gz: 2d6131e668d24603309ae2b25893b3bdde2d1764f971e18acec87b1fbb26250a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 92d7e42dffe104f2c5e8a3c6289962af0ea643f27ecac103e714298b11827dd1089bd71503116bacd044cb779fca5acd192cba47d59314d991ff4d3c5514d39e
|
|
7
|
+
data.tar.gz: 8ca0350721e961e55d556bf67a9fa8a8b940e21578ac1faba965d1e9fe34968f06c4f5e5ec3ea729d7305581396be595a1fa8cd8a6664f2f97502e99cbeaf93c
|
data/bin/markdownr
CHANGED
|
@@ -43,6 +43,10 @@ OptionParser.new do |opts|
|
|
|
43
43
|
options[:hard_wrap] = false
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
+
opts.on("--verbose", "Print each request (time, IP, method, path) to stdout") do
|
|
47
|
+
options[:verbose] = true
|
|
48
|
+
end
|
|
49
|
+
|
|
46
50
|
opts.on("-v", "--version", "Show version") do
|
|
47
51
|
puts "markdownr #{MarkdownServer::VERSION}"
|
|
48
52
|
exit
|
|
@@ -64,6 +68,7 @@ MarkdownServer::App.set :allow_robots, options[:allow_robots] || false
|
|
|
64
68
|
MarkdownServer::App.set :index_file, options[:index_file]
|
|
65
69
|
MarkdownServer::App.set :link_tooltips, options.fetch(:link_tooltips, true)
|
|
66
70
|
MarkdownServer::App.set :hard_wrap, options.fetch(:hard_wrap, true)
|
|
71
|
+
MarkdownServer::App.set :verbose, options[:verbose] || false
|
|
67
72
|
MarkdownServer::App.set :port, options[:port]
|
|
68
73
|
MarkdownServer::App.set :bind, options[:bind]
|
|
69
74
|
MarkdownServer::App.set :server_settings, { max_threads: options[:threads], min_threads: 1 }
|
data/lib/markdown_server/app.rb
CHANGED
|
@@ -31,6 +31,7 @@ module MarkdownServer
|
|
|
31
31
|
set :protection, false
|
|
32
32
|
set :host_authorization, { permitted_hosts: [] }
|
|
33
33
|
set :behind_proxy, false
|
|
34
|
+
set :verbose, false
|
|
34
35
|
set :session_secret, ENV.fetch("MARKDOWNR_SESSION_SECRET", SecureRandom.hex(64))
|
|
35
36
|
set :sessions, key: "markdownr_session", same_site: :strict, httponly: true
|
|
36
37
|
end
|
|
@@ -817,6 +818,13 @@ module MarkdownServer
|
|
|
817
818
|
end
|
|
818
819
|
end
|
|
819
820
|
|
|
821
|
+
before do
|
|
822
|
+
if settings.verbose
|
|
823
|
+
$stdout.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} #{client_ip} #{request.request_method} #{request.fullpath}"
|
|
824
|
+
$stdout.flush
|
|
825
|
+
end
|
|
826
|
+
end
|
|
827
|
+
|
|
820
828
|
get "/" do
|
|
821
829
|
redirect "/browse/"
|
|
822
830
|
end
|
|
@@ -1167,6 +1175,15 @@ module MarkdownServer
|
|
|
1167
1175
|
when ".epub"
|
|
1168
1176
|
redirect @download_href
|
|
1169
1177
|
|
|
1178
|
+
when ".html"
|
|
1179
|
+
send_file real_path, type: "text/html"
|
|
1180
|
+
|
|
1181
|
+
when ".css"
|
|
1182
|
+
send_file real_path, type: "text/css"
|
|
1183
|
+
|
|
1184
|
+
when ".js"
|
|
1185
|
+
send_file real_path, type: "application/javascript"
|
|
1186
|
+
|
|
1170
1187
|
else
|
|
1171
1188
|
content = File.read(real_path, encoding: "utf-8") rescue nil
|
|
1172
1189
|
if content.nil? || content.encoding == Encoding::BINARY || !content.valid_encoding?
|
data/views/layout.erb
CHANGED
|
@@ -777,6 +777,7 @@
|
|
|
777
777
|
background: #faf8f4;
|
|
778
778
|
flex-shrink: 0;
|
|
779
779
|
cursor: grab;
|
|
780
|
+
touch-action: none;
|
|
780
781
|
}
|
|
781
782
|
.link-ctx-popup-header.is-dragging {
|
|
782
783
|
cursor: grabbing;
|
|
@@ -861,8 +862,8 @@
|
|
|
861
862
|
position: absolute;
|
|
862
863
|
bottom: 0;
|
|
863
864
|
right: 0;
|
|
864
|
-
width:
|
|
865
|
-
height:
|
|
865
|
+
width: 36px;
|
|
866
|
+
height: 36px;
|
|
866
867
|
cursor: nwse-resize;
|
|
867
868
|
touch-action: none;
|
|
868
869
|
border-bottom-right-radius: 5px;
|
|
@@ -982,7 +983,9 @@
|
|
|
982
983
|
.blb-usage li { margin-bottom: 0.15rem; }
|
|
983
984
|
.blb-usage p { margin: 0; }
|
|
984
985
|
|
|
986
|
+
|
|
985
987
|
/* Footnote tooltips */
|
|
988
|
+
sup[id^="fnref:"] { position: relative; }
|
|
986
989
|
.footnote-tooltip {
|
|
987
990
|
position: absolute;
|
|
988
991
|
bottom: 100%;
|
|
@@ -999,8 +1002,8 @@
|
|
|
999
1002
|
z-index: 150;
|
|
1000
1003
|
box-shadow: 0 2px 8px rgba(0,0,0,0.25);
|
|
1001
1004
|
margin-bottom: 6px;
|
|
1005
|
+
cursor: pointer;
|
|
1002
1006
|
}
|
|
1003
|
-
.footnote-tooltip { cursor: pointer; }
|
|
1004
1007
|
.footnote-tooltip::after {
|
|
1005
1008
|
content: '';
|
|
1006
1009
|
position: absolute;
|
|
@@ -1015,9 +1018,6 @@
|
|
|
1015
1018
|
.footnote-tooltip a { color: #d4b96a; }
|
|
1016
1019
|
.footnote-tooltip p { margin: 0; }
|
|
1017
1020
|
.footnote-tooltip p + p { margin-top: 0.3rem; }
|
|
1018
|
-
sup[id^="fnref:"] {
|
|
1019
|
-
position: relative;
|
|
1020
|
-
}
|
|
1021
1021
|
|
|
1022
1022
|
/* Responsive */
|
|
1023
1023
|
@media (max-width: 768px) {
|
|
@@ -1426,10 +1426,6 @@
|
|
|
1426
1426
|
tooltip.style.left = '50%';
|
|
1427
1427
|
tooltip.style.transform = 'translateX(-50%)';
|
|
1428
1428
|
tooltip.style.removeProperty('--arrow-offset');
|
|
1429
|
-
// Clamp tooltip to viewport.
|
|
1430
|
-
// document.documentElement.clientWidth is more reliable than window.innerWidth
|
|
1431
|
-
// on Android browsers (e.g. EinkBro) which may return a pre-scaled layout
|
|
1432
|
-
// viewport width for window.innerWidth rather than the CSS viewport width.
|
|
1433
1429
|
var viewportWidth = Math.min(window.innerWidth, document.documentElement.clientWidth);
|
|
1434
1430
|
var rect = tooltip.getBoundingClientRect();
|
|
1435
1431
|
var shift = 0;
|
|
@@ -1453,19 +1449,16 @@
|
|
|
1453
1449
|
sup.addEventListener('mouseleave', hideTooltip);
|
|
1454
1450
|
|
|
1455
1451
|
// Touch: first tap shows tooltip, second tap navigates
|
|
1456
|
-
// Using touchend instead of click so no hover media query check is needed —
|
|
1457
|
-
// touchend only fires on real touch, regardless of what (hover:none) reports.
|
|
1458
1452
|
var linkTouchMoved = false;
|
|
1459
1453
|
link.addEventListener('touchstart', function() { linkTouchMoved = false; }, { passive: true });
|
|
1460
1454
|
link.addEventListener('touchmove', function() { linkTouchMoved = true; }, { passive: true });
|
|
1461
1455
|
link.addEventListener('touchend', function(e) {
|
|
1462
|
-
if (linkTouchMoved) return;
|
|
1456
|
+
if (linkTouchMoved) return;
|
|
1463
1457
|
if (tooltip.parentNode === sup) {
|
|
1464
1458
|
// Tooltip already showing — let the link navigate
|
|
1465
1459
|
return;
|
|
1466
1460
|
}
|
|
1467
1461
|
e.preventDefault();
|
|
1468
|
-
// Dismiss any other open tooltip
|
|
1469
1462
|
document.querySelectorAll('.footnote-tooltip').forEach(function(t) {
|
|
1470
1463
|
if (t.parentNode) t.parentNode.removeChild(t);
|
|
1471
1464
|
});
|
|
@@ -1482,7 +1475,7 @@
|
|
|
1482
1475
|
window.location.hash = fnHref;
|
|
1483
1476
|
});
|
|
1484
1477
|
|
|
1485
|
-
// Dismiss tooltip when
|
|
1478
|
+
// Dismiss tooltip when clicking elsewhere
|
|
1486
1479
|
document.addEventListener('click', function(e) {
|
|
1487
1480
|
if (tooltip.parentNode === sup && !sup.contains(e.target)) {
|
|
1488
1481
|
hideTooltip();
|