Ctify_ v26.5.5
"Cite makes it possible to add footnotes to a page."
One feature that I frequently use in MediaWiki is inline citation (<ref>...</ref>). Surprisingly, there’s no native support in PmWiki, so I built it myself.
In local/config.php, add this.
Markup('ref', 'fulltext',
'/\\[\\[ref\\]\\](.*?)\\[\\[\\/ref\\]\\]/is',
function($m) {
static $refcount = 0;
$refcount++;
//$content = htmlspecialchars($m[1], ENT_QUOTES);
$content = $m[1];
return "<sup class=\"pm-ref\" data-ref=\"$content\">[$refcount]</sup>";
}
);In pub/custom.js, add this.
function sanitize(html) {
const temp = document.createElement("div");
temp.innerHTML = html;
temp.querySelectorAll("*").forEach(el => {
if (!["A","B","I","EM","STRONG","BR"].includes(el.tagName)) {
el.replaceWith(...el.childNodes);
}
if (el.tagName === "A") {
el.setAttribute("target", "_blank");
el.setAttribute("rel", "nofollow noopener");
}
});
return temp.innerHTML;
}
document.addEventListener("DOMContentLoaded", function() {
let tooltip = null;
let pinned = false;
let activeRef = null;
function createTooltip(ref) {
removeTooltip();
tooltip = document.createElement("div");
tooltip.className = "pm-ref-tooltip";
tooltip.innerHTML = sanitize(ref.getAttribute("data-ref"));
document.body.appendChild(tooltip);
const rect = ref.getBoundingClientRect();
tooltip.style.left = rect.left + rect.width / 2 + "px";
tooltip.style.top = rect.top - 8 + "px";
tooltip.style.transform = "translate(-50%, -100%)";
}
function removeTooltip() {
if (tooltip) {
tooltip.remove();
tooltip = null;
}
pinned = false;
activeRef = null;
}
document.querySelectorAll(".pm-ref").forEach(ref => {
ref.addEventListener("mouseenter", function() {
if (!pinned) {
createTooltip(ref);
}
});
ref.addEventListener("mouseleave", function() {
if (!pinned) {
removeTooltip();
}
});
ref.addEventListener("click", function(e) {
e.stopPropagation();
if (pinned && activeRef === ref) {
// clicking the same ref closes it
removeTooltip();
} else {
createTooltip(ref);
pinned = true;
activeRef = ref;
}
});
});
// click anywhere else → close
document.addEventListener("click", function() {
if (pinned) {
removeTooltip();
}
});
});In pub/custom.css, add this.
.pm-ref {
cursor: pointer;
position: relative;
}
#pm-ref-popup {
position: fixed;
left: 10px;
right: 10px;
bottom: 10px;
background: #222;
color: #fff;
padding: 12px 16px;
border-radius: 10px;
font-size: 0.9em;
z-index: 2000;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.pm-ref-tooltip {
position: fixed;
background: #222;
color: #fff;
padding: 6px 10px;
border-radius: 6px;
max-width: 300px;
font-size: 0.85em;
z-index: 9999;
pointer-events: auto;
}
.pm-ref-tooltip a {
color:white;
text-decoration: underline;
}To use it, you can write [[ref]]...[[/ref]].
Sure, it’s more verbose than the MediaWiki version, but apparently this is how PmWiki custom markup works.
I tried to emulate <ref></ref>, but somehow it isn’t compatible with how PmWiki preprocesses wikitext internally, so I gave up and used the standard double-bracket syntax instead. Sorry about that.
Regarding the behavior: on desktop, you can both hover over and click the footnote. On mobile, you can tap the footnote, and it will show a floating box with the content. Tap anywhere else to close the box.
You can also add normal wikitext link syntax inside the footnote.
This feature is already shipped in ctify_ v26.5.5.
After some testing, I realized that this kind of footnote may actually break the vertical spacing of unordered lists.
So I modified .pm-ref in custom.css and added an explicit line-height property to the li element.
li {
line-height: 1.6;
}
.pm-ref {
font-size: 0.75em;
position: relative;
top: -0.3em; /* tweak this value */
line-height: 1;
}It's still far from perfect. Sometimes, the footnote marker looks slightly clipped, but I think it's better than having the whole list spaced weirdly. Sorry about that.




