Commit 5f33af3c authored by Denis Salem's avatar Denis Salem
Browse files

done with chapters engine

parent df4a0fd7
......@@ -2,7 +2,7 @@ author_description: I'm a artist and software engineer
author_email: denissalem 47 tuxfamily D07 org
author_name: Denis Salem
blog_description: A fancy static blog generator for everyone!
blog_keywords: blog static foss open-source denissalem free software generator web content python script linux
blog_keywords: blog static foss open-source denissalem free software generator web content python script linux jamstack
blog_language: fr
blog_name: VenC
blog_url: https://denissalem.tuxfamily.org/VenC
......@@ -27,14 +27,14 @@ path:
reverse_thread_order: false
feed_lenght: 5
text_editor: gvim
disable_rss_feed: false
disable_atom_feed: false
disable_main_thread: false
disable_rss_feed: true
disable_atom_feed: true
disable_main_thread: true
disable_threads: ""
disable_archives: true
disable_categories: false
disable_single_entries: true
disable_categories: true
disable_single_entries: false
banner: 'https://download.tuxfamily.org/dsalem/img/2017_-_Denis_Salem_-_CC_By_SA_-_VenC-logo.svg'
path_encoding: 'windows-1252'
server_port: 8888
sort_by: 'title'
sort_by: 'chapter'
authors: 'Denis Salem'
categories: '1. Présentation'
categories: ''
tags: ''
title: '1. Présentation'
title: 'Présentation'
chapter: 1
---VENC-BEGIN-PREVIEW---
---VENC-END-PREVIEW---
VenC est une application python conçue pour linux et similaire à [Octopress](http://octopress.org)/[Jekyll](http://jekyllrb.com) ou [Pelican](http://docs.getpelican.com/en/stable/) pour gérer et créer vos blogs statiques via la console. Avec VenC, tout est fichier texte, pas de base de données. La configuration de chaque blog repose sur un unique et petit fichier [Yaml](http://yaml.org/), les thèmes consistent en une poignée de templates HTML à modifier ou créer soi même, les publications quant à elles, se présentent sous la forme d'une partie [YAML](http://yaml.org/) et d'une autre [Markdown](https://daringfireball.net/projects/markdown/syntax) ou [reStructuredText](http://docutils.sourceforge.net/rst.html).
......
authors: 'Denis Salem'
categories: '2. Installation'
categories: ''
chapter: 2
tags: ''
title: Installation
---VENC-BEGIN-PREVIEW---
......
authors: ''
categories: '3. Tutoriels > 1. Créer son blog en moins de 5 minutes!'
categories: ''
chapter: 3.1
tags: ''
title: Créer son blog en moins de 5 minutes!
---VENC-BEGIN-PREVIEW---
......
......@@ -18,7 +18,6 @@
<header>
<h1><a href=".:GetRootPage:."><img src=".:GetRelativeOrigin:.logo.png" alt=".:GetBlogName:." title=".:GetBlogName:." /></a></h1>
</header>
.:TreeForBlogCategories::<ul>::<li><a href="{path}#entry-content">{value}</a>::</li>::</ul>:.
<ul>.:ForBlogDates::<li><a href="{path}">{value}</a></li>:.</ul>
.:Chapters::<ul class="chapter-level{level}">::<li>{index}. <a href="{path}">{title}</a>::</li>::</ul>:.
</aside>
<div id="content">
......@@ -144,12 +144,13 @@
DONE | Update command help with.
DONE | Handle ftp encoding error.
DONE | Sort by metadata.
DONE | Speed up blog exportation (nine times faster!).
DONE | Escape patterns
WIP | Chapters engine.
DONE | Speed up blog exportation (almost nine times faster!).
DONE | Escape patterns.
DONE | Chapters engine.
TODO | Fix unit test.
TODO | Fix pattern (i.e .:GetEntryTitle:.) access in template's metadata.
TODO | Open with navigator manual.
TODO | Client-side search engine.
TODO | Fix unit test.
TODO | Reorganize themes dependencies in setup (adding default templates, scripts, and pages to include).
TODO | Add relevant templates for themes.
TODO | fix FAQ https://stackoverflow.com/questions/14547631/python-locale-error-unsupported-locale-setting.
......@@ -162,6 +163,7 @@
TODO | Make some dependencies optional.
TODO | Split themes from main branch
TODO | Add translation for Deutsch and Spanish.
TODO | Add ForMetadata, ForMetadataIfExists
TODO | Add docutils reStructuredText parser settings override.
TODO | Decrease halt_level to render reStructuredText even if errors occurs.
TODO | Access {count} and {weight} from LeavesForEntrycategories.
......
......@@ -89,7 +89,8 @@ non_contextual_pattern_names_blog = {
"GetBlogMetadataIfExists" : "get_blog_metadata_if_exists",
"ForBlogDates" : "for_blog_dates",
"LeavesForBlogCategories" : "leaves_for_blog_categories",
"TreeForBlogCategories" : "tree_for_blog_categories"
"TreeForBlogCategories" : "tree_for_blog_categories",
"Chapters" : "get_chapters"
}
non_contextual_pattern_names_datastore = {
......
......@@ -52,7 +52,9 @@ class DataStore:
self.html_categories_leaves = {}
self.html_blog_dates = {}
self.generation_timestamp = datetime.datetime.now()
self.chapters = {}
self.raw_chapters = {}
self.chapters_index = []
self.html_chapters = {}
# Build entries
for filename in yield_entries_content():
......@@ -61,26 +63,22 @@ class DataStore:
self.entries = sorted(self.entries, key = lambda entry : self.sort_by(entry))
for entry_index in range(0, len(self.entries)):
current_entry = self.entries[entry_index]
if entry_index > 0:
self.entries[entry_index-1].next_entry = self.entries[entry_index]
self.entries[entry_index].previous_entry = self.entries[entry_index-1]
self.entries[entry_index-1].next_entry = current_entry
current_entry.previous_entry = self.entries[entry_index-1]
# Update entriesPerDates
if self.blog_configuration["path"]["dates_directory_name"] != '':
formatted_date = self.entries[entry_index].date.strftime(self.blog_configuration["path"]["dates_directory_name"])
formatted_date = current_entry.date.strftime(self.blog_configuration["path"]["dates_directory_name"])
entries_indexes = self.get_entries_index_for_given_date(formatted_date)
if entries_indexes != None:
self.entries_per_dates[entries_indexes].count +=1
self.entries_per_dates[entries_indexes].related_to.append(entry_index)
else:
self.entries_per_dates.append(MetadataNode(formatted_date, entry_index))
try:
self.update_chapters(self.entries[entry_index].chapter, entry_index)
except AttributeError:
pass
# Update entriesPerCategories
try:
sub_folders = urllib.parse.quote(self.blog_configuration["path"]["categories_sub_folders"]+'/', encoding=self.blog_configuration["path_encoding"])
......@@ -90,13 +88,45 @@ class DataStore:
notify("\"{0}\": ".format(sub_folders)+str(e), color="YELLOW")
sub_folders = sub_folders if sub_folders != '/' else ''
build_categories_tree(entry_index, self.entries[entry_index].raw_categories, self.entries_per_categories, self.categories_leaves, self.max_category_weight, self.set_max_category_weight, encoding=self.blog_configuration["path_encoding"], sub_folders=sub_folders)
build_categories_tree(entry_index, current_entry.raw_categories, self.entries_per_categories, self.categories_leaves, self.max_category_weight, self.set_max_category_weight, encoding=self.blog_configuration["path_encoding"], sub_folders=sub_folders)
self.update_chapters(current_entry)
# build chapters index
for chapter in sorted(self.raw_chapters.keys()):
top = self.chapters_index
index = ''
levels = [str(level) for level in chapter.split('.') if str(level) != '']
len_levels = len(levels)
for i in range(0, len_levels):
l = levels[i]
if index == '':
index = l
else:
index += '.'+l
f = filter(lambda c : c.index == index, top)
try:
top = next(f).sub_chapters
except StopIteration:
try:
top.append(
Chapter(index, self.raw_chapters[index][1], self.raw_chapters[index][2])
)
except KeyError:
top.append(
Chapter(index, '', '')
)
top = top[-1].sub_chapters
# Setup BlogDates Data
self.blog_dates = list()
for node in self.entries_per_dates:
try:
sub_folders = urllib.parse.quote(self.blog_configuration["path"]["dates_sub_folders"]+'/', encoding=self.blog_configuration["path_encoding"])
except UnicodeEncodeError as e:
sub_folders = self.blog_configuration["path"]["dates_sub_folders"]+'/'
notify("\"{0}\": ".format(sub_folders)+str(e), color="YELLOW")
......@@ -110,9 +140,55 @@ class DataStore:
"weight": node.weight
})
def update_chapters(self, chapter, entry_index):
pass
def get_chapters(self, argv):
key = ''.join(argv)
if not key in self.html_chapters.keys():
self.html_chapters[key] = self.build_html_chapters(argv, self.chapters_index, 0)
return self.html_chapters[key]
def build_html_chapters(self, argv, top, level):
lo, io, ic, lc = argv
if top == []:
return ''
output = lo.format(**{"level" :level})
for sub_chapters in top:
output += io.format(**{
"index": sub_chapters.index,
"title": sub_chapters.title,
"path": sub_chapters.path,
"level": level
})
output += self.build_html_chapters(argv, sub_chapters.sub_chapters, level+1)
output += ic
output += lc
return output
def update_chapters(self, entry):
try:
chapter = str(entry.chapter)
[ int(level) for level in chapter.split('.') if level != '']
except ValueError as e: # weak test to check attribute conformity
return
except AttributeError as e: # does entry has chapter?
return
if chapter in self.raw_chapters.keys():
from venc2.helpers import die
die(messages.chapter_already_exists.format(
entry.title,
entry.id,
self.raw_chapters[chapter][1],
self.raw_chapters[chapter][0],
chapter
))
else:
self.raw_chapters[chapter] = (entry.id, entry.title, entry.url)
def sort_by(self, entry):
try:
return getattr(entry, self.blog_configuration["sort_by"])
......
......@@ -23,11 +23,11 @@ import urllib.parse
from venc2.helpers import notify
class Chapter:
def __init__(self, chapter, entry):
def __init__(self, index, title, path):
self.sub_chapters = []
self.chapter = chapter
self.url = entry.url
self.title = entry.title
self.index = index
self.title = title
self.path = path
class MetadataNode:
......
......@@ -99,3 +99,4 @@ class Messages:
malformed_patterns_missing_closing_symbols = "Malformed patterns in \"{0}\": One or more closing symbols are missing."
malformed_patterns_missing_opening_symbols = "Malformed patterns in \"{0}\": One or more closing symbols are missing."
loading_data = "Loading data..."
chapter_already_exists = "Chapters \"{0}\" (id = {1}) and \"{2}\" (id = {3}) have the same index \"{4}\"."
......@@ -97,5 +97,6 @@ class Messages:
malformed_patterns_missing_closing_symbols = "Motifs mal formés dans \"{0}\": Il manque un ou plusieurs symboles de fermeture."
malformed_patterns_missing_opening_symbols = "Motifs mal formés dans \"{0}\": Il manque un ou plusieurs symboles d'ouverture."
loading_data = "Chargement des données..."
chapter_already_exists = "Les chapitres \"{0}\" (id = {1}) et \"{2}\" (id = {3}) ont le même index \"{4}\"."
......@@ -161,9 +161,6 @@ class ProcessedString():
elif self.len_open_pattern_pos < self.len_close_pattern_pos:
l = self.open_pattern_pos + self.close_pattern_pos
mn, mx = min(l), max(l)
if ressource == "4__12-14-2018-23-58__escape":
print(string, escapes, self.open_pattern_pos, self.close_pattern_pos)
die(messages.malformed_patterns_missing_opening_symbols.format(ressource))
self.string = string
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment