markdownr 0.6.14 → 0.6.16

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1a7ba09af27621d312b09f8fbf2d590664c9265762e40705487e8efdc88851b
4
- data.tar.gz: 70e8227e25b38fbf729c0d1d84a7e48a1f874a4306cfb26c13e1e897f8137da4
3
+ metadata.gz: ae47c745347215a97c8448c31431bde10bf60935740970585d3b01626aab4d49
4
+ data.tar.gz: 75c279c8578e8ef37e82748431b605dfa38fa786a1a3f162331dbbe5086b91a1
5
5
  SHA512:
6
- metadata.gz: 933b70b7b1b9187e84f4e0a5f80a74be842d874476c1119d47571a629d98be0a81b6888a9b32e74df4a5e9ef976b79dbe196b6d0e94659498949ca990afb1289
7
- data.tar.gz: 2e33af70f39e9dbbb29e6a38fdcb7b4bacb8838511b640ada29048ba4bcdd02d424c11f19d717e68eb42ded4c24e543c7db94ab246680274ecee2b75af00b486
6
+ metadata.gz: f4b4af8f7f2b1d175c156b3a93b4f66f6300e715a0cef021d7fd97b222af522fa0b7be26e8a09224db705aec240762766f7b005bdfb1825803396b2e452982bc
7
+ data.tar.gz: 6e220707c92e1f80fe676b9353514d426c03419b6514fc2d0ed49f9f1d431ed595065c22588aea028369a1edf07c53591bfa851eac4009b8211cf0d4ffa6868a
@@ -1,3 +1,3 @@
1
1
  module MarkdownServer
2
- VERSION = "0.6.14"
2
+ VERSION = "0.6.16"
3
3
  end
data/views/layout.erb CHANGED
@@ -2167,6 +2167,19 @@
2167
2167
  }
2168
2168
  }
2169
2169
 
2170
+ // StudyLight pronunciation: play audio instead of popup
2171
+ function playStudylightPronunc(anchor) {
2172
+ var href = anchor.getAttribute('href') || '';
2173
+ if (!anchor.classList.contains('pronunc-link')) return false;
2174
+ var m = href.match(/studylight\.org\/lexicons\/eng\/(hebrew|greek)\/(\d+)\.html/);
2175
+ if (!m) return false;
2176
+ var audioUrl = 'https://www.studylight.org/multi-media/audio/lexicons/eng/' + m[1] + '.html?n=' + m[2];
2177
+ if (!anchor._slAudio) anchor._slAudio = new Audio(audioUrl);
2178
+ anchor._slAudio.currentTime = 0;
2179
+ anchor._slAudio.play();
2180
+ return true;
2181
+ }
2182
+
2170
2183
  // Left-click on desktop
2171
2184
  document.addEventListener('click', function(e) {
2172
2185
  if (popup && popup.contains(e.target)) return;
@@ -2174,6 +2187,7 @@
2174
2187
  if (!anchor) { hidePopup(); return; }
2175
2188
  var href = anchor.getAttribute('href');
2176
2189
  if (!href || isAnchorOnly(href)) { hidePopup(); return; }
2190
+ if (playStudylightPronunc(anchor)) { e.preventDefault(); return; }
2177
2191
  if (!anchor.closest('.md-content') && !anchor.closest('.frontmatter')) { hidePopup(); return; }
2178
2192
  if (!shouldPopup(href)) { hidePopup(); return; }
2179
2193
  e.preventDefault();
@@ -2197,6 +2211,7 @@
2197
2211
  if (!anchor) { hidePopup(); return; }
2198
2212
  var href = anchor.getAttribute('href');
2199
2213
  if (!href || isAnchorOnly(href)) { hidePopup(); return; }
2214
+ if (playStudylightPronunc(anchor)) { e.preventDefault(); return; }
2200
2215
  if (!anchor.closest('.md-content') && !anchor.closest('.frontmatter')) { hidePopup(); return; }
2201
2216
  if (!shouldPopup(href)) { hidePopup(); return; }
2202
2217
  e.preventDefault();
@@ -2219,6 +2234,7 @@
2219
2234
  var href = a.getAttribute('href');
2220
2235
  if (!href || isAnchorOnly(href)) return;
2221
2236
  if (!shouldPopup(href)) return;
2237
+ if (a.classList.contains('pronunc-link') && /studylight\.org\/lexicons\/eng\//.test(href)) return;
2222
2238
  a.addEventListener('mouseenter', function(e) {
2223
2239
  clearTimeout(hoverTimer);
2224
2240
  if (popup) return;
@@ -731,6 +731,19 @@
731
731
  }
732
732
  }
733
733
 
734
+ // StudyLight pronunciation: play audio instead of popup
735
+ function playStudylightPronunc(anchor) {
736
+ var href = anchor.getAttribute('href') || '';
737
+ if (!anchor.classList.contains('pronunc-link')) return false;
738
+ var m = href.match(/studylight\.org\/lexicons\/eng\/(hebrew|greek)\/(\d+)\.html/);
739
+ if (!m) return false;
740
+ var audioUrl = 'https://www.studylight.org/multi-media/audio/lexicons/eng/' + m[1] + '.html?n=' + m[2];
741
+ if (!anchor._slAudio) anchor._slAudio = new Audio(audioUrl);
742
+ anchor._slAudio.currentTime = 0;
743
+ anchor._slAudio.play();
744
+ return true;
745
+ }
746
+
734
747
  // Left-click on desktop
735
748
  document.addEventListener('click', function(e) {
736
749
  if (popup && popup.contains(e.target)) return;
@@ -738,6 +751,7 @@
738
751
  if (!anchor) { hidePopup(); return; }
739
752
  var href = anchor.getAttribute('href');
740
753
  if (!href || isAnchorOnly(href)) { hidePopup(); return; }
754
+ if (playStudylightPronunc(anchor)) { e.preventDefault(); return; }
741
755
  if (!shouldPopup(href)) { hidePopup(); return; }
742
756
  e.preventDefault();
743
757
  handleLink(anchor, e.clientX, e.clientY, false);
@@ -761,6 +775,7 @@
761
775
  if (!anchor) { hidePopup(); return; }
762
776
  var href = anchor.getAttribute('href');
763
777
  if (!href || isAnchorOnly(href)) { hidePopup(); return; }
778
+ if (playStudylightPronunc(anchor)) { e.preventDefault(); return; }
764
779
  if (!shouldPopup(href)) { hidePopup(); return; }
765
780
  e.preventDefault();
766
781
  var touch = e.changedTouches[0];
@@ -778,6 +793,7 @@
778
793
  var href = a.getAttribute('href');
779
794
  if (!href || isAnchorOnly(href)) return;
780
795
  if (!shouldPopup(href)) return;
796
+ if (a.classList.contains('pronunc-link') && /studylight\.org\/lexicons\/eng\//.test(href)) return;
781
797
 
782
798
  a.addEventListener('mouseenter', function(e) {
783
799
  clearTimeout(hoverTimer);
@@ -1027,4 +1043,98 @@
1027
1043
  if (toolbar) top -= toolbar.offsetHeight + 4;
1028
1044
  window.scrollTo({ top: top, behavior: 'instant' });
1029
1045
  })();
1046
+
1047
+ // Inject verse speaker icon for interlinear pages
1048
+ (function() {
1049
+ var verses = document.querySelectorAll('.verse[data-verse]');
1050
+ if (!verses.length) return;
1051
+
1052
+ function audioUrlFromLink(a) {
1053
+ if (!a) return null;
1054
+ var href = a.getAttribute('href') || '';
1055
+ var m = href.match(/studylight\.org\/lexicons\/eng\/(hebrew|greek)\/(\d+)\.html/);
1056
+ if (!m) return null;
1057
+ return 'https://www.studylight.org/multi-media/audio/lexicons/eng/' + m[1] + '.html?n=' + m[2];
1058
+ }
1059
+
1060
+ verses.forEach(function(verse) {
1061
+ var verseNum = verse.querySelector('.verse-num');
1062
+ if (!verseNum) return;
1063
+ var words = verse.querySelectorAll('.word');
1064
+ if (!words.length) return;
1065
+
1066
+ // Collect audio URLs for all words in this verse
1067
+ var urls = [];
1068
+ words.forEach(function(w) {
1069
+ var link = w.querySelector('.pronunc-link');
1070
+ var url = audioUrlFromLink(link);
1071
+ if (url) urls.push(url);
1072
+ });
1073
+ if (!urls.length) return;
1074
+
1075
+ // Create a column-flex container to replace the bare verse-num,
1076
+ // with the number at top (row 1) and speaker icon at row 5
1077
+ var wrapper = document.createElement('span');
1078
+ wrapper.style.cssText = 'display:flex;flex-direction:column;align-self:stretch;align-items:center;margin-right:4px;';
1079
+
1080
+ // Row 1: verse number
1081
+ verseNum.style.cssText += ';margin:0;';
1082
+ wrapper.appendChild(verseNum);
1083
+
1084
+ // Spacer to push icon down to row 5
1085
+ var spacer = document.createElement('span');
1086
+ spacer.style.cssText = 'flex:1;';
1087
+ wrapper.appendChild(spacer);
1088
+
1089
+ // Row 5: speaker icon
1090
+ var btn = document.createElement('button');
1091
+ btn.textContent = '\u{1F50A}';
1092
+ btn.title = 'Audio from the excellent studylight.org';
1093
+ btn.style.cssText = 'background:none;border:none;cursor:pointer;padding:0;font-size:1em;line-height:1;opacity:0.6;';
1094
+ btn.addEventListener('mouseleave', function() { if (!btn._playing) btn.style.opacity = '0.6'; });
1095
+
1096
+ var audioCache = [];
1097
+ var preloaded = false;
1098
+ function preloadAll() {
1099
+ if (preloaded) return;
1100
+ preloaded = true;
1101
+ urls.forEach(function(u) {
1102
+ var a = new Audio(u);
1103
+ a.preload = 'auto';
1104
+ a.load();
1105
+ audioCache.push(a);
1106
+ });
1107
+ }
1108
+ // Start preloading on hover so audio is ready before click
1109
+ btn.addEventListener('mouseenter', function() {
1110
+ btn.style.opacity = '1';
1111
+ preloadAll();
1112
+ });
1113
+
1114
+ btn.addEventListener('click', function() {
1115
+ if (btn._playing) return;
1116
+ btn._playing = true;
1117
+ btn.style.opacity = '1';
1118
+ preloadAll();
1119
+
1120
+ var i = 0;
1121
+ function playNext() {
1122
+ if (i >= audioCache.length) {
1123
+ btn._playing = false;
1124
+ btn.style.opacity = '0.6';
1125
+ return;
1126
+ }
1127
+ var audio = audioCache[i];
1128
+ audio.currentTime = 0;
1129
+ audio.onended = function() { i++; playNext(); };
1130
+ audio.onerror = function() { i++; playNext(); };
1131
+ audio.play().catch(function() { i++; playNext(); });
1132
+ }
1133
+ playNext();
1134
+ });
1135
+
1136
+ wrapper.appendChild(btn);
1137
+ verse.insertBefore(wrapper, verse.firstChild);
1138
+ });
1139
+ })();
1030
1140
  </script>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markdownr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.14
4
+ version: 0.6.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Dunn