diff --git a/README.md b/README.md
index 7a5de37..af4b100 100644
--- a/README.md
+++ b/README.md
@@ -29,9 +29,9 @@ raw: Nom
URI
Texte Alternatif
-abbr: NOM (en majuscule)
- Définition du NOM
- nom (forme à afficher dans l'artile (optionnel))
+abbr: abbrev
+ Définition de abbrev
+ ABBR (forme à afficher dans l'artile (optionnel))
# L'image doit d'abord être configurée
# Utiliser l'image précisée comme défaut dans les réseaux sociaux
@@ -158,13 +158,14 @@ Vous pouvez avoir un Nom identique pour file: et link:
### Abréviations
```
-# NOM sera remplacé par "nom" dans la page si défini en entête
-# sinon, NOM sera conservé
-# - Toujours écrire en majuscule les ABBR dans l'article brut
-# - Mettre '!' devant NOM dans l'article
+# abbrev sera remplacé par "ABBR" dans la page si défini en entête
+# sinon, abbrev sera conservé
+# - Toujours écrire dans l'article :
+# - entre parenthèses ET majuscules les "(ABBREV)"
+
-Avec ce !NOM.
-# HTML: nom
+Avec cette (ABBREV).
+# HTML: ABBR
```
### Images
diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py
index 6767edd..d2e16eb 100644
--- a/src/var/lib/tyto/program/check.py
+++ b/src/var/lib/tyto/program/check.py
@@ -126,7 +126,6 @@ def check_process(target):
if not db.post: sys.exit(1)
global post_bottom, article_bottom
- global post_words
global date_wip, hash_wip, date_www, hash_www, post_bottom
global post_err
date_wip = hash_wip = date_www = hash_www = ''
@@ -189,11 +188,13 @@ def check_process(target):
tyto.protect_icodes(post_bottom)
post_bottom = tyto.protect_article
- # Check tags configuration
- check_headers(post_header.rsplit('\n'))
+ # Check header tags configurations
+ check_needed_tags(post_header.rsplit('\n'))
+ check_opt_tags(post_header.rsplit('\n'))
+ #print("In Dev: return from process...")
if post_err: return
-
- # Check for valid contents
+
+ # Check for valid contents
check_content(post_bottom)
# Remove db (if exists) on post error and return
@@ -202,19 +203,8 @@ def check_process(target):
os.remove(db.config)
return
-
- # Count words in article.
- # Quotes, block-codes, icode = 1 per each
- # At db creation, remove title numbers
- post_words = 0
- for line in post_bottom.rsplit("\n"):
- if not line \
- or line.startswith(tyto.nolinewords) \
- or line.startswith("#") and \
- not line.startswith(tyto.titles_tags):
- continue
- post_words = post_words + len(line.strip().split(" "))
-
+ # COunt words
+ count_words(post_bottom.rsplit("\n"))
# Create article's database
create_database()
@@ -226,6 +216,7 @@ def check_process(target):
#---------------------------------#
def file_to_string():
global article, post_header, post_bottom
+ global ln_header, ln_bottom, ln_article
post_header = post_bottom = ''
sep = content = False
@@ -246,14 +237,37 @@ def file_to_string():
# Check if separator or exit
if not sep:
- logs.out("6", '----- > %s'%db.uri_file, True)
+ logs.out("6", '"-----" > %s'%db.uri_file, True)
if not content:
if db.exists and tyto.exists(db.config):
os.remove(db.config)
logs.out("18", db.uri_file, True)
+ # +2 > (start at 0 + separator line)
+ ln_article = len(article.splitlines()) + 1
+ ln_header = len(post_header.splitlines()) + 2
+ ln_bottom = len(post_bottom.splitlines()) + 2
+
+#=========================================#
+# Count words in article. #
+# Quotes, block-codes, icode = 1 per each #
+# At db creation, remove title numbers #
+#-----------------------------------------"
+def count_words(post_bottom):
+ global post_words
+ post_words = 0
+ for line in post_bottom:
+ if not line \
+ or line.startswith(tyto.nolinewords) \
+ or line.startswith("#") and \
+ not line.startswith(tyto.titles_tags):
+ continue
+
+ post_words = post_words + len(line.strip().split(" "))
+
+
#=============================================#
# Check if bcodes and quotes #
# Check inline code, for markers on same line #
@@ -267,8 +281,7 @@ def if_icodes_bcodes_quotes(post_bottom):
nbr_titles = nbr_quotes = nbr_bcodes = nbr_ancs = 0
for ln, line in enumerate(post_bottom.rsplit('\n'), 1):
- # Pass Comments, count titles
- # Count titles
+ # Comments, count titles
if not line:
continue
elif line.startswith(tyto.titles_tags):
@@ -277,35 +290,38 @@ def if_icodes_bcodes_quotes(post_bottom):
elif line.startswith('#'):
continue
- # Pass quotes
+ # quotes
elif line.startswith(tyto.words_tags[11][0]) and not in_bcode:
quote = in_quote = True
- nbr_quotes += 1
continue
elif line.startswith(tyto.words_tags[11][1]):
in_quote = False
+ nbr_quotes += 1
continue
- # Pass bcode
+ # bcode
elif line.startswith(tyto.words_tags[12][0]) and not in_quote:
bcode = in_bcode = True
- nbr_bcodes += 1
continue
elif line.startswith(tyto.words_tags[12][1]):
in_bcode = False
+ nbr_bcodes += 1
continue
if in_bcode or in_quote:
continue
+
elif line.startswith(tyto.single_tags[1][0]):
nbr_ancs += 1
+
+ # icodes
elif tyto.words_tags[9][0] or tyto.words_tags[9][1] in line:
icode_m1 = icode_m2 = 0
icode_m1 = line.count(tyto.words_tags[9][0])
icode_m2 = line.count(tyto.words_tags[9][1])
if icode_m1 != icode_m2:
- print(" ├─", line)
- logs.out("8", 'icode: L=%s. "%s %s" > %s'%(ln,
+ logs.out("8", 'L=%s. icode "%s" + "%s" > %s'%(
+ ln + ln_header,
tyto.words_tags[9][0], tyto.words_tags[9][1],
db.uri_file
), False
@@ -315,6 +331,505 @@ def if_icodes_bcodes_quotes(post_bottom):
icode = True
+#=========================================#
+# Check needed tags from article's header #
+# Each one must be uniq. Only first taken #
+#-----------------------------------------#
+def check_needed_tags(post_header):
+ global post_err
+ global title, author, about, tags, date
+ global stat_tags
+
+ title = author = about = tags = ''
+ date = ()
+ stat_tags = 0
+
+ # Check post header for each needed tags
+ for tag in tyto.needed_header_tags:
+ for ln, line in enumerate(post_header, 1):
+ # Break if already set
+ if globals()[tag]: break
+
+ # Set data from tag
+ if line.startswith('%s:'%tag):
+ globals()[tag] = line.rsplit('%s:'%tag)[1].lstrip()
+ # Stat for "tags:"
+ if tag == 'tags':
+ stat_tags = len(globals()[tag].strip().split(","))
+
+ # Check if unused needed tags
+ for tag in tyto.needed_header_tags:
+ if not globals()[tag]:
+ logs.out("17", '%s:'%tag, False)
+ post_err = True
+
+ # Check date format
+ # Set french format in post DB
+ if not post_err:
+ check_date(date)
+
+
+#================================#
+# Check Date format and validity #
+# Create False date_check #
+#--------------------------------#
+def check_date(date):
+ global post_err
+
+ # Check if article date is valid (True)
+ fmt_article = "%Y-%m-%d"
+
+ try:
+ bool(datetime.strptime(date, fmt_article))
+ except ValueError:
+ post_err = True
+ logs.out("3", 'date: "%s" (YYYY-MM-DD) > %s'%(date, db.uri_file), False)
+
+ # Create date_check (epoch) from article's Date + now TIME
+ if not post_err:
+ fmt_check = '%Y-%m-%d %H:%M:%S'
+ time_check = strftime("%H:%M:%S", gmtime())
+ date_check = date + ' ' + time_check
+ date_check = time.mktime(time.strptime(date_check, fmt_check))
+
+ # Set franch format in post DB
+ if lang_site == 'fr':
+ date = date.rsplit('-')
+ date = date[2] + '/' + date[1] + '/' + date[0]
+
+ date = (date, date_check)
+
+
+#===========================================#
+# Check optional tags from article's header #
+# Multiple settings for each on 3 lines #
+#-------------------------------------------#
+def check_opt_tags(post_header):
+ global stat_links, stat_images, stat_files, stat_raws, stat_abbrs
+ global stat_snpics, snpic_url
+ global opt_tags_post_name
+ global files_post
+
+ # Statistics
+ stat_links = stat_images = stat_files = stat_raws = stat_abbrs = 0
+ stat_snpics = 0
+ files_post = (())
+
+ # Set default post pic
+ snpic_url = '%s/template/%s'%(dom.www_url, dom.logo)
+
+ # Search for term in article
+ opt_tags_post_name = \
+ {
+ 'link' : "_%s",
+ 'image' : "_image:%s",
+ 'file' : "__%s",
+ 'raw' : "_raw:%s",
+ 'abbr' : "(%s)"
+ }
+
+ # Check post header for each optional tags
+ for tag in tyto.opt_header_tags:
+ for ln, line in enumerate(post_header, 1):
+ if line.startswith('%s:'%tag):
+ check_3lines(tag, ln, line)
+
+
+#============================================#
+# Do stats, check 3 lines tags from ln #
+# Set data for each 2 next lines #
+# Exception for snpic (Different conditions) #
+#--------------------------------------------#
+def check_3lines(tag, ln, line):
+ global post_err, db_tag, files_post
+
+ stat_tag = "stat_%ss"%tag
+
+ # Create variable for post DB
+ globals()[stat_tag] += 1
+ db_tag = '%s_%s'%(tag, globals()[stat_tag])
+ globals()[db_tag] = (())
+
+ # NAME
+ #-----
+ # ln is legacy (from loop), so take line content
+ # Take only first word if not a long name tag
+ if tag in tyto.opt_tags_long_name:
+ name = line.rsplit('%s:'%tag)[1].lstrip()
+ else:
+ name = line.rsplit('%s:'%tag)[1].lstrip().rsplit(' ')[0]
+ if tag == "abbr":
+ name = name.upper()
+
+ if not name:
+ logs.out("2", 'L=%s. "%s: %s" > %s'%(
+ ln, tag, tr.name, db.uri_file
+ ), False)
+ post_err = True
+
+ # snpic only needs a Name
+ elif tag == "snpic":
+ check_snpic(name)
+ return
+
+ elif not isin(r'\b%s\b'%(opt_tags_post_name[tag]%name), post_bottom):
+ logs.out("12", '"%s" > %s'%(
+ opt_tags_post_name[tag]%name, db.uri_file
+ ), False)
+ post_err = True
+
+ globals()[db_tag] = ((name),)
+
+ # URI/URL and Alt-Text
+ #---------------------
+ # loop 1,2. Next real line from start tag
+ for l in range(1,3):
+ if l == 1: data_log = "URI/URL"
+ elif l == 2: data_log = "Alt-Text"
+
+ ln += 1
+ try:
+ # ln - 1 as string post_header starts with 0
+ data = post_header.rsplit('\n')[ln - 1].lstrip()
+ if data.startswith(tyto.headers): data = ''
+ except:
+ data = ''
+
+ if not data:
+ logs.out("2", 'L=%s. "%s" (%s:) > %s'%(
+ ln, data_log, tag, db.uri_file
+ ), False)
+ post_err = True
+
+ # For tags having URI, check if file exists
+ # Set data for post DB
+ if l == 1 and tag in tyto.opt_tags_check_uri:
+ check_file_uri(tag, data, ln)
+ globals()[db_tag] = globals()[db_tag] + ((web_uri),)
+ files_post = files_post + (('%s'%web_uri),)
+ else:
+ globals()[db_tag] = globals()[db_tag] + ((data),)
+
+
+#=====================#
+# Find in post_bottom #
+#---------------------#
+def isin(term, post_file):
+ for line in post_file.rsplit('\n'):
+ if re.search(term, line):
+ return(True)
+ return(False)
+
+
+#===================================#
+# Check if file exists #
+# Get filetype, filename, i=var nbr #
+#-----------------------------------#
+def check_file_uri(filetype, filename, ln):
+ global post_err, err, web_uri
+
+ # Set file uri from filename
+ # (@ = images/, / = articles/, else = post_dir)
+ if filename.startswith('@'):
+ if filetype == 'image' or filetype == "snpic":
+ fileuri = dom.images_d + filename[1: len(filename)]
+ elif filetype == 'file' or filetype == 'raw':
+ fileuri = dom.files_d + filename[1: len(filename)]
+
+ else:
+ post_dir = db.uri_file.split("/")[-1]
+ post_dir = db.uri_file.rsplit(post_dir)[0]
+ if filename.startswith('/'):
+ fileuri = post_dir + filename[1: len(filename)]
+ else:
+ fileuri = post_dir + filename
+
+ # Check if file exists
+ if not filetype == "snpic" and not tyto.exists(fileuri):
+ logs.out("1", "L=%s. %s > %s"%(ln, fileuri, db.uri_file), False)
+ post_err = True
+ return
+
+ web_uri = '/' + fileuri.replace(dom.articles_d, "")
+
+
+#====================================#
+# Check for snpic #
+# (Used pic for social network) #
+# Needs: #
+# - a Name #
+# - an image tag set with same name #
+#-----------------------------------#
+def check_snpic(name):
+ global snpic_url, snpic_post, post_err
+
+ try:
+ snpic_post
+ return
+ except:
+ pass
+
+ # Search post_header for image: %name
+ Found = False
+ tag = tyto.opt_header_tags[1]
+ for ln, line in enumerate(post_header.rsplit('\n'), 1):
+ if line.startswith('%s:'%tag):
+ try:
+ check_name = line.rsplit('%s:'%tag)[1].lstrip().rsplit(' ')[0]
+ except:
+ check_name = ''
+
+ if check_name == name:
+ Found = True
+ snpic_post = post_header.rsplit('\n')[ln].lstrip()
+ check_file_uri("snpic", snpic_post, ln)
+ break
+
+ if not Found:
+ logs.out("27", '"%s: %s" > %s'%(tag, name, db.uri_file), False)
+ return
+
+ snpic_post = True
+ snpic_url = dom.www_url + web_uri
+
+
+#===========================#
+# Check tags in post_bottom #
+#---------------------------#
+def check_content(post_bottom):
+ global post_err
+
+ # Check if anchor has target
+ # Count anchors target
+ #---------------------------
+ for ln, line in enumerate(post_bottom.rsplit('\n'), 1):
+ # Anchor link
+ if tyto.words_tags[0][0] and tyto.words_tags[0][1] in line:
+ anchors = re.findall(r">_(.*?)_<", line)
+ for anchor in anchors:
+ css_anchor = anchor.rsplit(':')[0]
+ tag = '%s %s'%(tyto.single_tags[1][0], css_anchor)
+ if not tag in post_bottom:
+ logs.out("12", 'L=%s. anchor "%s" > %s'%(
+ ln + ln_header, tag, db.uri_file
+ ), False)
+ post_err = True
+
+ # Anchor source "->"
+ if line.startswith(tyto.single_tags[1][0]):
+ set_css = tyto.get_css(line)
+ is_uniq_anchor = "%s %s"%(tyto.single_tags[1][0], set_css)
+ c_uniq_anchor = post_bottom.count(is_uniq_anchor)
+ if c_uniq_anchor > 1:
+ logs.out("15", 'L=%s. %sx "%s" > %s'%(
+ ln + ln_header, c_uniq_anchor, is_uniq_anchor,
+ db.uri_file
+ ), False)
+ post_err = True
+ break
+
+
+ # Lists: check if contents are valid
+ #-----------------------------------
+ inlist = False
+ markers_lists = '%s, %s, or space'%(
+ tyto.markers_lists[0],
+ tyto.markers_lists[1]
+ )
+ for ln, line in enumerate(article.rsplit('\n'), 1):
+ if line.startswith('-('): inlist = True;continue
+ elif line.startswith('-)'): inlist = False
+ if not inlist: continue
+
+ if inlist and not line or not line[0] in tyto.markers_lists:
+ logs.out("3", 'line %s must start with %s'%(
+ ln, markers_lists
+ ), False
+ )
+ post_err = True
+
+
+ # Check for all match _TAGS:NAME from content in header
+ #------------------------------------------------------
+ set_tags = ()
+ for ln, line in enumerate(post_bottom):
+ for htag in tyto.head_tags:
+ match = False
+ ptag = '_%s'%htag
+
+ if line.startswith(ptag):
+ ptag_set = line.rsplit(':', 1)[1].lstrip().rsplit(' ')[0]
+ if ptag_set in set_tags: continue
+ for hline in post_header:
+ if re.search(r"^%s\s+%s$"%(htag,ptag_set), hline):
+ match = True
+ set_tags = (ptag_set)
+
+ if match: continue
+ else:
+ logs.out("12", "%s %s"%(htag, ptag_set), False)
+ post_err = True
+
+
+ # Check tags for words (strongs, italics...)
+ # Set stats for each one
+ #-------------------------------------------
+ for tag in tyto.words_tags:
+ c_opened = c_closed = 0
+
+ if tag[5] == 'w':
+ c_opened = post_bottom.count(tag[0])
+ c_closed = post_bottom.count(tag[1])
+ # Useless tag now, replace
+ post_bottom = post_bottom.replace(tag[0], '')
+ post_bottom = post_bottom.replace(tag[1], '')
+ elif tag[5] == 't':
+ for line in post_bottom.rsplit('\n'):
+ if line.startswith(tag[0]): c_opened += 1
+ if line.startswith(tag[1]): c_closed += 1
+
+ if c_opened != c_closed:
+ logs.out("8", '%s "%s" + "%s" > %s'%(
+ tag[4], tag[0], tag[1], db.uri_file
+ ), False)
+ post_err = True
+ return # Useless and could code errors to check nexts
+ else:
+ globals()['post_%s'%tag[4]] = int(c_opened)
+
+
+ # Template Tags (warning for not paired symbols)
+ #-----------------------------------------------
+ for tag in tyto.tpl_tags:
+ tpl1 = post_bottom.count(tag[0])
+ tpl2 = post_bottom.count(tag[1])
+
+ if tpl1 != tpl2:
+ logs.out("22", '"%s" + "%s" > %s'%(
+ tag[0], tag[1], db.uri_file
+ ), False)
+
+
+#===============================#
+# Create new article's database #
+#------------------------------&co-#
+def create_database():
+ # Post Configurations
+ #--------------------
+ database = \
+ '# Post Configurations\n' + \
+ 'post_id = "%s"\n'%db.uri_id + \
+ 'post_src = "%s"\n'%db.uri_file + \
+ 'post_wip = "%s"\n'%srv_post_wip_uri + \
+ 'post_www = "%s"\n'%srv_post_www_uri + \
+ '\n' + \
+ 'direc_src = "%s"\n'%direc_src + \
+ 'short_src = "%s"\n'%src_post_short_uri + \
+ 'short_srv = "%s"\n'%srv_post_short_uri + \
+ 'sub_uri = "%s"\n'%sub_uri + \
+ 'http_wip = "%s"\n'%http_wip + \
+ 'http_www = "%s"\n'%http_www + \
+ '\n' + \
+ 'date_chk = "%s"\n'%tyto.nowdate() + \
+ 'hash_chk = "%s"\n'%db.hash_post + \
+ 'date_wip = "%s"\n'%date_wip + \
+ 'hash_wip = "%s"\n'%hash_wip + \
+ 'date_www = "%s"\n'%date_www + \
+ 'hash_www = "%s"\n'%hash_www + \
+ '\n# Needed tags configurations\n' + \
+ 'title = "%s"\n'%title + \
+ 'about = "%s"\n'%about + \
+ 'author = "%s"\n'%author + \
+ 'tags = "%s"\n'%tags + \
+ 'date = "%s"\n'%date + \
+ 'snpic = "%s"\n'%snpic_url + \
+ '\n# Used files\n' + \
+ 'uris = %s'%str(files_post)
+
+
+ # Tags configuration
+ #-------------------
+ datas_tag = ''
+ if stat_abbrs > 0:
+ for i in range(1, stat_abbrs + 1):
+ datas_tag = '%s\nabbr_%s = %s'%(
+ datas_tag, i, globals()['abbr_%s'%i]
+ )
+
+ if stat_links > 0:
+ for i in range(1, stat_links + 1):
+ datas_tag = '%s\nlink_%s = %s'%(
+ datas_tag, i, globals()['link_%s'%i]
+ )
+
+ if stat_images > 0:
+ for i in range(1, stat_images + 1):
+ datas_tag = '%s\nimage_%s = %s'%(
+ datas_tag, i, globals()['image_%s'%i]
+ )
+
+ if stat_files > 0:
+ for i in range(1, stat_files + 1):
+ datas_tag = '%s\nfile_%s = %s'%(
+ datas_tag, i, globals()['file_%s'%i]
+ )
+
+ if stat_raws > 0:
+ for i in range(1, stat_raws + 1):
+ datas_tag = '%s\nraw_%s = %s'%(
+ datas_tag, i, globals()['raw_%s'%i]
+ )
+
+ opt_tags = ''
+ if datas_tag:
+ opt_tags = \
+ '\n# Optional tags configurations' + \
+ '%s\n'%datas_tag
+
+ # Statistics configurations
+ #--------------------------
+ stat_words = post_words - nbr_titles # Count real words
+
+ db_stats = \
+ '# Statistics configurations\n' + \
+ 'uniq_anchors = %d\n'%nbr_ancs + \
+ 'uniq_abbrs = %d\n'%stat_abbrs + \
+ 'uniq_links = %d\n'%stat_links + \
+ 'uniq_images = %d\n'%stat_images + \
+ 'uniq_files = %d\n'%stat_files + \
+ 'uniq_raws = %d\n'%stat_raws + \
+ '\n# Statistics from post content\n' + \
+ 'stat_tags = %d\n'%stat_tags + \
+ 'stat_lines = %d\n'%ln_article + \
+ 'stat_words = %d\n'%stat_words + \
+ 'stat_titles = %d\n'%nbr_titles + \
+ 'stat_paragraphs = %d\n'%post_paragraphs + \
+ 'stat_anchors = %d\n'%post_anchors + \
+ 'stat_strongs = %d\n'%post_strongs + \
+ 'stat_bolds = %d\n'%post_bolds + \
+ 'stat_emphasis = %d\n'%post_emphasis + \
+ 'stat_italics = %d\n'%post_italics + \
+ 'stat_dels = %d\n'%post_dels + \
+ 'stat_underlines = %d\n'%post_underlines + \
+ 'stat_cites = %d\n'%post_cites + \
+ 'stat_customs = %d\n'%post_customs + \
+ 'stat_icodes = %d\n'%tyto.nbr_icodes + \
+ 'stat_bcodes = %d\n'%nbr_bcodes + \
+ 'stat_quotes = %d\n'%nbr_quotes + \
+ 'stat_lists = %d\n'%post_lists
+
+ # Create Post DB
+ #---------------
+ database = '%s\n%s\n%s'%(database, opt_tags, db_stats)
+ tyto.set_file(db.config, 'new', database)
+ logs.out("21", db.uri_file, False)
+
+
+
+
+
+
+
#==================================#
# Check tags from article's header #
#----------------------------------#
@@ -334,77 +849,12 @@ def check_headers(post_header):
snpic_name = ''
# Needed Tags
- title = author = tags = about = ''
+ title = author = about = tags = ''
date = ()
# Statistics
stat_links = stat_images = stat_files = stat_raws = stat_abbrs = 0
-###
- # First session for needed tags #
- # Read articles lines, till separator #
- #-------------------------------------#
- for ln, line in enumerate(post_header, 1):
- # Set each needed tag #
- # Only the first one is set #
- #---------------------------#
- tag = tyto.headers[0] # title:
- if line.startswith(tag):
- if title: continue
- title = line.rsplit(tag)[1].lstrip()
- continue
-
- tag = tyto.headers[1] # about:
- if line.startswith(tag):
- if about: continue
- about = line.rsplit(tag)[1].lstrip()
- continue
-
- tag = tyto.headers[2] # author:
- if line.startswith(tag):
- if author: continue
- author = line.rsplit(tag)[1].lstrip()
- continue
-
- tag = tyto.headers[3] # tags:
- if line.startswith(tag):
- if tags: continue
- tags = line.rsplit(tag)[1].lstrip()
- post_tags = len(tags.strip().split(","))
- continue
-
- tag = tyto.headers[4] # date:
- if line.startswith(tag):
- if date: continue
- date = line.rsplit(tag)[1].lstrip()
- check_date(date, ln, line)
-
- if not post_err:
- if lang_site == 'fr':
- date = date.rsplit('-')
- date = date[2] + '/' + date[1] + '/' + date[0]
- date = (date, date_check)
- continue
-
-
- # Check needed tags #
- #-------------------#
- # Set needed tags
- need_headers = \
- {
- tyto.headers[0] : title,
- tyto.headers[1] : about,
- tyto.headers[2] : author,
- tyto.headers[3] : tags,
- tyto.headers[4] : date
- }
-
- # Check if set needed tags
- for tag in need_headers:
- if not need_headers[tag]:
- logs.out("17", tag, False)
- post_err = True
-
###
# Second session for optional tags #
@@ -707,280 +1157,3 @@ def check_headers(post_header):
post_err = True
-#================================#
-# Check Date format and validity #
-# Create False date_check #
-#--------------------------------#
-def check_date(date, ln, line):
- global post_err, date_check
-
- # Check if article date is valid (True)
- fmt_article = "%Y-%m-%d"
-
- try:
- bool(datetime.strptime(date, fmt_article))
- except ValueError:
- post_err = True
- print(" ├─", line)
- logs.out("3", 'date: L=%s. "%s" > %s'%(
- ln, date, db.uri_file
- ), False)
-
- # Create date_check (epoch) from article's Date + now TIME
- if not post_err:
- fmt_check = '%Y-%m-%d %H:%M:%S'
- time_check = strftime("%H:%M:%S", gmtime())
- date_check = date + ' ' + time_check
- date_check = time.mktime(time.strptime(date_check, fmt_check))
-
-
-#===================================#
-# Check if file exists #
-# Get filetype, filename, i=var nbr #
-#-----------------------------------#
-def check_file_uri(filetype, filename, ln):
- global post_err, err, web_uri
-
- # Set file uri from filename
- # (@ = images/, / = articles/, else = post_dir)
- if filename.startswith('@'):
- if filetype == 'image':
- fileuri = dom.images_d + filename[1: len(filename)]
- elif filetype == 'file':
- fileuri = dom.files_d + filename[1: len(filename)]
-
- else:
- post_dir = db.uri_file.split("/")[-1]
- post_dir = db.uri_file.rsplit(post_dir)[0]
- if filename.startswith('/'):
- fileuri = post_dir + filename[1: len(filename)]
- else:
- fileuri = post_dir + filename
-
- # Check if file exists
- if not tyto.exists(fileuri):
- logs.out("1", "L=%s. %s > %s"%(ln, fileuri, db.uri_file), False)
- post_err = True
- return
-
- web_uri = '/' + fileuri.replace(dom.articles_d, "")
-
-
-#===========================#
-# Check tags in post_bottom #
-#---------------------------#
-def check_content(post_bottom):
- global post_err
-
- #print("post_bottom")
- #print(post_bottom)
-
- # Check tags for words (strongs, italics...)
- # Set stats for each one
- #-------------------------------------------
- for tag in tyto.words_tags:
- c_opened = c_closed = 0
-
- if tag[5] == 'w':
- c_opened = post_bottom.count(tag[0])
- c_closed = post_bottom.count(tag[1])
- # Useless tag now, replace
- post_bottom = post_bottom.replace(tag[0], '')
- post_bottom = post_bottom.replace(tag[1], '')
- elif tag[5] == 't':
- for line in post_bottom.rsplit('\n'):
- if line.startswith(tag[0]): c_opened += 1
- if line.startswith(tag[1]): c_closed += 1
-
- if c_opened != c_closed:
- logs.out("8", '%s: "%s", "%s"'%(tag[4], tag[0], tag[1]), False)
- post_err = True
- return # Useless and could code errors to check nexts
- else:
- globals()['post_%s'%tag[4]] = int(c_opened)
-
-
- # Check if anchor has target
- # Count anchors target
- #---------------------------
- for line in post_bottom.rsplit('\n'):
- # Anchor link
- if tyto.words_tags[0][0] and tyto.words_tags[0][1] in line:
- anchors = re.findall(r">_(.*?)_<", line)
- for anchor in anchors:
- css_anchor = anchor.rsplit(':')[0]
- tag = '%s %s'%(tyto.single_tags[1][0], css_anchor)
- if not tag in post_bottom:
- logs.out("6", 'anchor, %s'%tag, False)
- post_err = True
-
- # Anchor source "->"
- elif line.startswith(tyto.single_tags[1][0]):
- set_css = tyto.get_css(line)
- is_uniq_anchor = "%s %s"%(tyto.single_tags[1][0], set_css)
- c_uniq_anchor = post_bottom.count(is_uniq_anchor)
- if c_uniq_anchor > 1:
- logs.out("15", '%s "%s"'%(c_uniq_anchor, is_uniq_anchor), False)
- post_err = True
- break
-
-
- # Lists: check if contents are valid
- #-----------------------------------
- inlist = False
- markers_lists = '%s, %s, or space'%(
- tyto.markers_lists[0],
- tyto.markers_lists[1]
- )
- for ln, line in enumerate(article.rsplit('\n'), 1):
- if line.startswith('-('): inlist = True;continue
- elif line.startswith('-)'): inlist = False
- if not inlist: continue
-
- if inlist and not line or not line[0] in tyto.markers_lists:
- logs.out("3", 'line %s must start with %s'%(
- ln, markers_lists
- ), False
- )
- post_err = True
-
-
- # Check for all match _TAGS:NAME from content in header
- #------------------------------------------------------
- set_tags = ()
- for ln, line in enumerate(post_bottom):
- for htag in tyto.head_tags:
- match = False
- ptag = '_%s'%htag
-
- if line.startswith(ptag):
- ptag_set = line.rsplit(':', 1)[1].lstrip().rsplit(' ')[0]
- if ptag_set in set_tags: continue
- for hline in post_header:
- if re.search(r"^%s\s+%s$"%(htag,ptag_set), hline):
- match = True
- set_tags = (ptag_set)
-
- if match: continue
- else:
- logs.out("12", "%s %s"%(htag, ptag_set), False)
- post_err = True
-
-
- # Template Tags (warning for not paired symbols)
- #-----------------------------------------------
- for tag in tyto.tpl_tags:
- tpl1 = post_bottom.count(tag[0])
- tpl2 = post_bottom.count(tag[1])
-
- if tpl1 != tpl2:
- logs.out("22", '"%s", "%s"'%(tag[0], tag[1]), False)
-
-
-#===============================================#
-# Create new article's database at each check ! #
-#-----------------------------------------------#
-def create_database():
- database = '# Post Configuration for Tyto\n' + \
- 'post_id = "%s"\n'%db.uri_id + \
- 'post_src = "%s"\n'%db.uri_file + \
- 'post_wip = "%s"\n'%srv_post_wip_uri + \
- 'post_www = "%s"\n'%srv_post_www_uri + \
- '\n' + \
- 'direc_src = "%s"\n'%direc_src + \
- 'short_src = "%s"\n'%src_post_short_uri + \
- 'short_srv = "%s"\n'%srv_post_short_uri + \
- 'sub_uri = "%s"\n'%sub_uri + \
- 'http_wip = "%s"\n'%http_wip + \
- 'http_www = "%s"\n'%http_www + \
- '\n' + \
- 'date_chk = "%s"\n'%tyto.nowdate() + \
- 'hash_chk = "%s"\n'%db.hash_post + \
- 'date_wip = "%s"\n'%date_wip + \
- 'hash_wip = "%s"\n'%hash_wip + \
- 'date_www = "%s"\n'%date_www + \
- 'hash_www = "%s"\n'%hash_www + \
- '\n# Post configuration from needed tags\n' + \
- 'title = "%s"\n'%title + \
- 'about = "%s"\n'%about + \
- 'author = "%s"\n'%author + \
- 'tags = "%s"\n'%tags + \
- 'date = %s\n'%str(date) + \
- 'snpic = "%s"\n'%snpic_url + \
- '\n# Used files\n' + \
- 'uris = (%s)\n'%files_post + \
- '\n# Post configuration from optional tags'
-
- if stat_abbrs > 0:
- for i in range(1, stat_abbrs + 1):
- database = '%s\nabbr_%s = %s'%(
- database, i, globals()['abbr_%s'%i]
- )
-
- if stat_links > 0:
- for i in range(1, stat_links + 1):
- database = '%s\nlink_%s = %s'%(
- database, i, globals()['link_%s'%i]
- )
-
- if stat_images > 0:
- for i in range(1, stat_images + 1):
- database = '%s\nimage_%s = %s'%(
- database, i, globals()['image_%s'%i]
- )
-
- if stat_files > 0:
- for i in range(1, stat_files + 1):
- database = '%s\nfile_%s = %s'%(
- database, i, globals()['file_%s'%i]
- )
-
- if stat_raws > 0:
- for i in range(1, stat_raws + 1):
- database = '%s\nraw_%s = %s'%(
- database, i, globals()['raw_%s'%i]
- )
-
- # Count real words
- stat_words = post_words - nbr_titles
-
- db_stats = '\n# Statistics from optional tags\n' + \
- 'uniq_anchors = %d\n'%nbr_ancs + \
- 'uniq_abbrs = %d\n'%stat_abbrs + \
- 'uniq_links = %d\n'%stat_links + \
- 'uniq_images = %d\n'%stat_images + \
- 'uniq_files = %d\n'%stat_files + \
- 'uniq_raws = %d\n'%stat_raws + \
- '\n# Statistics from post content\n' + \
- 'stat_tags = %d\n'%post_tags + \
- 'stat_words = %d\n'%stat_words + \
- 'stat_titles = %d\n'%nbr_titles + \
- 'stat_paragraphs = %d\n'%post_paragraphs + \
- 'stat_anchors = %d\n'%post_anchors + \
- 'stat_strongs = %d\n'%post_strongs + \
- 'stat_bolds = %d\n'%post_bolds + \
- 'stat_emphasis = %d\n'%post_emphasis + \
- 'stat_italics = %d\n'%post_italics + \
- 'stat_dels = %d\n'%post_dels + \
- 'stat_underlines = %d\n'%post_underlines + \
- 'stat_cites = %d\n'%post_cites + \
- 'stat_customs = %d\n'%post_customs + \
- 'stat_icodes = %d\n'%tyto.nbr_icodes + \
- 'stat_bcodes = %d\n'%nbr_bcodes + \
- 'stat_quotes = %d\n'%nbr_quotes + \
- 'stat_lists = %d\n'%post_lists
-
-
- database = '%s\n%s'%(database, db_stats)
- tyto.set_file(db.config, 'new', database)
- logs.out("21", db.uri_file, False)
-
-
-#=====================#
-# Find in post_bottom #
-#---------------------#
-def isin(term, post_bottom):
- for x in post_bottom.rsplit('\n'):
- if re.search(r'%s'%term, x):
- return(True)
- return(False)
diff --git a/src/var/lib/tyto/program/logs.py b/src/var/lib/tyto/program/logs.py
index 6320d84..9ff1ea7 100644
--- a/src/var/lib/tyto/program/logs.py
+++ b/src/var/lib/tyto/program/logs.py
@@ -36,7 +36,7 @@ def out(nbr, value, out):
'3' : ' ╞ %s%s%s %s'%(CR, lang.data_inv, CS, value),
'4' : ' ╘ %sUnable to create file%s: %s'%(CR, CS, value),
'5' : ' ╘ %s%s%s > "%s"'%(CR, lang.no_arg, CS, value),
- '6' : ' ╞ %s%s%s > "%s"'%(CR, lang.sep_inv, CS, value),
+ '6' : ' ╞ %s%s%s > %s'%(CR, lang.sep_inv, CS, value),
'7' : ' ╘ %s%s%s > %s'%(CR, lang.post_inv, CS, value),
'8' : ' ╞ %s%s%s %s'%(CR, lang.mark_np, CS, value),
'9' : ' ╞ Article %shas changed%s. Check it first'%(CR, CS),
@@ -45,7 +45,7 @@ def out(nbr, value, out):
'12' : ' ╞ %s%s%s > %s'%(CR, lang.post_inc, CS, value),
'13' : ' ╞ %s%s%s'%(CR, lang.no_fidi, CS),
'14' : ' ╞ %sMismatch%s program start'%(CR, CS),
- '15' : ' ╞ Anchor %snot uniq%s: %s'%(CR, CS, value),
+ '15' : ' ╞ %s%s%s %s'%(CR, lang.anch_nu, CS, value),
'16' : ' ╞ %s%s%s "%s = ?"'%(CR, lang.unused_c, CS, value),
'17' : ' ╞ %s%s%s "%s ?"'%(CR, lang.unused_v, CS, value),
'18' : ' ╘ %s%s%s > %s'%(CR, lang.unused_p, CS, value),
@@ -57,6 +57,7 @@ def out(nbr, value, out):
'24' : ' ╞ %s%s%s > %s'%(CY, lang.unused_r, CS, value),
'25' : ' ╞ Article %snot yet checked%s: %s'%(CY, CS, value),
'26' : ' ╞ %sNo index%s article %s'%(CY, CS, value),
+ '27' : ' ╞ %s%s%s %s'%(CY, lang.snpic_d, CS, value),
'28' : ' ╘ %s (%s)'%(lang.ntd, value),
'29' : ' ╞ %sEmpty configuration%s %s'%(CY, CS, value),
'30' : ' ╞ Article %snot yet wip%s: %s'%(CY, CS, value),
diff --git a/src/var/lib/tyto/program/show.py b/src/var/lib/tyto/program/show.py
index 63a0cb8..6f7a266 100644
--- a/src/var/lib/tyto/program/show.py
+++ b/src/var/lib/tyto/program/show.py
@@ -145,7 +145,12 @@ def read_lines(f):
if not tyto.exists(f): logs.out("1", f, True)
datas = open(f).read()
- for line in datas.rsplit('\n'):
- print(' │', line)
+ ln_datas = len(datas.splitlines()) + 1
+ sp_max = len(str(ln_datas))
+ spaces = '%s'%(sp_max * " ")
+ for ln, line in enumerate(datas.rsplit('\n'), 1):
+ sp = sp_max - len(str(ln))
+
+ print(' │ %s %s│ %s'%(ln, int(sp) * " ", line))
dom.valid()
diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py
index f934bf9..295f4cf 100644
--- a/src/var/lib/tyto/program/tyto.py
+++ b/src/var/lib/tyto/program/tyto.py
@@ -61,6 +61,40 @@ trans = [
]
+# Needed header tags
+needed_header_tags = \
+(
+'title',
+'about',
+'author',
+'tags',
+'date'
+)
+
+# Optional header tags
+opt_header_tags = \
+(
+'link',
+'image',
+'file',
+'abbr',
+'raw',
+'snpic'
+)
+
+opt_tags_long_name = \
+(
+'link',
+'file'
+)
+
+opt_tags_check_uri = \
+(
+'image',
+'file',
+'raw'
+)
+
# Set all tags used in article's header
headers = (
'title:',
diff --git a/src/var/lib/tyto/translations/logs_en.py b/src/var/lib/tyto/translations/logs_en.py
index 41340f2..03cbeab 100644
--- a/src/var/lib/tyto/translations/logs_en.py
+++ b/src/var/lib/tyto/translations/logs_en.py
@@ -41,5 +41,7 @@ unused_v = "Unused value in article"
unused_p = "Empty article"
mark_np = "Not paired marks"
symb_np = "Not paired symbols"
+snpic_d = "Using default snpic. Not found"
+anch_nu = "Anchor not uniq"
laterout = "Maybe later..."
diff --git a/src/var/lib/tyto/translations/logs_fr.py b/src/var/lib/tyto/translations/logs_fr.py
index f0b184d..bf5ee0b 100644
--- a/src/var/lib/tyto/translations/logs_fr.py
+++ b/src/var/lib/tyto/translations/logs_fr.py
@@ -41,5 +41,7 @@ unused_v = "Valeur manquante dans l'article"
unused_p = "L'article est vide"
mark_np = "Marqueurs non jumelés"
symb_np = "Symboles non jumelés"
+snpic_d = "snpic utilisé par défaut. Manquant"
+anch_nu = "Ancre non unique"
laterout = "Pour plus tard..."