-#!/usr/bin/python
+"""module constants: Standard constants for treecutter"""
+
valid_scripts = [".py", ".pl"]
PREFIXES = {
-#!/usr/bin/python
+"""module directory: scanning for content"""
+
import os
import fnmatch
-from lxml import etree
-import treecutter.constants as const
-from treecutter.docbook import Docbook
import re
from itertools import chain
+from treecutter.docbook import Docbook
+
class Directory:
"""Class containing the state of the directory with articles"""
self._basepath = re.compile(r"[/\w\._-]*/[\w-]+")
def translations(self, directory):
+ """look for translation files"""
paths = (self._cwd, directory)
- for dirname, dirnames, filenames in chain.from_iterable(
+ for dirname, _, filenames in chain.from_iterable(
os.walk(path) for path in paths
):
for filename in filenames:
return self._translations
def scan(self, draftflag, levelflag):
- for dirname, dirnames, filenames in os.walk(self._cwd):
+ """scan for xml files to include"""
+ for dirname, _, filenames in os.walk(self._cwd):
for filename in filenames:
if fnmatch.fnmatch(filename, "*.xml"):
file_ = os.path.join(dirname, filename)
draft = doc.status() == "draft"
level = doc.userlevel()
- # doc = etree.parse(file_)
- # title = doc.xpath(u'/db:article/db:info/db:title',namespaces=const.XPATH)
- # menu = doc.xpath(u'/db:article/db:info/db:titleabbrev',namespaces=const.XPATH)
- # draft = doc.xpath(u'/db:article[@status="draft"]',namespaces=const.XPATH)
if draft and draftflag:
draft = False
if title and menu and not draft and level <= levelflag:
self._tree.append(link)
def set(self):
+ """Return the simple set of the tree"""
return set(self._tree)
-#!/usr/bin/python
+"""module docbook: Docbook operations"""
import os
import subprocess
import re
+from time import time
+import getpass
+import gnupg
from lxml import etree
from lxml.builder import ElementMaker
from pkg_resources import resource_filename, resource_listdir
-from time import time
import treecutter.constants as const
from treecutter.image import Image
-# from treecutter.tools import warning
-
class Docbook:
"""Class representing a docbook document"""
self._dirname = os.path.dirname(self._filename)
def title(self):
+ """Find the title in the document"""
t = self._doc.xpath(
"/db:article/db:info/db:title", namespaces=const.XPATH
)
return (t, ta)
def status(self):
+ """Get the status from the document"""
status = self._doc.xpath(
"/db:article[@status]", namespaces=const.XPATH
)
return None
def role(self):
+ """Get the role from the document"""
art = self._doc.xpath("/db:article[@role]", namespaces=const.XPATH)
if art:
return art[0].get("role")
return "index"
def userlevel(self):
+ """Get the userlevel from the document"""
lvl = self._doc.xpath(
"/db:article[@userlevel]", namespaces=const.XPATH
)
return 0
def expand_imageobjects(self):
+ """Work through the image objects and adust them"""
cwd = os.getcwd()
db = ElementMaker(namespace=const.DB_NS, nsmap=const.NSMAP)
images = self._doc.xpath(
os.chdir(cwd)
def parse_xincludes(self):
+ """Parse xincludes and if needed execute scripts"""
cwd = os.getcwd()
for c in self._doc.xpath(
"//xi:include[@parse='text']", namespaces=const.XPATH
href = c.get("href")
alang = c.get("accept-language")
xpointer = c.get("xpointer")
- (p, ext) = os.path.splitext(href)
+ (_, ext) = os.path.splitext(href)
if ext in const.valid_scripts:
exe = []
script = os.path.join(
exe.append("lang=" + alang)
if xpointer:
exe.append("xptr=" + xpointer)
- if exe == []:
+ if not exe:
continue
- print(" executing %15s" % (href)),
+ print(f" executing {href:>15}", end="")
ts = time()
os.chdir(self._dirname)
- xml = subprocess.Popen(
+ with subprocess.Popen(
exe, stdout=subprocess.PIPE, stderr=subprocess.PIPE
- )
- (stdout, stderr) = xml.communicate()
+ ) as xml:
+ stdout, _ = xml.communicate()
# print xml.returnvalue
# if stderr:
# warning("%s : %s" % (" ".join(exe),stderr))
# exit
os.chdir(cwd)
te = time()
- print(" [%5.2f s] (%s)" % (round(te - ts, 2), xpointer))
+ print(f" [{te - ts:5.2f} s] ({xpointer})")
xstr = etree.fromstring(stdout)
# inserting the generated code and remove the xinclude reference
idp = c.getparent()
idp.remove(c)
def xinclude(self):
+ """xinclude handling"""
self._doc.xinclude()
def collect_links(self):
+ """Collect all links in the document"""
res = []
for r in self._doc.xpath(
"//db:link[@xlink:href]", namespaces=const.XPATH
if r.get("security") == "encrypt":
with open(rf, "rb") as f:
gpg = gnupg.GPG()
- status = gpg.encrypt_file(
+ gpg.encrypt_file(
f,
None,
passphrase=getpass.getpass(rf + " password:"),
return res
def collect_images(self):
+ """Collect all images of the document"""
res = []
for i in self._doc.xpath(
"//db:imagedata[@fileref]", namespaces=const.XPATH
return res
def collect_videos(self):
+ """Collect all videos of the document"""
res = []
for i in self._doc.xpath(
"//db:videodata[@fileref]", namespaces=const.XPATH
return res
def collect_forms(self):
+ """Collect all forms of the document"""
res = []
for i in self._doc.xpath(
"//html:form[@action]", namespaces=const.XPATH
):
- pyscript = re.split("\.py", i.get("action"), 1)[0] + ".py"
+ pyscript = re.split(r"\.py", i.get("action"), 1)[0] + ".py"
im = os.path.join(self._dirname, pyscript)
if os.path.isfile(im):
res.append(im)
return res
def tostring(self):
+ """Docbook to string"""
return etree.tostring(self._doc, encoding="UTF-8", pretty_print=False)
def xslt(self, transform):
+ """XSLT transform"""
return etree.tostring(transform(self._doc))
def clean(self):
+ """cleaning xml"""
+
def recursively_empty(e):
if e.text:
return False
return all((recursively_empty(c) for c in e.iterchildren()))
context = etree.iterwalk(self._doc)
- for action, elem in context:
+ for _, elem in context:
parent = elem.getparent()
if recursively_empty(elem):
parent.remove(elem)
-#!/usr/bin/python
+"""module image: image tools"""
+
+import os
+import subprocess
from PIL import Image as PIL_Image
from libxmp import consts
from libxmp import XMPFiles
-from treecutter.tools import sizeof_fmt
-import os
-import subprocess
-import errno
+from treecutter.tools import sizeof_fmt
class Image:
self._format = {}
def filename(self):
+ """Return filename"""
return self._filename
def infostr(self):
+ """Get infostring"""
im = PIL_Image.open(self._filename)
w, d = im.size
im.close()
byte = os.path.getsize(self._filename)
- return "[%dx%d (%s)]" % (w, d, sizeof_fmt(byte))
+ return f"[{w}x{d} ({sizeof_fmt(byte)})]"
def resize(self, x, y, pad=0):
+ """Resize image"""
size = (x, y)
outfile, ext = os.path.splitext(self._filename)
- outfile = "%s.%dx%d%s" % (outfile, size[0], size[1], ext)
+ outfile = f"{outfile}.{size[0]}x{size[1]}{ext}"
if not os.path.exists(outfile):
im = PIL_Image.open(self._filename)
im.thumbnail(size, PIL_Image.LANCZOS)
+ str(retcode)
+ "]"
)
- exit
else:
cmd = [
"exiftool",
+ str(retcode)
+ "]"
)
- exit
xmpfile.close_file()
self._format[size] = outfile
return outfile
def generated(self):
+ """Mark generated files in XMP"""
xmpfile = XMPFiles(file_path=self._filename)
xmp = xmpfile.get_xmp()
if not xmp:
return cr == "treecutter"
def thumbnail(self):
+ """Create thumbnail"""
return self.resize(50, 50, 1)
def slider(self):
+ """Create website slider"""
return self.resize(700, 438, 1)
def caption(self):
+ """Add captions"""
cap = "Beskrivning saknas"
xmpfile = XMPFiles(file_path=self._filename)
xmp = xmpfile.get_xmp()
-#!/usr/bin/python
+"""link module: module handling the website links"""
+
import re
import glob
from treecutter.page import Page
self._link = link
# find the representations of the link.
self._pages = []
- self._langregexp = re.compile(".*\.(\w\w)\.xml")
+ self._langregexp = re.compile(r".*\.(\w\w)\.xml")
path = link
if self._link[-1] == "/":
path = path + "index"
- lang = self._scan_languages(path)
- for l in lang:
- self._pages.append(Page(self, l))
+ languages = self._scan_languages(path)
+ for lang in languages:
+ self._pages.append(Page(self, lang))
- def add_page(self, l):
- self._pages.append(Page(self, l))
+ def add_page(self, lang):
+ """Add webpage to the page collection"""
+ self._pages.append(Page(self, lang))
def _scan_languages(self, path):
- lang = []
- for l in glob.glob("." + path + "*.xml"):
- langcode = self._langregexp.search(l).group(1)
- lang.append((langcode, l))
- return lang
+ """Scan availible languages"""
+ languages = []
+ for lang in glob.glob("." + path + "*.xml"):
+ langcode = self._langregexp.search(lang).group(1)
+ languages.append((langcode, lang))
+ return languages
def link(self):
+ """Return internal link"""
return self._link
def prepare(self):
+ """Setup the pages"""
for page in self._pages:
page.prepare()
def languages(self):
+ """Return availible languages"""
p = []
for page in self._pages:
p.append(page.language())
return p
def render(self, transform):
+ """Render the page collection"""
for page in self._pages:
page.render(transform)
def template(self, sitemap, style, tdir, subdir):
+ """Template the page collection"""
for page in self._pages:
page.template(sitemap, style, tdir, subdir)
def page(self, lang):
+ """Return page in language lang"""
for page in self._pages:
if page.language() == lang:
return page
return None
def resources(self):
+ """Return page resources"""
res = set()
for page in self._pages:
res = res.union(page.resources())
-#!/usr/bin/python
+"""Main module: main function module to start the core."""
+
import os
from time import time
import argparse
+import sys
from treecutter.directory import Directory
from treecutter.sitemap import Sitemap
from treecutter.tools import translate
def main():
-
+ """Runs the treecutter application"""
parser = argparse.ArgumentParser(
description="Process docbook article tree."
)
dir_ = Directory()
t1 = time()
totrans = dir_.translations(args.style)
- print("Translate [%d] : [" % (len(totrans))),
+ print(f"Translate [{len(totrans)}] : [", end="")
translate(totrans)
print("]")
t2 = time()
- print("Translate[%5.2f s]" % (round(t2 - t1, 2)))
-
+ print(f"Translate[{t2 - t1:5.2f} s]")
sitemap = Sitemap(args)
# Scanning current directory and subdirectory for docbook articles
sitemap.write_map()
dirsitemap = Sitemap(args)
- for l in sitemap.linklist():
- if l in dirset:
- dirsitemap.add_link(l)
+ for link in sitemap.linklist():
+ if link in dirset:
+ dirsitemap.add_link(link)
# Generate a pygraphviz image of the site (TODO: currently not used)
dirsitemap.graph()
t1 = time()
dirsitemap.publish()
t2 = time()
- print("Publish [%5.2f s]" % (round(t2 - t1, 2)))
- print("Total [%5.2f s]" % (round(t2 - ts, 2)))
+ print(f"Publish [{t2 - t1:5.2f} s]")
+ print(f"Total [{t2 - ts:5.2f} s]")
return 0
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
+"""Page module: representing a page"""
+
import os
-import subprocess
-import tempfile
-import re
-import getpass
-import gnupg
import codecs
-from lxml import etree
-from lxml.builder import ElementMaker
-
-# from jinja2 import Template
import jinja2
-from time import time
-import treecutter.constants as const
+
from treecutter.docbook import Docbook
from treecutter.tools import mkdir_p
class Page:
"""Class representing a version of a webpage"""
+ # pylint: disable=too-many-instance-attributes
+ # not yet clear if this can be cut down to 7
def __init__(self, link, page):
self._link = link
self._file = page[1]
self._status = None
def language(self):
+ """Returns language of the page"""
return self._lang
def resources(self):
+ """Return the resources for the page (images etc.)"""
return set(self._resources)
def menu(self):
+ """Menu item of the page"""
return self._menu
def set_article(self, art):
+ """Set the article to be rendered for the page"""
self._rendered_article = art
def prepare(self):
+ """Collect all collaterals to the page"""
self._doc = Docbook(self._file)
(self._title, self._menu) = self._doc.title()
self._doc.expand_imageobjects()
self._resources = doc + img + vid + form
def render(self, transform):
+ """Render the page to xhtml5"""
self._rendered_article = self._doc.xslt(transform["xhtml5"])
def template(self, sitemap, style, tdir, subdir):
- htmlmenu = sitemap.gen_menu(self._lang, None, "links")
- levelmenu = sitemap.gen_menu(self._lang, self, "tree")
- langmenu = sitemap.lang_menu(self._lang, self._link)
- article = self._rendered_article
- templateLoader = jinja2.FileSystemLoader(searchpath="/")
- templateEnv = jinja2.Environment(loader=templateLoader)
-
- templateVars = {
+ """Template the page to html"""
+
+ templateloader = jinja2.FileSystemLoader(searchpath="/")
+ templateenv = jinja2.Environment(loader=templateloader)
+
+ templatevars = {
"title": self._title,
- "menu": htmlmenu,
- "article": article,
- "levelmenu": levelmenu,
- "langmen": langmenu,
+ "menu": sitemap.gen_menu(self._lang, None, "links"),
+ "article": self._rendered_article,
+ "levelmenu": sitemap.gen_menu(self._lang, self, "tree"),
+ "langmen": sitemap.lang_menu(self._lang, self._link),
"subdir": subdir,
}
- s = style
- t = s + self._template + "." + self._lang + ".html.tmpl"
- template = templateEnv.get_template(t)
- templateout = template.render(templateVars)
+ t = style + self._template + "." + self._lang + ".html.tmpl"
+ template = templateenv.get_template(t)
+ templateout = template.render(templatevars)
outfile = tdir + "html".join(self._file.rsplit("xml", 1))
mkdir_p(os.path.dirname(outfile))
- out = codecs.open(outfile, "w", "utf-8")
- out.write(templateout)
- out.close()
+ with codecs.open(outfile, "w", "utf-8") as out:
+ out.write(templateout)
-#!/usr/bin/python
+"""module sitemap: generate sitemap and structure"""
+
import os
import codecs
import re
import shutil
-import sys
import gettext
import tempfile
+from time import time
from lxml import etree
from lxml.builder import ElementMaker
-from time import time
-from treecutter import constants as const
+
from treecutter.trie import Trie
from treecutter.link import Link
from treecutter.tools import (
self._tranlang = {}
self._tmptarget = tempfile.mkdtemp() + "/"
- # The sitemap uses a trie structure to keep track of links
- # A link represents the path to the document and the link
- # representing the text on the site.
- # A link can have several pages in different languages.
def add_link(self, link):
+ """The sitemap uses a trie structure to keep track of links
+ A link represents the path to the document and the link
+ representing the text on the site.
+ A link can have several pages in different languages."""
tokens = list(
filter(
None,
self._tree.add(tokens, Link(link))
def write_map(self):
+ """Write sitemap.txt"""
f = codecs.open(self._file, "w", "utf-8")
s = "\n".join(link.link() for link in self._tree)
f.write(s)
f.close()
def read_map(self):
+ """Read sitemap.txt"""
try:
f = codecs.open(self._file, "r", "utf-8")
sml = f.read().split()
except IOError:
print("INFO: Could not read sitemap.txt - one will be created")
- # Create a set of the current tree for comparison with the
- # directory scan
def set(self):
+ """Create a set of the current tree for comparison with the directory scan"""
return set(link.link() for link in self._tree)
def linklist(self):
+ """Return link list of tree"""
return [link.link() for link in self._tree]
- # Main driver in the application processing the documents
- # in the collected sitemap
def process(self):
+ """Main driver in the application processing the documents in
+ the collected sitemap"""
t1 = time()
for link in self._tree:
link.prepare()
t2 = time()
- print("Prepare [%5.2f s]" % (round(t2 - t1, 2)))
+ print(f"Prepare [{t2 - t1:5.2f} s]")
for link in self._tree:
self._sitelang = self._sitelang.union(set(link.languages()))
for tran in self._sitelang:
"iso_639_3", languages=[tran]
)
t3 = time()
- print("Language [%5.2f s]" % (round(t3 - t2, 2)))
+ print(f"Language [{t3 - t2:5.2f} s]")
transform = {}
transform["xhtml5"] = etree.XSLT(
etree.parse(self._style + "docbook.xhtml5.xsl")
for link in self._tree:
link.render(transform)
t4 = time()
- print("Render [%5.2f s]" % (round(t4 - t3, 2)))
+ print(f"Render [{t4 - t3:5.2f} s]")
for link in self._tree:
link.template(self, self._style, self._tmptarget, self._subdir)
t5 = time()
- print("Template [%5.2f s]" % (round(t5 - t4, 2)))
+ print(f"Template [{t5 - t4:5.2f} s]")
t6 = time()
res = set()
# Collect all files used by the documents
outfile = self._tmptarget + f
mkdir_p(os.path.dirname(outfile))
shutil.copyfile(f, outfile)
- print("Resources[%5.2f s]" % (round(t6 - t5, 2)))
+ print(f"Resources[{t6 - t5:5.2f} s]")
# TODO: Improve the sitemap, it is a page that is generated from
# the ground up and added a bit adhoc.
sitmaplink = Link("/sitemap")
- for l in self._sitelang:
- sitmaplink.add_page((l, "/sitemap." + l + ".xml"))
- for l in self._sitelang:
- txtmenu = self.gen_menu(l, None, "tree sitemap")
- sitmaplink.page(l).set_article(txtmenu)
- f = open(self._tmptarget + "sitemap." + l + ".txt", "w")
+ for lang in self._sitelang:
+ sitmaplink.add_page((lang, "/sitemap." + lang + ".xml"))
+ for lang in self._sitelang:
+ txtmenu = self.gen_menu(lang, None, "tree sitemap")
+ sitmaplink.page(lang).set_article(txtmenu)
+ f = open(self._tmptarget + "sitemap." + lang + ".txt", "w")
f.write(txtmenu)
f.close()
- sitmaplink.page(l).template(
+ sitmaplink.page(lang).template(
self, self._style, self._tmptarget, self._subdir
)
t7 = time()
- print("Sitemap [%5.2f s]" % (round(t7 - t6, 2)))
+ print(f"Sitemap [{t7 - t6:5.2f} s]")
def graph(self):
+ """Return graph"""
self._tree.graph()
def gen_menu(self, lang, page, cssclass):
+ """Generate menu in html"""
return self._tree.menu(lang, page, cssclass, self._subdir)
def lang_menu(self, lang, link):
+ """Generate language menu"""
html = ElementMaker()
menu = html.ul()
- for l in link.languages():
- isoxml = "//iso_639_3_entry[@*='" + l + "']"
+ for lang in link.languages():
+ isoxml = "//iso_639_3_entry[@*='" + lang + "']"
ln = self._isocode.xpath(isoxml)[0].get("name")
if lang != "en":
ln = self._tranlang[lang].ugettext(ln)
p = link.link()
if p[-1] == "/":
p = p + "index"
- p = p + "." + l
- li = html.li(html.a(ln, href=self._subdir + p, hreflang=l))
+ p = p + "." + lang
+ li = html.li(html.a(ln, href=self._subdir + p, hreflang=lang))
menu.append(li)
- # print type(etree.tostring(menu,encoding='unicode',pretty_print=False))
return etree.tostring(menu, encoding="unicode", pretty_print=False)
def publish(self):
+ """Publish the site"""
print("Size [ %7s ]" % (sizeof_fmt(get_folder_size(self._tmptarget))))
ssh_cmd(self._output, "mkdir -p")
publish(self._tmptarget, self._output)
-#!/usr/bin/python
-# from __future__ import print_function
+"""tools module: contain simple tools for treecutter"""
+
import os
import subprocess
import errno
def mkdir_p(path):
+ """Make a directory structure like mkdir -p"""
try:
os.makedirs(path)
except OSError as exc: # Python >2.5
def publish(src, target):
+ """Publish the website to the final destination"""
cmd = ["rsync", "-a", "--copy-links", "--partial", src, target]
retcode = subprocess.call(cmd)
if retcode:
- error("%s : retruncode %s" % (" ".join(cmd), str(retcode)))
+ print(f"{cmd} : retruncode {retcode}")
def ssh_cmd(target, command):
+ """ssh to another site"""
t = target.split(":")
c = command.split()
if len(t) == 1:
cmd = ["ssh", t[0], c[0], c[1], t[1]]
retcode = subprocess.call(cmd)
if retcode:
- error("%s : retruncode %s" % (" ".join(cmd), str(retcode)))
+ print(f"{cmd} : retruncode {retcode}")
def sizeof_fmt(num, suffix="B"):
+ """Summarize directory size"""
for unit in ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]:
if abs(num) < 1024.0:
- return "%3.1f%s%s" % (num, unit, suffix)
+ return f"{num:3.1f}{unit}{suffix}"
num /= 1024.0
- return "%.1f%s%s" % (num, "Yi", suffix)
+ return f"{num:.1f}Yi{suffix}"
def get_folder_size(folder):
+ """Get foldersize recursivley"""
total_size = os.path.getsize(folder)
if os.path.isfile(folder):
return total_size
# proc = subprocess.Popen(args, env={'PATH': os.getenv('PATH')})
def translate(files):
+ """translate availible files"""
for f in files:
- out = subprocess.check_output(["translate.sh", f])
+ subprocess.check_output(["translate.sh", f])
sys.stdout.write("#")
-
-
-# def warning(*objs):
-# print("WARNING: ", *objs, file=sys.stderr)
-
-# def error(*objs):
-# print("ERROR: ", *objs, file=sys.stderr)
-#!/usr/bin/python
+"""module trie: Trie structure to reperesent the website"""
+
import pygraphviz as pgv
class Node:
+ """Node of a trie with content"""
+
def __init__(self, token, value):
self._token = token
self._value = value
self._children = []
def token(self):
+ """Internal token"""
return self._token
def value(self):
+ """Value"""
return self._value
def children(self):
+ """Node children"""
return self._children
class Trie:
+ """Trie class structure"""
+
def __init__(self):
self._root = []
def __iter__(self):
+ """Trie iterator"""
return self.inorder(self._root)
- def inorder(self, t):
- for l in t:
- yield l.value()
- for x in self.inorder(l.children()):
- yield x
+ def inorder(self, tree):
+ """inorder traversal of the trie tree"""
+ for leaf in tree:
+ yield leaf.value()
+ # Delegate the recursive call directly
+ yield from self.inorder(leaf.children())
def _add(self, trie, key, content):
+ """internal add function"""
# is the key a leaf
k = key.pop(0)
if key == []:
self._add(ch.children(), key, content)
def add(self, key, content):
+ """Add node to the trie"""
self._add(self._root, key, content)
- def _graph(self, trie, G):
- for l in trie:
- G.add_node(l.token())
- for ch in l.children():
- G.add_edge(l.token(), ch.token())
- self._graph(l.children(), G)
+ def _graph(self, trie, g):
+ """Generate a graph of the trie - internal"""
+ for leaf in trie:
+ g.add_node(leaf.token())
+ for ch in leaf.children():
+ g.add_edge(leaf.token(), ch.token())
+ self._graph(leaf.children(), g)
def graph(self):
- G = pgv.AGraph(directed=True)
- G.add_node("sitemap")
+ """Generate a sitemap graph of the site"""
+ g = pgv.AGraph(directed=True)
+ g.add_node("sitemap")
for ch in self._root:
- G.add_edge("sitemap", ch.token())
- self._graph(self._root, G)
+ g.add_edge("sitemap", ch.token())
+ self._graph(self._root, g)
- # G.layout('dot')
- # G.draw('g.png')
- # print G.string()
+ # g.layout('dot')
+ # g.draw('g.png')
+ # print g.string()
def _menu(self, trie, lang, page, css, subdir):
- html = "<ul%s>\n" % css
- for l in trie:
+ """create a formated menue of the trie"""
+ html = f"<ul{css}>\n"
+ for leaf in trie:
sel = ""
- p = l.value().page(lang)
+ p = leaf.value().page(lang)
if p == page:
sel = ' class="selected"'
- if p != None:
- html += '<li%s><a href="%s%s">%s</a>\n' % (
- sel,
- subdir,
- l.value().link(),
- p.menu(),
- )
+ if p is not None:
+ link = leaf.value().link()
+ html += f'<li{sel}><a href="{subdir}{link}">{p.menu()}</a>\n'
else:
- link = l.value().link()
+ link = leaf.value().link()
if link[-1] == "/":
link = link + "index"
- html += '<li%s><a href="%s%s.en" hreflang="en">%s</a>\n' % (
- sel,
- subdir,
- link,
- l.value().page("en").menu(),
- )
- if l.children():
- html += self._menu(l.children(), lang, page, "", subdir)
+ html += f"""<li{sel}><a href="{subdir}{link}.en"
+ hreflang="en">{leaf.value().page("en").menu()}</a>\n"""
+ if leaf.children():
+ html += self._menu(leaf.children(), lang, page, "", subdir)
html += "</li>\n"
html += "</ul>\n"
return html
def menu(self, lang, page, cssclass, subdir):
+ """Create menue types of the trie"""
css = ""
if cssclass:
css = ' class="' + cssclass + '"'