1
0
Fork 0
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:
Pelle Nilsson 2013-06-10 21:43:03 +02:00
parent 18c76ce0b0
commit 116ca6fad1
15 changed files with 238 additions and 209 deletions

View file

@ -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,

View file

@ -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">

View file

@ -0,0 +1,2 @@
<div id="collections" class="collections">
</div>

View file

@ -0,0 +1,5 @@
<div id="collectionTemplate" class="collectionTemplate">
<span class="collectionheading"></span>
<span class="collectioncontents"></span>
</div>
</div>

View file

@ -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>

View file

@ -0,0 +1,3 @@
if (this.gamebook) {
gamebook.turnTo(1);
}

168
templates/html/script.html Normal file
View 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
View 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;}

View file

@ -0,0 +1 @@
<title>Gamebook</title>

View file

@ -0,0 +1,2 @@
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1">

View file

@ -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{}

View file

@ -0,0 +1 @@
\documentclass[A5,twocolumn]{article}

View file

@ -0,0 +1 @@
\usepackage[top=3.3cm, bottom=3.3cm, left=2cm, right=2cm]{geometry}

1
templates/tex/title.tex Normal file
View file

@ -0,0 +1 @@
\title{Gamebook}

View file

@ -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.