mirror of
https://github.com/Oreolek/gamebookformat.git
synced 2024-05-15 07:28:18 +03:00
Include templates from a template.
Should make it much easier to override specific parts of default templates.
This commit is contained in:
parent
18c76ce0b0
commit
116ca6fad1
22
templates.py
22
templates.py
|
@ -1,7 +1,11 @@
|
|||
import re
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
PREPROCESS_RE = re.compile("^\s*#")
|
||||
INCLUDE_RE = re.compile('^\s*#include\s*"(\w+)"')
|
||||
|
||||
class Templates (object):
|
||||
def __init__(self, templatedirs, extension):
|
||||
self.extension = extension
|
||||
|
@ -23,11 +27,27 @@ class Templates (object):
|
|||
def get_in(self, templatedir, name):
|
||||
filename = self.get_template_filename(templatedir, name)
|
||||
f = open(filename, "r")
|
||||
template = f.read()
|
||||
template = self.read_template(f);
|
||||
f.close()
|
||||
self.cached_templates[name] = template
|
||||
return template
|
||||
|
||||
def read_template(self, f):
|
||||
res = ""
|
||||
for line in f.readlines():
|
||||
if PREPROCESS_RE.match(line):
|
||||
res += self.preprocessline(line)
|
||||
else:
|
||||
res += line
|
||||
return res
|
||||
|
||||
def preprocessline(self, line):
|
||||
m = INCLUDE_RE.match(line)
|
||||
if m:
|
||||
return self.get(m.group(1))
|
||||
else:
|
||||
raise Exception("Bad preprocessor line '%s' in template." % line)
|
||||
|
||||
def get_template_filename(self, templatedir, name):
|
||||
return os.path.join(templatedir,
|
||||
self.extension,
|
||||
|
|
|
@ -2,202 +2,15 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>Gamebook Title Here</title>
|
||||
#include "viewport"
|
||||
#include "title"
|
||||
<script>
|
||||
var gamebook = {
|
||||
'player' : {
|
||||
'currentSection' : null,
|
||||
'collections' : {},
|
||||
|
||||
'collect' : function(type, name) {
|
||||
this.collections[type] = {
|
||||
'name' : name,
|
||||
'contents' : [],
|
||||
'add' : function(what) {
|
||||
if (this.contents.indexOf(what) === -1
|
||||
&& !(what in gamebook.dropped[type])) {
|
||||
this.contents.push(what);
|
||||
this.contents.sort();
|
||||
}
|
||||
},
|
||||
'drop' : function(what) {
|
||||
var i = this.contents.indexOf(what);
|
||||
if (i >= 0) {
|
||||
this.contents.splice(i, 1);
|
||||
gamebook.dropped[type][what] = true;
|
||||
}
|
||||
},
|
||||
'has' : function(what) {
|
||||
return this.contents.indexOf(what) >= 0;
|
||||
}
|
||||
};
|
||||
gamebook.dropped[type] = {};
|
||||
gamebook.addCollectionView(type, name);
|
||||
},
|
||||
|
||||
'add' : function(type, what) {
|
||||
this.collections[type].add(what);
|
||||
gamebook.updateCollectionsView();
|
||||
},
|
||||
|
||||
'drop' : function(type, what) {
|
||||
this.collections[type].drop(what);
|
||||
gamebook.updateCollectionsView();
|
||||
},
|
||||
|
||||
'has' : function(type, what) {
|
||||
return this.collections[type].has(what);
|
||||
}
|
||||
},
|
||||
|
||||
'sections' : {},
|
||||
|
||||
'turnToFunctions' : {},
|
||||
|
||||
'dropped' : {},
|
||||
|
||||
'addSection' : function(nr, element) {
|
||||
var section = {'element' : element, 'nr' : nr};
|
||||
this.sections[nr] = section;
|
||||
},
|
||||
|
||||
'turnTo' : function(nr) {
|
||||
console.log("Turning to " + nr + ".");
|
||||
if (!nr in this.sections) {
|
||||
throw new Exception("Can not turn to non-existing section "
|
||||
+ nr + ".");
|
||||
}
|
||||
this.displaySection(nr);
|
||||
},
|
||||
|
||||
'displaySection' : function(nr) {
|
||||
if (this.player.currentSection) {
|
||||
this.player.currentSection.element.style.display = 'none';
|
||||
}
|
||||
var e = this.sections[nr].element;
|
||||
this.runActions(e.getElementsByClassName('sectiontext')[0]);
|
||||
e.style.display = 'block';
|
||||
this.player.currentSection = gamebook.sections[nr];
|
||||
},
|
||||
|
||||
'runActions' : function(e) {
|
||||
var enableNextLink = true;
|
||||
var hasXorScope = false;
|
||||
var hasAutoScope = false;
|
||||
var xorEnableNext = false;
|
||||
var autoDisableAllRemainingLinks = false;
|
||||
Array.prototype.forEach.call(e.childNodes, function(c) {
|
||||
if (/sectionref$/.test(c.className)) {
|
||||
if (enableNextLink && !autoDisableAllRemainingLinks) {
|
||||
gamebook.enableLink(c);
|
||||
if (hasAutoScope) {
|
||||
autoDisableAllRemainingLinks = true;
|
||||
}
|
||||
} else {
|
||||
gamebook.disableLink(c);
|
||||
}
|
||||
enableNextLink = !(hasXorScope && !xorEnableNext);
|
||||
hasAutoScope = false;
|
||||
hasXorScope = false;
|
||||
} else if (c.className === 'collect') {
|
||||
gamebook.player.collect(c.dataset.type, c.dataset.name);
|
||||
} else if (c.className === 'add') {
|
||||
gamebook.player.add(c.dataset.type, c.dataset.what);
|
||||
} else if (c.className === 'drop') {
|
||||
gamebook.player.drop(c.dataset.type, c.dataset.what);
|
||||
} else if (c.className === 'has') {
|
||||
enableNextLink = gamebook.player.has(c.dataset.type,
|
||||
c.dataset.what);
|
||||
console.log("has " + c.dataset.type +
|
||||
" " + c.dataset.what + " " + enableNextLink);
|
||||
} else if (c.className === 'hasnot') {
|
||||
enableNextLink = !gamebook.player.has(c.dataset.type,
|
||||
c.dataset.what);
|
||||
console.log("has not " + c.dataset.type +
|
||||
" " + c.dataset.what + " " + enableNextLink);
|
||||
} else if (c.className === 'xor') {
|
||||
hasXorScope = true;
|
||||
xorEnableNext = !enableNextLink;
|
||||
} else if (c.className === 'auto') {
|
||||
hasAutoScope = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
'enableLink' : function(e) {
|
||||
e.addEventListener('click',
|
||||
gamebook.getTurnToFunction(e.dataset.ref));
|
||||
e.className = "enabledsectionref";
|
||||
},
|
||||
|
||||
'disableLink' : function(e) {
|
||||
e.removeEventListener('click',
|
||||
gamebook.getTurnToFunction(e.dataset.ref));
|
||||
e.className = "disabledsectionref";
|
||||
},
|
||||
|
||||
'addCollectionView' : function(type, name) {
|
||||
var ce = document.getElementById('collections');
|
||||
var template = document.getElementById('collectionTemplate');
|
||||
var e = template.cloneNode(true);
|
||||
e.className = "collection";
|
||||
e.getElementsByClassName('collectionheading')[0].innerHTML = name;
|
||||
e.dataset.type = type;
|
||||
ce.appendChild(e);
|
||||
},
|
||||
|
||||
'updateCollectionsView' : function() {
|
||||
var ce = document.getElementById('collections');
|
||||
Array.prototype.forEach.call(ce.childNodes, function(c) {
|
||||
if (c.className === 'collection') {
|
||||
var type = c.dataset.type;
|
||||
var collection = gamebook.player.collections[type];
|
||||
var cc = c.getElementsByClassName('collectioncontents')[0];
|
||||
cc.innerHTML = collection.contents.join(', ');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
'getTurnToFunction' : function(nr) {
|
||||
if (nr in this.turnToFunctions) {
|
||||
return this.turnToFunctions[nr];
|
||||
} else {
|
||||
var f = function () {
|
||||
gamebook.turnTo(nr);
|
||||
};
|
||||
this.turnToFunctions[nr] = f;
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#include "script"
|
||||
</script>
|
||||
<style>
|
||||
.enabledsectionref {font-weight: bold; cursor: pointer;}
|
||||
.disabledsectionref {font-weight: bold; color: #aaa; cursor: not-allowed;}
|
||||
.sectionnumber {font-weight: bolder;
|
||||
margin-left: 50%%;
|
||||
margin-right: 50%%;}
|
||||
.section {display: none; width: 90%%; margin-left: 5%%; margin-right: 5%%;}
|
||||
.sectiontext {margin-top: 0.5em;}
|
||||
.gamebook {max-width: 30em; padding: 1em; width: 100%%; font-size: 133%%;}
|
||||
.collections {margin-top: 4em;}
|
||||
.collection {background: #ddd; margin-top: 1em;}
|
||||
.collectionheading {}
|
||||
.collectionheading::after {content: ": ";}
|
||||
.collectioncontents {}
|
||||
.collect {}
|
||||
.add {font-weight: bold;}
|
||||
.found {font-weight: bold; cursor: pointer;}
|
||||
.drop {font-style: italic;}
|
||||
.has {font-style: italic;}
|
||||
.hasnot {font-style: italic;}
|
||||
.collectionTemplate {display: none;}
|
||||
#include "style"
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- TODO definitely need to add content here, but mostly book specific? -->
|
||||
#include "intro"
|
||||
<div class="gamebook">
|
||||
|
|
2
templates/html/collections.html
Normal file
2
templates/html/collections.html
Normal file
|
@ -0,0 +1,2 @@
|
|||
<div id="collections" class="collections">
|
||||
</div>
|
5
templates/html/collectiontemplate.html
Normal file
5
templates/html/collectiontemplate.html
Normal file
|
@ -0,0 +1,5 @@
|
|||
<div id="collectionTemplate" class="collectionTemplate">
|
||||
<span class="collectionheading"></span>
|
||||
<span class="collectioncontents"></span>
|
||||
</div>
|
||||
</div>
|
|
@ -1,14 +1,7 @@
|
|||
<div id="collections" class="collections">
|
||||
</div>
|
||||
<div id="collectionTemplate" class="collectionTemplate">
|
||||
<span class="collectionheading"></span>
|
||||
<span class="collectioncontents"></span>
|
||||
</div>
|
||||
</div>
|
||||
#include "collections"
|
||||
#include "collectiontemplate"
|
||||
<script>
|
||||
if (this.gamebook) {
|
||||
gamebook.turnTo(1);
|
||||
}
|
||||
#include "endscript"
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
3
templates/html/endscript.html
Normal file
3
templates/html/endscript.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
if (this.gamebook) {
|
||||
gamebook.turnTo(1);
|
||||
}
|
168
templates/html/script.html
Normal file
168
templates/html/script.html
Normal file
|
@ -0,0 +1,168 @@
|
|||
var gamebook = {
|
||||
'player' : {
|
||||
'currentSection' : null,
|
||||
'collections' : {},
|
||||
|
||||
'collect' : function(type, name) {
|
||||
this.collections[type] = {
|
||||
'name' : name,
|
||||
'contents' : [],
|
||||
'add' : function(what) {
|
||||
if (this.contents.indexOf(what) === -1
|
||||
&& !(what in gamebook.dropped[type])) {
|
||||
this.contents.push(what);
|
||||
this.contents.sort();
|
||||
}
|
||||
},
|
||||
'drop' : function(what) {
|
||||
var i = this.contents.indexOf(what);
|
||||
if (i >= 0) {
|
||||
this.contents.splice(i, 1);
|
||||
gamebook.dropped[type][what] = true;
|
||||
}
|
||||
},
|
||||
'has' : function(what) {
|
||||
return this.contents.indexOf(what) >= 0;
|
||||
}
|
||||
};
|
||||
gamebook.dropped[type] = {};
|
||||
gamebook.addCollectionView(type, name);
|
||||
},
|
||||
|
||||
'add' : function(type, what) {
|
||||
this.collections[type].add(what);
|
||||
gamebook.updateCollectionsView();
|
||||
},
|
||||
|
||||
'drop' : function(type, what) {
|
||||
this.collections[type].drop(what);
|
||||
gamebook.updateCollectionsView();
|
||||
},
|
||||
|
||||
'has' : function(type, what) {
|
||||
return this.collections[type].has(what);
|
||||
}
|
||||
},
|
||||
|
||||
'sections' : {},
|
||||
|
||||
'turnToFunctions' : {},
|
||||
|
||||
'dropped' : {},
|
||||
|
||||
'addSection' : function(nr, element) {
|
||||
var section = {'element' : element, 'nr' : nr};
|
||||
this.sections[nr] = section;
|
||||
},
|
||||
|
||||
'turnTo' : function(nr) {
|
||||
console.log("Turning to " + nr + ".");
|
||||
if (!nr in this.sections) {
|
||||
throw new Exception("Can not turn to non-existing section "
|
||||
+ nr + ".");
|
||||
}
|
||||
this.displaySection(nr);
|
||||
},
|
||||
|
||||
'displaySection' : function(nr) {
|
||||
if (this.player.currentSection) {
|
||||
this.player.currentSection.element.style.display = 'none';
|
||||
}
|
||||
var e = this.sections[nr].element;
|
||||
this.runActions(e.getElementsByClassName('sectiontext')[0]);
|
||||
e.style.display = 'block';
|
||||
this.player.currentSection = gamebook.sections[nr];
|
||||
},
|
||||
|
||||
'runActions' : function(e) {
|
||||
var enableNextLink = true;
|
||||
var hasXorScope = false;
|
||||
var hasAutoScope = false;
|
||||
var xorEnableNext = false;
|
||||
var autoDisableAllRemainingLinks = false;
|
||||
Array.prototype.forEach.call(e.childNodes, function(c) {
|
||||
if (/sectionref$/.test(c.className)) {
|
||||
if (enableNextLink && !autoDisableAllRemainingLinks) {
|
||||
gamebook.enableLink(c);
|
||||
if (hasAutoScope) {
|
||||
autoDisableAllRemainingLinks = true;
|
||||
}
|
||||
} else {
|
||||
gamebook.disableLink(c);
|
||||
}
|
||||
enableNextLink = !(hasXorScope && !xorEnableNext);
|
||||
hasAutoScope = false;
|
||||
hasXorScope = false;
|
||||
} else if (c.className === 'collect') {
|
||||
gamebook.player.collect(c.dataset.type, c.dataset.name);
|
||||
} else if (c.className === 'add') {
|
||||
gamebook.player.add(c.dataset.type, c.dataset.what);
|
||||
} else if (c.className === 'drop') {
|
||||
gamebook.player.drop(c.dataset.type, c.dataset.what);
|
||||
} else if (c.className === 'has') {
|
||||
enableNextLink = gamebook.player.has(c.dataset.type,
|
||||
c.dataset.what);
|
||||
console.log("has " + c.dataset.type +
|
||||
" " + c.dataset.what + " " + enableNextLink);
|
||||
} else if (c.className === 'hasnot') {
|
||||
enableNextLink = !gamebook.player.has(c.dataset.type,
|
||||
c.dataset.what);
|
||||
console.log("has not " + c.dataset.type +
|
||||
" " + c.dataset.what + " " + enableNextLink);
|
||||
} else if (c.className === 'xor') {
|
||||
hasXorScope = true;
|
||||
xorEnableNext = !enableNextLink;
|
||||
} else if (c.className === 'auto') {
|
||||
hasAutoScope = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
'enableLink' : function(e) {
|
||||
e.addEventListener('click',
|
||||
gamebook.getTurnToFunction(e.dataset.ref));
|
||||
e.className = "enabledsectionref";
|
||||
},
|
||||
|
||||
'disableLink' : function(e) {
|
||||
e.removeEventListener('click',
|
||||
gamebook.getTurnToFunction(e.dataset.ref));
|
||||
e.className = "disabledsectionref";
|
||||
},
|
||||
|
||||
'addCollectionView' : function(type, name) {
|
||||
var ce = document.getElementById('collections');
|
||||
var template = document.getElementById('collectionTemplate');
|
||||
var e = template.cloneNode(true);
|
||||
e.className = "collection";
|
||||
e.getElementsByClassName('collectionheading')[0].innerHTML = name;
|
||||
e.dataset.type = type;
|
||||
ce.appendChild(e);
|
||||
},
|
||||
|
||||
'updateCollectionsView' : function() {
|
||||
var ce = document.getElementById('collections');
|
||||
Array.prototype.forEach.call(ce.childNodes, function(c) {
|
||||
if (c.className === 'collection') {
|
||||
var type = c.dataset.type;
|
||||
var collection = gamebook.player.collections[type];
|
||||
var cc = c.getElementsByClassName('collectioncontents')[0];
|
||||
cc.innerHTML = collection.contents.join(', ');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
'getTurnToFunction' : function(nr) {
|
||||
if (nr in this.turnToFunctions) {
|
||||
return this.turnToFunctions[nr];
|
||||
} else {
|
||||
var f = function () {
|
||||
gamebook.turnTo(nr);
|
||||
};
|
||||
this.turnToFunctions[nr] = f;
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
20
templates/html/style.html
Normal file
20
templates/html/style.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
.enabledsectionref {font-weight: bold; cursor: pointer;}
|
||||
.disabledsectionref {font-weight: bold; color: #aaa; cursor: not-allowed;}
|
||||
.sectionnumber {font-weight: bolder;
|
||||
margin-left: 50%%;
|
||||
margin-right: 50%%;}
|
||||
.section {display: none; width: 90%%; margin-left: 5%%; margin-right: 5%%;}
|
||||
.sectiontext {margin-top: 0.5em;}
|
||||
.gamebook {max-width: 30em; padding: 1em; width: 100%%; font-size: 133%%;}
|
||||
.collections {margin-top: 4em;}
|
||||
.collection {background: #ddd; margin-top: 1em;}
|
||||
.collectionheading {}
|
||||
.collectionheading::after {content: ": ";}
|
||||
.collectioncontents {}
|
||||
.collect {}
|
||||
.add {font-weight: bold;}
|
||||
.found {font-weight: bold; cursor: pointer;}
|
||||
.drop {font-style: italic;}
|
||||
.has {font-style: italic;}
|
||||
.hasnot {font-style: italic;}
|
||||
.collectionTemplate {display: none;}
|
1
templates/html/title.html
Normal file
1
templates/html/title.html
Normal file
|
@ -0,0 +1 @@
|
|||
<title>Gamebook</title>
|
2
templates/html/viewport.html
Normal file
2
templates/html/viewport.html
Normal file
|
@ -0,0 +1,2 @@
|
|||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1, maximum-scale=1">
|
|
@ -1,10 +1,9 @@
|
|||
\documentclass[A5,twocolumn]{article}
|
||||
#include "documentclass"
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage[hidelinks]{hyperref}
|
||||
|
||||
\usepackage[top=3.3cm, bottom=3.3cm, left=2cm, right=2cm]{geometry}
|
||||
|
||||
#include "geometry"
|
||||
\newif\ifpdf
|
||||
\ifx\pdfoutput\undefined
|
||||
\pdffalse
|
||||
|
@ -16,7 +15,7 @@
|
|||
\fi
|
||||
\fi
|
||||
|
||||
\title{Gamebook}
|
||||
#include "title"
|
||||
\author{}
|
||||
\date{}
|
||||
|
||||
|
|
1
templates/tex/documentclass.tex
Normal file
1
templates/tex/documentclass.tex
Normal file
|
@ -0,0 +1 @@
|
|||
\documentclass[A5,twocolumn]{article}
|
1
templates/tex/geometry.tex
Normal file
1
templates/tex/geometry.tex
Normal file
|
@ -0,0 +1 @@
|
|||
\usepackage[top=3.3cm, bottom=3.3cm, left=2cm, right=2cm]{geometry}
|
1
templates/tex/title.tex
Normal file
1
templates/tex/title.tex
Normal file
|
@ -0,0 +1 @@
|
|||
\title{Gamebook}
|
4
todo.org
4
todo.org
|
@ -1,4 +1,4 @@
|
|||
* TODO [27/59] [45%]
|
||||
* TODO [28/59] [47%]
|
||||
- [X] Debug output
|
||||
- [X] DOT output
|
||||
- [X] LaTeX output
|
||||
|
@ -36,7 +36,7 @@
|
|||
- [ ] Book option to set author
|
||||
- [ ] Book option to set date
|
||||
- [ ] Quote strings to not break formatting.
|
||||
- [ ] Include other templates from a template.
|
||||
- [X] Include other templates from a template.
|
||||
- [ ] Template for book introduction (including rules etc)
|
||||
Sections with some markup (has number 0?) are added as chapters
|
||||
of introduction, otherwise formatted identical to other sections.
|
||||
|
|
Loading…
Reference in a new issue