138 lines
5.8 KiB
Python
138 lines
5.8 KiB
Python
"""
|
||
pydoc – Create a simple website from multiple Markdown files
|
||
|
||
Copyright (c) 2023 Helmut Kaczmarek <code@helmutkaczmarek.de>
|
||
|
||
This program is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU General Public License for more details.
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
"""
|
||
|
||
import os
|
||
import shutil
|
||
import subprocess
|
||
import configparser
|
||
|
||
# Load settings from the configuration file
|
||
def load_settings(config_path):
|
||
config = configparser.ConfigParser()
|
||
config.read(config_path)
|
||
settings = config['Settings']
|
||
return settings
|
||
|
||
# Function for converting the Markdown files to HTML
|
||
def convert_to_html(markdown_file, html_file, template_file):
|
||
pandoc_cmd = [
|
||
'pandoc', markdown_file, '-o', html_file,
|
||
'--template', template_file
|
||
]
|
||
subprocess.run(pandoc_cmd)
|
||
|
||
# Function for processing the Markdown files
|
||
def process_markdown_files(src_dir, dest_dir, settings):
|
||
converted_count = 0
|
||
template_file = settings['template_file']
|
||
css_path = settings['css_path']
|
||
|
||
for root, _, files in os.walk(src_dir):
|
||
for file in files:
|
||
if file.lower().endswith('.md'):
|
||
markdown_path = os.path.join(root, file)
|
||
relative_path = os.path.relpath(markdown_path, src_dir)
|
||
html_path = os.path.join(dest_dir, os.path.splitext(relative_path)[0] + '.html')
|
||
|
||
if not os.path.exists(markdown_path):
|
||
if os.path.exists(html_path):
|
||
os.remove(html_path)
|
||
continue
|
||
|
||
os.makedirs(os.path.dirname(html_path), exist_ok=True)
|
||
print(f"Converting {markdown_path} to {html_path}")
|
||
convert_to_html(markdown_path, html_path, template_file)
|
||
converted_count += 1
|
||
|
||
return converted_count
|
||
|
||
# Copy asset files from source to destination directory
|
||
def copy_assets(src_dir, dest_dir):
|
||
for item in os.listdir(src_dir):
|
||
src_item = os.path.join(src_dir, item)
|
||
dest_item = os.path.join(dest_dir, item)
|
||
if os.path.isfile(src_item):
|
||
shutil.copy(src_item, dest_item)
|
||
elif os.path.isdir(src_item):
|
||
shutil.copytree(src_item, dest_item, dirs_exist_ok=True)
|
||
|
||
# Main function
|
||
def main():
|
||
try:
|
||
settings = load_settings('settings.conf')
|
||
|
||
markdown_dir = settings['markdown_dir']
|
||
html_dir = settings['html_dir']
|
||
assets_dir = settings['assets_dir']
|
||
|
||
print("Starting Pydoc...")
|
||
|
||
# Backup original content of the template file
|
||
original_template_content = None
|
||
with open(settings['template_file'], 'r', encoding='utf-8') as f:
|
||
original_template_content = f.read()
|
||
|
||
# Update template file to include the correct CSS path
|
||
updated_template_content = original_template_content.replace('{{ css_path }}', settings['css_path'])
|
||
with open(settings['template_file'], 'w', encoding='utf-8') as f:
|
||
f.write(updated_template_content)
|
||
|
||
# Delete and create HTML directory
|
||
shutil.rmtree(html_dir, ignore_errors=True)
|
||
os.makedirs(html_dir, exist_ok=True)
|
||
|
||
# Convert markdown files
|
||
num_converted = process_markdown_files(markdown_dir, html_dir, settings)
|
||
|
||
# Copy asset files
|
||
copy_assets(assets_dir, html_dir)
|
||
|
||
# Restore original content of the template file
|
||
with open(settings['template_file'], 'w', encoding='utf-8') as f:
|
||
f.write(original_template_content)
|
||
|
||
if num_converted > 0:
|
||
print(f"Finished converting {num_converted} files and copying assets. Everything seems to be finde. Note: If the CSS in subdirectories does not look as expected, check whether the full path to the style sheet is specified in 'css_path' (see 'settings.conf').")
|
||
else:
|
||
print("No files converted. Check the source directories.")
|
||
|
||
# Check if Pandoc template file contains "{{ css_path }}"
|
||
if '<link rel="stylesheet" href="{{ css_path }}">' not in original_template_content:
|
||
print("INFO: The template.txt should contain '{{ css_path }}' as a placeholder for the path to the CSS file, so that the paths to the CSS file in subdirectories are set correctly.")
|
||
except FileNotFoundError:
|
||
print("Cannot convert Markdown files. Missing configuration file. Here is an example for 'settings.conf':\n"
|
||
"\n"
|
||
"[Settings]\n"
|
||
"markdown_dir = C:\\Path\\to\\Markdown\n"
|
||
"html_dir = C:\\Path\\To\\HTML\n"
|
||
"assets_dir = C:\\Path\\To\\Assets\n"
|
||
"template_file = C:\\Path\\to\\template.txt\n"
|
||
"css_path = C:\\Path\\to\\style.css # The full path to the CSS file is important for the style sheet to work in subdirectories.")
|
||
except (KeyError, ValueError, configparser.MissingSectionHeaderError):
|
||
print("There are problems in the 'settings.conf'. Maybe a typo crept in? Here is an example for 'settings.conf':\n"
|
||
"\n"
|
||
"[Settings]\n"
|
||
"markdown_dir = C:\\Path\\to\\Markdown\n"
|
||
"html_dir = C:\\Path\\To\\HTML\n"
|
||
"assets_dir = C:\\Path\\To\\Assets\n"
|
||
"template_file = C:\\Path\\to\\template.txt\n"
|
||
"css_path = C:\\Path\\to\\style.css # The full path to the CSS file is important for the style sheet to work in subdirectories.")
|
||
|
||
if __name__ == "__main__":
|
||
main() |