Compare commits

...

5 Commits

Author SHA1 Message Date
de90183cd4 all meta 2023-05-11 11:38:20 +02:00
d4486046aa better parser 2023-05-11 11:38:12 +02:00
f4db82a1d2 more 2023-05-11 11:32:52 +02:00
c38a60c339 more 2023-05-11 11:28:40 +02:00
a25d3df0f2 wiki 2023-05-11 11:07:49 +02:00
10 changed files with 98 additions and 252 deletions

View File

@ -0,0 +1,5 @@
#+TITLE: Emulation Software
#+FILETAGS: :emulation:
** Pages in this category
- [[../wiiu.org][Nintendo Wii U]]
- [[../cemu.org][CEMU]]

7
gamewiki/meta/games.org Normal file
View File

@ -0,0 +1,7 @@
#+TITLE: Games
#+FILETAGS: :games:
** Pages in this category
- [[../newsupermariobrosu.org][New Super Mario Bros U]]
- [[../mariokart8.org][Mario Kart 8]]
- [[../newsuperluigiu.org][New Super Luigi U]]
- [[../borderlands2.org][Borderlands 2]]

3
gamewiki/meta/guides.org Normal file
View File

@ -0,0 +1,3 @@
#+TITLE: Guides
#+FILETAGS: :guides:
** Pages in this category

6
gamewiki/meta/mario.org Normal file
View File

@ -0,0 +1,6 @@
#+TITLE: The Super Mario saga
#+FILETAGS: :mario:
** Pages in this category
- [[../newsupermariobrosu.org][New Super Mario Bros U]]
- [[../mariokart8.org][Mario Kart 8]]
- [[../newsuperluigiu.org][New Super Luigi U]]

View File

@ -1,224 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2023-05-10 Wed 13:56 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Nintendo</title>
<meta name="author" content="user" />
<meta name="generator" content="Org Mode" />
<style>
#content { max-width: 60em; margin: auto; }
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #e6e6e6;
border-radius: 3px;
background-color: #f2f2f2;
padding: 8pt;
font-family: monospace;
overflow: auto;
margin: 1.2em;
}
pre.src {
position: relative;
overflow: auto;
}
pre.src:before {
display: none;
position: absolute;
top: -8px;
right: 12px;
padding: 3px;
color: #555;
background-color: #f2f2f299;
}
pre.src:hover:before { display: inline; margin-top: 14px;}
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
pre.src-authinfo::before { content: 'Authinfo'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
pre.src-css:before { content: 'CSS'; }
pre.src-D:before { content: 'D'; }
pre.src-ditaa:before { content: 'ditaa'; }
pre.src-dot:before { content: 'Graphviz'; }
pre.src-calc:before { content: 'Emacs Calc'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-fortran:before { content: 'Fortran'; }
pre.src-gnuplot:before { content: 'gnuplot'; }
pre.src-haskell:before { content: 'Haskell'; }
pre.src-hledger:before { content: 'hledger'; }
pre.src-java:before { content: 'Java'; }
pre.src-js:before { content: 'Javascript'; }
pre.src-latex:before { content: 'LaTeX'; }
pre.src-ledger:before { content: 'Ledger'; }
pre.src-lisp:before { content: 'Lisp'; }
pre.src-lilypond:before { content: 'Lilypond'; }
pre.src-lua:before { content: 'Lua'; }
pre.src-matlab:before { content: 'MATLAB'; }
pre.src-mscgen:before { content: 'Mscgen'; }
pre.src-ocaml:before { content: 'Objective Caml'; }
pre.src-octave:before { content: 'Octave'; }
pre.src-org:before { content: 'Org mode'; }
pre.src-oz:before { content: 'OZ'; }
pre.src-plantuml:before { content: 'Plantuml'; }
pre.src-processing:before { content: 'Processing.js'; }
pre.src-python:before { content: 'Python'; }
pre.src-R:before { content: 'R'; }
pre.src-ruby:before { content: 'Ruby'; }
pre.src-sass:before { content: 'Sass'; }
pre.src-scheme:before { content: 'Scheme'; }
pre.src-screen:before { content: 'Gnu Screen'; }
pre.src-sed:before { content: 'Sed'; }
pre.src-sh:before { content: 'shell'; }
pre.src-sql:before { content: 'SQL'; }
pre.src-sqlite:before { content: 'SQLite'; }
/* additional languages in org.el's org-babel-load-languages alist */
pre.src-forth:before { content: 'Forth'; }
pre.src-io:before { content: 'IO'; }
pre.src-J:before { content: 'J'; }
pre.src-makefile:before { content: 'Makefile'; }
pre.src-maxima:before { content: 'Maxima'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-picolisp:before { content: 'Pico Lisp'; }
pre.src-scala:before { content: 'Scala'; }
pre.src-shell:before { content: 'Shell Script'; }
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
/* additional language identifiers per "defun org-babel-execute"
in ob-*.el */
pre.src-cpp:before { content: 'C++'; }
pre.src-abc:before { content: 'ABC'; }
pre.src-coq:before { content: 'Coq'; }
pre.src-groovy:before { content: 'Groovy'; }
/* additional language identifiers from org-babel-shell-names in
ob-shell.el: ob-shell is the only babel language using a lambda to put
the execution function name together. */
pre.src-bash:before { content: 'bash'; }
pre.src-csh:before { content: 'csh'; }
pre.src-ash:before { content: 'ash'; }
pre.src-dash:before { content: 'dash'; }
pre.src-ksh:before { content: 'ksh'; }
pre.src-mksh:before { content: 'mksh'; }
pre.src-posh:before { content: 'posh'; }
/* Additional Emacs modes also supported by the LaTeX listings package */
pre.src-ada:before { content: 'Ada'; }
pre.src-asm:before { content: 'Assembler'; }
pre.src-caml:before { content: 'Caml'; }
pre.src-delphi:before { content: 'Delphi'; }
pre.src-html:before { content: 'HTML'; }
pre.src-idl:before { content: 'IDL'; }
pre.src-mercury:before { content: 'Mercury'; }
pre.src-metapost:before { content: 'MetaPost'; }
pre.src-modula-2:before { content: 'Modula-2'; }
pre.src-pascal:before { content: 'Pascal'; }
pre.src-ps:before { content: 'PostScript'; }
pre.src-prolog:before { content: 'Prolog'; }
pre.src-simula:before { content: 'Simula'; }
pre.src-tcl:before { content: 'tcl'; }
pre.src-tex:before { content: 'TeX'; }
pre.src-plain-tex:before { content: 'Plain TeX'; }
pre.src-verilog:before { content: 'Verilog'; }
pre.src-vhdl:before { content: 'VHDL'; }
pre.src-xml:before { content: 'XML'; }
pre.src-nxml:before { content: 'XML'; }
/* add a generic configuration mode; LaTeX export needs an additional
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
pre.src-conf:before { content: 'Configuration File'; }
table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.equation-container {
display: table;
text-align: center;
width: 100%;
}
.equation {
vertical-align: middle;
}
.equation-label {
display: table-cell;
text-align: right;
vertical-align: middle;
}
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { }
</style>
</head>
<body>
<div id="content" class="content">
<h1 class="title">Nintendo</h1>
<div id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org1b89164">1. Pages in this category</a></li>
</ul>
</div>
</div>
<div id="outline-container-org1b89164" class="outline-2">
<h2 id="org1b89164"><span class="section-number-2">1.</span> Pages in this category</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li><a href="../wiiu.html">Nintendo Wii U</a></li>
<li><a href="../nus.html">NUS Downloader</a></li>
</ul>
</div>
</div>
</div>
<div id="postamble" class="status">
<p class="author">Author: user</p>
<p class="date">Created: 2023-05-10 Wed 13:56</p>
<p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
</body>
</html>

4
gamewiki/meta/piracy.org Normal file
View File

@ -0,0 +1,4 @@
#+TITLE: Software Piracy
#+FILETAGS: :piracy:
** Pages in this category
- [[../nus.org][NUS Downloader]]

View File

@ -35,3 +35,5 @@ tutorials, tips and tricks for beating levels, as well as creative ways to
complete them. These videos are not just for beginners, as they also feature complete them. These videos are not just for beginners, as they also feature
some impressive gameplay, such as coordinated and stylish 4-player level some impressive gameplay, such as coordinated and stylish 4-player level
completions, which are among my personal favorites. completions, which are among my personal favorites.
** Related articles
- [[../newsupermariobrosu.org][New Super Mario Bros U]]

View File

@ -18,3 +18,5 @@ Controller; the left and right triggers can be used for the motion segment in
this and other levels. this and other levels.
* New Super Luigi U * New Super Luigi U
Before playing the game, also read about [[./newsuperluigiu.org][New Super Luigi U]] Before playing the game, also read about [[./newsuperluigiu.org][New Super Luigi U]]
** Related articles
- [[../newsuperluigiu.org][New Super Luigi U]]

View File

@ -1,6 +1,12 @@
import glob import glob
import re
from typing import TypeVar, Iterator
T = TypeVar("T")
class WikiArticle: class WikiArticle:
'''Abstract class that defines an article in the wiki'''
def __init__(self, filename): def __init__(self, filename):
def tags(content): def tags(content):
for line in content: for line in content:
@ -20,16 +26,35 @@ class WikiArticle:
with open(filename, 'r') as f: with open(filename, 'r') as f:
content = f.readlines() content = f.readlines()
self.content = [c.strip() for c in content] self.content = [c for c in content]
self.title = title(content) self.title = title(content)
self.tags = tags(content) self.tags = tags(content)
self.filename = filename self.filename = filename
def enrich(self, linked_articles: Iterator):
'''Generator that returns content that will end up in the document before html conversion'''
content = map(identity, self.content)
def rep():
for line in content:
if line.strip() == self.header: break
else: yield line
yield self.header + '\n'
for w in linked_articles:
yield f'- [[../{w.filename}][{w.title}]]\n'
return rep()
def __repr__(self): def __repr__(self):
return f'{type(self).__name__}({self.title}, {self.filename}, {self.tags})' return f'{type(self).__name__}({self.title}, {self.filename}, {self.tags})'
class ContentArticle(WikiArticle): pass class ContentArticle(WikiArticle):
'''The articles we wrote'''
def __init__(self, filename):
self.header = '** Related articles'
super().__init__(filename)
class MetaPage(WikiArticle): class MetaPage(WikiArticle):
'''Wiki article containing code that must be generated by this program'''
def __init__(self, filename): def __init__(self, filename):
self.header = '** Pages in this category' self.header = '** Pages in this category'
super().__init__(filename) super().__init__(filename)
@ -37,22 +62,10 @@ class MetaPage(WikiArticle):
raise Exception(f'Multiple tags in metapage: {self.filename}') raise Exception(f'Multiple tags in metapage: {self.filename}')
self.meta = self.tags[0] self.meta = self.tags[0]
correct_section = list(filter(lambda l: l == self.header, self.content)) correct_section = list(filter(lambda l: l.strip() == self.header, self.content))
if len(correct_section) != 1: if len(correct_section) != 1:
raise Exception(f'Invalid meta section in {filename}') raise Exception(f'Invalid meta section in {filename}')
def replace_content(self, wikiarticles):
content = map(identity, self.content)
def rep():
for line in content:
if line == self.header: break
else: yield line
yield self.header
for w in wikiarticles:
yield f'- [[../{w.filename}][{w.title}]]'
return rep()
identity = lambda x: x identity = lambda x: x
def merge(d1, d2): def merge(d1, d2):
d1.update(d2) d1.update(d2)
@ -64,26 +77,51 @@ def files():
def metafiles(): def metafiles():
return glob.glob('meta/*.org') return glob.glob('meta/*.org')
def invert_map(map_: list[ContentArticle]):
def invert_map(map_: list[WikiArticle]):
'''from {a: [1, 2], b: [2, 3]} to {1: [a], 2: [a, b], 3: [b]}''' '''from {a: [1, 2], b: [2, 3]} to {1: [a], 2: [a, b], 3: [b]}'''
keys = set(i for e in map_ for i in e.tags) keys = set(i for e in map_ for i in e.tags)
res = dict() res: dict[str, list[WikiArticle]] = dict()
for k in keys: for k in keys:
res[k] = res.get(k, []) + [w for w in map_ if k in w.tags] res[k] = res.get(k, []) + [w for w in map_ if k in w.tags]
return res return res
def write_meta_page(m: MetaPage, content: list[str]): def links(article: ContentArticle):
def haslink(line):
return re.findall(r'\[\[(.+?)\]\]', line)
def yield_links(line):
i = 0
while i < len(line)-1:
sub = line[i:]
if sub.startswith('[[./') and ']]' in sub and '.org' in sub: # org link to one org file
ridx = sub.index('.org')
yield sub[4:ridx+4] # skip initial [[
i += sub.index(']]')
i += 1
for line in article.content:
if haslink(line):
yield from yield_links(line)
def writetodisk(m: WikiArticle, content: list[str]):
with open(m.filename, 'w') as f: with open(m.filename, 'w') as f:
f.writelines(map(lambda l: l+'\n', content)) f.writelines(content)
if __name__ == '__main__': if __name__ == '__main__':
files = [ContentArticle(f) for f in files()] files_ = [ContentArticle(f) for f in files()]
meta = [MetaPage(f) for f in metafiles()] byfilename = {c.filename: c for c in files_}
meta = {m.meta: m for m in meta} meta_ = [MetaPage(f) for f in metafiles()]
print(meta) meta = {m.meta: m for m in meta_}
tags = invert_map(files)
tags = invert_map(files_)
for t, articles in tags.items(): for t, articles in tags.items():
if t in meta: if t in meta:
newcontent = meta[t].replace_content(articles) newcontent = meta[t].enrich(articles)
write_meta_page(meta[t], newcontent) writetodisk(meta[t], newcontent)
for f in files_:
related = set(links(f))
if related:
newcontent = f.enrich(map(lambda f: byfilename[f], related))
writetodisk(f, newcontent)

View File

@ -60,3 +60,6 @@ providing a much smoother experience.
Vulkan also allows us to use a new experimental VSync technique which allows Vulkan also allows us to use a new experimental VSync technique which allows
Cemu to use the game's built-in frame-pacing instead. This avoids tearing and Cemu to use the game's built-in frame-pacing instead. This avoids tearing and
reduces input latency compared to previous methods. reduces input latency compared to previous methods.
** Related articles
- [[../cemu.org][CEMU]]
- [[../nus.org][NUS Downloader]]