[1.9.32] - Working on creating modules (header, navbar, sidebar, footer)
This commit is contained in:
parent
fb2c2cb86a
commit
8a66677925
|
@ -10,6 +10,9 @@ Tyto - Littérateur
|
|||
|
||||
# CURRENTLY IN DEV (in devel branch) !
|
||||
|
||||
## [1.9.32]
|
||||
- Working on creating modules (header, navbar, sidebar, header)
|
||||
|
||||
## [1.9.31]
|
||||
- Fix replacing markers starting LINE with HTML
|
||||
- Added tpl_files directory
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Package: tyto
|
||||
Version: 1.9.31
|
||||
Version: 1.9.32
|
||||
Section: custom
|
||||
Priority: optional
|
||||
Architecture: all
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
# Version: 1.9.31
|
||||
# Version: 1.9.32
|
||||
# Updated: 2023-10-18 1697613100
|
||||
# Tyto - Littérateur
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -625,6 +625,7 @@ css = tyto
|
|||
separator = |
|
||||
article_code = yes
|
||||
static = no
|
||||
navbar = yes
|
||||
|
||||
[WEBSITE_MODULES]
|
||||
navbar = yes
|
||||
|
|
|
@ -116,3 +116,60 @@ quote = """<blockquote class="%s"%s%s%s>%s
|
|||
%s
|
||||
</blockquote>"""
|
||||
|
||||
page_tpl = """<!-- %s -->
|
||||
<!Doctype html>
|
||||
<html lang="%s">
|
||||
<head>
|
||||
%s
|
||||
</head>
|
||||
<body>
|
||||
<div id="site_container">
|
||||
|
||||
%s
|
||||
|
||||
%s
|
||||
|
||||
<!-- div contains <article> and <aside> -->
|
||||
<div id="site_article_aside">
|
||||
<article id="site_article">
|
||||
<header id="site_article_header">
|
||||
<h1 id="site_article_title">%s</h1>
|
||||
</header>
|
||||
%s
|
||||
<footer id="site_article_footer">
|
||||
%s
|
||||
</footer>
|
||||
</article>
|
||||
%s
|
||||
</div> <!-- site_article_aside -->
|
||||
|
||||
</div> <!-- #site_container -->
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
module_header = """<!-- Header (logo, description) -->
|
||||
<header id="site_header">
|
||||
<div id="site_logo">
|
||||
<a id="site_logo_link" href="%s" title="%s">
|
||||
<img id="site_logo_image" src="%s" alt="%s" title="%s">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div id="site_infos">
|
||||
<p id="site_infos_title">%s</p>
|
||||
<p id="site_infos_text">%s</p>
|
||||
</div<
|
||||
</header>"""
|
||||
|
||||
module_navbar = """<!-- Menu navbar -->
|
||||
<nav id="site_menu">
|
||||
<menu id="site_menu_items">
|
||||
%s
|
||||
</menu>
|
||||
</nav>"""
|
||||
|
||||
module_aside = """<!-- Aside articles navigation -->
|
||||
"""
|
||||
|
||||
module_footer = """<!-- Website footer-->
|
||||
"""
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
# file program :
|
||||
#--------------------------
|
||||
|
||||
import sys
|
||||
import args, debug, tyto, tools, post, domain
|
||||
import sys, os
|
||||
import args, debug, tyto, tools, post, domain, check, langs
|
||||
|
||||
|
||||
#=====================================#
|
||||
|
@ -100,14 +100,21 @@ def convert(target):
|
|||
if not post.is_article(target):
|
||||
return False
|
||||
|
||||
# Article has errors
|
||||
if post.chk_errors:
|
||||
post.error = debug.out(10, "'check'", post.uri, True, 2, False)
|
||||
# Check/Create modules files
|
||||
# navbar, sidebar, header, footer
|
||||
if not get_modules("wip"):
|
||||
return False
|
||||
|
||||
if post.has_changed and not args.force:
|
||||
post.error = debug.out(106, "'check'", post.uri, True, 1,False)
|
||||
return False
|
||||
# Article has errors or changed : needs check first
|
||||
if post.has_changed or post.chk_errors:
|
||||
if post.has_changed: debug.out(106, "'check'", post.uri, True, 1,False)
|
||||
elif post.chk_errors: debug.out(10, "'check'", post.uri, True, 2, False)
|
||||
args.force = True
|
||||
check.is_article(target)
|
||||
if post.error != 0:
|
||||
return False
|
||||
is_article(target)
|
||||
return
|
||||
|
||||
# Get raw post from database
|
||||
raw_post = tools.b64_convert("decode", post.cf.get("TEXTS", "post"))
|
||||
|
@ -211,50 +218,32 @@ def words_tags():
|
|||
# anchors, paragraphs... #
|
||||
#-------------------------#
|
||||
def sl_tags():
|
||||
global html_post
|
||||
|
||||
for ln, line in enumerate(html_post.rsplit("\n")):
|
||||
css = ""
|
||||
|
||||
# Paragraphs
|
||||
if line.lstrip().startswith(post.ptags[2][0]):
|
||||
css = tools.get_css(line, post.ptags[2][0], "?")
|
||||
html_post = \
|
||||
html_post.replace(
|
||||
html_post.rsplit("\n")[ln],
|
||||
post.ptags[2][3]%css
|
||||
)
|
||||
text_replace(html_post.rsplit("\n")[ln], post.ptags[2][3]%css)
|
||||
|
||||
elif line.lstrip().startswith(post.ptags[2][1]):
|
||||
text_replace(line, post.ptags[2][4])
|
||||
|
||||
# DIVs
|
||||
if line.lstrip().startswith(post.ptags[4][0]):
|
||||
css = tools.get_css(line, post.ptags[4][0], "?")
|
||||
html_post = \
|
||||
html_post.replace(
|
||||
html_post.rsplit("\n")[ln],
|
||||
post.ptags[4][3]%css
|
||||
)
|
||||
text_replace(html_post.rsplit("\n")[ln], post.ptags[4][3]%css)
|
||||
elif line.lstrip().startswith(post.ptags[4][1]):
|
||||
text_replace(line, post.ptags[4][4])
|
||||
|
||||
# <br>
|
||||
elif line.lstrip().startswith(post.html_brline[0]):
|
||||
css = tools.get_css(line, post.html_brline[0][0], "?")
|
||||
html_post = \
|
||||
html_post.replace(
|
||||
html_post.rsplit("\n")[ln],
|
||||
post.html_brline[1]%css
|
||||
)
|
||||
|
||||
text_replace(html_post.rsplit("\n")[ln], post.html_brline[1]%css)
|
||||
# <hr>
|
||||
elif line.lstrip().startswith(post.html_hrline[0]):
|
||||
css = tools.get_css(line, post.html_hrline[0][0], "?")
|
||||
html_post = \
|
||||
html_post.replace(
|
||||
html_post.rsplit("\n")[ln],
|
||||
post.html_hrline[1]%css
|
||||
)
|
||||
text_replace(html_post.rsplit("\n")[ln],post.html_hrline[1]%css)
|
||||
|
||||
# Anchors
|
||||
elif line.lstrip().startswith(post.anchor_target[0]):
|
||||
|
@ -281,8 +270,6 @@ def split_size(size):
|
|||
# Convert images tags to HTML #
|
||||
#-----------------------------#
|
||||
def images():
|
||||
global html_post
|
||||
|
||||
for key, val in post.cf.items("IMAGES"):
|
||||
if key.startswith("html"):
|
||||
continue
|
||||
|
@ -343,11 +330,10 @@ def images():
|
|||
style = ' style="height:%s;"'%height
|
||||
|
||||
|
||||
html_post = \
|
||||
html_post.replace(
|
||||
html_post.rsplit("\n")[ln],
|
||||
html_val%(css, figcap_o, css, style, figcap_c)
|
||||
)
|
||||
text_replace(
|
||||
html_post.rsplit("\n")[ln],
|
||||
html_val%(css, figcap_o, css, style, figcap_c)
|
||||
)
|
||||
|
||||
|
||||
#=========================================================#
|
||||
|
@ -595,3 +581,136 @@ def convert_list(markdown_str, mark_b, mark_c):
|
|||
work_str += " "*(cur_rank-i-1) + CLOSING[rank_stack.pop()]
|
||||
|
||||
return work_str
|
||||
|
||||
|
||||
#=========#
|
||||
# Modules #====================================================================
|
||||
#---------#
|
||||
#============================================#
|
||||
# Check / Create modules files (.raw + .html #
|
||||
# process: "wip" or "www" #
|
||||
# - navbar #
|
||||
# - sidebar #
|
||||
# - header #
|
||||
# - footer #
|
||||
#--------------------------------------------#
|
||||
def get_modules(srv):
|
||||
# Modules settings
|
||||
raws_uris = {
|
||||
"header" : domain.wrk_header,
|
||||
"navbar" : domain.wrk_navbar,
|
||||
"sidebar" : domain.wrk_sidebar,
|
||||
"footer" : domain.wrk_footer
|
||||
}
|
||||
|
||||
raws_sets = \
|
||||
{
|
||||
"header" : tyto.module_header%(
|
||||
"/template/%s"%domain.logo, domain.about,
|
||||
"/template/%s"%domain.logo, domain.about, domain.about,
|
||||
domain.title,
|
||||
domain.about
|
||||
),
|
||||
"navbar" : langs.logs.navbar_header%(
|
||||
domain.title, domain.wrk_articles,
|
||||
domain.wrk_navbar,
|
||||
domain.wip_navbar,
|
||||
domain.www_navbar
|
||||
),
|
||||
"sidebar" : langs.logs.sidebar_header%(
|
||||
domain.title, domain.wrk_articles,
|
||||
domain.wrk_sidebar,
|
||||
domain.wip_sidebar,
|
||||
domain.www_sidebar
|
||||
),
|
||||
"footer" : tyto.module_footer,
|
||||
}
|
||||
|
||||
create_html_mods = {
|
||||
"header" : navbar_check,
|
||||
}
|
||||
|
||||
# Create user raw files modules in modules/ directory
|
||||
for module in raws_uris:
|
||||
if not os.path.exists(raws_uris[module]):
|
||||
tools.create_file(raws_uris[module], raws_sets[module])
|
||||
|
||||
# Create HTML module from raw files
|
||||
for module in create_html_mods:
|
||||
if not create_html_mods[module](srv):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
#
|
||||
# Navbar Creation #
|
||||
#
|
||||
def navbar_check(srv):
|
||||
# navbar is NOT activated in domain configuration file
|
||||
navbar_contents = "<!-- Menu navbar -->"
|
||||
if srv == "wip": srv_file = domain.wip_navbar
|
||||
elif srv == "www": srv_file = domain.www_navbar
|
||||
|
||||
if not domain.navbar:
|
||||
tools.create_file(srv_file, navbar_contents)
|
||||
return True
|
||||
|
||||
# Create navbar HTML file in srv, from raw
|
||||
if not navbar_html_create(srv_file):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
#
|
||||
# Create navbar HTML file in wip, from raw
|
||||
#
|
||||
def navbar_html_create(srv_file):
|
||||
items = False
|
||||
|
||||
with open(domain.wrk_navbar, "r") as f:
|
||||
navbar_raw = f.read().rsplit("\n")
|
||||
navbar_html = ""
|
||||
title = title_html = ""
|
||||
|
||||
|
||||
for ln, line in enumerate(navbar_raw, 1):
|
||||
if line.lstrip().startswith("#") or \
|
||||
not line or \
|
||||
line.isspace():
|
||||
continue
|
||||
|
||||
html_line = '<li class="site_menu_item"%s href="%s">%s</li>'
|
||||
|
||||
# Get folder title (if set)
|
||||
if line.lstrip().startswith(">"):
|
||||
title = line.lstrip()[1:].lstrip()
|
||||
title_html = ' title="%s"'%title
|
||||
continue
|
||||
|
||||
# Get directory name and check if exists
|
||||
folder = line.lstrip()
|
||||
if not os.path.join(domain.wrk_articles, folder):
|
||||
post.error = \
|
||||
debug.out(6, 'Navbar. %s) "%s"'%(
|
||||
ln, folder
|
||||
), domain.wrk_navbar, True, 2, False)
|
||||
return False
|
||||
else:
|
||||
items = True
|
||||
if not folder.startswith("/"):
|
||||
folder = "/%s"%folder
|
||||
html_line = html_line%(title_html, folder, folder)
|
||||
if not navbar_html: navbar_html = html_line
|
||||
else: navbar_html = "%s\n%s"%(navbar_html, html_line)
|
||||
title = title_html = ""
|
||||
|
||||
if not items:
|
||||
post.error = \
|
||||
debug.out(9, 'Navbar', domain.wrk_navbar, True, 2, False)
|
||||
return False
|
||||
|
||||
tools.create_file(srv_file, tyto.module_navbar%navbar_html)
|
||||
|
||||
return True
|
||||
|
|
|
@ -1,12 +1,50 @@
|
|||
/*
|
||||
* Raw empty styles used by Tyto _ Littérateur
|
||||
* Raw empty styles used by Tyto - Littérateur
|
||||
* "tyto" is default. replace with YOUR domain css name if changed
|
||||
* Some classes from markers, like paragraphs, lists... can have custom classes
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Article styles
|
||||
* Template website
|
||||
*/
|
||||
/* Contains all website, after <body> */
|
||||
div#site_container {}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Header (Logo, Description)
|
||||
*/
|
||||
header#site_header {}
|
||||
/* Website Logo */
|
||||
div#site_logo {}
|
||||
a#site_logo_link {}
|
||||
img#site_logo_image {}
|
||||
/* Website about*/
|
||||
div#site_infos {}
|
||||
p#site_infos_title {}
|
||||
p#site_infos_text {}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Website Menu navbar
|
||||
*/
|
||||
nav#site_menu {}
|
||||
menu#site_menu_items {}
|
||||
li.site_menu_item {}
|
||||
|
||||
|
||||
/* div contains <article> and <aside> */
|
||||
div#site_article_aside {}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Article contents styles
|
||||
*/
|
||||
/* Template article */
|
||||
article#site_article {}
|
||||
header#site_article_header {}
|
||||
h1#site_article_title {}
|
||||
footer#site_article_footer {}
|
||||
|
||||
/* Generic for all links <a class="tyto" */
|
||||
a.tyto {}
|
||||
|
@ -17,8 +55,10 @@ a.file {}
|
|||
/* Specific link for non target file <a class="tyto link" */
|
||||
a.link {}
|
||||
|
||||
/* anchor link <a class="tyto anchor_link" */
|
||||
/* anchor link to target anchor <a class="tyto anchor_link" */
|
||||
a.anchor_link {}
|
||||
/* a#YOURCSS {} */
|
||||
/* Generic for all target anchors*/
|
||||
a.anchor_target {}
|
||||
|
||||
/* hr and br */
|
||||
|
@ -82,13 +122,3 @@ a.post_logo {}
|
|||
img.post_logo {}
|
||||
/* Legacy image link has also a.tyto OR a.MYCUSTOMCSS */
|
||||
img.tyto {}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Binary file not shown.
|
@ -50,32 +50,32 @@ anchor_title = "Anchor title"
|
|||
# logs for debug
|
||||
#---------------
|
||||
# Errors
|
||||
err_arg = "Argument error"
|
||||
err_hole = "Current directory error"
|
||||
err_date = "Date error"
|
||||
err_lang = "Lang error"
|
||||
err_dir = "Directory error"
|
||||
err_no_dir = "Directory unused"
|
||||
err_cd = "Directory not created"
|
||||
err_no_file = "File unused"
|
||||
err_cr_file = "File not created"
|
||||
err_bad_uri = "URI error"
|
||||
err_post_sep = "Separator unused"
|
||||
err_post_head = "Header is empty"
|
||||
err_post_empty = "Article is empty"
|
||||
err_ini_file = "Configuration error"
|
||||
err_post_data = "Data unused"
|
||||
err_post_title = "Title error"
|
||||
err_post_paired = "Markers not paired"
|
||||
err_post_in_tag = "Markers without contents"
|
||||
err_post_datatag= "Data reserved"
|
||||
err_post_id_yet = "ID used yet"
|
||||
err_post_global = "Article Error"
|
||||
err_arg = "Argument error"
|
||||
err_hole = "Current directory error"
|
||||
err_date = "Date error"
|
||||
err_lang = "Lang error"
|
||||
err_dir = "Directory error"
|
||||
err_no_dir = "Directory unused"
|
||||
err_cd = "Directory not created"
|
||||
err_no_file = "File unused"
|
||||
err_cr_file = "File not created"
|
||||
err_bad_uri = "URI error"
|
||||
err_post_sep = "Separator unused"
|
||||
err_post_head = "Header is empty"
|
||||
err_post_empty = "Article is empty"
|
||||
err_ini_file = "Configuration error"
|
||||
err_post_data = "Data unused"
|
||||
err_post_title = "Title error"
|
||||
err_post_paired = "Markers not paired"
|
||||
err_post_in_tag = "Markers without contents"
|
||||
err_post_datatag = "Data reserved"
|
||||
err_post_id_yet = "ID used yet"
|
||||
err_post_global = "Article Error"
|
||||
|
||||
# Warnings
|
||||
warn_no_dom = "Domain not configured"
|
||||
domain_off = "Domain deactivated"
|
||||
reset_dom = "RESET domain"
|
||||
warn_no_dom = "Domain not configured"
|
||||
domain_off = "Domain deactivated"
|
||||
reset_dom = "RESET domain"
|
||||
warn_post_chk = "Article changed"
|
||||
|
||||
# infos
|
||||
|
@ -126,3 +126,54 @@ tyto [action] [target] [options]
|
|||
--debug, -D : show more logs
|
||||
--errors, -E : Show mainly warnings and errors logs
|
||||
"""
|
||||
|
||||
#
|
||||
# Modules (navbar, sidebar...)
|
||||
#
|
||||
navbar_header = """#
|
||||
#=====================================================#
|
||||
# Navbar cnfiguration file used by Tyto - Littérateur #
|
||||
#-----------------------------------------------------#
|
||||
#
|
||||
# Domain Name : %s
|
||||
# Domain URI : %s
|
||||
|
||||
# WRK : %s
|
||||
# WIP : %s
|
||||
# WWW : %s
|
||||
|
||||
# How to configure this file:
|
||||
# - Add one directory URI per line
|
||||
# - - URI is from domain directory articles/
|
||||
# - - Option:
|
||||
# - - - Add title folder before the directory line "> Directory title"
|
||||
|
||||
# Examples:
|
||||
# > All last news
|
||||
# news !
|
||||
# > About this website
|
||||
# about/website
|
||||
#------------------------------------------------------------------------------
|
||||
"""
|
||||
|
||||
sidebar_header = """#
|
||||
#========================================================================#
|
||||
# Fichier de config de la barre latérale utilisée par Tyto - Littérateur #
|
||||
#------------------------------------------------------------------------#
|
||||
#
|
||||
# Nom du domaine : %s
|
||||
# URI du domaine : %s
|
||||
|
||||
# WRK : %s
|
||||
# WIP : %s
|
||||
# WWW : %s
|
||||
|
||||
# How to configure this file:
|
||||
# - Add one article file URI per line
|
||||
# - - URI is from domain directory articles/
|
||||
|
||||
# Examples:
|
||||
# index.tyto
|
||||
# dir/index.tyto
|
||||
#------------------------------------------------------------------------------
|
||||
"""
|
||||
|
|
|
@ -50,27 +50,27 @@ anchor_title = "Titre de l'ancre"
|
|||
# logs for debug
|
||||
#---------------
|
||||
# Errors
|
||||
err_arg = "Argument invalide"
|
||||
err_hole = "Dossier courant invalide"
|
||||
err_date = "Date invalide"
|
||||
err_lang = "Format de langue invalide"
|
||||
err_dir = "Dossier non compatible"
|
||||
err_no_dir = "Dossier inexistant"
|
||||
err_cd = "Dossier non créé"
|
||||
err_no_file = "Fichier manquant"
|
||||
err_cr_file = "Fichier non créé"
|
||||
err_bad_uri = "URI non compatible"
|
||||
err_post_sep = "Séparateur manquant"
|
||||
err_post_head = "Entête vide"
|
||||
err_post_empty = "Article vide"
|
||||
err_ini_file = "Configuration invalide"
|
||||
err_post_data = "Donnée manquante"
|
||||
err_post_title = "Titre invalide"
|
||||
err_post_paired = "Marqueurs non apairés"
|
||||
err_post_in_tag = "Marqueurs sans contenu"
|
||||
err_post_datatag= "Donnée réservée"
|
||||
err_post_id_yet = "Identité déjà utilisée"
|
||||
err_post_global = "Article erronné"
|
||||
err_arg = "Argument invalide"
|
||||
err_hole = "Dossier courant invalide"
|
||||
err_date = "Date invalide"
|
||||
err_lang = "Format de langue invalide"
|
||||
err_dir = "Dossier non compatible"
|
||||
err_no_dir = "Dossier inexistant"
|
||||
err_cd = "Dossier non créé"
|
||||
err_no_file = "Fichier manquant"
|
||||
err_cr_file = "Fichier non créé"
|
||||
err_bad_uri = "URI non compatible"
|
||||
err_post_sep = "Séparateur manquant"
|
||||
err_post_head = "Entête vide"
|
||||
err_post_empty = "Article vide"
|
||||
err_ini_file = "Configuration invalide"
|
||||
err_post_data = "Donnée manquante"
|
||||
err_post_title = "Titre invalide"
|
||||
err_post_paired = "Marqueurs non apairés"
|
||||
err_post_in_tag = "Marqueurs sans contenu"
|
||||
err_post_datatag = "Donnée réservée"
|
||||
err_post_id_yet = "Identité déjà utilisée"
|
||||
err_post_global = "Article erronné"
|
||||
|
||||
# Warnings
|
||||
warn_no_dom = "Domaine non configuré"
|
||||
|
@ -126,3 +126,54 @@ tyto [action] [target] [options]
|
|||
--debug, -D : montrer plus de logs
|
||||
--errors, -E : montrer surtout les avertissements et erreurs
|
||||
"""
|
||||
|
||||
#
|
||||
# Modules (navbar, sidebar...)
|
||||
#
|
||||
navbar_header = """#
|
||||
#=============================================================================#
|
||||
# Fichier de config de la barre de menu utilisé par Tyto - Littérateur #
|
||||
#-----------------------------------------------------------------------------#
|
||||
#
|
||||
# Nom du domaine : %s
|
||||
# URI du domaine : %s
|
||||
|
||||
# WRK : %s
|
||||
# WIP : %s
|
||||
# WWW : %s
|
||||
|
||||
# Comment configurer ce fichier :
|
||||
# - Ajouter un URI de dossier par ligne
|
||||
# - - URI depuis le dossier articles/ du domaine
|
||||
# - - Option :
|
||||
# - - - Ajouter le titre du dossier avant la ligne "> TITRE du dossier"
|
||||
|
||||
# Exemples:
|
||||
# > Toutes les dernières nouvelles
|
||||
# news
|
||||
# > À propos de ce site
|
||||
# a-propos/website
|
||||
#------------------------------------------------------------------------------
|
||||
"""
|
||||
|
||||
sidebar_header = """#
|
||||
#========================================================================#
|
||||
# Fichier de config de la barre latérale utilisée par Tyto - Littérateur #
|
||||
#------------------------------------------------------------------------#
|
||||
#
|
||||
# Nom du domaine : %s
|
||||
# URI du domaine : %s
|
||||
|
||||
# WRK : %s
|
||||
# WIP : %s
|
||||
# WWW : %s
|
||||
|
||||
# Comment configurer ce fichier :
|
||||
# - Ajouter un URI d'article par ligne
|
||||
# - - URI depuis le dossier articles/ du domaine
|
||||
|
||||
# Exemples :
|
||||
# index.tyto
|
||||
# dir/index.tyto
|
||||
#------------------------------------------------------------------------------
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue