[1.9.28] - See changelog

This commit is contained in:
Cyrille L 2023-10-27 17:40:10 +02:00
parent b9a41bb8bb
commit b6730f2f77
11 changed files with 254 additions and 135 deletions

View File

@ -9,6 +9,18 @@ Tyto - Littérateur
# CURRENTLY IN DEV !
## [1.9.28]
- readme
- - updated tyto article, with comments to show how to
- multiple targets
- - fix CSS classe name error
- - reset stats, post.error, HEADERS datas
- check process:
- - Added hr and br tags (CSS class name check)
- - fix blockquote title HTML
- - New method to split separator in article
- - fix icode, bcode contents HTML signs (converted)
## [1.9.27]
- fix when target article .tyto is missing
- Nearly all stats are added in DB from modules

145
README.md
View File

@ -18,17 +18,24 @@ tyto
## Exemple d'article
```
Pour ne pas inclure cet article dans les sitemaps :
#================================================#
# Entete de l'article #
# Fin de l'entête avec au moins 5 tirets "-----" #
# Toute ligne de commentaire "# ..." est ignorée #
#================================================#
# Pour ne pas inclure cet article dans les sitemaps :
! NoSitemap
# Données uniques sur UNE ligne
title: tests d'un article
about: À propos de cet article de test
tags: hello, my big world,here
tags: Tyto, tuto,
author: echolib
date: 2023-09-30
logo: /testimg/hi.png
date: 2023-10-27
link: Lien à reprendre
# Données multiple sur 3 lignes
link: cliquer sur ce Lien
https://
Text alternatif
@ -36,89 +43,99 @@ link: Réservez ici
https://
Billets
file: voir l'image
PNGs/hi.png
Un png !
image: MyCar
PNGs/hi.png
Un png !
file: télécharger ce fichier
@PDFs/hello.pdf
@/PDFs/hello.pdf
Un PDF !
abbr: css
Cascading StyleSheet
CSS
abbr: HTML
Hyper Text Markup Langage
HTML
code: test
@RAWS/test.py
Du code à afficher en HTML
-----
#=====================================================================#
# Contenu de l'article #
# Les classe optionnelles non renseignées deviennent celle du domaine #
#=====================================================================#
# La ligne suivante est un commentaire HTML "<!-- Commentaire -->"
;; Commentaire
-> top
#1 Titre en h2
((
;; HTML comment
# Show logo set in header, using '_image:logo'
_image:logo tyto_logo w=120
))
-> newtitle
#2 Titre en h3 décalé dans le texte
# Ceci est une ancre avec l'ID uniq1 (ID unique)
-> uniq1
-> top
# Créer un lien vers l'ancre "uniq1"
>_uniq1: Go to uniq1 anchor_<
# Ceci est une ligne <hr> ayant pour classe hrcss
-- hrcss
# Les Titres de l'article de #1 à #5 (<h2> à <h6>)
#1 Titre en h2
# Contenu dans un paragraphe ayant pour classe "mypar"
(( mypar
Un long paragraphe...
# Retour à la ligne avec un <br /> de classe brcss
# (les retours à la ligne vides ne sont pas pris en compte)
| brcss
Il faut __cliquer sur ce Lien, __Réservez ici et --télécharger ce fichier
ou encore faire une ::CSS pour du beau rendu ::HTML
# Un paragraphe dans le paragraphe ayant pour classe, celle du domaine
((
Parce que c'est *_bien_* comme /_présentation_/ *_erreur
ou pas, si fermé_*
/_ ;_echolib_; _/
Un /_court_/ paragraphe de :_1984_: pour de ~_vrai_~ +_faux en gras_+
Il faut le ._souligner_. et *_Très Gras_*
))
# Créer un icode (utiliser la balise <code>)
# /!\ ! Doit être sur une ligne
{_<ol>, <ul>_}
((
Il /_faut_/ ce __Lien à reprendre et __Réservez ici et --télécharger ce fichier
ou encore faire une ::css pour du ::HTML. __Réservez ici et --voir l'image
icode 1 : {_hello(_world_)_}, icode 2 : {_print("")_}
icode 3 : {_{__}_}, icode 4 : {_echo "Hello"_}
))
((
_image:MyCar
<: mylist
+ Item 1
++ Sub-Item 1
+++ Sub-Sub-item 1
==== >_top: Go to Top_<
==== >_top: Another anchor_<
:>
))
_code:test
{{
# Du code brut pour Tyto
{{
Un exemple de code
}}
#2 Un exemple de block code ayant pour classe python
# Tout contenu entre les marqueurs "{{" et "}}" est conservé
{{ python
# Un commentaire et du code
def hello(world):
world and print(world) or print("NoMore")
}}
[[
["
#2 Citation
# Dans un block div [[ ... ]] (classe CSS mydiv),
# La citation entre [" ... "] (classe CSS mycite)
# est placée dans un paragraphe (classe CSS mycite)
# ! Tout commentaire "# ..." dans la citation sera affiché...
[[ mydiv
[" mycite
;; A great quote here !
cite: Someone
date: 2023-10-13
book: A History
lang: EN
lang: en
link: https://...
((
(( mycite
Here, i am
))
"]
]]
# Créer une liste ol/ul entre <: ... :> (classe mylist)
# dans un paragraphe (classe du domaine)
# "+" pour ol, "=" pour ul
# Ajouter toujours un signe pour un sous-item ou /!\ au changement de signe
#2 Une liste mixée {_<ol>, <ul>_}
((
<: mylist
+ numeric o: item 1
++ numeric ol sub-Item 1
+++ numeric ol sub-sub-item 1
==== ul item >_top: Go to Top_<
==== ul item >_top: Another anchor_<
:>
))
```

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3
# Version: 1.9.27
# Version: 1.9.28
# Updated: 2023-10-18 1697613100
# Tyto - Littérateur

View File

@ -71,19 +71,19 @@ def manage(action, target):
# Also used with multiple (loop) #
#--------------------------------#
def is_article(target):
if not valid(target):
if not valid(target) or post.error != 0:
if targets: return
else: sys.exit(post.error)
# When all is OK
# Will create post database, but now, show some values
print("Final texts string")
"""
for ln, line in enumerate(texts, post.head_lines + 1):
print(">", ln, line)
print()
"""
# Write to post database
cf_update_values("after")
@ -104,6 +104,36 @@ def valid(target):
post.error = debug.out(210, post.chk_date, post.uri, True, 0, False)
return False
# Reset: must be done only when multiple targets
if targets:
post.title = ("title:", False)
post.about = ("about:", False)
post.date = ("date:", False)
post.tags = ("tags:", False)
post.author = ("author:", False)
post.logo = ("logo:", False) # optional
post.stats_bcodes = 0
post.stats_quotes = 0
post.stats_parags = 0
post.stats_lists = 0
post.stats_divs = 0
post.stats_links = 0
post.stats_images = 0
post.stats_files = 0
post.stats_raws = 0
post.stats_codes = 0
post.stats_abbrs = 0
post.stats_text_links = 0
post.stats_text_files = 0
post.stats_text_images = 0
post.stats_text_abbrs = 0
post.stats_text_codes = 0
post.stats_text_raws = 0
post.error = 0
# Reset post database (Old values are prepared)
tools.create_file(post.cf_uri, post.ini_template)
post.cf_load()
@ -168,6 +198,8 @@ def valid(target):
post.error == 0 and sl_ptags(post.ptags[4]) \
or tools.exit(targets, post.error)
post.error > 0 and tools.exit(targets, post.error)
return True
@ -192,6 +224,7 @@ def ol_tags():
stats_total_files = 0
sitemap = "True"
stats_tyto_head_coms = 0
for ln, line in enumerate(headers, 1):
# Optional one line markers
@ -215,24 +248,24 @@ def ol_tags():
# ===========================
elif not post.title[1] and line.startswith(post.title[0]):
post.title = (post.title[0], ol_tag_value(line, False))
if not is_ol_tag(post.title[0], post.title[1]):
if not is_ol_tag(post.title[0], post.title[1]):
return False
post.cf_set("HEADERS", "title", post.title[1])
post.cf_set("HEADERS", "title", post.title[1])
elif not post.about[1] and line.startswith(post.about[0]):
post.about = (post.about[0], ol_tag_value(line, False))
if not is_ol_tag(post.about[0], post.about[1]):
if not is_ol_tag(post.about[0], post.about[1]):
return False
post.cf_set("HEADERS", "about", post.about[1])
post.cf_set("HEADERS", "about", post.about[1])
elif not post.date[1] and line.startswith(post.date[0]):
post.date = (post.date[0], ol_tag_value(line, False))
if not is_ol_tag(post.date[0], post.date[1]):
if not is_ol_tag(post.date[0], post.date[1]):
return False
elif not is_valid_date(post.date[1]):
return False
post.date = ("date:", tools.local_date(post.date[1]))
post.cf_set("HEADERS", "date", post.date[1])
post.cf_set("HEADERS", "date", post.date[1])
elif not post.author[1] and line.startswith(post.author[0]):
post.author = (post.author[0], ol_tag_value(line, True))
@ -242,9 +275,9 @@ def ol_tags():
elif not post.tags[1] and line.startswith(post.tags[0]):
post.tags = (post.tags[0], ol_tag_value(line, True))
if not is_ol_tag(post.tags[0], post.tags[1]):
if not is_ol_tag(post.tags[0], post.tags[1]):
return False
post.cf_set("HEADERS", "tags", post.tags[1])
post.cf_set("HEADERS", "tags", post.tags[1])
# Default domain logo for this post
if not post.logo[1]:
@ -568,6 +601,9 @@ def sl_ptags(markers):
), post.uri, True, 2, False)
return False
continue
csstest = tools.get_css(line, markers[0], ln)
if post.error > 0:
return
index0 = line.index(markers[0][0])
tag_ln = ln
content = line
@ -578,8 +614,8 @@ def sl_ptags(markers):
if line.lstrip().startswith(markers[1]):
if index0 < 0:
post.error = \
debug.out(53, '%s: %s) %s...'%(
markers[2], ln, markers[0]
debug.out(53, '%s) %s: %s...'%(
ln, markers[2], markers[0]
), post.uri, True, 2, False)
return False
index1 = line.index(markers[1][0])
@ -607,7 +643,7 @@ def sl_ptags(markers):
markers[2].upper(),
"html_%s"%post.ptags_stats[markers[2]],
tools.b64_convert("encode",
convert[markers[2]](content)
convert[markers[2]](content, ln)
)
)
@ -619,29 +655,28 @@ def sl_ptags(markers):
# ----------------------
if index1 >= 0 and index0 < 0:
post.error = \
debug.out(53, '%s: %s) %s...'%(
markers[2], tag_ln, markers[0]
debug.out(53, '%s) %s: %s...'%(
tag_ln, markers[2], markers[0]
), post.uri, True,2, False)
return False
if index0 >= 0 and index1 < 0:
post.error = \
debug.out(53, '%s: %s) ...%s'%(
markers[2], tag_ln, markers[1]
debug.out(53, '%s) %s: ...%s'%(
tag_ln, markers[2], markers[1]
), post.uri, True,2, False)
return False
if index0 != index1:
post.error = \
debug.out(53, '%s: %s) %s...%s'%(
markers[2], tag_ln, markers[0], markers[1]
debug.out(53, '%s) %s: %s...%s'%(
tag_ln, markers[2], markers[0], markers[1]
), post.uri, True,2, False)
return False
return True
#==========================================#
# icodes (SAME LINE) #
# Check if opened and closed markers match #
@ -697,8 +732,13 @@ def icodes():
for icode in icodes:
stats_text_icodes += 1
icnew = markers[0][4] + icode + markers[0][5]
line = line.replace(icnew, "")
icnew = markers[0][4] + \
tools.convert_html_signs(icode) + \
markers[0][5]
icrep = markers[0][4] + \
icode + \
markers[0][5]
line = line.replace(icrep, "")
# Set HTML [ICODES] to post database
html_val = icnew.replace(markers[0][4], markers[0][2]%css)
@ -720,8 +760,13 @@ def icodes():
for icode in icodes:
stats_text_icodes += 1
icnew = markers[1][4] + icode + markers[1][5]
line = line.replace(icnew, "")
icnew = markers[1][4] + \
tools.convert_html_signs(icode) + \
markers[1][5]
icrep = markers[1][4] + \
icode + \
markers[1][5]
line = line.replace(icrep, "")
# Set HTML [ICODES] to post database
html_val = icnew.replace(markers[1][4], markers[1][2]%css)
@ -761,7 +806,7 @@ def sl_stags():
for ln, line in enumerate(texts, post.head_lines + 1):
linels = line.lstrip()
# legacy Tyto Titles
# Tyto Titles
if linels.startswith(post.tyto_titles):
if not linels[3:]:
post.error = \
@ -832,10 +877,18 @@ def sl_stags():
)
)
# BR line
elif line.lstrip().startswith(post.html_brline[0]):
brcss = tools.get_css(line, post.html_brline[0], ln)
# HR line
elif line.lstrip().startswith(post.html_hrline[0]):
hrcss = tools.get_css(line, post.html_hrline[0], ln)
# Anchor source
elif line.lstrip().startswith(post.anchor_target[0]):
anchor_id = tools.get_css(line, post.anchor_target[0])
anchor_id = tools.get_css(line, post.anchor_target[0], ln)
if anchor_id in anchors_ids:
post_error = \
debug.out(54, '%s) "%s"'%(ln, anchor_id), post.uri, True, 2, False)

View File

@ -99,15 +99,35 @@ def is_tyto_format():
global head_lines, text_lines, lines
head_contents = text_contents = ""
separator = False
with open(uri, "r") as contents:
contents = contents.read()
try:
head_contents = contents.rsplit(sep)[0]
text_contents = contents.rsplit(sep)[1]
except:
error = debug.out(21, sep, uri, True, 2, False)
return False
for line in contents.rsplit("\n"):
if not line:
line = " "
if line.startswith(sep):
separator = True
continue
if separator:
if not text_contents: text_contents = line
else: text_contents = "%s\n%s"%(text_contents, line)
else:
if not head_contents: head_contents = line
else: head_contents = "%s\n%s"%(head_contents, line)
if not separator:
error = debug.out(21, sep, uri, True, 2, False)
return False
print("===")
print(head_contents)
print("===")
print(text_contents)
print("===")
if not head_contents:
error = debug.out(22, "?", uri, True, 2, False)
@ -118,7 +138,7 @@ def is_tyto_format():
return False
lines = len(contents.splitlines())
head_lines = len(head_contents.splitlines())
head_lines = len(head_contents.splitlines()) + 1 # Count with sep line
text_lines = len(text_contents.splitlines())
return True
@ -301,31 +321,38 @@ nositemap = "! NoSitemap" # Article will not be included in sitemap
# One Line needed
sep = "-----" # Splitter between header and article texts
# Will replace "Fals" with title value
# Will replace "Fals" with data value
title = ("title:", False)
about = ("about:", False)
date = ("date:", False)
tags = ("tags:", False)
author = ("author:", False)
logo = ("logo:", False) # optional
logo = ("logo:", False) # optional
# Multiple lines (3) markers
ml_tags = ("link:", "image:", "file:", "raw:", "code:", "abbr:")
ml_tags = (
"link:",
"image:",
"file:",
"raw:",
"code:",
"abbr:"
)
ml_tags_marks = {
"link:" : "__",
"file:" : "--",
"image:" : "_image:",
"abbr:" : "::",
"raw:" : "_raw:",
"code:" : "_code:"
ml_tags[0] : "__",
ml_tags[2] : "--",
ml_tags[1] : "_image:",
ml_tags[5] : "::",
ml_tags[3] : "_raw:",
ml_tags[4] : "_code:"
}
ml_tags_stats = {
"link:" : stats_links,
"file:" : stats_files,
"image:" : stats_images,
"abbr:" : stats_abbrs,
"raw:" : stats_raws,
"code:" : stats_codes,
ml_tags[0] : stats_links,
ml_tags[2] : stats_files,
ml_tags[1] : stats_images,
ml_tags[5] : stats_abbrs,
ml_tags[3] : stats_raws,
ml_tags[4] : stats_codes,
}
# Markers with uri in value2
@ -344,11 +371,11 @@ ptags = (
)
ptags_stats = {
"bcodes" : stats_bcodes,
"quotes" : stats_quotes,
"parags" : stats_parags,
"lists" : stats_lists,
"divs" : stats_divs,
ptags[0][2] : stats_bcodes,
ptags[1][2] : stats_quotes,
ptags[2][2] : stats_parags,
ptags[3][2] : stats_lists,
ptags[4][2] : stats_divs,
}
# Tyto Titles #1 = <h2>

View File

@ -36,6 +36,8 @@ from hashlib import blake2b
import sys, os, configparser, datetime, time, base64
import debug, domain, post
import post
#=========================================#
# Write to post database, error was found #
@ -46,7 +48,8 @@ def exit(targets, error):
post.cf_set("CHECK", "errors", "True")
post.cf_write()
if targets: return
if targets:
return
sys.exit(error)
@ -192,7 +195,7 @@ def b64_convert(action, content):
def convert_html_signs(string):
string = string.replace('<', '&lt;')
string = string.replace('>', '&gt;')
astring = string.replace('"', '&quot;')
string = string.replace('"', '&quot;')
string = string.replace("'", '&apos;')
return string
@ -203,13 +206,15 @@ def convert_html_signs(string):
# Only take the first name #
# Exit all process if _... #
#--------------------------#
def get_css(line, mark):
def get_css(line, mark, ln):
css = line.rsplit(mark)[1].lstrip().rsplit(" ")[0]
css = css or domain.css
# Tyto use _abc as markers
if css.startswith("_"):
debug.out(56, "'_...' (CSS: %s)"%css, post.uri, True, 2, True)
post.error = \
debug.out(56, '%s) CSS: "%s"'%(ln, css), post.uri, True, 2, False)
return "NameError"
return css

View File

@ -46,13 +46,13 @@ import tyto, tools, post, domain
# Create HTML bcode #
# convert raw lines #
#-------------------#
def bcode(lines):
def bcode(lines, ln):
lines = lines.rsplit("\n")
html_bcode = ""
for ln, line in enumerate(lines):
if ln == 0: # Opened marker
css = tools.get_css(line, post.ptags[0][0])
css = tools.get_css(line, post.ptags[0][0], ln)
continue
if ln == len(lines) - 1: # Closed marker
@ -65,7 +65,7 @@ def bcode(lines):
if ln == 1:
fc = len(line) - len(line.lstrip())
line = tyto.code_line%(ln, line[fc:])
line = tyto.code_line%(ln, tools.convert_html_signs(line[fc:]))
if not html_bcode: html_bcode = line
else: html_bcode = "%s\n%s"%(html_bcode, line)
@ -80,7 +80,7 @@ def bcode(lines):
# Create HTML quote #
# convert raw lines #
#-------------------#
def quote(lines):
def quote(lines, ln):
lines = lines.rsplit("\n")
# Template
html_quote = "<!-- Quote -->"
@ -98,7 +98,7 @@ def quote(lines):
# Open Marker (Unused in HTML). Get user CSS class
if ln == 0:
css = tools.get_css(line, post.ptags[1][0])
css = tools.get_css(line, post.ptags[1][0], ln)
continue
# Closed marker (Unused in HTML)
@ -140,8 +140,13 @@ def quote(lines):
blockquote_lang = ' lang="%s"'%lang
# <footer> tag
if book: footer_book = ' - <cite class="quote">%s</cite>'%book
if cite: footer_cite = '-- %s'%cite
if book:
book = " - %s"%book
footer_book = ' - <cite class="quote">%s</cite>'%book
if cite:
footer_cite = '-- %s'%cite
if date:
footer_date = ' (%s)'%date
block_time_on = '\n<time datetime="%s">'%date
@ -149,7 +154,7 @@ def quote(lines):
if date or book or cite:
blockquote_title = ' title="%s%s%s"'%(
footer_cite, footer_book, footer_date
footer_cite, book, footer_date
)
footer = '<footer class="quote">\n' + \
'<p class="quote">' + \
@ -174,7 +179,7 @@ def quote(lines):
# Create HTML list #
# convert raw lines #
#-------------------#
def list(lines):
def list(lines, ln):
lines = lines.rsplit("\n")
list_raw = ""
@ -184,7 +189,7 @@ def list(lines):
# Open Marker (Unused in HTML). Get user CSS class
if ln == 0:
css = tools.get_css(line, post.ptags[3][0])
css = tools.get_css(line, post.ptags[3][0], ln)
continue
# Closed marker (Unused in HTML)