Wiki Download: Difference between revisions
Appearance
| Line 95: | Line 95: | ||
wiki2md.lua | wiki2md.lua | ||
-- pandoc renders mediawiki " "-indented blocks as inline code + line breaks; turn them into code blocks | -- pandoc renders mediawiki " "-indented blocks as inline code + line breaks; turn them into code blocks | ||
-- untagged code blocks (e.g. from < pre >) get "plain", so gfm writes them fenced | -- untagged code blocks (e.g. from < pre >) get "plain", so gfm writes them fenced | ||
Latest revision as of 20:22, 25 October 2026
Download all Wiki Articles
In order to migrate to Markdown format, and most probable LeafWiki, I need to export all my Wiki pages.
Export/Download
wiki-download.py
import pathlib import requests API = "https://entorb.net/wiki/api.php" OUT = pathlib.Path("export") s = requests.Session() def all_titles(ns=0): params = { "action": "query", "list": "allpages", "aplimit": "max", "apnamespace": ns, "apfilterredir": "nonredirects", "format": "json", } while True: r = s.get(API, params=params).json() for p in r["query"]["allpages"]: yield p["title"] if "continue" not in r: break params.update(r["continue"]) def wikitext(title): r = s.get( API, params={ "action": "query", "prop": "revisions", "rvprop": "content", "rvslots": "main", "titles": title, "format": "json", "formatversion": 2, }, ).json() return r["query"]["pages"][0]["revisions"][0]["slots"]["main"]["content"] def to_path(title): if title == "Python": return OUT / "Python/index" if title == "C++": return OUT / "Cpp" if title == "Notepad++": return OUT / "Notepad-plus-plus" name = title.replace("/", "-") # a literal "/" never becomes a folder name = name.replace(" - ", "/") # "Python - Math" -> Python/Math name = name.replace(" ", "-") return OUT / (name + ".wiki") for title in all_titles(ns=0): path = to_path(title) path.parent.mkdir(parents=True, exist_ok=True) path.write_text(wikitext(title), encoding="utf-8") print(title, "->", path)
Convert to Markdown
requires pandoc
wiki2md.sh
#!/bin/bash
set -e
# no args: fan out one process per file; with arg: convert that file
if [ $# -eq 0 ]; then
find export -name '*.wiki' -print0 | xargs -0 -n1 -P 4 "$0"
exit
fi
f=$1
echo "$f"
out="md/${f#export/}"
out="${out%.wiki}.md"
mkdir -p "$(dirname "$out")"
title="${f#export/}"
title="${title%.wiki}"
{
title="${title//_/ }"
echo "# ${title//\// - }"
echo
tags=$(grep -o '\[\[Category:[^]|]*' "$f" | sed 's/.*Category://; s/ /_/g; s/^/#/' | tr '\n' ' ' || true)
[ -n "$tags" ] && printf 'Tags: %s\n\n' "${tags% }"
pandoc -f mediawiki -t gfm --wrap=none --lua-filter=wiki2md.lua "$f" |
# opening fence: "``` lang" -> "```lang", bare "```" -> "```plain" (pandoc drops "plain")
awk '/^```/ { if (!f) { sub(/ /, ""); if ($0 ~ /^`+$/) $0 = $0 "plain" } f = !f } 1'
} >"$out"
wiki2md.lua
-- pandoc renders mediawiki " "-indented blocks as inline code + line breaks; turn them into code blocks
-- untagged code blocks (e.g. from < pre >) get "plain", so gfm writes them fenced
function CodeBlock(el)
if #el.classes == 0 then
el.classes = { "plain" }
return el
end
end
-- categories are emitted as #tags by wiki2md.sh
function Link(el)
if el.target:match("^Category:") then
return {}
end
end
-- text of a Code, or of an autolinked URL inside code (Link of Code only); nil otherwise
local function code_text(x)
if x.t == "Code" then
return x.text
end
if x.t == "Link" then
local s = ""
for _, y in ipairs(x.content) do
if y.t ~= "Code" then
return nil
end
s = s .. y.text
end
return s
end
end
function Para(el)
if #el.content == 0 then
return {}
end
local lines, cur, has_code = {}, "", false
for _, x in ipairs(el.content) do
local text = code_text(x)
if text then
cur = cur .. text:gsub("\u{A0}", " ")
has_code = true
elseif x.t == "Space" then
cur = cur .. " "
elseif x.t == "Str" and x.text:match("^%s*$") then
cur = cur .. x.text
elseif x.t == "LineBreak" then
table.insert(lines, cur)
cur = ""
else
return nil
end
end
if not has_code then
return nil
end
table.insert(lines, cur)
while #lines > 0 and lines[#lines]:match("^%s*$") do
table.remove(lines)
end
return pandoc.CodeBlock(table.concat(lines, "\n"), pandoc.Attr("", { "plain" }))
end