@@ -1,2 +1,5 @@ | |||||
*.pyc | *.pyc | ||||
pelican/output/ | pelican/output/ | ||||
# Ignore VIM temporary files. | |||||
*.swp |
@@ -0,0 +1,208 @@ | |||||
<!DOCTYPE html> | |||||
<html> | |||||
<meta charset="utf-8"> | |||||
<head> | |||||
<style> | |||||
#header | |||||
{ | |||||
background: #856d51; | |||||
padding: 0.7em; | |||||
text-align: left; | |||||
} | |||||
#header a | |||||
{ | |||||
color: white; | |||||
text-decoration: none; | |||||
padding: 0.5em 1em 0.5em 1em; | |||||
} | |||||
#title | |||||
{ | |||||
color: #433729; | |||||
} | |||||
iframe | |||||
{ | |||||
width: 720px; | |||||
height: 720px; | |||||
} | |||||
html | |||||
{ | |||||
font-family: sans-serif; | |||||
} | |||||
body | |||||
{ | |||||
line-height: 1.5em; | |||||
} | |||||
body | |||||
{ | |||||
background: #FAFAFA; | |||||
} | |||||
table | |||||
{ | |||||
border-collapse: collapse; | |||||
width: 100%; | |||||
} | |||||
table, th, td | |||||
{ | |||||
border: 1px solid #aaa; | |||||
padding: 0.5em; | |||||
margin-top: 0.5em; | |||||
margin-bottom: 0.5em; | |||||
} | |||||
code, pre | |||||
{ | |||||
font-family: monospace, serif; | |||||
font-size: 1em; | |||||
color: #7f0a0c; | |||||
background: #f5f5f5; | |||||
white-space: pre-wrap; | |||||
} | |||||
.contents | |||||
{ | |||||
background: #FFFFFF; | |||||
width: 720px; | |||||
padding: 1em; | |||||
margin-top: 2em; | |||||
margin-bottom: 2em; | |||||
border: 1px solid #E0E0E0; | |||||
text-align: left; | |||||
color: #444; | |||||
} | |||||
</style> | |||||
<title> | |||||
PSKOV - Opensource Game Studio static site generator | |||||
</title> | |||||
</head> | |||||
<body> | |||||
<div id="header"> | |||||
<strong id="title">PSKOV</strong> | |||||
<a href="index.html">Tool</a> | |||||
<a href="education.html">Education</a> | |||||
</div> | |||||
<center><h1> | |||||
Education: 01. Why | |||||
</h1></center> | |||||
<center><div class="contents"> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>< Back</th> | |||||
<th>Index</th> | |||||
<th>Next ></th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td>Not available</td> | |||||
<td><a href="education.html">Education</a></td> | |||||
<td><a href="education.02.deps.html">02. Dependencies</a></td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<p></div><div class="contents"></p> | |||||
<p>In this document we briefly explain why <strong>PSKOV</strong> was created.</p> | |||||
<p>Estimated completion time: 5 minutes.</p> | |||||
<p><strong>Table of contents</strong></p> | |||||
<ul> | |||||
<li><a href="#why">01. Why</a></li> | |||||
<li><a href="#features">02. Features</a></li> | |||||
</ul> | |||||
<p><a name="why"/></p> | |||||
<h2 id="01why">01. Why</h2> | |||||
<p>You might know there already exist quite a lot of <a href="https://medium.com/codingthesmartway-com-blog/top-static-site-generators-for-2019-26a4c8afcc05">static site generators</a>, why create another one? Because <strong>they are not good enough</strong> for <a href="http://opengamestudio.org">Opensource Game Studio</a> needs.</p> | |||||
<p>Here's a list of <strong>features we don't need</strong>:</p> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>№</th> | |||||
<th>Unwelcome feature</th> | |||||
<th>Note</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td>1</td> | |||||
<td>Learning anything beyond HTML, CSS, JavaScript, and Markdown</td> | |||||
<td>These technologies are enough to deliver information to users</td> | |||||
</tr> | |||||
<tr> | |||||
<td>2</td> | |||||
<td>Server side</td> | |||||
<td>Nobody should be able to pull the plug on you except yourself</td> | |||||
</tr> | |||||
<tr> | |||||
<td>3</td> | |||||
<td>Installation</td> | |||||
<td>We had enough updates that were never requested</td> | |||||
</tr> | |||||
<tr> | |||||
<td>4</td> | |||||
<td>Comprehensible source code</td> | |||||
<td>Single file with just enough number of lines</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<p><a name="features"/></p> | |||||
<h2 id="02features">02. Features</h2> | |||||
<p>Consequently, here is a list of <strong>PSKOV features</strong>:</p> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>№</th> | |||||
<th>PSKOV feature</th> | |||||
<th>Note</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td>1</td> | |||||
<td>Bare HTML, CSS, JavaScript, and Markdown</td> | |||||
<td>No need for template language, web framework or anything else</td> | |||||
</tr> | |||||
<tr> | |||||
<td>2</td> | |||||
<td>Client side</td> | |||||
<td><strong>PSKOV</strong> is a client side JavaScript application, it runs solely on your device</td> | |||||
</tr> | |||||
<tr> | |||||
<td>3</td> | |||||
<td>Optional installation</td> | |||||
<td><strong>PSKOV</strong> is available at <a href="http://opengamestudio.org/pskov">http://opengamestudio.org/pskov</a>. However, if you want to keep <strong>PSKOV</strong> locally, you can get <strong>PSKOV</strong> single HTML file <a href="http://opengamestudio.org/pskov-201905.html">here</a> and open it locally</td> | |||||
</tr> | |||||
<tr> | |||||
<td>4</td> | |||||
<td>Comprehensible source code</td> | |||||
<td><strong>PSKOV</strong> is a <a href="http://opengamestudio.org/pskov-201905.html">single HTML file</a> with less than 10000 lines of code</td> | |||||
</tr> | |||||
<tr> | |||||
<td>5</td> | |||||
<td>Decades long support (DLS)</td> | |||||
<td>You can use <strong>PSKOV</strong> on both Windows 2000 and Windows 2030*</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<p>* Windows 2030 does not (yet) exist, we simply refer to the fact that <strong>PSKOV</strong> is designed to work for operating systems released in the range of years 2000-2030</p> | |||||
<p></div><div class="contents"></p> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>< Back</th> | |||||
<th>Index</th> | |||||
<th>Next ></th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td>Not available</td> | |||||
<td><a href="education.html">Education</a></td> | |||||
<td><a href="education.02.deps.html">02. Dependencies</a></td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div></center> | |||||
<script type="text/javascript"> | |||||
</script> | |||||
</body> | |||||
</html> | |||||
@@ -0,0 +1,165 @@ | |||||
<!DOCTYPE html> | |||||
<html> | |||||
<meta charset="utf-8"> | |||||
<head> | |||||
<style> | |||||
#header | |||||
{ | |||||
background: #856d51; | |||||
padding: 0.7em; | |||||
text-align: left; | |||||
} | |||||
#header a | |||||
{ | |||||
color: white; | |||||
text-decoration: none; | |||||
padding: 0.5em 1em 0.5em 1em; | |||||
} | |||||
#title | |||||
{ | |||||
color: #433729; | |||||
} | |||||
iframe | |||||
{ | |||||
width: 720px; | |||||
height: 720px; | |||||
} | |||||
html | |||||
{ | |||||
font-family: sans-serif; | |||||
} | |||||
body | |||||
{ | |||||
line-height: 1.5em; | |||||
} | |||||
body | |||||
{ | |||||
background: #FAFAFA; | |||||
} | |||||
table | |||||
{ | |||||
border-collapse: collapse; | |||||
width: 100%; | |||||
} | |||||
table, th, td | |||||
{ | |||||
border: 1px solid #aaa; | |||||
padding: 0.5em; | |||||
margin-top: 0.5em; | |||||
margin-bottom: 0.5em; | |||||
} | |||||
code, pre | |||||
{ | |||||
font-family: monospace, serif; | |||||
font-size: 1em; | |||||
color: #7f0a0c; | |||||
background: #f5f5f5; | |||||
white-space: pre-wrap; | |||||
} | |||||
.contents | |||||
{ | |||||
background: #FFFFFF; | |||||
width: 720px; | |||||
padding: 1em; | |||||
margin-top: 2em; | |||||
margin-bottom: 2em; | |||||
border: 1px solid #E0E0E0; | |||||
text-align: left; | |||||
color: #444; | |||||
} | |||||
</style> | |||||
<title> | |||||
PSKOV - Opensource Game Studio static site generator | |||||
</title> | |||||
</head> | |||||
<body> | |||||
<div id="header"> | |||||
<strong id="title">PSKOV</strong> | |||||
<a href="index.html">Tool</a> | |||||
<a href="education.html">Education</a> | |||||
</div> | |||||
<center><h1> | |||||
Education: 02. Dependencies | |||||
</h1></center> | |||||
<center><div class="contents"> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>< Back</th> | |||||
<th>Index</th> | |||||
<th>Next ></th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td><a href="education.01.why.html">01. Why</a></td> | |||||
<td><a href="education.html">Education</a></td> | |||||
<td><a href="education.03.site.html">03. Site</a></td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<p></div><div class="contents"></p> | |||||
<p>In this document we teach how to install <strong>PSKOV</strong> dependencies.</p> | |||||
<p>Estimated completion time: ?? minutes.</p> | |||||
<p><strong>Table of contents</strong></p> | |||||
<ul> | |||||
<li><a href="#deps">01. Dependencies</a></li> | |||||
<li><a href="#lfsa">02. Install LFSA</a></li> | |||||
<li><a href="#showdown">03. Showdown</a></li> | |||||
</ul> | |||||
<p><a name="deps"/></p> | |||||
<h2 id="01dependencies">01. Dependencies</h2> | |||||
<p>We designed <strong>PSKOV</strong> to run inside web browsers. Hence, here is a list of <strong>PSKOV dependencies</strong>:</p> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>№</th> | |||||
<th>Dependency</th> | |||||
<th>Note</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td>1</td> | |||||
<td>Web browser of 2010 or newer</td> | |||||
<td><strong>PSKOV</strong> needs ECMAScript 5 (2009), any modern web browser should work</td> | |||||
</tr> | |||||
<tr> | |||||
<td>2</td> | |||||
<td>Local file system access (LFSA)</td> | |||||
<td><a href="http://opengamestudio.org/lfsa">LFSA</a> gives <strong>PSKOV</strong> access to your local file system</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<p>Since <strong>PSKOV</strong> is a client side JavaScript application, it has no direct access to your local file system to generate files. That's why we have also created <a href="http://opengamestudio.org/lfsa">LFSA</a>, a tiny Python server to provide read/write access to your local file system at 8000 port. LFSA is under 200 lines of code, feel free to <a href="TODO-LFSA-SRC">inspect it</a> to make sure we don't steal your data.</p> | |||||
<p><a name="lfsa"/></p> | |||||
<h2 id="02installlfsa">02. Install LFSA</h2> | |||||
<p>TODO </p> | |||||
<p><a name="showdown"/></p> | |||||
<h2 id="03showdown">03. Showdown</h2> | |||||
<p>Tell Showdown.JS is used to convert Markdown to HTML, so users should refer to Showdown.JS for rules.</p> | |||||
<p></div><div class="contents"></p> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>< Back</th> | |||||
<th>Index</th> | |||||
<th>Next ></th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td><a href="education.01.why.html">01. Why</a></td> | |||||
<td><a href="education.html">Education</a></td> | |||||
<td><a href="education.03.site.html">03. Site</a></td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div></center> | |||||
<script type="text/javascript"> | |||||
</script> | |||||
</body> | |||||
</html> | |||||
@@ -0,0 +1,312 @@ | |||||
<!DOCTYPE html> | |||||
<html> | |||||
<meta charset="utf-8"> | |||||
<head> | |||||
<style> | |||||
#header | |||||
{ | |||||
background: #856d51; | |||||
padding: 0.7em; | |||||
text-align: left; | |||||
} | |||||
#header a | |||||
{ | |||||
color: white; | |||||
text-decoration: none; | |||||
padding: 0.5em 1em 0.5em 1em; | |||||
} | |||||
#title | |||||
{ | |||||
color: #433729; | |||||
} | |||||
iframe | |||||
{ | |||||
width: 720px; | |||||
height: 720px; | |||||
} | |||||
html | |||||
{ | |||||
font-family: sans-serif; | |||||
} | |||||
body | |||||
{ | |||||
line-height: 1.5em; | |||||
} | |||||
body | |||||
{ | |||||
background: #FAFAFA; | |||||
} | |||||
table | |||||
{ | |||||
border-collapse: collapse; | |||||
width: 100%; | |||||
} | |||||
table, th, td | |||||
{ | |||||
border: 1px solid #aaa; | |||||
padding: 0.5em; | |||||
margin-top: 0.5em; | |||||
margin-bottom: 0.5em; | |||||
} | |||||
code, pre | |||||
{ | |||||
font-family: monospace, serif; | |||||
font-size: 1em; | |||||
color: #7f0a0c; | |||||
background: #f5f5f5; | |||||
white-space: pre-wrap; | |||||
} | |||||
.contents | |||||
{ | |||||
background: #FFFFFF; | |||||
width: 720px; | |||||
padding: 1em; | |||||
margin-top: 2em; | |||||
margin-bottom: 2em; | |||||
border: 1px solid #E0E0E0; | |||||
text-align: left; | |||||
color: #444; | |||||
} | |||||
</style> | |||||
<title> | |||||
PSKOV - Opensource Game Studio static site generator | |||||
</title> | |||||
</head> | |||||
<body> | |||||
<div id="header"> | |||||
<strong id="title">PSKOV</strong> | |||||
<a href="index.html">Tool</a> | |||||
<a href="education.html">Education</a> | |||||
</div> | |||||
<center><h1> | |||||
Education: 03. Site | |||||
</h1></center> | |||||
<center><div class="contents"> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>< Back</th> | |||||
<th>Index</th> | |||||
<th>Next ></th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td><a href="education.02.deps.html">02. Dependencies</a></td> | |||||
<td><a href="education.html">Education</a></td> | |||||
<td><a href="education.04.lang.html">04. Language</a></td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<p></div><div class="contents"></p> | |||||
<p>In this document we create a simple static web site with two pages.</p> | |||||
<p>Estimated completion time: ? minutes.</p> | |||||
<p><strong>Table of contents</strong></p> | |||||
<ul> | |||||
<li><a href="#inspiration">01. Inspiration</a></li> | |||||
<li><a href="#cfg">02. Investigate <code>cfg</code> file</a></li> | |||||
<li><a href="#item">03. Investigate <code>item.template</code> file</a></li> | |||||
<li><a href="#md">04. Investigate <code>index.md</code> and <code>cv.md</code> files</a></li> | |||||
<li><a href="#lfsa">05. Launch LFSA</a></li> | |||||
<li><a href="#gen">06. Generate the site</a></li> | |||||
</ul> | |||||
<p><a name="inspiration"/></p> | |||||
<h2 id="01inspiration">01. Inspiration</h2> | |||||
<p>Suppose you are a great Russian painter named Valentin Serov. Everytime anyone wants to know about you they refer to <a href="https://en.wikipedia.org/wiki/Valentin_Serov">Wikipedia</a>. You wake up earlier today with a distinct desire to have your very own personal web site.</p> | |||||
<p>You set on to create the following pages:</p> | |||||
<ul> | |||||
<li>About me</li> | |||||
<li>Curriculum vitae (CV)</li> | |||||
</ul> | |||||
<p>Some time later you have the following files in your <a href="https://github.com/OGStudio/site-pskov-sample/tree/master/01.TwoPages">site directory</a>:</p> | |||||
<ul> | |||||
<li>cfg</li> | |||||
<li>item.template</li> | |||||
<li>index.md</li> | |||||
<li>cv.md</li> | |||||
</ul> | |||||
<p>Let's look at their contents closer.</p> | |||||
<p><a name="cfg"/></p> | |||||
<h2 id="02investigatecfgfile">02. Investigate <code>cfg</code> file</h2> | |||||
<p><code>cfg</code> file has the following contents:</p> | |||||
<pre><code>input = . | |||||
item = item.template | |||||
</code></pre> | |||||
<p><code>cfg</code> is an <a href="https://en.wikipedia.org/wiki/INI_file">INI file</a> with the following keys specified:</p> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>Key</th> | |||||
<th>Description</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td><code>input</code></td> | |||||
<td>Points to a directory where <code>item</code>'s file is located</td> | |||||
</tr> | |||||
<tr> | |||||
<td><code>item</code></td> | |||||
<td>Points to an HTML template file that will be used to generate HTML files out of Markdown ones</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<p>In our case, <code>item.template</code> file is located alongside <code>cfg</code>, so we use <code>.</code> to denote current directory.</p> | |||||
<p><a name="item"/></p> | |||||
<h2 id="03investigateitemtemplatefile">03. Investigate <code>item.template</code> file</h2> | |||||
<p><code>item.template</code> file has the following contents:</p> | |||||
<pre><code><!DOCTYPE html> | |||||
<html> | |||||
<meta charset="utf-8"> | |||||
<head> | |||||
<style> | |||||
- - - - Style was collapsed for brevity - - - - | |||||
</style> | |||||
<title>Serov</title> | |||||
</head> | |||||
<body> | |||||
<div id="header"> | |||||
<strong>Serov</strong> | |||||
<a href="index.html">About me</a> | |||||
<a href="cv.html">CV</a> | |||||
</div> | |||||
<center> | |||||
<h1>PSKOV_ITEM_TITLE</h1> | |||||
<div class="contents"> | |||||
PSKOV_ITEM_CONTENTS | |||||
</div> | |||||
</center> | |||||
</body> | |||||
</html> | |||||
</code></pre> | |||||
<p><strong>Note</strong>: style was collapsed for brevity.</p> | |||||
<p>As you can see, <code>item.template</code> is an average HTML file with two constants specified:</p> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>PSKOV constant</th> | |||||
<th>Description</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td><code>PSKOV_ITEM_TITLE</code></td> | |||||
<td>Provides title from <code>Title:</code> part of page's header section</td> | |||||
</tr> | |||||
<tr> | |||||
<td><code>PSKOV_ITEM_CONTENTS</code></td> | |||||
<td>Provides HTML contents generated out of Markdown contents</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<p><strong>Notes</strong>:</p> | |||||
<ul> | |||||
<li>other <strong>PSKOV</strong> constants are described later</li> | |||||
<li>page's header section is described below</li> | |||||
</ul> | |||||
<p><a name="md"/></p> | |||||
<h2 id="04investigateindexmdandcvmdfiles">04. Investigate <code>index.md</code> and <code>cv.md</code> files</h2> | |||||
<p><code>index.md</code> file has the following contents:</p> | |||||
<pre><code> Title: About me | |||||
Slug: index | |||||
Hi, my name is Valentin Serov. Here's my self-portrait: | |||||
![Valentin Serov self-portrait][serov-portrait] | |||||
- - - - Contents were collapsed for brevity - - - - | |||||
Have a look at my [CV][cv] now. | |||||
[serov]: https://en.wikipedia.org/wiki/Valentin_Serov | |||||
[revolution]: https://en.wikipedia.org/wiki/Russian_Revolution | |||||
[serov-portrait]: myself.jpg | |||||
[serov-work]: mywork.jpg | |||||
[girl-with-peaches]: https://en.wikipedia.org/wiki/Girl_with_Peaches | |||||
[pskov]: http://opengamestudio.org/pskov | |||||
[cv]: cv.html | |||||
</code></pre> | |||||
<p><code>index.md</code> starts with a so-called header section:</p> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>Header constant</th> | |||||
<th>Description</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td><code>Title:</code></td> | |||||
<td>Provides value for <code>PSKOV_ITEM_TITLE</code> constant when generating HTML out of Markdown</td> | |||||
</tr> | |||||
<tr> | |||||
<td><code>Slug:</code></td> | |||||
<td>Tells <strong>PSKOV</strong> that this particular Markdown file should be saved under <code><slug>.html</code> filename</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<p>The rest of <code>index.md</code> contents is what any Markdown file looks like.</p> | |||||
<p><strong>Note</strong>: <code>cv</code> page is referenced as <code>cv.html</code>, not <code>cv.md</code></p> | |||||
<p><code>cv.md</code> file has the following contents:</p> | |||||
<pre><code> Title: Curriculum vitae | |||||
Slug: cv | |||||
Here's my CV in case my paintings still interest you. I took a bit of a modern IT approach to structure my CV as key-value pairs of a dictionary (map), enjoy! | |||||
| Key | Value | | |||||
|---|---| | |||||
| Name | Valentin Serov | | |||||
| Age | 46 | | |||||
| Marital status | Married | | |||||
| Country | Russian Empire | | |||||
| Alma mater | Imperial Academy of Arts | | |||||
| Education | * Member Academy of Arts (1898) <br> * Full Member Academy of Arts (1903) | | |||||
</code></pre> | |||||
<p>As you can see, there's nothing new in <code>cv.md</code> except for a Markdown table.</p> | |||||
<p><a name="lfsa"/></p> | |||||
<h2 id="05launchlfsa">05. Launch LFSA</h2> | |||||
<p>Launch LFSA so that it points to directory with the files we just observed:</p> | |||||
<pre><code>$ /path/to/local-file-system-access.py /path/to/dir/01.TwoPages | |||||
</code></pre> | |||||
<p>You should see output similar to this:</p> | |||||
<pre><code>DIR: '/Users/kornerr/p/site-pskov-sample/01.TwoPages' | |||||
PORT: '8000' | |||||
</code></pre> | |||||
<p><a name="gen"/></p> | |||||
<h2 id="06generatethesite">06. Generate the site</h2> | |||||
<p>Now it's finally time to generate your personal web site:</p> | |||||
<ul> | |||||
<li>Go to <a href="http://opengamestudio.org/pskov">Tool</a> page</li> | |||||
<li>Make sure<ul> | |||||
<li><code>Path:</code> points to the same directory you specified before</li> | |||||
<li><code>Input directory:</code> and <code>Item template:</code> have values from <code>cfg</code></li></ul></li> | |||||
<li>Press <code>Generate</code> button to generate HTML files right where Markdown ones reside</li> | |||||
<li>Open generated <code>index.html</code> from the site's directory</li> | |||||
<li>You should see your web site running locally</li> | |||||
</ul> | |||||
<p>Take time to observe your new shiny personal web site consisting of two pages.</p> | |||||
<p></div><div class="contents"></p> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>< Back</th> | |||||
<th>Index</th> | |||||
<th>Next ></th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td><a href="education.02.deps.html">02. Dependencies</a></td> | |||||
<td><a href="education.html">Education</a></td> | |||||
<td><a href="education.04.lang.html">04. Language</a></td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div></center> | |||||
<script type="text/javascript"> | |||||
</script> | |||||
</body> | |||||
</html> | |||||
@@ -0,0 +1,251 @@ | |||||
<!DOCTYPE html> | |||||
<html> | |||||
<meta charset="utf-8"> | |||||
<head> | |||||
<style> | |||||
#header | |||||
{ | |||||
background: #856d51; | |||||
padding: 0.7em; | |||||
text-align: left; | |||||
} | |||||
#header a | |||||
{ | |||||
color: white; | |||||
text-decoration: none; | |||||
padding: 0.5em 1em 0.5em 1em; | |||||
} | |||||
#title | |||||
{ | |||||
color: #433729; | |||||
} | |||||
iframe | |||||
{ | |||||
width: 720px; | |||||
height: 720px; | |||||
} | |||||
html | |||||
{ | |||||
font-family: sans-serif; | |||||
} | |||||
body | |||||
{ | |||||
line-height: 1.5em; | |||||
} | |||||
body | |||||
{ | |||||
background: #FAFAFA; | |||||
} | |||||
table | |||||
{ | |||||
border-collapse: collapse; | |||||
width: 100%; | |||||
} | |||||
table, th, td | |||||
{ | |||||
border: 1px solid #aaa; | |||||
padding: 0.5em; | |||||
margin-top: 0.5em; | |||||
margin-bottom: 0.5em; | |||||
} | |||||
code, pre | |||||
{ | |||||
font-family: monospace, serif; | |||||
font-size: 1em; | |||||
color: #7f0a0c; | |||||
background: #f5f5f5; | |||||
white-space: pre-wrap; | |||||
} | |||||
.contents | |||||
{ | |||||
background: #FFFFFF; | |||||
width: 720px; | |||||
padding: 1em; | |||||
margin-top: 2em; | |||||
margin-bottom: 2em; | |||||
border: 1px solid #E0E0E0; | |||||
text-align: left; | |||||
color: #444; | |||||
} | |||||
</style> | |||||
<title> | |||||
PSKOV - Opensource Game Studio static site generator | |||||
</title> | |||||
</head> | |||||
<body> | |||||
<div id="header"> | |||||
<strong id="title">PSKOV</strong> | |||||
<a href="index.html">Tool</a> | |||||
<a href="education.html">Education</a> | |||||
</div> | |||||
<center><h1> | |||||
Education: 04. Language | |||||
</h1></center> | |||||
<center><div class="contents"> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>< Back</th> | |||||
<th>Index</th> | |||||
<th>Next ></th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td><a href="education.03.site.html">03. Site</a></td> | |||||
<td><a href="education.html">Education</a></td> | |||||
<td><a href="education.05.blog.html">05. Blog</a></td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<p></div><div class="contents"></p> | |||||
<p>In this document we add language selection.</p> | |||||
<p>Estimated completion time: ? minutes.</p> | |||||
<p><strong>Table of contents</strong></p> | |||||
<ul> | |||||
<li><a href="#localization">01. Localization</a></li> | |||||
<li><a href="#cfg">02. Investigate <code>cfg</code> file</a></li> | |||||
<li><a href="#item">03. Investigate template files</a></li> | |||||
<li><a href="#md">04. Investigate Markdown files</a></li> | |||||
<li><a href="#gen">05. Launch LFSA and generate the site</a></li> | |||||
</ul> | |||||
<p><a name="localization"/></p> | |||||
<h2 id="01localization">01. Localization</h2> | |||||
<p>Now that you have your web site in English you start to wonder why there's no Russian version, you're Russian after all!</p> | |||||
<p>You set on to create the following <a href="https://github.com/OGStudio/site-pskov-sample/tree/master/02.Language">directory structure</a>:</p> | |||||
<ul> | |||||
<li><code>cfg</code></li> | |||||
<li><code>en/item.template</code></li> | |||||
<li><code>en/index.md</code></li> | |||||
<li><code>en/cv.md</code></li> | |||||
<li><code>ru/item.template</code></li> | |||||
<li><code>ru/index.md</code></li> | |||||
<li><code>ru/cv.md</code></li> | |||||
</ul> | |||||
<p>Let's look at the contents of these files closer.</p> | |||||
<p><a name="cfg"/></p> | |||||
<h2 id="02investigatecfgfile">02. Investigate <code>cfg</code> file</h2> | |||||
<p><code>cfg</code> file has the following contents:</p> | |||||
<pre><code>input = en;ru | |||||
item = item.template | |||||
</code></pre> | |||||
<p>As you see, <code>input</code> can accept multiple directories separated by <code>;</code> symbol: <strong>PSKOV</strong> will go over each directory specified and run as before.</p> | |||||
<p>In this case, both <code>en/</code> and <code>ru/</code> directories have their own <code>item.template</code> file.</p> | |||||
<p><a name="item"/></p> | |||||
<h2 id="03investigatetemplatefiles">03. Investigate template files</h2> | |||||
<ul> | |||||
<li><p><code>en/item.template</code> contents:</p> | |||||
<pre><code>- - - - Collapsed for brevity - - - - | |||||
<title>Serov</title> | |||||
</head> | |||||
<body> | |||||
<div id="header"> | |||||
<strong>Serov</strong> | |||||
<a href="index.html">About me</a> | |||||
<a href="cv.html">CV</a> | |||||
<div id="lang"> | |||||
<a href="../en/PSKOV_ITEM_URL">EN</a> | |||||
<a href="../ru/PSKOV_ITEM_URL">RU</a> | |||||
</div> | |||||
</div> | |||||
<center> | |||||
- - - - Collapsed for brevity - - - - | |||||
</code></pre></li> | |||||
<li><p><code>ru/item.template</code> contents:</p> | |||||
<pre><code>- - - - Collapsed for brevity - - - - | |||||
<title>Серов</title> | |||||
</head> | |||||
<body> | |||||
<div id="header"> | |||||
<strong>Серов</strong> | |||||
<a href="index.html">Обо мне</a> | |||||
<a href="cv.html">Резюме</a> | |||||
<div id="lang"> | |||||
<a href="../en/PSKOV_ITEM_URL">EN</a> | |||||
<a href="../ru/PSKOV_ITEM_URL">RU</a> | |||||
</div> | |||||
</div> | |||||
<center> | |||||
- - - - Collapsed for brevity - - - - | |||||
</code></pre></li> | |||||
</ul> | |||||
<p><strong>Note</strong>: beginning and ending were collapsed for brevity.</p> | |||||
<p>As you can see, both <code>en/item.template</code> and <code>ru/item.template</code> look similar to <code>item.template</code> we saw <a href="education.03.site.html">before</a>.</p> | |||||
<p>The changes include:</p> | |||||
<ul> | |||||
<li>use of <code><div id="lang">...</div></code> section to present language selection</li> | |||||
<li>localization of titles into English and Russian</li> | |||||
</ul> | |||||
<p>Language selection uses new <strong>PSKOV</strong> constant:</p> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>PSKOV constant</th> | |||||
<th>Description</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td><code>PSKOV_ITEM_URL</code></td> | |||||
<td>Provides <code><slug>.html</code> value for the page</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<p>As you see, <code>PSKOV_ITEM_URL</code> is all you need to have your page in as many languages as you please.</p> | |||||
<p><a name="md"/></p> | |||||
<h2 id="04investigatemarkdownfiles">04. Investigate Markdown files</h2> | |||||
<p><code>en/index.md</code> and <code>en/cv.md</code> files look exactly as <a href="education.03.site.html">before</a>. <code>ru/index.md</code> and <code>ru/cv.md</code> are simply Russian variants of the same pages.</p> | |||||
<p>For example, <code>ru/cv.md</code> has the following contents:</p> | |||||
<pre><code> Title: Резюме | |||||
Slug: cv | |||||
Здесь вы можете увидеть моё резюме в том случае, если мои произведения всё ещё вас интересуют. Я использовал современный подход ИТ для структурирования своего резюме в виде пар ключ-значение словаря (карты). Наслаждайтесь! | |||||
| Ключ | Значение | | |||||
|---|---| | |||||
| Имя | Валентин Серов | | |||||
| Возраст | 46 | | |||||
| Семейное положение | Женат | | |||||
| Страна | Российская Империя | | |||||
| Учёба | Императорская Академия художеств | | |||||
| Звания | * академик ИАХ (1898) <br> * действительный член ИАХ (1903) | | |||||
</code></pre> | |||||
<p><strong>Note</strong>: Russian page has exactly the same <code>Slug:</code> value as English one.</p> | |||||
<p><a name="gen"/></p> | |||||
<h2 id="05launchlfsaandgeneratethesite">05. Launch LFSA and generate the site</h2> | |||||
<p>Launch LFSA so that it points to directory with the files we just observed:</p> | |||||
<pre><code>$ /path/to/local-file-system-access.py /path/to/dir/02.Language | |||||
</code></pre> | |||||
<p>Generate the site:</p> | |||||
<ul> | |||||
<li>Go to <a href="http://opengamestudio.org/pskov">Tool</a> page</li> | |||||
<li>Press <code>Generate</code> button</li> | |||||
<li>Open generated <code>en/index.html</code> or <code>ru/index.html</code> from the site's directory locally</li> | |||||
<li>Switch language to verify language selection works fine</li> | |||||
</ul> | |||||
<p>Take time to observe just how little effort you spent to have your web site localized.</p> | |||||
<p></div><div class="contents"></p> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>< Back</th> | |||||
<th>Index</th> | |||||
<th>Next ></th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td><a href="education.03.site.html">03. Site</a></td> | |||||
<td><a href="education.html">Education</a></td> | |||||
<td><a href="education.05.blog.html">05. Blog</a></td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div></center> | |||||
<script type="text/javascript"> | |||||
</script> | |||||
</body> | |||||
</html> | |||||
@@ -0,0 +1,141 @@ | |||||
<!DOCTYPE html> | |||||
<html> | |||||
<meta charset="utf-8"> | |||||
<head> | |||||
<style> | |||||
#header | |||||
{ | |||||
background: #856d51; | |||||
padding: 0.7em; | |||||
text-align: left; | |||||
} | |||||
#header a | |||||
{ | |||||
color: white; | |||||
text-decoration: none; | |||||
padding: 0.5em 1em 0.5em 1em; | |||||
} | |||||
#title | |||||
{ | |||||
color: #433729; | |||||
} | |||||
iframe | |||||
{ | |||||
width: 720px; | |||||
height: 720px; | |||||
} | |||||
html | |||||
{ | |||||
font-family: sans-serif; | |||||
} | |||||
body | |||||
{ | |||||
line-height: 1.5em; | |||||
} | |||||
body | |||||
{ | |||||
background: #FAFAFA; | |||||
} | |||||
table | |||||
{ | |||||
border-collapse: collapse; | |||||
width: 100%; | |||||
} | |||||
table, th, td | |||||
{ | |||||
border: 1px solid #aaa; | |||||
padding: 0.5em; | |||||
margin-top: 0.5em; | |||||
margin-bottom: 0.5em; | |||||
} | |||||
code, pre | |||||
{ | |||||
font-family: monospace, serif; | |||||
font-size: 1em; | |||||
color: #7f0a0c; | |||||
background: #f5f5f5; | |||||
white-space: pre-wrap; | |||||
} | |||||
.contents | |||||
{ | |||||
background: #FFFFFF; | |||||
width: 720px; | |||||
padding: 1em; | |||||
margin-top: 2em; | |||||
margin-bottom: 2em; | |||||
border: 1px solid #E0E0E0; | |||||
text-align: left; | |||||
color: #444; | |||||
} | |||||
</style> | |||||
<title> | |||||
PSKOV - Opensource Game Studio static site generator | |||||
</title> | |||||
</head> | |||||
<body> | |||||
<div id="header"> | |||||
<strong id="title">PSKOV</strong> | |||||
<a href="index.html">Tool</a> | |||||
<a href="education.html">Education</a> | |||||
</div> | |||||
<center><h1> | |||||
Education | |||||
</h1></center> | |||||
<center><div class="contents"> | |||||
<p>Here you can find a set of documents to make you proficient in generating static sites with <strong>PSKOV</strong>. You are encouraged to read the documents in order.</p> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>№</th> | |||||
<th>Document</th> | |||||
<th>Details</th> | |||||
<th>Demonstration</th> | |||||
<th>Estimated completion time</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td>1</td> | |||||
<td><a href="education.01.why.html">Why</a></td> | |||||
<td>Find out why <strong>PSKOV</strong> was created</td> | |||||
<td>-</td> | |||||
<td>5 minutes</td> | |||||
</tr> | |||||
<tr> | |||||
<td>2</td> | |||||
<td><a href="education.02.deps.html">Dependencies</a></td> | |||||
<td>Install dependencies to start using <strong>PSKOV</strong></td> | |||||
<td>-</td> | |||||
<td>?? minutes</td> | |||||
</tr> | |||||
<tr> | |||||
<td>3</td> | |||||
<td><a href="education.03.site.html">Site</a></td> | |||||
<td>Learn how to create a simple static web site with two pages</td> | |||||
<td>TODO Link</td> | |||||
<td>?? minutes</td> | |||||
</tr> | |||||
<tr> | |||||
<td>4</td> | |||||
<td>Language</td> | |||||
<td>?</td> | |||||
<td>TODO Link</td> | |||||
<td>?</td> | |||||
</tr> | |||||
<tr> | |||||
<td>5</td> | |||||
<td>Blog</td> | |||||
<td>?</td> | |||||
<td>TODO Link</td> | |||||
<td>?</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div></center> | |||||
<script type="text/javascript"> | |||||
</script> | |||||
</body> | |||||
</html> | |||||
@@ -0,0 +1,96 @@ | |||||
<!DOCTYPE html> | |||||
<html> | |||||
<meta charset="utf-8"> | |||||
<head> | |||||
<style> | |||||
#header | |||||
{ | |||||
background: #856d51; | |||||
padding: 0.7em; | |||||
text-align: left; | |||||
} | |||||
#header a | |||||
{ | |||||
color: white; | |||||
text-decoration: none; | |||||
padding: 0.5em 1em 0.5em 1em; | |||||
} | |||||
#title | |||||
{ | |||||
color: #433729; | |||||
} | |||||
iframe | |||||
{ | |||||
width: 720px; | |||||
height: 720px; | |||||
} | |||||
html | |||||
{ | |||||
font-family: sans-serif; | |||||
} | |||||
body | |||||
{ | |||||
line-height: 1.5em; | |||||
} | |||||
body | |||||
{ | |||||
background: #FAFAFA; | |||||
} | |||||
table | |||||
{ | |||||
border-collapse: collapse; | |||||
width: 100%; | |||||
} | |||||
table, th, td | |||||
{ | |||||
border: 1px solid #aaa; | |||||
padding: 0.5em; | |||||
margin-top: 0.5em; | |||||
margin-bottom: 0.5em; | |||||
} | |||||
code, pre | |||||
{ | |||||
font-family: monospace, serif; | |||||
font-size: 1em; | |||||
color: #7f0a0c; | |||||
background: #f5f5f5; | |||||
white-space: pre-wrap; | |||||
} | |||||
.contents | |||||
{ | |||||
background: #FFFFFF; | |||||
width: 720px; | |||||
padding: 1em; | |||||
margin-top: 2em; | |||||
margin-bottom: 2em; | |||||
border: 1px solid #E0E0E0; | |||||
text-align: left; | |||||
color: #444; | |||||
} | |||||
</style> | |||||
<title> | |||||
PSKOV - Opensource Game Studio static site generator | |||||
</title> | |||||
</head> | |||||
<body> | |||||
<div id="header"> | |||||
<strong id="title">PSKOV</strong> | |||||
<a href="index.html">Tool</a> | |||||
<a href="education.html">Education</a> | |||||
</div> | |||||
<center><h1> | |||||
Tool | |||||
</h1></center> | |||||
<center><div class="contents"> | |||||
<p><strong>PSKOV</strong> is a static site generator that runs in your web browser. What you see now has also been generated with <strong>PSKOV</strong>. If you're new to <strong>PSKOV</strong>, visit <a href="education.html">education page</a>.</p> | |||||
<iframe id="pskov" src="pskov-201905.html"> | |||||
<p>ERROR Your browser does not support iframes</p> | |||||
</iframe> | |||||
</div></center> | |||||
<script type="text/javascript"> | |||||
</script> | |||||
</body> | |||||
</html> | |||||
@@ -0,0 +1,93 @@ | |||||
<!DOCTYPE html> | |||||
<html> | |||||
<meta charset="utf-8"> | |||||
<head> | |||||
<style> | |||||
#header | |||||
{ | |||||
background: #856d51; | |||||
padding: 0.7em; | |||||
text-align: left; | |||||
} | |||||
#header a | |||||
{ | |||||
color: white; | |||||
text-decoration: none; | |||||
padding: 0.5em 1em 0.5em 1em; | |||||
} | |||||
#title | |||||
{ | |||||
color: #433729; | |||||
} | |||||
iframe | |||||
{ | |||||
width: 720px; | |||||
height: 720px; | |||||
} | |||||
html | |||||
{ | |||||
font-family: sans-serif; | |||||
} | |||||
body | |||||
{ | |||||
line-height: 1.5em; | |||||
} | |||||
body | |||||
{ | |||||
background: #FAFAFA; | |||||
} | |||||
table | |||||
{ | |||||
border-collapse: collapse; | |||||
width: 100%; | |||||
} | |||||
table, th, td | |||||
{ | |||||
border: 1px solid #aaa; | |||||
padding: 0.5em; | |||||
margin-top: 0.5em; | |||||
margin-bottom: 0.5em; | |||||
} | |||||
code, pre | |||||
{ | |||||
font-family: monospace, serif; | |||||
font-size: 1em; | |||||
color: #7f0a0c; | |||||
background: #f5f5f5; | |||||
white-space: pre-wrap; | |||||
} | |||||
.contents | |||||
{ | |||||
background: #FFFFFF; | |||||
width: 720px; | |||||
padding: 1em; | |||||
margin-top: 2em; | |||||
margin-bottom: 2em; | |||||
border: 1px solid #E0E0E0; | |||||
text-align: left; | |||||
color: #444; | |||||
} | |||||
</style> | |||||
<title> | |||||
PSKOV - Opensource Game Studio static site generator | |||||
</title> | |||||
</head> | |||||
<body> | |||||
<div id="header"> | |||||
<strong id="title">PSKOV</strong> | |||||
<a href="index.html">Tool</a> | |||||
<a href="education.html">Education</a> | |||||
</div> | |||||
<center><h1> | |||||
PSKOV_ITEM_TITLE | |||||
</h1></center> | |||||
<center><div class="contents"> | |||||
PSKOV_ITEM_CONTENTS | |||||
</div></center> | |||||
<script type="text/javascript"> | |||||
</script> | |||||
</body> | |||||
</html> | |||||
@@ -0,0 +1 @@ | |||||
../pskov-201905.html |
@@ -1,411 +1,4 @@ | |||||
<!DOCTYPE html> | <!DOCTYPE html> | ||||
<html> | <html> | ||||
<meta charset="utf-8"> | |||||
<head> | |||||
<style> | |||||
table | |||||
{ | |||||
border-collapse: collapse; | |||||
} | |||||
table, th, td | |||||
{ | |||||
border: 1px solid #aaa; | |||||
padding: 0.5em; | |||||
margin-top: 0.5em; | |||||
margin-bottom: 0.5em; | |||||
} | |||||
.error | |||||
{ | |||||
color: red; | |||||
} | |||||
.section | |||||
{ | |||||
text-align: center; | |||||
font-weight: bold; | |||||
} | |||||
</style> | |||||
</head> | |||||
<body> | |||||
<table> | |||||
<tr> | |||||
<td colspan="2" class="section"> | |||||
<a href="http://opengamestudio.org/lfsa">Local file system access</a> | |||||
</td> | |||||
</tr> | |||||
<tr> | |||||
<td>Path:</td> | |||||
<td id="lfsaPath">Updating...</td> | |||||
</tr> | |||||
<tr> | |||||
<td colspan="2" class="section"> | |||||
Configuration | |||||
<button type="button" onclick="window.pskovTool.saveCfg()">Save</button> | |||||
</td> | |||||
</tr> | |||||
<tr> | |||||
<td>Input directory:</td> | |||||
<td><input id="input"></input> | |||||
</tr> | |||||
<tr> | |||||
<td>News item template:</td> | |||||
<td><input id="item"></input> | |||||
</tr> | |||||
<tr> | |||||
<td>News preview template:</td> | |||||
<td><input id="preview"></input> | |||||
</tr> | |||||
<tr> | |||||
<td>Index template:</td> | |||||
<td><input id="index"></input> | |||||
</tr> | |||||
<tr> | |||||
<td>Output directory:</td> | |||||
<td><input id="output"></input> | |||||
</tr> | |||||
<tr> | |||||
<td colspan="2" class="section">Log</td> | |||||
</tr> | |||||
<tr> | |||||
<td id="log" colspan="2"></td> | |||||
</tr> | |||||
</table> | |||||
<script type="text/javascript"> | |||||
<!-- LFSA.js --> | |||||
// LFSA class to communicate with local-file-system-access instance. | |||||
function LFSA() | |||||
{ | |||||
this.host = "http://127.0.0.1"; | |||||
this.port = 8000; | |||||
} | |||||
LFSA.prototype.get = function(url, successCallback, failureCallback) | |||||
{ | |||||
var req = new XMLHttpRequest(); | |||||
req.addEventListener( | |||||
"load", | |||||
function() | |||||
{ | |||||
//console.log("get.successCallback.responseText: '" + this.responseText + "'"); | |||||
successCallback(this.responseText); | |||||
} | |||||
); | |||||
req.addEventListener( | |||||
"error", | |||||
function() | |||||
{ | |||||
failureCallback(); | |||||
} | |||||
); | |||||
req.addEventListener( | |||||
"abort", | |||||
function() | |||||
{ | |||||
failureCallback(); | |||||
} | |||||
); | |||||
const prefix = this.host + ":" + this.port; | |||||
const addr = prefix + url; | |||||
//console.log("GET addr: '" + addr + "'"); | |||||
req.open("GET", addr); | |||||
req.send(); | |||||
} | |||||
LFSA.prototype.requestPath = function(successCallback, failureCallback) | |||||
{ | |||||
this.get("/path", successCallback, failureCallback); | |||||
} | |||||
LFSA.prototype.post = function(url, data, successCallback, failureCallback) | |||||
{ | |||||
var req = new XMLHttpRequest(); | |||||
req.addEventListener( | |||||
"load", | |||||
function() | |||||
{ | |||||
console.log("POST.successCallback.responseText: '" + this.responseText + "'"); | |||||
successCallback(this.responseText); | |||||
} | |||||
); | |||||
req.addEventListener( | |||||
"error", | |||||
function() | |||||
{ | |||||
failureCallback(); | |||||
} | |||||
); | |||||
req.addEventListener( | |||||
"abort", | |||||
function() | |||||
{ | |||||
failureCallback(); | |||||
} | |||||
); | |||||
const prefix = this.host + ":" + this.port; | |||||
const addr = prefix + url; | |||||
console.log("POST addr: '" + addr + "'"); | |||||
req.open("POST", addr); | |||||
req.send(data); | |||||
} | |||||
LFSA.prototype.requestFileList = function(dir, successCallback, failureCallback) | |||||
{ | |||||
this.post( | |||||
"/list", | |||||
dir, | |||||
function(response) | |||||
{ | |||||
var json = JSON.parse(response); | |||||
successCallback(json); | |||||
}, | |||||
failureCallback | |||||
); | |||||
} | |||||
LFSA.prototype.requestFile = function(path, successCallback, failureCallback) | |||||
{ | |||||
this.post( | |||||
"/read", | |||||
path, | |||||
successCallback, | |||||
failureCallback | |||||
); | |||||
} | |||||
LFSA.prototype.saveFile = function(path, contents, successCallback, failureCallback) | |||||
{ | |||||
var data = {}; | |||||
data["path"] = path; | |||||
data["contents"] = btoa(contents); | |||||
var datastr = JSON.stringify(data); | |||||
this.post( | |||||
"/write", | |||||
datastr, | |||||
successCallback, | |||||
failureCallback | |||||
); | |||||
} | |||||
<!-- Reusable --> | |||||
function fileExists(fileName, fileList) | |||||
{ | |||||
for (var id in fileList) | |||||
{ | |||||
var file = fileList[id]; | |||||
if (file.path === fileName) | |||||
{ | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
// Topic: Create GUID / UUID in JavaScript? | |||||
// Source: https://stackoverflow.com/a/2117523 | |||||
function generateUUID() | |||||
{ | |||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace( | |||||
/[xy]/g, | |||||
function(c) | |||||
{ | |||||
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); | |||||
return v.toString(16); | |||||
} | |||||
); | |||||
} | |||||
function LOG(message) | |||||
{ | |||||
var log = document.getElementById("log"); | |||||
var now = new Date(); | |||||
log.innerHTML += now.toISOString() + " " + message + "<br>"; | |||||
} | |||||
function parseINI(contents) | |||||
{ | |||||
var cfg = { }; | |||||
var lines = contents.split(/\r\n|\r|\n/); | |||||
for (var id in lines) | |||||
{ | |||||
var line = lines[id]; | |||||
var keyAndValue = line.split(/=/); | |||||
if (keyAndValue.length == 2) | |||||
{ | |||||
var key = keyAndValue[0].trim(); | |||||
var value = keyAndValue[1].trim(); | |||||
cfg[key] = value; | |||||
} | |||||
} | |||||
return cfg; | |||||
} | |||||
// ReporterSubscription class. | |||||
function ReporterSubscription(id, callback, reporter) | |||||
{ | |||||
this.id = id; | |||||
this.callback = callback; | |||||
this.reporter = reporter; | |||||
} | |||||
// Reporter class. | |||||
function Reporter(name) | |||||
{ | |||||
this.name = | |||||
(typeof name !== "undefined") ? | |||||
name : | |||||
""; | |||||
this.subscriptions = []; | |||||
} | |||||
Reporter.prototype.report = function() | |||||
{ | |||||
for (var id in this.subscriptions) | |||||
{ | |||||
var subscription = this.subscriptions[id]; | |||||
subscription.callback(); | |||||
} | |||||
} | |||||
Reporter.prototype.subscribe = function(callback) | |||||
{ | |||||
var id = generateUUID(); | |||||
var subscription = new ReporterSubscription(id, callback, this); | |||||
this.subscriptions.push(subscription); | |||||
return subscription; | |||||
} | |||||
<!-- Tool.js --> | |||||
// Tool class. | |||||
function Tool() | |||||
{ | |||||
this.lfsa = new LFSA(); | |||||
this.cfgExists = false; | |||||
this.cfgExistsChanged = new Reporter(); | |||||
this.cfg = {}; | |||||
this.cfgChanged = new Reporter(); | |||||
this.cfgSaved = new Reporter(); | |||||
} | |||||
// Tool's startup sequence. | |||||
Tool.prototype.run = function() | |||||
{ | |||||
var self = this; | |||||
this.refreshLFSAPath(); | |||||
this.checkCfgExistence(); | |||||
this.cfgExistsChanged.subscribe(function(){ | |||||
LOG("cfgExistsChanged. cfgExists: '" + self.cfgExists + "'"); | |||||
}); | |||||
this.cfgExistsChanged.subscribe(function(){ | |||||
self.readCfg(); | |||||
}); | |||||
this.cfgChanged.subscribe(function(){ | |||||
LOG("cfgChanged. cfg: '" + self.cfg + "'"); | |||||
}); | |||||
this.cfgChanged.subscribe(function(){ | |||||
self.displayCfg(); | |||||
}); | |||||
this.cfgSaved.subscribe(function(){ | |||||
self.readCfg(); | |||||
}); | |||||
} | |||||
Tool.prototype.refreshLFSAPath = function() | |||||
{ | |||||
var lfsaPath = document.getElementById("lfsaPath"); | |||||
var success = function(response) | |||||
{ | |||||
lfsaPath.innerHTML = response; | |||||
} | |||||
var failure = function() | |||||
{ | |||||
lfsaPath.innerHTML = "<span class='error'>Error</span>"; | |||||
} | |||||
this.lfsa.requestPath(success, failure); | |||||
} | |||||
Tool.prototype.checkCfgExistence = function() | |||||
{ | |||||
var self = this; | |||||
var success = function(fileList) | |||||
{ | |||||
var cfgExists = fileExists("cfg", fileList); | |||||
if (!cfgExists) | |||||
{ | |||||
LOG("ERROR `cfg` file does not exist"); | |||||
return; | |||||
} | |||||
// Report. | |||||
self.cfgExists = true; | |||||
self.cfgExistsChanged.report(); | |||||
} | |||||
var failure = function() | |||||
{ | |||||
LOG("ERROR Could not check if `cfg` exists"); | |||||
} | |||||
this.lfsa.requestFileList("", success, failure); | |||||
} | |||||
Tool.prototype.readCfg = function() | |||||
{ | |||||
var self = this; | |||||
var success = function(contents) | |||||
{ | |||||
self.cfg = parseINI(contents); | |||||
self.cfgChanged.report(); | |||||
} | |||||
var failure = function() | |||||
{ | |||||
LOG("ERROR Could not read `cfg` file"); | |||||
} | |||||
this.lfsa.requestFile("cfg", success, failure); | |||||
} | |||||
Tool.prototype.displayCfg = function() | |||||
{ | |||||
var input = document.getElementById("input"); | |||||
input.value = this.cfg["input"]; | |||||
var item = document.getElementById("item"); | |||||
item.value = this.cfg["item"]; | |||||
var preview = document.getElementById("preview"); | |||||
preview.value = this.cfg["preview"]; | |||||
var index = document.getElementById("index"); | |||||
index.value = this.cfg["index"]; | |||||
var output = document.getElementById("output"); | |||||
output.value = this.cfg["output"]; | |||||
} | |||||
Tool.prototype.saveCfg = function() | |||||
{ | |||||
// Compose cfg file to save. | |||||
var cfgFile = ""; | |||||
var input = document.getElementById("input"); | |||||
cfgFile += "input = " + input.value + "\n"; | |||||
var item = document.getElementById("item"); | |||||
cfgFile += "item = " + item.value + "\n"; | |||||
var preview = document.getElementById("preview"); | |||||
cfgFile += "preview = " + preview.value + "\n"; | |||||
var index = document.getElementById("index"); | |||||
cfgFile += "index = " + index.value + "\n"; | |||||
var output = document.getElementById("output"); | |||||
cfgFile += "output = " + output.value + "\n"; | |||||
// Save file. | |||||
var self = this; | |||||
var success = function() | |||||
{ | |||||
self.cfgSaved.report(); | |||||
} | |||||
var failure = function() | |||||
{ | |||||
LOG("ERROR Could not save `cfg` file"); | |||||
} | |||||
this.lfsa.saveFile("cfg", cfgFile, success, failure); | |||||
} | |||||
<!-- Startup --> | |||||
window.pskovTool = new Tool(); | |||||
window.pskovTool.run() | |||||
</script> | |||||
</body> | |||||
<meta http-equiv="refresh" content="0; URL='en/index.html'"/> | |||||
</html> | </html> |