Add entire stuff
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 277 B |
After Width: | Height: | Size: 779 B |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 141 B |
After Width: | Height: | Size: 134 B |
After Width: | Height: | Size: 262 B |
After Width: | Height: | Size: 126 B |
After Width: | Height: | Size: 172 B |
After Width: | Height: | Size: 546 B |
After Width: | Height: | Size: 171 B |
After Width: | Height: | Size: 233 B |
|
@ -0,0 +1,37 @@
|
||||||
|
import PIL
|
||||||
|
import random
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
size=(60,40)
|
||||||
|
dirtlevel=3*16
|
||||||
|
gravellevel=5*16
|
||||||
|
|
||||||
|
dirt=Image.open("default_dirt.png")
|
||||||
|
gravel=Image.open("default_gravel.png")
|
||||||
|
grass=Image.open("default_grass_side.png")
|
||||||
|
stone=Image.open("default_stone.png")
|
||||||
|
orechance=0.1
|
||||||
|
|
||||||
|
minerals=["gold","iron","copper","coal","diamond","mese","tin"]
|
||||||
|
minimgs=[]
|
||||||
|
|
||||||
|
for mineral in minerals:
|
||||||
|
minimgs.append(Image.open("default_mineral_"+mineral+".png").convert("RGBA"))
|
||||||
|
|
||||||
|
result=Image.new("RGBA",(size[0]*16,size[1]*16))
|
||||||
|
|
||||||
|
for x in range(0,size[0]*16,16):
|
||||||
|
for y in range(0,size[1]*16,16):
|
||||||
|
if (y <= dirtlevel):
|
||||||
|
result.paste(dirt,(x,y))
|
||||||
|
elif (y <= gravellevel):
|
||||||
|
result.paste(gravel,(x,y))
|
||||||
|
else:
|
||||||
|
result.paste(stone,(x,y))
|
||||||
|
r=random.random()
|
||||||
|
if (r < orechance):
|
||||||
|
i=int(round(random.random()*(len(minimgs)-1),0))
|
||||||
|
result.paste(minimgs[i],(x,y),minimgs[i])
|
||||||
|
if (y == 0):
|
||||||
|
result.paste(grass,(x,y),grass)
|
||||||
|
result.save("background.png")
|
|
@ -0,0 +1,100 @@
|
||||||
|
:root {
|
||||||
|
--selection-color: white;
|
||||||
|
--selection-bg: skyblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 120%;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.justify-content-center {
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
}
|
||||||
|
label.btn {
|
||||||
|
padding: 0.15rem 1rem;
|
||||||
|
}
|
||||||
|
::-moz-selection {
|
||||||
|
color: var(--selection-color);
|
||||||
|
background: var(--selection-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
color: var(--selection-color);
|
||||||
|
background: var(--selection-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.col-md-4, div.col-lg {
|
||||||
|
padding: 10px;
|
||||||
|
background: rgba(255, 255, 255, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.position-fixed {
|
||||||
|
position:fixed;
|
||||||
|
padding:0;
|
||||||
|
margin:0;
|
||||||
|
overflow-y: scroll;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
z-index: 1000;
|
||||||
|
width:17.5%;
|
||||||
|
height:80%;
|
||||||
|
background: rgba(255, 255, 255, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.affix {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
/*overflow-x: scroll;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
li.a.nav-link {
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.a.nav-link h1, li.a.nav-link h1,h2,h3,h4,h5,h6 {
|
||||||
|
margin-top:0px;
|
||||||
|
margin-bottom:0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.nav-link:active, a.nav-link.active {
|
||||||
|
background-color: grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.nav-link h1 {
|
||||||
|
font-size:120%;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.nav-link h2 {
|
||||||
|
margin-left: 30px;
|
||||||
|
text-decoration: underline;
|
||||||
|
font-size:110%
|
||||||
|
}
|
||||||
|
|
||||||
|
a.nav-link h3 {
|
||||||
|
margin-left: 60px;
|
||||||
|
font-size: 100%;
|
||||||
|
text-decoration:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.nav-link h4 {
|
||||||
|
margin-left: 90px;
|
||||||
|
font-size: 75%
|
||||||
|
}
|
||||||
|
|
||||||
|
a.nav-link h5 {
|
||||||
|
margin-left: 120px;
|
||||||
|
font-size: 75%
|
||||||
|
}
|
||||||
|
|
||||||
|
a.nav-link h6 {
|
||||||
|
margin-left: 150px;
|
||||||
|
font-size: 75%
|
||||||
|
}
|
|
@ -0,0 +1,228 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
print("**Minetest lua_api.txt Markdown parser - mt-lua-api-pyparse - converts Markdown to HTML document with navigation**")
|
||||||
|
print("**Written by Lars Müller alias LMD in Python 3.5 - requires Python >= 3.2**")
|
||||||
|
print("**Furthermore, this script has to be in the same folder as generate_bg.py, template.html, jumbotron.css, and the images taken from Minetest Game.**")
|
||||||
|
print("**The images taken from Minetest Game are licensed under CC-BY-SA 3.0, credits go to the Minetest Artists.**")
|
||||||
|
from cgi import html
|
||||||
|
import urllib.request as url
|
||||||
|
import urllib.parse as parse
|
||||||
|
print("**Generating underground Minetest scene...**")
|
||||||
|
exec(open("generate_bg.py","r").read()) # IMPORTANT - GENERATES THE BEAUTIFUL BACKGROUND !
|
||||||
|
print("**...finished generating scene.**")
|
||||||
|
import math
|
||||||
|
|
||||||
|
# This python script grabs the newest lua_api.txt from Minetest GitHub repo and converts it to HTML, plus adding some bookmarks & css
|
||||||
|
# So mainly MD -> HTML. Written by me to improve my rusty Python skills.
|
||||||
|
# © Lars Müller @appguru.eu
|
||||||
|
|
||||||
|
print("**Grabbing newest lua_api.txt, make sure you have an internet connection...**")
|
||||||
|
|
||||||
|
link = "https://raw.githubusercontent.com/minetest/minetest/master/doc/lua_api.txt" # Grab newest lua_api.txt
|
||||||
|
f = url.urlopen(link)
|
||||||
|
markdown = parse.unquote(str(f.read().decode("ascii","ignore"))) # Read & convert
|
||||||
|
|
||||||
|
print("**...grabbed newest lua_api.txt from official Minetest repository.**")
|
||||||
|
|
||||||
|
liste=0 # Which sublist we are in right NOW
|
||||||
|
headers=[] # Stores all the headers + IDs
|
||||||
|
ID=0 # Stores header ID counter
|
||||||
|
|
||||||
|
print("**Starting parsing...**")
|
||||||
|
|
||||||
|
def parse_markdown(string,lco=0,parent=False): # PARSES A SINGLE LINE !
|
||||||
|
global liste
|
||||||
|
global ID
|
||||||
|
global headers
|
||||||
|
suffix=""
|
||||||
|
prefix=""
|
||||||
|
if string.find("*") != -1 and (string[0:string.find("*")].count(" ") == string.find("*")) and not (parent or string[string.find("*")+1]=="*"): # LISTS
|
||||||
|
#print("Liste : "+str(liste)+", lco : "+str(lco))
|
||||||
|
prevliste=liste
|
||||||
|
liste=1+int(string.find("*")/3)
|
||||||
|
if (liste > prevliste):
|
||||||
|
for i in range(0,liste-prevliste):
|
||||||
|
prefix+="<ul>"
|
||||||
|
elif (liste < prevliste):
|
||||||
|
for i in range(0,prevliste-liste):
|
||||||
|
prefix+="</ul>"
|
||||||
|
return prefix+"<li>"+parse_markdown(string[string.find("*")+2:],lco=lco+2,parent=True)+"</li>"+suffix
|
||||||
|
if not parent and liste != 0:
|
||||||
|
for i in range(0,liste):
|
||||||
|
prefix+="</ul>"
|
||||||
|
liste=0
|
||||||
|
if (len(string)) == 0:
|
||||||
|
return prefix+"<br>"
|
||||||
|
if (string[-2:]==" "):
|
||||||
|
return prefix+parse_markdown(string[:-2])+"<br>"
|
||||||
|
if (string[0]=="#"):
|
||||||
|
space=string.find(" ")
|
||||||
|
c=string[0:space-1].count("#")
|
||||||
|
if (space-1==c):
|
||||||
|
ID+=1
|
||||||
|
c+=1
|
||||||
|
temp="<h"+str(c)+'>'+parse_markdown(string[space+1:])+"</h"+str(c)+">"
|
||||||
|
headers.append((temp,str(ID)))
|
||||||
|
temp=prefix+temp[:3]+' id="gheader'+str(ID)+'"'+temp[3:]
|
||||||
|
return temp
|
||||||
|
bold=False
|
||||||
|
boldamount=string.count("**")
|
||||||
|
ba=0
|
||||||
|
italic=False
|
||||||
|
code=False
|
||||||
|
link=False
|
||||||
|
link2=False
|
||||||
|
codeamount=string.count("`")
|
||||||
|
ca=0
|
||||||
|
startindex=0
|
||||||
|
tags=[]
|
||||||
|
currentstring=""
|
||||||
|
index=-1
|
||||||
|
while index in range(-1,len(string)-1):
|
||||||
|
index+=1
|
||||||
|
appendtag=False
|
||||||
|
c=string[index]
|
||||||
|
if c == "`":
|
||||||
|
if ca < codeamount:
|
||||||
|
code=not code
|
||||||
|
ca=ca+1
|
||||||
|
if not code: # We have just closed a code fragment
|
||||||
|
tags.append((string[startindex+1:index],"code"))
|
||||||
|
continue
|
||||||
|
else: # A new one starts : SAVE INDEX + SAVE CURRENT STRING !
|
||||||
|
appendtag=True
|
||||||
|
elif not code:
|
||||||
|
if c == "*" and len(string) > index+1 and string[index+1] == "*":
|
||||||
|
if ba < boldamount:
|
||||||
|
index+=1
|
||||||
|
bold=not bold
|
||||||
|
ba=ba+1
|
||||||
|
if not bold: # We have just closed a code fragment
|
||||||
|
tags.append((string[startindex+1:index-1],"bold"))
|
||||||
|
continue
|
||||||
|
else: # A new one starts : SAVE INDEX + SAVE CURRENT STRING !
|
||||||
|
appendtag=True
|
||||||
|
elif c == "<" and not link:
|
||||||
|
appendtag=True
|
||||||
|
link=True
|
||||||
|
elif c == ">" and link:
|
||||||
|
link=False
|
||||||
|
tags.append((string[startindex+1:index],"link"))
|
||||||
|
continue
|
||||||
|
elif c == "[":
|
||||||
|
breakit=False
|
||||||
|
text=""
|
||||||
|
for i in range(index+2,len(string)-3):
|
||||||
|
c2=string[i]
|
||||||
|
if (c2 == "]"):
|
||||||
|
text=string[index+1:i]
|
||||||
|
if string[i+1]=="(":
|
||||||
|
for j in range(i+3,len(string)):
|
||||||
|
c3=string[j]
|
||||||
|
if (c3 == ")"):
|
||||||
|
breakit=True
|
||||||
|
tags.append((text,"link",string[i+2:j]))
|
||||||
|
index=j+1
|
||||||
|
break
|
||||||
|
if breakit:
|
||||||
|
continue
|
||||||
|
if appendtag:
|
||||||
|
tags.append((currentstring,"normal"))
|
||||||
|
currentstring=""
|
||||||
|
startindex=index
|
||||||
|
continue
|
||||||
|
if not bold and not code and not link and not link2:
|
||||||
|
currentstring+=c
|
||||||
|
if len(currentstring) != 0:
|
||||||
|
tags.append((currentstring,"normal"))
|
||||||
|
result=""
|
||||||
|
for tag in tags:
|
||||||
|
string=tag[0]
|
||||||
|
p=""
|
||||||
|
s=""
|
||||||
|
if tag[1]=="code":
|
||||||
|
p,s="<code>","</code>"
|
||||||
|
elif tag[1]=="bold":
|
||||||
|
p,s="<b>","</b>"
|
||||||
|
elif tag[1]=="link":
|
||||||
|
if len(tag) == 2:
|
||||||
|
if tag[0][0:4] == "http": # CHECK LINKS !
|
||||||
|
p,s='<a href="'+tag[0]+'">',"</a>"
|
||||||
|
else:
|
||||||
|
p,s='<a href="'+tag[2]+'">',"</a>"
|
||||||
|
elif tag[1]=="italic":
|
||||||
|
p,s="<em>","</em>"
|
||||||
|
result+=p+html.escape(string)+s
|
||||||
|
return prefix+"<p>"+result+"</p>"
|
||||||
|
|
||||||
|
def parse_md(string): # Parse line by line
|
||||||
|
lines=string.split("\n")
|
||||||
|
ret=""
|
||||||
|
for i in range(len(lines)-1,0,-1): # Convert alternate header writings(underlines)
|
||||||
|
if abs(len(lines[i-1])-len(lines[i])) < 3:
|
||||||
|
if lines[i].count("=")==len(lines[i]):
|
||||||
|
lines[i]=""
|
||||||
|
lines[i-1]="# "+lines[i-1]
|
||||||
|
elif lines[i].count("-")==len(lines[i]):
|
||||||
|
lines[i]=""
|
||||||
|
lines[i-1]="## "+lines[i-1]
|
||||||
|
i=0
|
||||||
|
for line in lines:
|
||||||
|
ret+=parse_markdown(line)
|
||||||
|
i=i+1
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def code(): # Parse multi-line code fragments
|
||||||
|
global markdown
|
||||||
|
last=-1
|
||||||
|
i=0
|
||||||
|
stuff=[]
|
||||||
|
while (i < len(markdown)):
|
||||||
|
if markdown[i:i+3]=="`"*3:
|
||||||
|
i=i+3
|
||||||
|
if last < 0:
|
||||||
|
start=-(last+1)
|
||||||
|
last=i
|
||||||
|
stuff.append((markdown[start:last-3],False))
|
||||||
|
else:
|
||||||
|
stuff.append((markdown[last:i-3],True))
|
||||||
|
last=-i-1
|
||||||
|
i=i+1
|
||||||
|
|
||||||
|
start=-(last+1)
|
||||||
|
stuff.append((markdown[start:],False))
|
||||||
|
#print(stuff)
|
||||||
|
|
||||||
|
markdown=""
|
||||||
|
for s in stuff:
|
||||||
|
if s[1]:
|
||||||
|
markdown+="<code>"+s[0]+"</code>"
|
||||||
|
else:
|
||||||
|
markdown+=parse_md(s[0])
|
||||||
|
|
||||||
|
code()
|
||||||
|
|
||||||
|
print("**...finished parsing.**")
|
||||||
|
|
||||||
|
nav=""
|
||||||
|
|
||||||
|
print("**Creating content table...**")
|
||||||
|
|
||||||
|
for header in headers:
|
||||||
|
nav+="""<li><a class="nav-link" href="#gheader"""+header[1]+"""">"""+header[0]+"""</a></li>""" # Create navbar
|
||||||
|
|
||||||
|
print("**...finished creating content table. "+str(len(headers))+" Headers are included.**")
|
||||||
|
|
||||||
|
# FINAL - THE FINAL HTML, BOOTSTRAP BASED DOCUMENT OUR HTML IS INSERTED IN
|
||||||
|
final = open('template.html', 'r').read()
|
||||||
|
print("**Inserting content into template file...**")
|
||||||
|
markdown=final.replace("<!--PLACESTUFF-->",markdown)
|
||||||
|
print("**...finished inserting content.**")
|
||||||
|
print("**Inserting content table into template file...**")
|
||||||
|
markdown=markdown.replace("<!--PLACENAV-->",nav)
|
||||||
|
print("**...finished inserting content table.**")
|
||||||
|
print("**Saving as lua_api.html...**")
|
||||||
|
file = open('lua_api.html', 'w') # SAVE AS lua_api.html
|
||||||
|
file.write(markdown)
|
||||||
|
print("**...saved.**")
|
||||||
|
print("**Parser finished successfully and lua_api.html was generated.**")
|
||||||
|
file.close()
|
|
@ -0,0 +1,58 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="Minetest Magic-CTF homepage">
|
||||||
|
<meta name="author" content="Lars Müller">
|
||||||
|
<link rel="icon" href="icon.png">
|
||||||
|
<div class="bg"></div>
|
||||||
|
|
||||||
|
<title>Minetest Lua API</title>
|
||||||
|
<link rel="shortcut icon" href="https://forum.minetest.net/styles/mt_v1/theme/images/favicon.ico">
|
||||||
|
|
||||||
|
<!-- Scripts and stylesheets -->
|
||||||
|
<!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> -->
|
||||||
|
<!-- Bootstrap core CSS -->
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
|
||||||
|
<link href="jumbotron.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<!-- Table of content -->
|
||||||
|
<div class="position-fixed">
|
||||||
|
<!--<div class="container">-->
|
||||||
|
<nav class="col-lg" id="contenttable">
|
||||||
|
<ul class="nav nav-pills nav-stacked affix" data-spy="affix" data-offset-top="205">
|
||||||
|
<!--PLACENAV-->
|
||||||
|
<!--Python script places stuff here-->
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<!--</div>-->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<body data-spy="scroll" data-target="#contenttable" data-offset="15">
|
||||||
|
|
||||||
|
<main role="main">
|
||||||
|
<div class="jumbotron" style="background: url('background.png') no-repeat center center fixed;background-size: 100% 100%;background-repeat: no-repeat;image-rendering:optimizeSpeed">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg">
|
||||||
|
<!--PLACESTUFF-->
|
||||||
|
<!--Python script places stuff here-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<footer class="container">
|
||||||
|
<p>Minetest is a free software game engine currently under development to create various games based on voxel gameplay, inspired by InfiniMiner, Minecraft, and the like. Minetest was originally created by Perttu Ahola (alias “celeron55”). </p>
|
||||||
|
<p>© Minetest Lua API Python Parser(mt-lua-api-pyparse) - Lars Müller</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</html>
|