1
0
Fork 0
mirror of https://github.com/Oreolek/gamebookformat.git synced 2024-06-26 03:41:04 +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
import os.path import os.path
import sys import sys
PREPROCESS_RE = re.compile("^\s*#")
INCLUDE_RE = re.compile('^\s*#include\s*"(\w+)"')
class Templates (object): class Templates (object):
def __init__(self, templatedirs, extension): def __init__(self, templatedirs, extension):
self.extension = extension self.extension = extension
@ -23,11 +27,27 @@ class Templates (object):
def get_in(self, templatedir, name): def get_in(self, templatedir, name):
filename = self.get_template_filename(templatedir, name) filename = self.get_template_filename(templatedir, name)
f = open(filename, "r") f = open(filename, "r")
template = f.read() template = self.read_template(f);
f.close() f.close()
self.cached_templates[name] = template self.cached_templates[name] = template
return 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): def get_template_filename(self, templatedir, name):
return os.path.join(templatedir, return os.path.join(templatedir,
self.extension, self.extension,

View file

@ -2,202 +2,15 @@
<html> <html>
<head> <head>
<meta charset='utf-8'> <meta charset='utf-8'>
<meta name="viewport" #include "viewport"
content="width=device-width, initial-scale=1, maximum-scale=1"> #include "title"
<title>Gamebook Title Here</title>
<script> <script>
var gamebook = { #include "script"
'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;
}
}
};
</script> </script>
<style> <style>
.enabledsectionref {font-weight: bold; cursor: pointer;} #include "style"
.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;}
</style> </style>
</head> </head>
<body> <body>
<!-- TODO definitely need to add content here, but mostly book specific? --> #include "intro"
<div class="gamebook"> <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"> #include "collections"
</div> #include "collectiontemplate"
<div id="collectionTemplate" class="collectionTemplate">
<span class="collectionheading"></span>
<span class="collectioncontents"></span>
</div>
</div>
<script> <script>
if (this.gamebook) { #include "endscript"
gamebook.turnTo(1);
}
</script> </script>
</body> </body>
</html> </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[utf8]{inputenc}
\usepackage[T1]{fontenc} \usepackage[T1]{fontenc}
\usepackage[hidelinks]{hyperref} \usepackage[hidelinks]{hyperref}
\usepackage[top=3.3cm, bottom=3.3cm, left=2cm, right=2cm]{geometry} #include "geometry"
\newif\ifpdf \newif\ifpdf
\ifx\pdfoutput\undefined \ifx\pdfoutput\undefined
\pdffalse \pdffalse
@ -16,7 +15,7 @@
\fi \fi
\fi \fi
\title{Gamebook} #include "title"
\author{} \author{}
\date{} \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] Debug output
- [X] DOT output - [X] DOT output
- [X] LaTeX output - [X] LaTeX output
@ -36,7 +36,7 @@
- [ ] Book option to set author - [ ] Book option to set author
- [ ] Book option to set date - [ ] Book option to set date
- [ ] Quote strings to not break formatting. - [ ] 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) - [ ] Template for book introduction (including rules etc)
Sections with some markup (has number 0?) are added as chapters Sections with some markup (has number 0?) are added as chapters
of introduction, otherwise formatted identical to other sections. of introduction, otherwise formatted identical to other sections.