markdownr 0.5.4 → 0.5.6
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 +11 -6
- data/lib/markdown_server/version.rb +1 -1
- data/views/layout.erb +44 -19
- 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: 6e04e007ceb9d03b7cadc1cfbb9b7d6d4df51f83d82fecba4fc22d52623b50fe
|
|
4
|
+
data.tar.gz: ed3c37ef77810c9cd2589314d9d3239fb77f48e0ac3e1ede670146db9ff2c1bc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dc882e485d1eadb2415443b5056dca89534fe1b561118d508060b126b53332a507ee2ef375faa648444cdc0ef394179de172acdee13981d30d8f89737dba6bed
|
|
7
|
+
data.tar.gz: 0feb715779946a7456559618e3493986520dcbbeeab7714caa7049e6d4d196a90471fbd90102e9b060ddee7c9f2028fbf6ab5215e9de85c0b793ec4d9776e18c
|
data/lib/markdown_server/app.rb
CHANGED
|
@@ -137,10 +137,12 @@ module MarkdownServer
|
|
|
137
137
|
label = display || heading_text
|
|
138
138
|
%(<a class="wiki-link" href="##{h(anchor)}">#{h(label)}</a>)
|
|
139
139
|
else
|
|
140
|
-
|
|
140
|
+
file_part, anchor_part = target.split("#", 2)
|
|
141
|
+
anchor_suffix = anchor_part ? "##{anchor_part.downcase.gsub(/\s+/, '-').gsub(/[^\w-]/, '')}" : ""
|
|
142
|
+
resolved = resolve_wiki_link(file_part)
|
|
141
143
|
label = display || target
|
|
142
144
|
if resolved
|
|
143
|
-
%(<a class="wiki-link" href="/browse/#{encode_path_component(resolved).gsub('%2F', '/')}">#{h(label)}</a>)
|
|
145
|
+
%(<a class="wiki-link" href="/browse/#{encode_path_component(resolved).gsub('%2F', '/')}#{anchor_suffix}">#{h(label)}</a>)
|
|
144
146
|
else
|
|
145
147
|
%(<span class="wiki-link broken">#{h(label)}</span>)
|
|
146
148
|
end
|
|
@@ -227,6 +229,7 @@ module MarkdownServer
|
|
|
227
229
|
str.scan(/\[\[([^\]]+)\]\]/) do |match|
|
|
228
230
|
raw = match[0]
|
|
229
231
|
m_start = $~.begin(0)
|
|
232
|
+
m_end = $~.end(0)
|
|
230
233
|
result += h(str[last_end...m_start])
|
|
231
234
|
target, display = raw.include?("|") ? raw.split("|", 2) : [raw, nil]
|
|
232
235
|
label = display || target
|
|
@@ -234,14 +237,16 @@ module MarkdownServer
|
|
|
234
237
|
anchor = target[1..].downcase.gsub(/\s+/, "-").gsub(/[^\w-]/, "")
|
|
235
238
|
result += %(<a class="wiki-link" href="##{h(anchor)}">#{h(label)}</a>)
|
|
236
239
|
else
|
|
237
|
-
|
|
240
|
+
file_part, anchor_part = target.split("#", 2)
|
|
241
|
+
anchor_suffix = anchor_part ? "##{anchor_part.downcase.gsub(/\s+/, '-').gsub(/[^\w-]/, '')}" : ""
|
|
242
|
+
resolved = resolve_wiki_link(file_part)
|
|
238
243
|
if resolved
|
|
239
|
-
result += %(<a class="wiki-link" href="/browse/#{encode_path_component(resolved).gsub('%2F', '/')}">#{h(label)}</a>)
|
|
244
|
+
result += %(<a class="wiki-link" href="/browse/#{encode_path_component(resolved).gsub('%2F', '/')}#{anchor_suffix}">#{h(label)}</a>)
|
|
240
245
|
else
|
|
241
246
|
result += %(<span class="wiki-link broken">#{h(label)}</span>)
|
|
242
247
|
end
|
|
243
248
|
end
|
|
244
|
-
last_end =
|
|
249
|
+
last_end = m_end
|
|
245
250
|
end
|
|
246
251
|
result += h(str[last_end..])
|
|
247
252
|
result
|
|
@@ -252,7 +257,7 @@ module MarkdownServer
|
|
|
252
257
|
when Array
|
|
253
258
|
value.map { |v|
|
|
254
259
|
str = v.to_s
|
|
255
|
-
if str
|
|
260
|
+
if str.include?("[[")
|
|
256
261
|
render_inline_wiki_links(str)
|
|
257
262
|
else
|
|
258
263
|
%(<span class="tag">#{h(str)}</span>)
|
data/views/layout.erb
CHANGED
|
@@ -1704,6 +1704,26 @@
|
|
|
1704
1704
|
historyStack = [];
|
|
1705
1705
|
}
|
|
1706
1706
|
|
|
1707
|
+
function applyPopupAnchor(hash) {
|
|
1708
|
+
if (!hash || !popup) return;
|
|
1709
|
+
var id = hash.replace(/^#/, '');
|
|
1710
|
+
try {
|
|
1711
|
+
var target = popup.querySelector('[id="' + id.replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"]');
|
|
1712
|
+
if (!target) return;
|
|
1713
|
+
// Scroll the popup container (which has overflow-y:auto) to the target,
|
|
1714
|
+
// accounting for the sticky header so the heading lands just below it
|
|
1715
|
+
var header = popup.querySelector('.link-ctx-popup-header');
|
|
1716
|
+
var headerHeight = header ? header.offsetHeight : 0;
|
|
1717
|
+
var targetTop = target.getBoundingClientRect().top;
|
|
1718
|
+
var popupTop = popup.getBoundingClientRect().top;
|
|
1719
|
+
popup.scrollTop += targetTop - popupTop - headerHeight - 8;
|
|
1720
|
+
// Append section heading text to the popup title
|
|
1721
|
+
if (/^H[1-6]$/.test(target.tagName)) {
|
|
1722
|
+
var titleEl = popup.querySelector('.link-ctx-popup-title span');
|
|
1723
|
+
if (titleEl) titleEl.textContent = titleEl.textContent + ' \u203a ' + target.textContent;
|
|
1724
|
+
}
|
|
1725
|
+
} catch(e) {}
|
|
1726
|
+
}
|
|
1707
1727
|
|
|
1708
1728
|
function handleLink(anchor, x, y, chained) {
|
|
1709
1729
|
if (!chained) historyStack = [];
|
|
@@ -1712,12 +1732,14 @@
|
|
|
1712
1732
|
var label = anchor.textContent.trim() || href;
|
|
1713
1733
|
// For chained popup navigation keep the current link rect; for new popups measure the anchor
|
|
1714
1734
|
var linkRect = chained ? currentPopupPos.linkRect : anchor.getBoundingClientRect();
|
|
1735
|
+
var linkHash = (function() { try { return new URL(href, location.href).hash; } catch(e) { return ''; } })();
|
|
1715
1736
|
|
|
1716
1737
|
if (isLocalMd(href)) {
|
|
1717
1738
|
var path = previewPath(href);
|
|
1718
1739
|
var cached = cache[path];
|
|
1719
1740
|
if (cached && typeof cached === 'object') {
|
|
1720
1741
|
showPopup(x, y, cached.title || label, cached.html, href, linkRect);
|
|
1742
|
+
applyPopupAnchor(linkHash);
|
|
1721
1743
|
} else if (cached === false) {
|
|
1722
1744
|
showPopup(x, y, label,
|
|
1723
1745
|
'<div class="link-ctx-popup-url">' + escHtml(href) + '</div>' +
|
|
@@ -1733,6 +1755,7 @@
|
|
|
1733
1755
|
var bodyHtml = data.html + (data.frontmatter_html || '');
|
|
1734
1756
|
cache[path] = { title: data.title, html: bodyHtml };
|
|
1735
1757
|
updatePopup(bodyHtml, data.title || label);
|
|
1758
|
+
applyPopupAnchor(linkHash);
|
|
1736
1759
|
})
|
|
1737
1760
|
.catch(function() {
|
|
1738
1761
|
cache[path] = false;
|
|
@@ -1786,7 +1809,7 @@
|
|
|
1786
1809
|
if (!anchor) { hidePopup(); return; }
|
|
1787
1810
|
var href = anchor.getAttribute('href');
|
|
1788
1811
|
if (!href || isAnchorOnly(href)) { hidePopup(); return; }
|
|
1789
|
-
if (!anchor.closest('.md-content')) { hidePopup(); return; }
|
|
1812
|
+
if (!anchor.closest('.md-content') && !anchor.closest('.frontmatter')) { hidePopup(); return; }
|
|
1790
1813
|
e.preventDefault();
|
|
1791
1814
|
handleLink(anchor, e.clientX, e.clientY);
|
|
1792
1815
|
});
|
|
@@ -1808,7 +1831,7 @@
|
|
|
1808
1831
|
if (!anchor) { hidePopup(); return; }
|
|
1809
1832
|
var href = anchor.getAttribute('href');
|
|
1810
1833
|
if (!href || isAnchorOnly(href)) { hidePopup(); return; }
|
|
1811
|
-
if (!anchor.closest('.md-content')) { hidePopup(); return; }
|
|
1834
|
+
if (!anchor.closest('.md-content') && !anchor.closest('.frontmatter')) { hidePopup(); return; }
|
|
1812
1835
|
e.preventDefault();
|
|
1813
1836
|
var touch = e.changedTouches[0];
|
|
1814
1837
|
handleLink(anchor, touch.clientX, touch.clientY);
|
|
@@ -1821,24 +1844,26 @@
|
|
|
1821
1844
|
<% if settings.link_tooltips %>
|
|
1822
1845
|
// Hover — same popup as click, triggered after a short delay when no popup is active
|
|
1823
1846
|
(function() {
|
|
1824
|
-
var content = document.querySelector('.md-content');
|
|
1825
|
-
if (!content) return;
|
|
1826
1847
|
var hoverTimer = null;
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
if (
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
if (
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1848
|
+
var containers = document.querySelectorAll('.md-content, .frontmatter');
|
|
1849
|
+
if (!containers.length) return;
|
|
1850
|
+
containers.forEach(function(container) {
|
|
1851
|
+
container.querySelectorAll('a').forEach(function(a) {
|
|
1852
|
+
var href = a.getAttribute('href');
|
|
1853
|
+
if (!href || isAnchorOnly(href)) return;
|
|
1854
|
+
if (!isLocalMd(href) && !isExternal(href)) return;
|
|
1855
|
+
a.addEventListener('mouseenter', function(e) {
|
|
1856
|
+
clearTimeout(hoverTimer);
|
|
1857
|
+
if (popup) return;
|
|
1858
|
+
var x = e.clientX, y = e.clientY;
|
|
1859
|
+
hoverTimer = setTimeout(function() {
|
|
1860
|
+
if (!popup) handleLink(a, x, y, false);
|
|
1861
|
+
}, 300);
|
|
1862
|
+
});
|
|
1863
|
+
a.addEventListener('mouseleave', function() {
|
|
1864
|
+
clearTimeout(hoverTimer);
|
|
1865
|
+
if (popup) mouseLeaveTimer = setTimeout(hidePopup, 150);
|
|
1866
|
+
});
|
|
1842
1867
|
});
|
|
1843
1868
|
});
|
|
1844
1869
|
})();
|