Browse Source
[IMP] initiate hugo site generation with lotusdoc and json content source
[IMP] initiate hugo site generation with lotusdoc and json content source
Stéphan Sainléger
1 year ago
11 changed files with 344 additions and 451 deletions
-
1.python-version
-
7config.toml
-
92content/my-first-post.md
-
81generate.py
-
177generate_lotusdocs.py
-
109generate_v2.py
-
160generate_v3.py
-
38hugo.toml
-
26init_hugo_toml.py
-
76structure.json
-
28update.sh
@ -0,0 +1 @@ |
|||
3.8.10 |
@ -1,7 +0,0 @@ |
|||
baseURL = 'http://example.org/' |
|||
languageCode = 'en-us' |
|||
title = 'My New Hugo Site' |
|||
theme = "hugo-theme-learn" |
|||
|
|||
[outputs] |
|||
home = [ "HTML", "RSS", "JSON"] |
@ -1,92 +0,0 @@ |
|||
____ |
|||
title: "My First Post" |
|||
date: 2022-10-29T15:59:37+02:00 |
|||
draft: false |
|||
____ |
|||
|
|||
# Procédures organisationnelles |
|||
|
|||
- [Nouveau fonctionnement du support Lokavaluto](https://docs.lokavaluto.fr/MAI9LEmBTH6hB6II6xUTxA) |
|||
- [Ancien fonctionnement du support Lokavaluto et pourquoi cela ne convenait pas](https://docs.lokavaluto.fr/S6uGRvQ-Rl25LiyCgPQvzg) |
|||
|
|||
# Odoo Community (v12) |
|||
|
|||
## Procédures d'utilisation |
|||
|
|||
- [Présentation et interface générale](https://docs.lokavaluto.fr/tgJjJkHfS_OZwj0JWvHsKw) |
|||
- [Paramétrage du compte utilisateur](https://docs.lokavaluto.fr/Sc_tIVdCTaSClMkdkg8PaQ) |
|||
- [Recherches et vues](https://docs.lokavaluto.fr/6pmPhxmATxSIgNYPKWruvQ) |
|||
- [Utilisation du chatter](https://docs.lokavaluto.fr/whiTd855THaucVX6hhBcHQ) |
|||
- [Utilisation du calendrier](https://docs.lokavaluto.fr/CJt7IS8OSSmD6yg7vrWTlg) |
|||
- [Gestion de la prospection (CRM)](https://docs.lokavaluto.fr/oE_BiLb_RwyrrRwvElbBWw) |
|||
- [Gestion des contacts, des membres et cartographie](https://docs.lokavaluto.fr/apAZA45PRwa0Cj5F1i8UDQ) |
|||
- [Tutoriel d’utilisation du module Membres pour les Monnaies Locales](https://docs.lokavaluto.fr/Z6I27taoSciMu5pvYjrLLA) |
|||
- [Gestion des relations entre contacts](https://docs.lokavaluto.fr/EZU8_sb7RwqyPh4Y9ItRIA) |
|||
- [Envoi des newsletter et email Marketing](https://docs.lokavaluto.fr/0RpWDYwWSnaIpH2Tz7-jrg) |
|||
- [Gestion des événements](https://docs.lokavaluto.fr/0zFFR8pgSEmdO45mkLzKTQ) |
|||
- [Gestion de Projet](https://docs.lokavaluto.fr/UYHemvLrQPewS0HlHEJSvQ) |
|||
- [Feuilles de temps](https://docs.lokavaluto.fr/Pl2GX0j1Qf2L5zVHD8nJeQ) |
|||
- [Facturation - Comptabilité : utilisation générale](https://docs.lokavaluto.fr/a5ZqnKcfT7OuivOb6F-DAA) |
|||
- [Ajout d'une adhésion](https://docs.lokavaluto.fr/9n0Zl9-sRGusmWYQBSkK9A) |
|||
- [Rapprochement bancaire](https://docs.lokavaluto.fr/HifCGFN3QNWIRgt30y5OnA) |
|||
- [Importer un relevé CSV Crédit coopératif dans Odoo](https://docs.lokavaluto.fr/9xgBdFP2Re-Ym_Jxr21Dpg) |
|||
- [Prélèvement SEPA dans Odoo](https://docs.lokavaluto.fr/RifSR2t4TH-ADXq3MzYsyQ) |
|||
- [Gestion du nantissement](https://docs.laroue.org/GAQ962niS_6dwu9I-aJisA) |
|||
- Gestion des immobilisations |
|||
- Comptabilité analytique |
|||
- Remises de chèques et bordereaux de remise |
|||
|
|||
## Procédures de configuration |
|||
|
|||
- [Liste et détail des modules et applications Odoo régulièrement utilisés](https://docs.lokavaluto.fr/hwh54P5-TbqPAacm6CuG5Q) |
|||
- [Installer une application ou un module](https://docs.lokavaluto.fr/koiNU5qpR1iYSsE9F9jhVw) |
|||
- [Création d'un utilisateur et gestion des droits d'accès](https://docs.lokavaluto.fr/xePpLWP7TpWLJRIpKOL44Q) |
|||
- [Création d'un site internet](https://docs.lokavaluto.fr/aJTv0fo1QuqaX8f5_bAfRA) (à rédiger) |
|||
- [Configuration initiale comptabilité/facturation](https://docs.lokavaluto.fr/dqZxMeDoTAipos_Nds01vQ) |
|||
- [Configuration des articles d'adhésion](https://docs.lokavaluto.fr/5n-dsw_fQn2lN3taiSqC8w) |
|||
- [Configuration et fonctionnement des adhésions en ligne avec Stripe](https://docs.lokavaluto.fr/FyTV4sPRSy2dBckgCV27Yg) (à rédiger) |
|||
- [Création et configuration des listes de diffusion](https://docs.lokavaluto.fr/mx5vKuPpTsae9pvCak7d3g) |
|||
- [Configuration et utilisation de l'édition en lot](https://docs.lokavaluto.fr/FlG8-e_gRfmu-7pRS9n9MQ) |
|||
- [Importer des données dans Odoo](https://docs.lokavaluto.fr/Nzj43P65T-Sfa0re00A7jA) |
|||
- [Exporter des données depuis Odoo](https://docs.lokavaluto.fr/UmQyyZ2fQ9WM7RMOq5T_6A) |
|||
- [Utilisation du mode développeur](https://docs.lokavaluto.fr/ZPAqfW93T4e0ct_Des2y4Q) |
|||
- [Création d'une webb app Odoo]() (à rédiger) |
|||
- [Procédure de nettoyage des bases de données Odoo](https://docs.lokavaluto.fr/Tleoi5cHQ9m-eGgTSvvtJg) |
|||
|
|||
# Autres outils |
|||
|
|||
- [**SOGO et Thunderbird:** Gérer ses courriels](https://docs.lokavaluto.fr/oNPVbLOyT5GnwfMenLWT_Q) |
|||
|
|||
# Cyclos |
|||
|
|||
- [Gestion administrative et comptable Monnaie numérique Cyclos](https://docs.lokavaluto.fr/-ffeZk52SSSShj6z3upleQ) |
|||
|
|||
# Procédures techniques |
|||
|
|||
## Général |
|||
|
|||
- [Installer le kit Lokavaluto / la suite Just Odoo It en moins de 2 heures](https://docs.elabore.coop/yp8m-2HtTjeAlZiyCbAC7w) |
|||
- [Configuration du Single Sign On (SSO) dans la suite Just Odoo It](https://docs.elabore.coop/rcWPOJGiTfKWYegB_-S94g) |
|||
|
|||
## OVH |
|||
|
|||
- [Procédère d'ouverture d'un Serveur Privé Virtuel (VPS) chez OVH](https://docs.lokavaluto.fr/ofxKNg8ST4SSryBOrs-qYA) |
|||
|
|||
## Odoo |
|||
|
|||
- [Copier une base de donnée Odoo d'une instance Odoo à une autre](https://docs.elabore.coop/FCiWj7IIRdCjy0BDhJGWrQ) |
|||
- [Mettre à jour / Modifier l’image Docker de Odoo dans la suite Just Odoo It](https://docs.elabore.coop/WdymXfpJSmGsQjnfbZHigw) |
|||
- [Installer un module Odoo “à la main” avec Just Odoo It](https://docs.elabore.coop/0QtrHIt2TH-MmrTsSlz8EQ) |
|||
|
|||
## Nextcloud |
|||
|
|||
- [Procédure de migration manuelle de Nextcloud](https://doc.myceliandre.fr/nextcloud-update-compose) |
|||
|
|||
## Gogocarto |
|||
|
|||
- [Installer et configurer une cartographie Gogocarto basée sur Odoo](https://docs.elabore.coop/xQanUX_IRHyTMjnCV6uGpQ) |
|||
|
|||
## Cyclos |
|||
|
|||
- [Installer et configurer Cyclos](https://docs.lokavaluto.fr/pBl-0OIiSeW9HQG1k_OLhQ) |
|||
- [Installation full stack Cyclos](https://docs.lokavaluto.fr/uxiFzvb4T-eDmt_RhaTblg) --> ce paramétrage est à intégrer dans le paramétrage de base |
@ -1,81 +0,0 @@ |
|||
import io |
|||
import os |
|||
import pypandoc |
|||
import panflute |
|||
import requests |
|||
import ipdb |
|||
|
|||
parent_dir = "./content" |
|||
|
|||
|
|||
def action(elem, doc): |
|||
if isinstance(elem, panflute.Image): |
|||
doc.images.append(elem) |
|||
elif isinstance(elem, panflute.Link): |
|||
doc.links.append(elem) |
|||
|
|||
|
|||
def find_link(elem, doc): |
|||
if type(elem) == panflute.elements.Link: |
|||
doc.link.append(elem) |
|||
print(panflute.stringify(elem)) |
|||
|
|||
|
|||
def create_folder_h3(elem, doc): |
|||
if type(elem) == panflute.elements.Header and elem.level == 3: |
|||
directory = panflute.stringify(elem) |
|||
path = os.path.join(parent_dir, directory) |
|||
print(path) |
|||
|
|||
|
|||
def download(link): |
|||
r = requests.get(link) |
|||
return r.text |
|||
|
|||
|
|||
def create_folder_h2(elem, doc): |
|||
if type(elem) == panflute.elements.Header and elem.level == 2: |
|||
doc.link = [] |
|||
directory = panflute.stringify(elem) |
|||
path = os.path.join(parent_dir, directory) |
|||
os.makedirs(path, exist_ok=True) |
|||
elem.next.walk(find_link) |
|||
for link in doc.link: |
|||
if link.url[-1] == "#": |
|||
md_content = download(link.url[:-1] + "/download") |
|||
print( |
|||
parent_dir |
|||
+ "/" |
|||
+ directory |
|||
+ "/" |
|||
+ panflute.stringify(link) |
|||
+ ".md" |
|||
) |
|||
with open( |
|||
parent_dir |
|||
+ "/" |
|||
+ directory |
|||
+ "/" |
|||
+ panflute.stringify(link) |
|||
+ ".md", |
|||
"w", |
|||
) as f: |
|||
hugo_head = """ |
|||
--- |
|||
title: %s |
|||
date: 2022-10-29T15:59:37+02:00 |
|||
draft: false |
|||
--- |
|||
|
|||
""" % ( |
|||
panflute.stringify(link) |
|||
) |
|||
f.write(hugo_head + md_content) |
|||
|
|||
|
|||
if __name__ == "__main__": |
|||
data = pypandoc.convert_file("content/posts/my-first-post.md", "json") |
|||
doc = panflute.load(io.StringIO(data)) |
|||
doc.images = [] |
|||
doc.links = [] |
|||
doc = panflute.run_filter(create_folder_h2, doc=doc) |
@ -0,0 +1,177 @@ |
|||
import json |
|||
import os |
|||
import re |
|||
import requests |
|||
import toml |
|||
from shutil import copytree, rmtree |
|||
|
|||
|
|||
def parse_for_toc(content): |
|||
# TODO: ADD .TableofContent directly to the page (see hugo theme ?) |
|||
content = content.replace("[TOC]", "") |
|||
return content |
|||
|
|||
|
|||
def parse_for_notice(content): |
|||
result = re.findall(":::warning.*?:::", content, re.MULTILINE | re.DOTALL) |
|||
for notice in result: |
|||
old = notice |
|||
content = content.replace( |
|||
old, |
|||
notice.replace(":::warning", '{{% alert context="warning" %}}').replace( |
|||
":::", "{{% /alert %}}" |
|||
), |
|||
) |
|||
result = re.findall(":::info.*?:::", content, re.MULTILINE | re.DOTALL) |
|||
for notice in result: |
|||
old = notice |
|||
content = content.replace( |
|||
old, |
|||
notice.replace(":::info", '{{% alert context="info" %}}').replace( |
|||
":::", "{{% /alert %}}" |
|||
), |
|||
) |
|||
result = re.findall(":::success.*?:::", content, re.MULTILINE | re.DOTALL) |
|||
for notice in result: |
|||
old = notice |
|||
content = content.replace( |
|||
old, |
|||
notice.replace(":::success", '{{% alert context="success" %}}').replace( |
|||
":::", "{{% /alert %}}" |
|||
), |
|||
) |
|||
result = re.findall(":::danger.*?:::", content, re.MULTILINE | re.DOTALL) |
|||
for notice in result: |
|||
old = notice |
|||
content = content.replace( |
|||
old, |
|||
notice.replace(":::danger", '{{% alert context="danger" %}}').replace( |
|||
":::", "{{% /alert %}}" |
|||
), |
|||
) |
|||
# print(content) |
|||
return content |
|||
|
|||
|
|||
def create_index_file(dir_path, dir_name): |
|||
#add _index.md for page organization |
|||
with open(dir_path + "/_index.md", "wb") as f: |
|||
print("Created", dir_path + "/_index.md") |
|||
index = """ |
|||
+++ |
|||
title = "{dir_name}" |
|||
chapter = true |
|||
weight = 5 |
|||
+++ |
|||
|
|||
# {dir_name} |
|||
|
|||
Discover what this Hugo theme is all about and the core-concepts behind it. |
|||
""".format( |
|||
dir_name=dir_name |
|||
) |
|||
f.write(b"%s" % index.encode("utf-8")) |
|||
|
|||
|
|||
def generate_directory_structure_and_files(node, parent_path="./content/"): |
|||
if "children" in node: |
|||
# If the node has children, it's a directory |
|||
dir_path = os.path.join(parent_path, node["technical_name"]) |
|||
os.makedirs(dir_path, exist_ok=True) # Create directory |
|||
create_index_file(dir_path, node["name"]) |
|||
for child in node["children"]: |
|||
generate_directory_structure_and_files(child, parent_path=dir_path) |
|||
elif "url" in node: |
|||
# If the node has a URL, it's a document |
|||
file_path = os.path.join(parent_path, node["technical_name"] + ".md") |
|||
link_url = node["url"] |
|||
if link_url: |
|||
with open(file_path, "wb") as f: |
|||
doc_link = link_url + "/download" |
|||
response = requests.get(doc_link) |
|||
hugo_header = '---\ntitle: "' + node["name"] + '"\n---\n\n' |
|||
content = parse_for_notice( |
|||
response.content.decode("utf-8") |
|||
).encode("utf-8") |
|||
content = parse_for_toc(content.decode("utf-8")).encode("utf-8") |
|||
f.write(hugo_header.encode("utf-8")) |
|||
f.write(content.replace(b"---", b"")) |
|||
print("Downloaded", doc_link, "to", file_path) |
|||
|
|||
|
|||
def generate_book_layout(node): |
|||
"""Copy the defaults layout repository 'docs' for the new/other books""" |
|||
layout_dir = "./themes/lotusdocs/layouts/" |
|||
layout_docs_dir = os.path.join(layout_dir, "docs") |
|||
layout_book_dir = os.path.join(layout_dir, node["technical_name"]) |
|||
# copy book layout folder from "layouts/docs" if it doesn't exist |
|||
if not os.path.exists(layout_book_dir): |
|||
# create the layout for the book |
|||
copytree(layout_docs_dir, layout_book_dir) |
|||
|
|||
|
|||
def generate_book_menu(node, weight): |
|||
"""Generate the menu displayed in the home page""" |
|||
book_config = { |
|||
"name": node["name"], |
|||
"url": node["technical_name"] + "/", |
|||
"identifier": node["technical_name"], |
|||
"weight": weight, |
|||
} |
|||
return book_config |
|||
|
|||
def generate_book_config(node): |
|||
"""Generate configuration for each book""" |
|||
book_config = { |
|||
"title": node["name"], |
|||
"darkMode": True |
|||
} |
|||
return book_config |
|||
|
|||
|
|||
def parse_json_file(json_file_path): |
|||
content_dir = "./content/" |
|||
config_path ="./hugo.toml" |
|||
# new_config_path = "./config_new.toml" # TO DELETE WHEN SCRIPT FINISHED |
|||
config_data_dict = toml.load(config_path) |
|||
|
|||
# Retrieve the init json data |
|||
with open(json_file_path, 'r') as json_file: |
|||
json_data = json.load(json_file) |
|||
|
|||
|
|||
if not os.path.exists(content_dir): |
|||
# Create content directory if it doesn't exist |
|||
os.makedirs(content_dir) |
|||
else: |
|||
# Delete the content directories files and sub-directories |
|||
rmtree(content_dir) |
|||
|
|||
nb_books = 0 |
|||
primary_menu = [] |
|||
books_config = [] |
|||
config_data_dict.update({"params": {}}) |
|||
# Loop on the json structure to build repositories and files |
|||
for book_node in json_data["books"]: |
|||
nb_books +=1 |
|||
generate_directory_structure_and_files(book_node) |
|||
generate_book_layout(book_node) |
|||
primary_menu.append(generate_book_menu(book_node, nb_books)) |
|||
# books_config.append(generate_book_config(book_node)) |
|||
config_data_dict["params"]["%s" % book_node["technical_name"]] = generate_book_config(book_node) |
|||
|
|||
|
|||
# Add the primary menu data to the whole config |
|||
config_data_dict.update({"menu": {"primary": primary_menu}}) |
|||
#config_data_dict.update({"params": {"primary": primary_menu}}) |
|||
print("WHOLE CONFIG") |
|||
print(config_data_dict) |
|||
|
|||
# Replace the config.toml content with the new params |
|||
with open(config_path, 'w') as toml_file: |
|||
toml.dump(config_data_dict, toml_file) |
|||
|
|||
|
|||
|
|||
parse_json_file("structure.json") |
|||
|
@ -1,109 +0,0 @@ |
|||
import io |
|||
import os |
|||
from bs4 import BeautifulSoup, Comment |
|||
import markdown |
|||
import ipdb |
|||
|
|||
parent_dir = "./content" |
|||
|
|||
|
|||
def parse_markdown_file(file_path): |
|||
with open(file_path, "r") as file: |
|||
markdown_text = file.read() |
|||
html = markdown.markdown(markdown_text) |
|||
print(html) |
|||
headings = [] |
|||
current_level = 0 |
|||
for line in html.split("\n"): |
|||
if line.startswith("<h1>"): |
|||
current_level = 1 |
|||
headings.append( |
|||
{"level": current_level, "text": line[4:-5], "children": []} |
|||
) |
|||
elif line.startswith("<h2>"): |
|||
if current_level < 2: |
|||
current_level = 2 |
|||
headings[-1]["children"].append( |
|||
{"level": current_level, "text": line[4:-5], "children": []} |
|||
) |
|||
else: |
|||
headings[-1]["children"].append( |
|||
{"level": current_level, "text": line[4:-5], "children": []} |
|||
) |
|||
elif line.startswith("<h3>"): |
|||
if current_level < 3: |
|||
current_level = 3 |
|||
headings[-1]["children"][-1]["children"].append( |
|||
{"level": current_level, "text": line[4:-5], "children": []} |
|||
) |
|||
else: |
|||
headings[-1]["children"][-1]["children"].append( |
|||
{"level": current_level, "text": line[4:-5], "children": []} |
|||
) |
|||
return headings |
|||
|
|||
|
|||
def parse_markdown_file_2(file_path): |
|||
with open(file_path, "r", encoding="utf-8") as f: |
|||
content = f.read() |
|||
html = markdown.markdown(content) |
|||
print(html) |
|||
soup = BeautifulSoup(html, "html.parser") |
|||
headings = [] |
|||
|
|||
def parse_element(element, level): |
|||
print(element) |
|||
if element.name == "h1": |
|||
heading = { |
|||
"text": element.text.strip(), |
|||
"level": level, |
|||
"subheadings": [], |
|||
"links": [], |
|||
} |
|||
headings.append(heading) |
|||
elif element.name == "h2": |
|||
subheading = { |
|||
"text": element.text.strip(), |
|||
"level": level, |
|||
"subheadings": [], |
|||
"links": [], |
|||
} |
|||
headings[-1]["subheadings"].append(subheading) |
|||
elif element.name == "h3": |
|||
subsubheading = {"text": element.text.strip(), "level": level, "links": []} |
|||
headings[-1]["subheadings"][-1]["subheadings"].append(subsubheading) |
|||
elif element.name == "ul": |
|||
links = [] |
|||
for li in element.find_all("li"): |
|||
link = li.find("a") |
|||
if link is not None: |
|||
links.append({"text": link.text.strip(), "url": link["href"]}) |
|||
if level == 1: |
|||
headings[-1]["links"].extend(links) |
|||
elif level == 2: |
|||
headings[-1]["subheadings"][-1]["links"].extend(links) |
|||
elif level == 3: |
|||
headings[-1]["subheadings"][-1]["subheadings"][-1]["links"].extend( |
|||
links |
|||
) |
|||
|
|||
for child in element.children: |
|||
if isinstance(child, str) or isinstance(child, Comment): |
|||
continue |
|||
parse_element(child, level + 1) |
|||
|
|||
parse_element(soup, 0) |
|||
|
|||
return headings |
|||
|
|||
|
|||
headings = parse_markdown_file_2("content/posts/my-first-post.md") |
|||
print(headings) |
|||
for heading in headings: |
|||
print(f"Titre de niveau {heading['level']}: {heading['text']}") |
|||
for subheading in heading["children"]: |
|||
print(f" Sous-titre de niveau {subheading['level']}: {subheading['text']}") |
|||
for subsubheading in subheading["children"]: |
|||
print( |
|||
f" Sous-sous-titre de niveau {subsubheading['level']}: {subsubheading['text']}" |
|||
) |
@ -1,160 +0,0 @@ |
|||
import os |
|||
import re |
|||
import requests |
|||
from bs4 import BeautifulSoup |
|||
import markdown |
|||
|
|||
|
|||
def parse_for_toc(content): |
|||
# TODO: ADD .TableofContent directly to the page (see hugo theme ?) |
|||
content = content.replace("[TOC]", "") |
|||
return content |
|||
|
|||
|
|||
def parse_for_notice(content): |
|||
result = re.findall(":::warning.*?:::", content, re.MULTILINE | re.DOTALL) |
|||
for notice in result: |
|||
old = notice |
|||
content = content.replace( |
|||
old, |
|||
notice.replace(":::warning", "{{% notice info %}}").replace( |
|||
":::", "{{% /notice %}}" |
|||
), |
|||
) |
|||
result = re.findall(":::info.*?:::", content, re.MULTILINE | re.DOTALL) |
|||
for notice in result: |
|||
old = notice |
|||
content = content.replace( |
|||
old, |
|||
notice.replace(":::info", "{{% notice note %}}").replace( |
|||
":::", "{{% /notice %}}" |
|||
), |
|||
) |
|||
result = re.findall(":::success.*?:::", content, re.MULTILINE | re.DOTALL) |
|||
for notice in result: |
|||
old = notice |
|||
content = content.replace( |
|||
old, |
|||
notice.replace(":::success", "{{% notice tip %}}").replace( |
|||
":::", "{{% /notice %}}" |
|||
), |
|||
) |
|||
result = re.findall(":::danger.*?:::", content, re.MULTILINE | re.DOTALL) |
|||
for notice in result: |
|||
old = notice |
|||
content = content.replace( |
|||
old, |
|||
notice.replace(":::danger", "{{% notice warning %}}").replace( |
|||
":::", "{{% /notice %}}" |
|||
), |
|||
) |
|||
# print(content) |
|||
return content |
|||
|
|||
|
|||
def parse_markdown_file(markdown_file_path, base_dir="./"): |
|||
with open(markdown_file_path, "r") as f: |
|||
markdown_text = f.read() |
|||
|
|||
html = markdown.markdown(markdown_text, extensions=["fenced_code"]) |
|||
|
|||
soup = BeautifulSoup(html, "html.parser") |
|||
|
|||
if not os.path.exists(base_dir): |
|||
os.makedirs(base_dir) |
|||
|
|||
current_heading_level = 1 |
|||
current_heading_dir = base_dir |
|||
last_heading_dir = base_dir |
|||
|
|||
for element in soup.children: |
|||
if element.name in ["h1", "h2", "h3"]: |
|||
# Get the text of the heading and the heading level |
|||
heading_text = element.text.strip() |
|||
heading_level = int(element.name[1]) |
|||
|
|||
# Determine the directory to create for the heading |
|||
print( |
|||
"heading_level: %s(%s) , heading_text: %s, base_dir: %s, last_heading_dir: %s, current_heading_dir: %s " |
|||
% ( |
|||
heading_level, |
|||
current_heading_level, |
|||
heading_text, |
|||
base_dir, |
|||
last_heading_dir, |
|||
current_heading_dir, |
|||
) |
|||
) |
|||
if heading_level == 1: |
|||
heading_dir = os.path.join(base_dir, heading_text) |
|||
current_heading_dir = heading_dir |
|||
last_heading_dir = base_dir |
|||
elif heading_level == current_heading_level: |
|||
heading_dir = os.path.join( |
|||
os.path.dirname(current_heading_dir), heading_text |
|||
) |
|||
last_heading_dir = heading_dir |
|||
current_heading_dir = heading_dir |
|||
elif heading_level >= current_heading_level: |
|||
heading_dir = os.path.join(current_heading_dir, heading_text) |
|||
last_heading_dir = current_heading_dir |
|||
current_heading_dir = heading_dir |
|||
else: |
|||
print("NOT SUPPORTED YET") |
|||
|
|||
if not os.path.exists(heading_dir): |
|||
os.makedirs(heading_dir) |
|||
# add _index.md for page organization |
|||
with open(heading_dir + "/_index.md", "wb") as f: |
|||
print("Created", heading_dir + "/_index.md") |
|||
index = """ |
|||
+++ |
|||
title = "{heading_text}" |
|||
chapter = true |
|||
weight = 5 |
|||
+++ |
|||
|
|||
# {heading_text} |
|||
|
|||
Discover what this Hugo theme is all about and the core-concepts behind it. |
|||
""".format( |
|||
heading_text=heading_text |
|||
) |
|||
f.write(b"%s" % index.encode("utf-8")) |
|||
|
|||
# Set the current heading level and directory |
|||
current_heading_level = heading_level |
|||
# last_heading_dir = current_heading_dir |
|||
# current_heading_dir = heading_dir |
|||
|
|||
elif element.name == "hr": |
|||
current_heading_level = 0 |
|||
current_heading_dir = base_dir |
|||
|
|||
elif element.name == "ul" and current_heading_level != 0: |
|||
# Get the links in the list |
|||
links = element.find_all("a") |
|||
for link in links: |
|||
# Get the text and href of the link |
|||
link_text = link.text.strip() |
|||
link_url = link["href"] |
|||
|
|||
file_path = os.path.join( |
|||
current_heading_dir, os.path.basename(link_text) |
|||
) |
|||
if link_url: |
|||
with open(file_path + ".md", "wb") as f: |
|||
doc_link = link_url + "/download" |
|||
response = requests.get(doc_link) |
|||
hugo_header = '---\ntitle: "' + link_text + '"\n---\n\n' |
|||
content = parse_for_notice( |
|||
response.content.decode("utf-8") |
|||
).encode("utf-8") |
|||
content = parse_for_toc(content.decode("utf-8")).encode("utf-8") |
|||
f.write(hugo_header.encode("utf-8")) |
|||
f.write(content.replace(b"---", b"")) |
|||
print("Downloaded", doc_link, "to", file_path) |
|||
|
|||
|
|||
headings = parse_markdown_file("content/my-first-post.md", base_dir="./content") |
|||
print(headings) |
@ -0,0 +1,38 @@ |
|||
baseURL = "http://example.org/" |
|||
languageCode = "en-us" |
|||
title = "My New Hugo Site" |
|||
|
|||
[outputs] |
|||
home = [ "HTML", "RSS", "JSON",] |
|||
|
|||
[module] |
|||
replacements = "github.com/colinwilson/lotusdocs -> lotusdocs" |
|||
[[module.imports]] |
|||
path = "github.com/colinwilson/lotusdocs" |
|||
disable = false |
|||
|
|||
[[module.imports]] |
|||
path = "github.com/gohugoio/hugo-mod-bootstrap-scss/v5" |
|||
disable = false |
|||
|
|||
[menu] |
|||
[[menu.primary]] |
|||
name = "User guide" |
|||
url = "user/" |
|||
identifier = "user" |
|||
weight = 1 |
|||
|
|||
[[menu.primary]] |
|||
name = "Developper guide" |
|||
url = "dev/" |
|||
identifier = "dev" |
|||
weight = 2 |
|||
|
|||
[params] |
|||
[[params.user]] |
|||
title = "User guide" |
|||
darkMode = true |
|||
|
|||
[[params.dev]] |
|||
title = "Developper guide" |
|||
darkMode = true |
@ -0,0 +1,26 @@ |
|||
|
|||
|
|||
def get_hugo_config_content(): |
|||
content = """ |
|||
baseURL = 'http://example.org/' |
|||
languageCode = 'en-us' |
|||
title = 'My New Hugo Site' |
|||
|
|||
[module] |
|||
[[module.imports]] |
|||
path = "github.com/colinwilson/lotusdocs" |
|||
disable = false |
|||
[[module.imports]] |
|||
path = "github.com/gohugoio/hugo-mod-bootstrap-scss/v5" |
|||
disable = false |
|||
""" |
|||
return content |
|||
|
|||
# Get TOML file content |
|||
toml_content = get_hugo_config_content() |
|||
|
|||
# Write the content in a hugo.toml file |
|||
with open('hugo.toml', 'w') as file: |
|||
file.write(toml_content) |
|||
|
|||
print("File hugo.toml generated with success.") |
@ -0,0 +1,76 @@ |
|||
{ |
|||
"books": [ |
|||
{ |
|||
"technical_name": "user", |
|||
"name": "User guide", |
|||
"children": [ |
|||
{ |
|||
"technical_name": "menu1-1", |
|||
"name": "Menu 1.1", |
|||
"children": [ |
|||
{ |
|||
"technical_name": "new_support", |
|||
"name": "Nouveau fonctionnement du support Lokavaluto", |
|||
"url": "https://docs.lokavaluto.fr/MAI9LEmBTH6hB6II6xUTxA" |
|||
}, |
|||
{ |
|||
"technical_name": "old_support", |
|||
"name": "Ancien fonctionnement du support Lokavaluto et pourquoi cela ne convenait pas", |
|||
"url": "https://docs.lokavaluto.fr/S6uGRvQ-Rl25LiyCgPQvzg" |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
"technical_name": "menu1-2", |
|||
"name": "Menu 1.2", |
|||
"children": [ |
|||
{ |
|||
"technical_name": "pres_general", |
|||
"name": "Présentation et interface générale", |
|||
"url": "https://docs.lokavaluto.fr/tgJjJkHfS_OZwj0JWvHsKw" |
|||
}, |
|||
{ |
|||
"technical_name": "old_support", |
|||
"name": "Ancien fonctionnement du support Lokavaluto et pourquoi cela ne convenait pas" |
|||
}, |
|||
{ |
|||
"technical_name": "menu1-2-1", |
|||
"name": "Menu 1.2.1", |
|||
"children": [ |
|||
{ |
|||
"technical_name": "prospe_management", |
|||
"name": "Gestion de la prospection (CRM)", |
|||
"url": "https://docs.lokavaluto.fr/oE_BiLb_RwyrrRwvElbBWw" |
|||
}, |
|||
{ |
|||
"technical_name": "contact_management", |
|||
"name": "Gestion des contacts, des membres et cartographie", |
|||
"url": "https://docs.lokavaluto.fr/apAZA45PRwa0Cj5F1i8UDQ" |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
"technical_name": "menu1-2-2", |
|||
"name": "Menu 1.2.2", |
|||
"children": [ |
|||
{ |
|||
"technical_name": "project_management", |
|||
"name": "Gestion de projet", |
|||
"url": "https://docs.lokavaluto.fr/UYHemvLrQPewS0HlHEJSvQ" |
|||
}, |
|||
{ |
|||
"technical_name": "event_management", |
|||
"name": "Gestion d'événements" |
|||
} |
|||
] |
|||
} |
|||
] |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
"technical_name": "dev", |
|||
"name": "Developper guide" |
|||
} |
|||
] |
|||
} |
@ -1,5 +1,29 @@ |
|||
#!/bin/bash |
|||
|
|||
python generate_v3.py |
|||
# Init hugo config file |
|||
python init_hugo_toml.py |
|||
|
|||
# find ./content -type f -exec sed -i 's/---/____/g' {} \; |
|||
# Start Hugo server in the background. This will import/update Lotusdocs module. |
|||
# The import of the module is important to get the themes files, because some of |
|||
# the sub-directories must be adapted to the future doc structure. |
|||
hugo server > init_hugo.log 2>&1 & |
|||
|
|||
# Wait for the end of the initialization process and stop hugo |
|||
while true; do |
|||
if grep -q "Web Server is available" init_hugo.log; then |
|||
# Initialization done |
|||
echo "Initialization complete. Web Server is available." |
|||
|
|||
# Get the PID of the Hugo process and store it in a file for later use |
|||
pgrep -f "hugo server" | kill |
|||
# You can stop the loop if you don't need to monitor the log anymore |
|||
break |
|||
fi |
|||
sleep 1 |
|||
done |
|||
# We don't need init_hugo.log anymore |
|||
rm init_hugo.log |
|||
|
|||
|
|||
# Generate Hugo Lotusdoc website structure and config |
|||
python generate_lotusdocs.py |
Write
Preview
Loading…
Cancel
Save
Reference in new issue