markdownr 0.6.7 → 0.6.9
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/lib/markdown_server/app.rb +56 -0
- data/lib/markdown_server/version.rb +1 -1
- 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: c1bd3ffb960e7f2e3750d7f70fe188c551d1fcf764a6517f65a4c45fee4634e4
|
|
4
|
+
data.tar.gz: 49a2c9f9a777fc280bc9bd98a38fb135873e9e2392edbe4d2ada07cd2d20e8b2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dc4bc27debd2a2093965e2bc46ce94364e18db6970659091ebe94febab5e37cefb1ddb0fcc64810006eeb1db1b72faef32543e3b186595c85619a85303b9b4bf
|
|
7
|
+
data.tar.gz: 54b2fbd599cdae2d6e582cdf73d8adb6363244ff9ecda175c9627bf9b1619f5ae510884f053f8d5d585551b539708db684de8a00ea51adce62e48c0946b93d8f
|
data/lib/markdown_server/app.rb
CHANGED
|
@@ -607,6 +607,19 @@ module MarkdownServer
|
|
|
607
607
|
out.length > 10_000 ? out[0, 10_000] : out
|
|
608
608
|
end
|
|
609
609
|
|
|
610
|
+
def markdownr_html(html)
|
|
611
|
+
# Extract .md-content from a trusted markdownr page, preserving HTML as-is
|
|
612
|
+
content = html[/<div[^>]+class="md-content"[^>]*>([\s\S]*?)<\/div>\s*(?:<div\s+class="frontmatter"|<\/div>\s*<\/div>|\z)/im, 1]
|
|
613
|
+
return page_html(html) unless content && content.length > 10
|
|
614
|
+
|
|
615
|
+
# Also extract frontmatter if present
|
|
616
|
+
fm = html[/<div\s+class="frontmatter">([\s\S]*?)<\/div>\s*<\/div>/im, 0] || ""
|
|
617
|
+
|
|
618
|
+
result = content.strip
|
|
619
|
+
result += "\n#{fm}" unless fm.empty?
|
|
620
|
+
result.length > 15_000 ? result[0, 15_000] : result
|
|
621
|
+
end
|
|
622
|
+
|
|
610
623
|
def blueletterbible_html(html, url)
|
|
611
624
|
base = "https://www.blueletterbible.org"
|
|
612
625
|
|
|
@@ -827,6 +840,24 @@ module MarkdownServer
|
|
|
827
840
|
end
|
|
828
841
|
end
|
|
829
842
|
|
|
843
|
+
def inject_pronunciation_icon(html, meta)
|
|
844
|
+
return html unless meta.is_a?(Hash) && meta["strongs"] && meta["language"]
|
|
845
|
+
strongs = meta["strongs"].to_s.strip
|
|
846
|
+
lang = meta["language"].to_s.strip.downcase
|
|
847
|
+
return html unless strongs.match?(/\A[GH]\d+\z/i) && %w[hebrew greek].include?(lang)
|
|
848
|
+
|
|
849
|
+
icon = %(<button class="pronunciation-btn" data-strongs="#{h(strongs.upcase)}" ) +
|
|
850
|
+
%(title="Play pronunciation" ) +
|
|
851
|
+
%(style="background:none;border:none;cursor:pointer;padding:0 0 0 6px;font-size:1.1em;vertical-align:middle;line-height:1;color:#888;" ) +
|
|
852
|
+
%(onclick="(function(btn){if(btn._loading)return;var a=btn._audio;if(a){a.currentTime=0;a.play();return;}btn._loading=true;btn.style.opacity='0.4';\
|
|
853
|
+
fetch('/pronunciation?strongs='+btn.dataset.strongs).then(function(r){return r.json()}).then(function(d){\
|
|
854
|
+
if(d.audio){a=new Audio(d.audio);btn._audio=a;a.play();}btn._loading=false;btn.style.opacity='1';}).catch(function(){\
|
|
855
|
+
btn._loading=false;btn.style.opacity='1';});})(this)">🔊</button>)
|
|
856
|
+
|
|
857
|
+
# Insert before the closing tag of the first <h2>
|
|
858
|
+
html.sub(%r{</h2>}) { " #{icon}</h2>" }
|
|
859
|
+
end
|
|
860
|
+
|
|
830
861
|
# Returns true when serving an HTML file that should have popup assets injected.
|
|
831
862
|
# Add additional path prefixes here as needed.
|
|
832
863
|
def inject_assets_for_html_path?(_relative_path)
|
|
@@ -1085,6 +1116,7 @@ module MarkdownServer
|
|
|
1085
1116
|
title = (meta.is_a?(Hash) && meta["title"]) || File.basename(real, ".md")
|
|
1086
1117
|
@current_wiki_dir = File.dirname(real)
|
|
1087
1118
|
html = render_markdown(body)
|
|
1119
|
+
html = inject_pronunciation_icon(html, meta)
|
|
1088
1120
|
|
|
1089
1121
|
frontmatter_html = ""
|
|
1090
1122
|
if meta && !meta.empty?
|
|
@@ -1097,6 +1129,26 @@ module MarkdownServer
|
|
|
1097
1129
|
JSON.dump({ title: title.to_s, html: html, frontmatter_html: frontmatter_html })
|
|
1098
1130
|
end
|
|
1099
1131
|
|
|
1132
|
+
get "/pronunciation" do
|
|
1133
|
+
content_type :json
|
|
1134
|
+
strongs = params[:strongs].to_s.strip.upcase
|
|
1135
|
+
halt 400, '{"error":"invalid strongs"}' unless strongs.match?(/\A[GH]\d+\z/)
|
|
1136
|
+
|
|
1137
|
+
prefix = strongs.start_with?("H") ? "wlc" : "tr"
|
|
1138
|
+
blb_url = "https://www.blueletterbible.org/lexicon/#{strongs.downcase}/nasb20/#{prefix}/0-1/"
|
|
1139
|
+
html = fetch_external_page(blb_url)
|
|
1140
|
+
halt 502, '{"error":"fetch failed"}' unless html
|
|
1141
|
+
|
|
1142
|
+
data_pronunc = html[/data-pronunc="([a-fA-F0-9]{20,})"/i, 1]
|
|
1143
|
+
halt 404, '{"error":"no audio found"}' unless data_pronunc
|
|
1144
|
+
|
|
1145
|
+
audio_url = "https://www.blueletterbible.org/lang/lexicon/lexPronouncePlayer.cfm?skin=#{data_pronunc}"
|
|
1146
|
+
headers "Cache-Control" => "public, max-age=86400"
|
|
1147
|
+
JSON.dump({ audio: audio_url })
|
|
1148
|
+
rescue StandardError
|
|
1149
|
+
halt 502, '{"error":"fetch failed"}'
|
|
1150
|
+
end
|
|
1151
|
+
|
|
1100
1152
|
get "/fetch-json" do
|
|
1101
1153
|
content_type :json
|
|
1102
1154
|
url = params[:url].to_s.strip
|
|
@@ -1133,6 +1185,9 @@ module MarkdownServer
|
|
|
1133
1185
|
title = raw.match(/^([GH]\d+ - \w+)/i)&.[](1)&.sub(" - ", " – ") ||
|
|
1134
1186
|
raw.sub(/ [-–] .*/, "").strip
|
|
1135
1187
|
JSON.dump({ title: title, html: blueletterbible_html(html, url) })
|
|
1188
|
+
elsif url.match?(%r{/definitions/[^/]+\.md(\?|#|\z)}i)
|
|
1189
|
+
title = page_title(html).sub(/ [-–] .*/, "").strip
|
|
1190
|
+
JSON.dump({ title: title, html: markdownr_html(html) })
|
|
1136
1191
|
elsif url.match?(/scrip\.risensavior\.com/i)
|
|
1137
1192
|
title = page_title(html).sub(/ [-–] .*/, "").strip
|
|
1138
1193
|
JSON.dump({ title: title, html: scrip_html(html) })
|
|
@@ -1240,6 +1295,7 @@ module MarkdownServer
|
|
|
1240
1295
|
@meta, body = parse_frontmatter(content)
|
|
1241
1296
|
@current_wiki_dir = File.dirname(real_path)
|
|
1242
1297
|
@content = render_markdown(body)
|
|
1298
|
+
@content = inject_pronunciation_icon(@content, @meta)
|
|
1243
1299
|
relative_dir = File.dirname(relative_path)
|
|
1244
1300
|
relative_dir = "" if relative_dir == "."
|
|
1245
1301
|
listing = -> { inline_directory_html(File.dirname(real_path), relative_dir) }
|