Compare commits

..

9 Commits

Author SHA1 Message Date
4b95426256 feat(qsgen3): Enhance output naming, URL structure, and sitemap
Implements several improvements to the qsgen3 site generator:

- **Filename Sanitization**: Introduces robust sanitization for output HTML filenames, converting to lowercase, replacing special characters with hyphens, and ensuring clean names.
- **Blog Post URL Structure**: Blog posts from content/posts/ are now generated with a blog/YYYY/MM/DD/ URL structure if a valid date is present in frontmatter. Defaults to blog/filename.html if no valid date.
- **Improved Title Fallback**: Uses the original filename (before sanitization) as a fallback title if not specified in frontmatter.
- **Enhanced Pandoc Error Handling**: Better logging for Pandoc execution and explicit check of its exit code, allowing the script to continue on single file errors.
- **Sitemap Integration**: Adds successfully generated pages to sitemap URL list.
- **Non-fatal Sitemap Generation**: Sitemap generation failures are now logged as warnings and do not halt the script.

Also, unignores the /scripts/ directory in .gitignore to include migration scripts in the repository.
2025-05-31 01:15:18 +02:00
1283eb30cb feat(migration): Add #showimg, #linkimg, #ytvideo conversion
Adds logic to migrate_qs2_to_qs3.py to convert:
- #showimg to Markdown image syntax ![alt](src).
- #linkimg to Markdown linked image syntax [![alt](src)](src).
- #ytvideo to HTML iframe embed for YouTube videos.

Image path processing handles absolute URLs and prepends /images/
for relative paths, aligning with previous qsgen2 behavior but
omitting hardcoded styling attributes for Markdown output.
2025-05-31 01:13:55 +02:00
f5d6d0eb49 docs: Enhance explanations in site.conf.example
Updated site.conf.example to provide clearer and more detailed descriptions for each configuration variable, improving usability for new users.
2025-05-31 00:14:51 +02:00
1b8898ae2e chore: Remove extraneous 'home' directory from project root 2025-05-31 00:07:30 +02:00
681857225b chore: Remove old qsgen2 files and directories
Deleted legacy files and directories from the previous qsgen2 system, including:
- Root qsgen3 script (qsgen2)
- HOWTO.md, THEME-HOWTO.md, qsg2-square.png
- include/ directory
- Suspicious quoted 'output' directory
2025-05-31 00:06:37 +02:00
47a4c04d96 refactor: Standardize theme structure and update configs
- Restructured 'minimal' theme to use 'static/css' and 'static/js' subdirectories for assets, aligning with qsgen3's expected theme structure.
- Moved 'minimaltemplate-v1.css' to 'themes/minimal/static/css/'.
- Moved JS files from 'themes/minimal/css/' to 'themes/minimal/static/js/'.
- Updated 'site.conf.example' to reflect 'minimal' theme usage and correct 'site_theme_css_file' path relative to the theme's static directory.
- Cleaned up redundant CSS variable definitions in 'bin/qsgen3' (_generate_index_page function).
2025-05-31 00:05:05 +02:00
8ffd19a0c4 refactor: Remove redundant root CSS files
Removed layouts/css/default.css and static/css/style.css as themes now provide their own CSS, making these files obsolete.
2025-05-31 00:03:08 +02:00
3dad33a939 build: Add output/ to .gitignore and untrack existing output dir 2025-05-31 00:01:19 +02:00
c470ac40c0 feat: Implement robust theme system and document architecture
- Implement flexible theme switching via site.conf (site_theme, site_theme_css_file).
- Ensure correct copying of theme static assets, with theme assets overriding root assets.
- Resolve CSS linking issues by checking file existence after static copy and using correct paths for Pandoc.
- Refactor path construction to prevent duplication when using absolute/relative output paths.
- Create comprehensive how-it-works.md detailing system architecture, theme creation, and overall workflow.
- Clarify design philosophy: qsgen3 remains design-agnostic, only linking main theme CSS automatically.
2025-05-31 00:00:21 +02:00
31 changed files with 2817 additions and 4008 deletions

4
.gitignore vendored
View File

@ -18,8 +18,10 @@ include/qsgen2/lang/*.new
include/qsgen2/lang/*.txt include/qsgen2/lang/*.txt
include/qsgen2/lang/*.en include/qsgen2/lang/*.en
# Generated site output
output/
# Scripts directory (temporary/conversion scripts) # Scripts directory (temporary/conversion scripts)
/scripts/
/tools/ /tools/
# Build output # Build output

220
HOWTO.md
View File

@ -1,220 +0,0 @@
# Quick Site Generator 2 (qsgen2) - User Guide
## Table of Contents
1. [Introduction](#introduction)
2. [Installation](#installation)
3. [Quick Start](#quick-start)
4. [Project Structure](#project-structure)
5. [Content Creation](#content-creation)
- [Pages](#pages)
- [Blog Posts](#blog-posts)
6. [Markup Languages](#markup-languages)
- [QSTags](#qstags)
- [Markdown](#markdown)
- [Conversion Between Formats](#conversion-between-formats)
7. [Themes and Templates](#themes-and-templates)
8. [Configuration](#configuration)
9. [Command Reference](#command-reference)
10. [Advanced Usage](#advanced-usage)
11. [Troubleshooting](#troubleshooting)
12. [Contributing](#contributing)
## Introduction
Quick Site Generator 2 (qsgen2) is a powerful static site generator written in Zsh. It's designed to be fast, flexible, and easy to use, with support for both custom QSTags and standard Markdown syntax.
## Installation
1. Clone the repository:
```bash
git clone https://github.com/kekePower/qsgen2.git
cd qsgen2
```
2. Make the script executable:
```bash
chmod +x qsgen2
```
3. Add to your PATH (optional):
```bash
echo 'export PATH="$PATH:'$(pwd)'"' >> ~/.zshrc
source ~/.zshrc
```
## Quick Start
1. Create a new site:
```bash
./qsgen2 new my-site
cd my-site
```
2. Build the site:
```bash
./qsgen2 build
```
3. Preview the site:
```bash
./qsgen2 serve
```
## Project Structure
```
my-site/
├── config # Site configuration
├── content/ # Source content
│ ├── pages/ # Static pages
│ └── blog/ # Blog posts
├── themes/ # Site themes
├── static/ # Static files (images, CSS, JS)
└── output/ # Generated site (created on build)
```
## Content Creation
### Pages
Create a new page:
```bash
./qsgen2 new page about
```
Pages use the `.qst` extension and can include QSTags or Markdown.
### Blog Posts
Create a new blog post:
```bash
./qsgen2 new post my-first-post
```
Blog posts use the `.blog` extension and support the same markup as pages.
## Markup Languages
### QSTags
QSTags is a simple markup language used by qsgen2. Example:
```
#H1 Welcome to My Site#EH1
#P This is a paragraph with #BDbold#EBD and #Iitalic#EI text.#EP
```
### Markdown
Markdown is also supported:
```markdown
# Welcome to My Site
This is a paragraph with **bold** and *italic* text.
```
### Conversion Between Formats
Convert a single file to Markdown:
```bash
./qsgen2 convert --to-markdown content/pages/about.qst content/pages/about.md
```
Convert all files to Markdown:
```bash
./qsgen2 convert --to-markdown --all
```
Convert back to QSTags:
```bash
./qsgen2 convert --to-qstags --all
```
## Themes and Templates
Themes are stored in the `themes` directory. Each theme can include:
- Page templates
- Blog post templates
- CSS/JavaScript
- Assets
## Configuration
Edit `config/site.conf` to customize your site:
```ini
site_name = "My Awesome Site"
site_url = "https://example.com"
site_author = "Your Name"
theme = "default"
```
## Command Reference
### Build Commands
- `build`: Build the site
- `clean`: Remove generated files
- `serve`: Start a local server
### Content Management
- `new page <name>`: Create a new page
- `new post <title>`: Create a new blog post
- `convert`: Convert between markup formats
### Utility Commands
- `version`: Show version information
- `help`: Show help message
## Advanced Usage
### Custom Build Scripts
Create a `build.zsh` file in your project root:
```bash
#!/usr/bin/env zsh
# Custom build script
# Clean previous build
./qsgen2 clean
# Convert all content to Markdown for editing
./qsgen2 convert --to-markdown --all
# Build the site
./qsgen2 build
# Optimize images
find output -name "*.jpg" -exec jpegoptim --strip-all {} \;
```
## Troubleshooting
### Common Issues
1. **Permission Denied**
```bash
chmod +x qsgen2
```
2. **Command Not Found**
Add qsgen2 to your PATH or use `./qsgen2`
3. **Build Errors**
Check for syntax errors in your content files
## Contributing
1. Fork the repository
2. Create a feature branch
3. Commit your changes
4. Push to the branch
5. Create a Pull Request
## License
MIT License - See LICENSE for details.
---
*Quick Site Generator 2 - A fast, flexible static site generator*

View File

@ -1,70 +1,45 @@
<img src="qsg2-square.png" width="150" align="left"> # qsgen3 - A Minimal Markdown Static Site Generator
# Quick Site Generator 2 This is a refactored version of qsgen, focusing on simplicity, Markdown with YAML frontmatter, and a Zsh-based build process.
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) ## Project Goals
Quick Site Generator 2 is a powerful static website generator written in Zsh, inspired by [Nikola](https://github.com/getnikola/nikola). It's designed to be fast, flexible, and easy to use, with support for both custom QSTags and standard Markdown syntax. - Remove QSTags and switch to Markdown + YAML frontmatter.
- Simplify codebase by removing multilingual and theme support.
- Refactor templating with uniform variables (e.g., `{{ content }}`, `{{ title }}`).
- Ensure future-proofing by avoiding complex dependencies (like AWK for long string manipulation) for core tasks.
- Provide a solid initial setup that works out of the box with a sample post, index, and layout.
- Include a converter script in `scripts/convert-qstags-to-md.sh` for legacy content.
## Features ## Structure
- 🚀 Blazing fast static site generation - `bin/qsgen3`: The main Zsh build script.
- 📝 Supports both QSTags and Markdown content - `site.conf`: Site configuration (INI format).
- 🌍 Multi-language support (en_US, en_UK, es_ES, fr_FR, nb_NO) - `content/`: Source Markdown files.
- 🎨 Themeable with custom templates (see [THEME-HOWTO.md](THEME-HOWTO.md)) - `content/posts/`: Blog posts.
- 📱 Responsive design ready - `content/pages/`: Static pages.
- 🔍 SEO friendly - `layouts/`: HTML templates.
- 🔄 Automatic rebuild on file changes - `layouts/base.html`: Base template for all pages.
- `layouts/post.html`: Template for individual blog posts.
- `layouts/page.html`: Template for static pages.
- `static/`: Static assets (CSS, images, etc.) copied as-is to the output.
- `output/`: The generated website.
- `scripts/`: Utility scripts (e.g., content converter).
## Quick Start ## Usage
1. **Installation** 1. Configure your site in `site.conf`.
2. Add Markdown content to the `content/` directory.
3. Customize templates in `layouts/`.
4. Run the build script:
```bash ```bash
git clone https://github.com/kekePower/qsgen2.git ./bin/qsgen3
cd qsgen2
chmod +x qsgen2
``` ```
5. Your static site will be generated in the `output/` directory.
2. **Create a new site** ## Dependencies
```bash
./qsgen2 new my-site
cd my-site
```
3. **Build and serve** - Zsh
```bash - A Markdown processor (e.g., Pandoc, CommonMark, or a Zsh-native solution if feasible for basic needs).
./qsgen2 build - Standard Unix utilities (grep, sed, find, etc.).
./qsgen2 serve
```
For detailed documentation, see the [HOWTO.md](HOWTO.md) guide.
## Recent Changes
- Added Norwegian (nb_NO) language support
- Improved internationalization (i18n) system
- Cleaned up temporary and backup files
- Updated documentation
- Added comprehensive HOWTO guide
## Requirements
- Zsh 5.8 or later
- Pandoc (for Markdown support)
- Basic Unix tools (sed, grep, etc.)
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Contributing
Contributions are welcome! Please read our [contributing guidelines](CONTRIBUTING.md) before submitting pull requests.
## Support
For support, please [open an issue](https://github.com/kekePower/qsgen2/issues) on GitHub.
---
*Created with ❤️ by kekePower*

View File

@ -1,194 +0,0 @@
# Creating Themes for Quick Site Generator 2
This guide explains how to create and customize themes for Quick Site Generator 2 (qsgen2). The theming system is designed to be simple yet flexible, allowing you to create beautiful, responsive websites with minimal effort.
## Table of Contents
1. [Theme Structure](#theme-structure)
2. [Template Files](#template-files)
- [pages.tpl](#pagestpl)
- [blogs.tpl](#blogstpl)
- [blog_index.tpl](#blog_indextpl)
- [blog_list.tpl](#blog_listtpl)
3. [Template Variables](#template-variables)
4. [Creating a New Theme](#creating-a-new-theme)
5. [Best Practices](#best-practices)
6. [Example Theme](#example-theme)
## Theme Structure
A qsgen2 theme consists of the following files:
```
theme-name/
├── pages.tpl # Template for regular pages
├── blogs.tpl # Template for blog posts
├── blog_index.tpl # Template for blog index page
├── blog_list.tpl # Template for blog post listings
└── css/ # Stylesheets and assets
├── style.css # Main stylesheet
└── webfont.js # Web font loader (optional)
```
## Template Files
### pages.tpl
This template is used for regular static pages. It should include the basic HTML structure, head section, and placeholders for dynamic content.
Key placeholders:
- `#sitename` - Site name from configuration
- `#pagetitle` - Title of the current page
- `#tagline` - Site tagline from configuration
- `BODY` - Main content area
### blogs.tpl
This template is used for individual blog posts. It includes placeholders for blog-specific content.
Key placeholders:
- `BLOGTITLE` - Title of the blog post
- `CALADAY` - Day of the month (numeric)
- `CALNDAY` - Day of the week (name)
- `CALMONTH` - Month name
- `CALYEAR` - Year
- `INGRESS` - Blog post excerpt/intro
- `BODY` - Main blog post content
### blog_index.tpl
This template is used for the blog index/archive page that lists all blog posts.
Key placeholders:
- `#sitename` - Site name from configuration
- `#tagline` - Site tagline from configuration
- `BODY` - Contains the list of blog posts (generated from blog_list.tpl)
### blog_list.tpl
This template defines how individual blog posts are displayed in the blog index.
Key placeholders:
- `BLOGURL` - URL of the blog post
- `BLOGTITLE` - Title of the blog post
- `INGRESS` - Blog post excerpt/intro
- `BLOGDATE` - Formatted date of the blog post
## Template Variables
These variables can be used in any template:
- `#sitename` - Site name from configuration
- `#tagline` - Site tagline from configuration
- `#pagetitle` - Current page title
- `#siteurl` - Base URL of the site
- `#currentyear` - Current year (for copyright notices)
## Creating a New Theme
1. **Create a new directory** in the `themes` folder with your theme name.
2. **Copy the template files** from the `minimal` theme as a starting point:
```bash
cp -r themes/minimal/* themes/your-theme-name/
```
3. **Customize the templates**:
- Edit the HTML structure in the `.tpl` files
- Update the CSS in the `css` directory
- Replace placeholder images with your own
4. **Test your theme** by setting it in your `site.conf`:
```ini
theme = "your-theme-name"
```
5. **Build your site** to see the changes:
```bash
./qsgen2 build
```
## Best Practices
1. **Responsive Design**
- Use responsive CSS frameworks or media queries
- Test on different screen sizes
2. **Performance**
- Minify CSS and JavaScript
- Optimize images
- Use web fonts sparingly
3. **Accessibility**
- Use semantic HTML5 elements
- Include alt text for images
- Ensure sufficient color contrast
4. **Browser Compatibility**
- Test in multiple browsers
- Use vendor prefixes for CSS properties
## Example Theme
Here's a minimal example of a theme structure:
```
my-theme/
├── pages.tpl
├── blogs.tpl
├── blog_index.tpl
├── blog_list.tpl
└── css/
└── style.css
```
### pages.tpl (example)
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>#sitename - #pagetitle</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/css/style.css" rel="stylesheet">
</head>
<body>
<header>
<h1>#sitename</h1>
<p>#tagline</p>
<nav>
<a href="/">Home</a>
<a href="/blog/">Blog</a>
</nav>
</header>
<main>
BODY
</main>
<footer>
<p>&copy; #currentyear #sitename. All rights reserved.</p>
</footer>
</body>
</html>
```
### blog_list.tpl (example)
```html
<article class="blog-post">
<h2><a href="BLOGURL">BLOGTITLE</a></h2>
<div class="post-meta">
<time datetime="BLOGDATE">BLOGDATE</time>
</div>
<div class="post-excerpt">
INGRESS
<a href="BLOGURL" class="read-more">Read more →</a>
</div>
</article>
```
## Conclusion
Creating themes for qsgen2 is straightforward once you understand the template system. Start with the minimal theme as a base, and customize it to match your design. Remember to test your theme thoroughly and follow web development best practices for the best results.
For more advanced theming options, refer to the official documentation or check out the source code of existing themes.

1245
bin/qsgen3 Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
---
title: "Hello, World!"
date: "2024-05-30"
author: "qsgen3"
draft: false
summary: "My first post using the qsgen3 static site generator."
---
Welcome to qsgen3!
This is your first post. You can edit it or delete it and start writing your own content.
## Markdown Features
Qsgen3 supports standard Markdown features, including:
- Headings
- **Bold** and *italic* text
- Lists:
- Unordered
- Ordered
- [Links](https://example.com)
- `Inline code`
```bash
# Code blocks
echo "Hello from a code block!"
```
Enjoy creating your site!

1029
how-it-works.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,88 +0,0 @@
# Here you set the colors you want in the output of view and search
#
# Black 0;30 Dark Gray 1;30
# Blue 0;34 Light Blue 1;34
# Green 0;32 Light Green 1;32
# Cyan 0;36 Light Cyan 1;36
# Red 0;31 Light Red 1;31
# Purple 0;35 Light Purple 1;35
# Brown 0;33 Yellow 1;33
# Light Gray 0;37 White 1;37
BLACK="\033[0;30m"
RED="\033[0;31m"
GREEN="\033[0;32m"
YELLOW="\033[0;33m"
BLUE="\033[0;34m"
MAGENTA="\033[0;35m"
CYAN="\033[0;36m"
WHITE="\033[0;37m"
BOLD_BLACK="\033[1;30m"
BOLD_RED="\033[1;31m"
BOLD_GREEN="\033[1;32m"
BOLD_YELLOW="\033[1;33m"
BOLD_BLUE="\033[1;34m"
BOLD_MAGENTA="\033[1;35m"
BOLD_CYAN="\033[1;36m"
BOLD_WHITE="\033[1;37m"
BLACK_BG="\033[40m"
RED_BG="\033[41m"
GREEN_BG="\033[42m"
YELLOW_BG="\033[43m"
BLUE_BG="\033[44m"
MAGENTA_BG="\033[45m"
CYAN_BG="\033[46m"
WHITE_BG="\033[47m"
END="\033[0m"
Black="\033[0;30m"
Red="\033[0;31m"
Green="\033[0;32m"
Yellow="\033[0;33m"
Blue="\033[0;34m"
Magenta="\033[0;35m"
Cyan="\033[0;36m"
White="\033[0;37m"
Bold_Black="\033[1;30m"
Bold_Red="\033[1;31m"
Bold_Green="\033[1;32m"
Bold_Yellow="\033[1;33m"
Bold_Blue="\033[1;34m"
Bold_Magenta="\033[1;35m"
Bold_Cyan="\033[1;36m"
Bold_White="\033[1;37m"
Black_bg="\033[40m"
Red_bg="\033[41m"
Green_bg="\033[42m"
Yellow_bg="\033[43m"
Blue_bg="\033[44m"
Magenta_bg="\033[45m"
Cyan_bg="\033[46m"
White_bg="\033[47m"
End="\033[0m"
black="\033[0;30m"
red="\033[0;31m"
green="\033[0;32m"
yellow="\033[0;33m"
blue="\033[0;34m"
magenta="\033[0;35m"
cyan="\033[0;36m"
white="\033[0;37m"
bold_black="\033[1;30m"
bold_red="\033[1;31m"
bold_green="\033[1;32m"
bold_yellow="\033[1;33m"
bold_blue="\033[1;34m"
bold_magenta="\033[1;35m"
bold_cyan="\033[1;36m"
bold_white="\033[1;37m"
black_bg="\033[40m"
red_bg="\033[41m"
green_bg="\033[42m"
yellow_bg="\033[43m"
blue_bg="\033[44m"
magenta_bg="\033[45m"
cyan_bg="\033[46m"
white_bg="\033[47m"
end="\033[0m"

View File

@ -1,15 +0,0 @@
function include() {
# This function is used to include other functions that will normally be in
# ${HOME}/bin/include/
# Edit this path to reflect your installation
local inc_file=${HOME}/bin/include/${1}.inc
if [[ ! -f ${inc_file} ]]; then
local inc_opt=$( echo ${1} | cut -d\/ -f2 )
echo "Supplied option \"${inc_opt}\" is not a valid include."
else
builtin source ${inc_file} ${2}
fi
}

View File

@ -1,11 +0,0 @@
# Converts a --with=option,option2 into an array
# Usage: InputToArray <input-string>
# Returns: $InputArray
function InputToArray () {
if [[ ${@} =~ "--with" ]]; then
InputArray=( $( echo ${@} | cut -d= -f2 | sed -e 's/\,/\ /g' ) )
fi
}

View File

@ -1,7 +0,0 @@
# Function: LOGGER
# Usage: loggy <message>
function loggy () {
echo "$$ - $(date +%T) - ${KODIVERSION} - ${@}" >> ${LOGGYLOGFILE}
}

View File

@ -1,9 +0,0 @@
# This function creates an array of a *nix path
# Example: /home/user/bin becomes an array of ( home user bin )
function slash_to_array () {
sta=( $( echo ${1} | sed -e "s/\//\ /g" ) )
# return ${sta}
}

View File

@ -1,39 +0,0 @@
# zini function to parse INI files and store their content in an associative array
zini() {
local ini_path="$1"
typeset -gA config
# Check if the file exists
if [[ ! -f "$ini_path" ]]; then
echo "Configuration file not found: $ini_path"
return 1
fi
local current_section=""
local line key value composite_key
# Read the INI file line by line
while IFS= read -r line || [[ -n $line ]]; do
line=$(echo $line | xargs) # Trim whitespace
# Skip empty lines and comments
[[ -z "$line" || "$line" == \;* ]] && continue
# Detect section headers
if [[ "$line" == \[*\]* ]]; then
current_section="${line:1:-1}"
else
# Parse key-value pairs
key=${line%%=*}
value=${line#*=}
key=$(echo $key | xargs) # Trim key
value=$(echo $value | xargs) # Trim value
# Store in associative array with 'section_key' format
composite_key="${current_section}_${key}"
config[$composite_key]="$value"
fi
done < "$ini_path"
# echo "Configuration loaded."
}

View File

@ -1,217 +0,0 @@
# Quick Site Generator 2 - English Language File
# This file contains all user-facing strings for the application
# Error Messages
error.missing_dependencies = "Missing required dependencies: %s"
error.config_validation_failed = "Configuration validation failed. Please check your configuration files."
error.config_missing_key = "Missing required configuration: %s"
error.invalid_url = "site_url must start with http:// or https://"
error.directory_not_found = "Directory does not exist: %s"
error.theme_not_found = "Theme directory not found: %s"
error.theme_config_not_found = "Theme configuration not found: %s"
error.theme_config_creation_failed = "Failed to create theme configuration: %s"
error.config_parse = "Failed to parse config file: %s"
error.invalid_path = "Invalid path: %s"
error.write_failed = "Failed to write to temporary file: %s"
error.move_failed = "Failed to move temporary file to: %s"
error.config_load_failed = "Failed to load configuration file: %s"
error.config_not_found = "No valid configuration file found."
error.create_blog_index_failed = "Failed to create blog index at: %s"
error.create_sample_post_failed = "Failed to create sample blog post at: %s"
error.create_sample_page_failed = "Failed to create sample page at: %s"
error.engine_not_found = "Engine not found or not executable: %s"
error.unknown_generator = "Unknown generator: %s"
error.unknown_option = "Unknown option: %s"
error.directory_not_empty = "Directory '%s' already exists and is not empty."
error.theme_creation_failed = "Failed to create theme: %s"
error.config_creation_failed = "Failed to create configuration file: %s"
error.directory_creation_failed = "Failed to create directory: %s"
error.file_creation_failed = "Failed to create file: %s"
error.layout_creation_failed = "Failed to create layout file: %s"
error.stylesheet_creation_failed = "Failed to create stylesheet: %s"
error.script_creation_failed = "Failed to create script file: %s"
# Warning Messages
warning.optional_dependency = "Optional tool '%s' is required for %s but not found"
warning.dependency_version = "%s version %s is below the recommended version %s"
warning.legacy_config = "Using legacy config file. Consider renaming '%s' to 'site.conf'"
warning.git_repo = "Warning: Running in a git repository directory. Make sure this is intended."
warning.outdated_dependencies = "Some dependencies are outdated:"
# Info Messages
info.legacy_config = "Warning: Using legacy '%s' file. Consider renaming to 'site.conf'"
info.legacy_config_used = "Using legacy config file. Consider renaming 'config' to 'site.conf'"
info.config_help = "Please create 'site.conf' in your project directory."
info.config_template = "You can use 'config.example' as a template."
info.git_repo_help = "If you want to generate the site, run from the project root directory."
info.usage = "Usage: %s <command> [options]"
info.engine_usage = "Usage: _run_engine <input>"
info.creating_blog_index = "Creating blog index file..."
info.creating_sample_post = "Creating sample blog post..."
info.creating_sample_page = "Creating sample page..."
info.setting_up_project = "Setting up project structure..."
info.creating_directories = "Creating project directories..."
info.initializing_blog = "Initializing blog..."
info.initializing_pages = "Initializing pages..."
info.initializing_theme = "Initializing theme..."
info.initializing_config = "Initializing configuration..."
info.initializing_complete = "Initialization complete!"
info.initializing_aborted = "Initialization aborted."
info.use_force_option = "Use --force to overwrite the existing directory."
info.get_started_instructions = "To get started"
info.happy_coding = "Happy coding!"
info.initializing_project = "Initializing project..."
info.initializing_blog_cache = "Initializing blog cache..."
info.initializing_pages_cache = "Initializing pages cache..."
# Debug Messages
debug.loading_config = "Loading config file: %s"
debug.loaded_config = "=== Loaded Configuration ==="
debug.config_value = "%s: %s"
debug.config_end = "==========================="
debug.raw_config = "=== Raw Config File ==="
debug.raw_config_end = "======================"
debug.blog_cache_update = "Updating blog cache at %s"
debug.blog_cache_bytes = "Blog cache updated with %d bytes"
debug.blog_cache_loading = "Loading blog index from cache"
debug.blog_cache_stale_new = "Blog cache stale: New or updated blogs detected"
debug.blog_cache_stale_missing = "Blog cache stale: Cache file does not exist"
debug.blog_cache_stale_old = "Blog cache stale: Cache is older than 1 hour"
debug.blog_cache_fresh = "Blog cache is fresh"
debug.pages_cache_update = "Updating pages cache at %s"
debug.pages_cache_bytes = "Pages cache updated with %d bytes"
debug.pages_cache_loading = "Loading pages index from cache"
debug.pages_cache_stale_new = "Pages cache stale: New or updated pages detected"
debug.pages_cache_stale_missing = "Pages cache stale: Cache file does not exist"
debug.pages_cache_stale_old = "Pages cache stale: Cache is older than 1 hour"
debug.pages_cache_fresh = "Pages cache is fresh"
# Blog Messages
blog.not_found = "No blog files found."
blog.generating = "Generating blog"
blog.no_template = "Unable to find the blog template: %s"
blog.cache_updated = "Blog cache updated"
blog.cache_loading = "Loading blog cache"
blog.cache_stale = "Blog cache is stale, rebuilding..."
blog.cache_fresh = "Blog cache is fresh"
blog.post_updated = "Updated blog post: %s"
blog.post_skipped = "Skipped (no changes): %s"
blog.post_error = "Error processing blog post: %s"
# Blog Generation Messages
blog.hello_world_title = "Hello, World!"
blog.published_on = "Published on"
blog.welcome_message = "Welcome to your new blog! This is a sample blog post."
blog.getting_started = "Getting Started"
blog.edit_this_post = "You can edit this post at %s"
blog.features = "Features"
blog.feature_markdown = "Markdown support"
blog.feature_easy_customize = "Easy to customize"
blog.feature_fast_lightweight = "Fast and lightweight"
blog.next_steps = "Next Steps"
blog.step_edit_post = "Edit this post"
blog.step_add_posts = "Add more posts"
blog.step_customize_theme = "Customize your theme"
blog.step_publish_site = "Publish your site"
blog.happy_blogging = "Happy blogging!"
blog.latest_posts = "Latest Posts"
blog.sample_post = "Blog Post"
blog.categories = "Categories"
blog.sample_category = "Category"
blog.archives = "Archives"
blog.tags = "Tags"
blog.about = "About"
blog.about_text = "This is a sample blog index page. You can edit it at %s"
# Page Generation Messages
page.about_me_title = "About Me"
page.welcome_title = "Welcome to My Site"
page.welcome_message = "This is a sample about page. You can edit it at %s"
page.my_story_title = "My Story"
page.my_story_content = "I'm a passionate developer who loves creating amazing websites with qsgen2!"
page.skills_title = "Skills"
page.skill_webdev = "Web Development"
page.skill_design = "Design"
page.skill_opensource = "Open Source"
page.contact_title = "Contact"
page.contact_content = "You can reach me at: email@example.com"
page.about_site_title = "About This Site"
page.about_site_content = "This site was built with [qsgen2](https://github.com/kekePower/qsgen2)."
# Success Messages
success.config_loaded = "Configuration loaded successfully"
success.build_complete = "Build completed successfully"
success.blog_index_created = "Created blog index at: %s"
success.sample_post_created = "Created sample blog post at: %s"
success.sample_page_created = "Created sample page at: %s"
success.project_initialized = "Project initialized successfully!"
success.theme_initialized = "Theme initialized successfully!"
success.config_initialized = "Configuration file created successfully!"
# System Messages
system.created_by = "- Created by kekePower - 2018-%s"
system.see_help = "- See '%s help' for more information."
# List Messages
list.pages_not_found = "_list_pages: No Pages found with ext %s"
list.pages_adding = "_list_pages: Adding file to array: %s"
list.blogs_not_found = "_list_blogs: No blog files found."
list.blogs_adding = "_list_blogs: Adding file to array: %s"
# Blog Cache Messages
blog_cache.hash = "_blog_cache: HASH VALUE:"
blog_cache.current = "1. _blog_cache:"
blog_cache.cache_file = "2. _blog_cache: current_cache:"
blog_cache.new_cache = "3. _blog_cache: new_cache_file:"
blog_cache.new_current = "4. _blog_cache: new_current_cache:"
# Pages Cache Messages
page_cache.hash = "PAGES HASH VALUE:"
page_cache.current = "1. pages_cache:"
page_cache.cache_file = "2. _pages_cache: current_cache:"
page_cache.pages_file = "2. _pages_cache: pages_file:"
# Navigation
nav.home = "Home"
nav.blog = "Blog"
nav.about = "About"
# Footer
footer.all_rights_reserved = "All rights reserved."
# Configuration
config.site_config_title = "Site Configuration"
config.theme_config_title = "Theme Configuration"
config.site_name_default = "My Awesome Site"
config.site_tagline_default = "A static site generated with qsgen2"
config.site_description_default = "This is my awesome static site"
config.your_name = "Your Name"
config.theme_description = "A custom theme for qsgen2"
config.theme_files_title = "Theme files (relative to theme directory)"
# CSS and JavaScript
css.main_styles = "Main Styles"
js.main_javascript = "Main JavaScript"
js.console_message = "Hello from qsgen2!"
js.add_custom_javascript = "Add any custom JavaScript here"
js.your_code_here = "Your code here"
# Last Updated Messages
last_updated.setting = "_last_updated: Setting date and version in footer"
last_updated.file_not_found = "_f_last_updated: File %s not found."
# Pages Messages
pages.generating = "Generating Pages"
pages.none = "* You do not have any pages *"
pages.no_template = "Unable to find the Pages template: %s"
# Pandoc Messages
pandoc.install = "Please install Pandoc."
pandoc.download = "https://github.com/jgm/pandoc/releases"
# Generator Messages
generator.not_found = "No valid generator found. Are you sure you've selected the correct generator in 'config'?"
# Build Messages
build.forced = "- Forced Update: Generating Everything"
build.using_engine = "Using the %s -engine for files:"

View File

@ -1,217 +0,0 @@
# Quick Site Generator 2 - English Language File
# This file contains all user-facing strings for the application
# Error Messages
error.missing_dependencies = "Missing required dependencies: %s"
error.config_validation_failed = "Configuration validation failed. Please check your configuration files."
error.config_missing_key = "Missing required configuration: %s"
error.invalid_url = "site_url must start with http:// or https://"
error.directory_not_found = "Directory does not exist: %s"
error.theme_not_found = "Theme directory not found: %s"
error.theme_config_not_found = "Theme configuration not found: %s"
error.theme_config_creation_failed = "Failed to create theme configuration: %s"
error.config_parse = "Failed to parse config file: %s"
error.invalid_path = "Invalid path: %s"
error.write_failed = "Failed to write to temporary file: %s"
error.move_failed = "Failed to move temporary file to: %s"
error.config_load_failed = "Failed to load configuration file: %s"
error.config_not_found = "No valid configuration file found."
error.create_blog_index_failed = "Failed to create blog index at: %s"
error.create_sample_post_failed = "Failed to create sample blog post at: %s"
error.create_sample_page_failed = "Failed to create sample page at: %s"
error.engine_not_found = "Engine not found or not executable: %s"
error.unknown_generator = "Unknown generator: %s"
error.unknown_option = "Unknown option: %s"
error.directory_not_empty = "Directory '%s' already exists and is not empty."
error.theme_creation_failed = "Failed to create theme: %s"
error.config_creation_failed = "Failed to create configuration file: %s"
error.directory_creation_failed = "Failed to create directory: %s"
error.file_creation_failed = "Failed to create file: %s"
error.layout_creation_failed = "Failed to create layout file: %s"
error.stylesheet_creation_failed = "Failed to create stylesheet: %s"
error.script_creation_failed = "Failed to create script file: %s"
# Warning Messages
warning.optional_dependency = "Optional tool '%s' is required for %s but not found"
warning.dependency_version = "%s version %s is below the recommended version %s"
warning.legacy_config = "Using legacy config file. Consider renaming '%s' to 'site.conf'"
warning.git_repo = "Warning: Running in a git repository directory. Make sure this is intended."
warning.outdated_dependencies = "Some dependencies are outdated:"
# Info Messages
info.legacy_config = "Warning: Using legacy '%s' file. Consider renaming to 'site.conf'"
info.legacy_config_used = "Using legacy config file. Consider renaming 'config' to 'site.conf'"
info.config_help = "Please create 'site.conf' in your project directory."
info.config_template = "You can use 'config.example' as a template."
info.git_repo_help = "If you want to generate the site, run from the project root directory."
info.usage = "Usage: %s <command> [options]"
info.engine_usage = "Usage: _run_engine <input>"
info.creating_blog_index = "Creating blog index file..."
info.creating_sample_post = "Creating sample blog post..."
info.creating_sample_page = "Creating sample page..."
info.setting_up_project = "Setting up project structure..."
info.creating_directories = "Creating project directories..."
info.initializing_blog = "Initializing blog..."
info.initializing_pages = "Initializing pages..."
info.initializing_theme = "Initializing theme..."
info.initializing_config = "Initializing configuration..."
info.initializing_complete = "Initialization complete!"
info.initializing_aborted = "Initialization aborted."
info.use_force_option = "Use --force to overwrite the existing directory."
info.get_started_instructions = "To get started"
info.happy_coding = "Happy coding!"
info.initializing_project = "Initializing project..."
info.initializing_blog_cache = "Initializing blog cache..."
info.initializing_pages_cache = "Initializing pages cache..."
# Debug Messages
debug.loading_config = "Loading config file: %s"
debug.loaded_config = "=== Loaded Configuration ==="
debug.config_value = "%s: %s"
debug.config_end = "==========================="
debug.raw_config = "=== Raw Config File ==="
debug.raw_config_end = "======================"
debug.blog_cache_update = "Updating blog cache at %s"
debug.blog_cache_bytes = "Blog cache updated with %d bytes"
debug.blog_cache_loading = "Loading blog index from cache"
debug.blog_cache_stale_new = "Blog cache stale: New or updated blogs detected"
debug.blog_cache_stale_missing = "Blog cache stale: Cache file does not exist"
debug.blog_cache_stale_old = "Blog cache stale: Cache is older than 1 hour"
debug.blog_cache_fresh = "Blog cache is fresh"
debug.pages_cache_update = "Updating pages cache at %s"
debug.pages_cache_bytes = "Pages cache updated with %d bytes"
debug.pages_cache_loading = "Loading pages index from cache"
debug.pages_cache_stale_new = "Pages cache stale: New or updated pages detected"
debug.pages_cache_stale_missing = "Pages cache stale: Cache file does not exist"
debug.pages_cache_stale_old = "Pages cache stale: Cache is older than 1 hour"
debug.pages_cache_fresh = "Pages cache is fresh"
# Blog Messages
blog.not_found = "No blog files found."
blog.generating = "Generating blog"
blog.no_template = "Unable to find the blog template: %s"
blog.cache_updated = "Blog cache updated"
blog.cache_loading = "Loading blog cache"
blog.cache_stale = "Blog cache is stale, rebuilding..."
blog.cache_fresh = "Blog cache is fresh"
blog.post_updated = "Updated blog post: %s"
blog.post_skipped = "Skipped (no changes): %s"
blog.post_error = "Error processing blog post: %s"
# Blog Generation Messages
blog.hello_world_title = "Hello, World!"
blog.published_on = "Published on"
blog.welcome_message = "Welcome to your new blog! This is a sample blog post."
blog.getting_started = "Getting Started"
blog.edit_this_post = "You can edit this post at %s"
blog.features = "Features"
blog.feature_markdown = "Markdown support"
blog.feature_easy_customize = "Easy to customize"
blog.feature_fast_lightweight = "Fast and lightweight"
blog.next_steps = "Next Steps"
blog.step_edit_post = "Edit this post"
blog.step_add_posts = "Add more posts"
blog.step_customize_theme = "Customize your theme"
blog.step_publish_site = "Publish your site"
blog.happy_blogging = "Happy blogging!"
blog.latest_posts = "Latest Posts"
blog.sample_post = "Blog Post"
blog.categories = "Categories"
blog.sample_category = "Category"
blog.archives = "Archives"
blog.tags = "Tags"
blog.about = "About"
blog.about_text = "This is a sample blog index page. You can edit it at %s"
# Page Generation Messages
page.about_me_title = "About Me"
page.welcome_title = "Welcome to My Site"
page.welcome_message = "This is a sample about page. You can edit it at %s"
page.my_story_title = "My Story"
page.my_story_content = "I'm a passionate developer who loves creating amazing websites with qsgen2!"
page.skills_title = "Skills"
page.skill_webdev = "Web Development"
page.skill_design = "Design"
page.skill_opensource = "Open Source"
page.contact_title = "Contact"
page.contact_content = "You can reach me at: email@example.com"
page.about_site_title = "About This Site"
page.about_site_content = "This site was built with [qsgen2](https://github.com/kekePower/qsgen2)."
# Success Messages
success.config_loaded = "Configuration loaded successfully"
success.build_complete = "Build completed successfully"
success.blog_index_created = "Created blog index at: %s"
success.sample_post_created = "Created sample blog post at: %s"
success.sample_page_created = "Created sample page at: %s"
success.project_initialized = "Project initialized successfully!"
success.theme_initialized = "Theme initialized successfully!"
success.config_initialized = "Configuration file created successfully!"
# System Messages
system.created_by = "- Created by kekePower - 2018-%s"
system.see_help = "- See '%s help' for more information."
# List Messages
list.pages_not_found = "_list_pages: No Pages found with ext %s"
list.pages_adding = "_list_pages: Adding file to array: %s"
list.blogs_not_found = "_list_blogs: No blog files found."
list.blogs_adding = "_list_blogs: Adding file to array: %s"
# Blog Cache Messages
blog_cache.hash = "_blog_cache: HASH VALUE:"
blog_cache.current = "1. _blog_cache:"
blog_cache.cache_file = "2. _blog_cache: current_cache:"
blog_cache.new_cache = "3. _blog_cache: new_cache_file:"
blog_cache.new_current = "4. _blog_cache: new_current_cache:"
# Pages Cache Messages
page_cache.hash = "PAGES HASH VALUE:"
page_cache.current = "1. pages_cache:"
page_cache.cache_file = "2. _pages_cache: current_cache:"
page_cache.pages_file = "2. _pages_cache: pages_file:"
# Navigation
nav.home = "Home"
nav.blog = "Blog"
nav.about = "About"
# Footer
footer.all_rights_reserved = "All rights reserved."
# Configuration
config.site_config_title = "Site Configuration"
config.theme_config_title = "Theme Configuration"
config.site_name_default = "My Awesome Site"
config.site_tagline_default = "A static site generated with qsgen2"
config.site_description_default = "This is my awesome static site"
config.your_name = "Your Name"
config.theme_description = "A custom theme for qsgen2"
config.theme_files_title = "Theme files (relative to theme directory)"
# CSS and JavaScript
css.main_styles = "Main Styles"
js.main_javascript = "Main JavaScript"
js.console_message = "Hello from qsgen2!"
js.add_custom_javascript = "Add any custom JavaScript here"
js.your_code_here = "Your code here"
# Last Updated Messages
last_updated.setting = "_last_updated: Setting date and version in footer"
last_updated.file_not_found = "_f_last_updated: File %s not found."
# Pages Messages
pages.generating = "Generating Pages"
pages.none = "* You do not have any pages *"
pages.no_template = "Unable to find the Pages template: %s"
# Pandoc Messages
pandoc.install = "Please install Pandoc."
pandoc.download = "https://github.com/jgm/pandoc/releases"
# Generator Messages
generator.not_found = "No valid generator found. Are you sure you've selected the correct generator in 'config'?"
# Build Messages
build.forced = "- Forced Update: Generating Everything"
build.using_engine = "Using the %s -engine for files:"

View File

@ -1,207 +0,0 @@
# Generador Rápido de Sitios 2 - Archivo de idioma español
# Este archivo contiene todas las cadenas visibles para el usuario de la aplicación
# Mensajes de error
error.missing_dependencies = "Faltan dependencias requeridas: %s"
error.config_validation_failed = "Error en la validación de la configuración. Por favor, verifique sus archivos de configuración."
error.config_missing_key = "Falta la configuración requerida: %s"
error.invalid_url = "site_url debe comenzar con http:// o https://"
error.directory_not_found = "El directorio no existe: %s"
error.theme_not_found = "Directorio del tema no encontrado: %s"
error.theme_config_not_found = "Configuración del tema no encontrada: %s"
error.theme_config_creation_failed = "Error al crear la configuración del tema: %s"
error.config_parse = "Error al analizar el archivo de configuración: %s"
error.invalid_path = "Ruta no válida: %s"
error.write_failed = "Error al escribir en el archivo temporal: %s"
error.move_failed = "Error al mover el archivo temporal a: %s"
error.config_load_failed = "Error al cargar el archivo de configuración: %s"
error.config_not_found = "No se encontró ningún archivo de configuración válido."
error.create_blog_index_failed = "Error al crear el índice del blog en: %s"
error.create_sample_post_failed = "Error al crear la entrada de blog de ejemplo en: %s"
error.create_sample_page_failed = "Error al crear la página de ejemplo en: %s"
error.engine_not_found = "Motor no encontrado o no ejecutable: %s"
error.unknown_generator = "Generador desconocido: %s"
error.unknown_option = "Opción desconocida: %s"
error.directory_not_empty = "El directorio '%s' ya existe y no está vacío."
error.theme_creation_failed = "Error al crear el tema: %s"
error.config_creation_failed = "Error al crear el archivo de configuración: %s"
error.directory_creation_failed = "Error al crear el directorio: %s"
error.file_creation_failed = "Error al crear el archivo: %s"
error.layout_creation_failed = "Error al crear el archivo de diseño: %s"
error.stylesheet_creation_failed = "Error al crear la hoja de estilos: %s"
error.script_creation_failed = "Error al crear el archivo de script: %s"
# Mensajes de advertencia
warning.optional_dependency = "La herramienta opcional '%s' es necesaria para %s pero no se encontró"
warning.dependency_version = "La versión %s de %s es inferior a la versión recomendada %s"
warning.legacy_config = "Usando archivo de configuración heredado. Considere renombrar '%s' a 'site.conf'"
warning.git_repo = "Advertencia: Ejecutando en un directorio de repositorio git. Asegúrese de que es intencionado."
warning.outdated_dependencies = "Algunas dependencias están desactualizadas:"
# Mensajes informativos
info.legacy_config = "Advertencia: Usando archivo heredado '%s'. Considere renombrarlo a 'site.conf'"
info.legacy_config_used = "Usando archivo de configuración heredado. Considere renombrar 'config' a 'site.conf'"
info.config_help = "Por favor, cree un archivo 'site.conf' en el directorio de su proyecto."
info.config_template = "Puede usar 'config.example' como plantilla."
info.git_repo_help = "Si desea generar el sitio, ejecútelo desde el directorio raíz del proyecto."
info.usage = "Uso: %s <comando> [opciones]"
info.engine_usage = "Uso: _run_engine <entrada>"
info.creating_blog_index = "Creando archivo de índice del blog..."
info.creating_sample_post = "Creando entrada de blog de ejemplo..."
info.creating_sample_page = "Creando página de ejemplo..."
info.setting_up_project = "Configurando la estructura del proyecto..."
info.creating_directories = "Creando directorios del proyecto..."
info.initializing_blog = "Inicializando blog..."
info.initializing_pages = "Inicializando páginas..."
info.initializing_theme = "Inicializando tema..."
info.initializing_config = "Inicializando configuración..."
info.initializing_complete = "¡Inicialización completada!"
info.initializing_aborted = "Inicialización cancelada."
info.use_force_option = "Use --force para sobrescribir el directorio existente."
info.get_started_instructions = "Para comenzar"
info.happy_coding = "¡Feliz programación!"
info.initializing_project = "Inicializando proyecto..."
info.initializing_blog_cache = "Inicializando caché del blog..."
info.initializing_pages_cache = "Inicializando caché de páginas..."
# Mensajes de depuración
debug.loading_config = "Cargando archivo de configuración: %s"
debug.loaded_config = "=== Configuración Cargada ==="
debug.config_value = "%s: %s"
debug.config_end = "============================"
debug.raw_config = "=== Archivo de Configuración en Bruto ==="
debug.raw_config_end = "=================================="
debug.blog_cache_update = "Actualizando caché del blog en %s"
debug.blog_cache_bytes = "Caché del blog actualizado con %d bytes"
debug.blog_cache_loading = "Cargando índice del blog desde la caché"
debug.blog_cache_stale_new = "Caché del blog desactualizado: Se detectaron blogs nuevos o actualizados"
debug.blog_cache_stale_missing = "Caché del blog desactualizado: El archivo de caché no existe"
debug.blog_cache_stale_old = "Caché del blog desactualizado: La caché tiene más de 1 hora"
debug.blog_cache_fresh = "La caché del blog está actualizada"
debug.pages_cache_update = "Actualizando caché de páginas en %s"
debug.pages_cache_bytes = "Caché de páginas actualizado con %d bytes"
debug.pages_cache_loading = "Cargando índice de páginas desde la caché"
debug.pages_cache_stale_new = "Caché de páginas desactualizado: Se detectaron páginas nuevas o actualizadas"
debug.pages_cache_stale_missing = "Caché de páginas desactualizado: El archivo de caché no existe"
debug.pages_cache_stale_old = "Caché de páginas desactualizado: La caché tiene más de 1 hora"
debug.pages_cache_fresh = "La caché de páginas está actualizada"
# Mensajes del Blog
blog.not_found = "No se encontraron archivos de blog."
blog.generating = "Generando blog"
blog.no_template = "No se pudo encontrar la plantilla del blog: %s"
blog.cache_updated = "Caché del blog actualizado"
blog.cache_loading = "Cargando caché del blog"
blog.cache_stale = "La caché del blog está desactualizada, reconstruyendo..."
blog.cache_fresh = "La caché del blog está actualizada"
blog.post_updated = "Entrada de blog actualizada: %s"
blog.post_skipped = "Omitido (sin cambios): %s"
blog.post_error = "Error al procesar la entrada del blog: %s"
# Mensajes de Generación del Blog
blog.hello_world_title = "¡Hola, Mundo!"
blog.published_on = "Publicado el"
blog.welcome_message = "¡Bienvenido a tu nuevo blog! Esta es una entrada de blog de ejemplo."
blog.getting_started = "Comenzando"
blog.edit_this_post = "Puedes editar esta entrada en %s"
blog.features = "Características"
blog.feature_markdown = "Soporte para Markdown"
blog.feature_easy_customize = "Fácil de personalizar"
blog.feature_fast_lightweight = "Rápido y ligero"
blog.next_steps = "Próximos pasos"
blog.step_edit_post = "Editar esta entrada"
blog.step_add_posts = "Añadir más entradas"
blog.step_customize_theme = "Personalizar tu tema"
blog.step_publish_site = "Publicar tu sitio"
blog.happy_blogging = "¡Feliz blogueo!"
blog.latest_posts = "Últimas entradas"
blog.sample_post = "Entrada de blog"
blog.categories = "Categorías"
blog.sample_category = "Categoría"
blog.archives = "Archivos"
blog.tags = "Etiquetas"
blog.about = "Acerca de"
blog.about_text = "Esta es una página de índice de blog de ejemplo. Puedes editarla en %s"
# Mensajes de Generación de Páginas
page.about_me_title = "Sobre Mí"
page.welcome_title = "Bienvenido a Mi Sitio"
page.welcome_message = "Esta es una página de ejemplo. Puedes editarla en %s"
page.my_story_title = "Mi Historia"
page.my_story_content = "¡Soy un desarrollador apasionado que adora crear sitios web increíbles con qsgen2!"
page.skills_title = "Habilidades"
page.skill_webdev = "Desarrollo Web"
page.skill_design = "Diseño"
page.skill_opensource = "Código Abierto"
page.contact_title = "Contacto"
page.contact_content = "Puedes contactarme en: email@example.com"
page.about_site_title = "Acerca de Este Sitio"
page.about_site_content = "Este sitio fue construido con [qsgen2](https://github.com/kekePower/qsgen2)."
# Mensajes de Éxito
success.config_loaded = "Configuración cargada exitosamente"
success.build_complete = "Construcción completada exitosamente"
success.blog_index_created = "Índice del blog creado en: %s"
success.sample_post_created = "Entrada de blog de ejemplo creada en: %s"
success.sample_page_created = "Página de ejemplo creada en: %s"
success.project_initialized = "¡Proyecto inicializado exitosamente!"
success.theme_initialized = "¡Tema inicializado exitosamente!"
success.config_initialized = "¡Archivo de configuración creado exitosamente!"
# Mensajes del Sistema
system.created_by = "- Creado por kekePower - 2018-%s"
system.see_help = "- Ver '%s help' para más información."
# Mensajes de Lista
list.pages_not_found = "_list_pages: No se encontraron páginas con la extensión %s"
list.pages_adding = "_list_pages: Añadiendo archivo al array: %s"
list.blogs_not_found = "_list_blogs: No se encontraron archivos de blog."
list.blogs_adding = "_list_blogs: Añadiendo archivo al array: %s"
# Navegación
nav.home = "Inicio"
nav.blog = "Blog"
nav.about = "Acerca de"
# Pie de Página
footer.all_rights_reserved = "Todos los derechos reservados."
# Configuración
config.site_config_title = "Configuración del Sitio"
config.theme_config_title = "Configuración del Tema"
config.site_name_default = "Mi Sitio Increíble"
config.site_tagline_default = "Un sitio estático generado con qsgen2"
config.site_description_default = "Este es mi increíble sitio estático"
config.your_name = "Tu Nombre"
config.theme_description = "Un tema personalizado para qsgen2"
config.theme_files_title = "Archivos del tema (relativo al directorio del tema)"
# CSS y JavaScript
css.main_styles = "Estilos Principales"
js.main_javascript = "JavaScript Principal"
js.console_message = "¡Hola desde qsgen2!"
js.add_custom_javascript = "Añade cualquier JavaScript personalizado aquí"
js.your_code_here = "Tu código aquí"
# Mensajes de Última Actualización
last_updated.setting = "_last_updated: Estableciendo fecha y versión en el pie de página"
last_updated.file_not_found = "_f_last_updated: Archivo %s no encontrado."
# Mensajes de Páginas
pages.generating = "Generando Páginas"
pages.none = "* No tienes páginas *"
pages.no_template = "No se pudo encontrar la plantilla de páginas: %s"
# Mensajes de Pandoc
pandoc.install = "Por favor, instala Pandoc."
pandoc.download = "https://github.com/jgm/pandoc/releases"
# Mensajes del Generador
generator.not_found = "No se encontró un generador válido. ¿Estás seguro de que has seleccionado el generador correcto en 'config'?"
generator.using = "Usando generador: %s"
generator.execution_failed = "Error en la ejecución del generador: %s"
generator.execution_success = "Generador ejecutado exitosamente: %s"
# Mensajes de Construcción
build.forced = "- Actualización forzada: Generando todo"
build.using_engine = "Usando el motor %s para archivos:"

View File

@ -1,209 +0,0 @@
# Générateur de Site Rapide 2 - Fichier de langue française
# Ce fichier contient toutes les chaînes visibles par l'utilisateur pour l'application
# Messages d'erreur
error.missing_dependencies = "Dépendances requises manquantes : %s"
error.config_validation_failed = "Échec de la validation de la configuration. Veuillez vérifier vos fichiers de configuration."
error.config_missing_key = "Configuration requise manquante : %s"
error.invalid_url = "site_url doit commencer par http:// ou https://"
error.directory_not_found = "Le répertoire n'existe pas : %s"
error.theme_not_found = "Répertoire du thème introuvable : %s"
error.theme_config_not_found = "Configuration du thème introuvable : %s"
error.theme_config_creation_failed = "Échec de la création de la configuration du thème : %s"
error.config_parse = "Échec de l'analyse du fichier de configuration : %s"
error.invalid_path = "Chemin invalide : %s"
error.write_failed = "Échec de l'écriture dans le fichier temporaire : %s"
error.move_failed = "Échec du déplacement du fichier temporaire vers : %s"
error.config_load_failed = "Échec du chargement du fichier de configuration : %s"
error.config_not_found = "Aucun fichier de configuration valide trouvé."
error.create_blog_index_failed = "Échec de la création de l'index du blog à : %s"
error.create_sample_post_failed = "Échec de la création d'un exemple d'article de blog à : %s"
error.create_sample_page_failed = "Échec de la création d'une page exemple à : %s"
error.engine_not_found = "Moteur introuvable ou non exécutable : %s"
error.unknown_generator = "Générateur inconnu : %s"
error.unknown_option = "Option inconnue : %s"
error.directory_not_empty = "Le répertoire '%s' existe déjà et n'est pas vide."
error.theme_creation_failed = "Échec de la création du thème : %s"
error.config_creation_failed = "Échec de la création du fichier de configuration : %s"
error.directory_creation_failed = "Échec de la création du répertoire : %s"
error.file_creation_failed = "Échec de la création du fichier : %s"
error.layout_creation_failed = "Échec de la création du fichier de mise en page : %s"
error.stylesheet_creation_failed = "Échec de la création de la feuille de style : %s"
error.script_creation_failed = "Échec de la création du fichier de script : %s"
# Messages d'avertissement
warning.optional_dependency = "L'outil optionnel '%s' est requis pour %s mais n'a pas été trouvé"
warning.dependency_version = "La version %s de %s est inférieure à la version recommandée %s"
warning.legacy_config = "Utilisation d'un fichier de configuration hérité. Envisagez de renommer '%s' en 'site.conf'"
warning.git_repo = "Attention : Exécution dans un répertoire de dépôt git. Assurez-vous que c'est intentionnel."
warning.outdated_dependencies = "Certaines dépendances ne sont pas à jour :"
# Messages d'information
info.legacy_config = "Attention : Utilisation du fichier hérité '%s'. Envisagez de le renommer en 'site.conf'"
info.legacy_config_used = "Utilisation du fichier de configuration hérité. Envisagez de renommer 'config' en 'site.conf'"
info.config_help = "Veuillez créer un fichier 'site.conf' dans votre répertoire de projet."
info.config_template = "Vous pouvez utiliser 'config.example' comme modèle."
info.git_repo_help = "Si vous souhaitez générer le site, exécutez depuis le répertoire racine du projet."
info.usage = "Utilisation : %s <commande> [options]"
info.engine_usage = "Utilisation : _run_engine <entrée>"
info.creating_blog_index = "Création du fichier d'index du blog..."
info.creating_sample_post = "Création d'un exemple d'article de blog..."
info.creating_sample_page = "Création d'une page exemple..."
info.setting_up_project = "Configuration de la structure du projet..."
info.creating_directories = "Création des répertoires du projet..."
info.initializing_blog = "Initialisation du blog..."
info.initializing_pages = "Initialisation des pages..."
info.initializing_theme = "Initialisation du thème..."
# Messages de débogage
debug.loading_config = "Chargement du fichier de configuration : %s"
debug.loaded_config = "=== Configuration Chargée ==="
debug.config_value = "%s : %s"
debug.config_end = "=========================="
debug.raw_config = "=== Fichier de Configuration Brut ==="
debug.raw_config_end = "================================"
debug.blog_cache_update = "Mise à jour du cache du blog à %s"
debug.blog_cache_bytes = "Cache du blog mis à jour avec %d octets"
debug.blog_cache_loading = "Chargement de l'index du blog depuis le cache"
debug.blog_cache_stale_new = "Cache du blog obsolète : Nouveaux blogs ou mises à jour détectés"
debug.blog_cache_stale_deleted = "Cache du blog obsolète : Blogs supprimés détectés"
debug.blog_cache_fresh = "Le cache du blog est à jour, reconstruction ignorée"
debug.blog_cache_rebuilding = "Reconstruction du cache du blog..."
debug.blog_cache_rebuilt = "Cache du blog reconstruit avec %d entrées"
debug.pages_cache_update = "Mise à jour du cache des pages à %s"
debug.pages_cache_bytes = "Cache des pages mis à jour avec %d octets"
debug.pages_cache_loading = "Chargement de l'index des pages depuis le cache"
debug.pages_cache_stale_new = "Cache des pages obsolète : Nouvelles pages ou mises à jour détectées"
debug.pages_cache_stale_deleted = "Cache des pages obsolète : Pages supprimées détectées"
debug.pages_cache_fresh = "Le cache des pages est à jour, reconstruction ignorée"
debug.pages_cache_rebuilding = "Reconstruction du cache des pages..."
debug.pages_cache_rebuilt = "Cache des pages reconstruit avec %d entrées"
debug.cache_hit = "Cache trouvé pour %s"
debug.cache_miss = "Cache manquant pour %s"
debug.cache_updated = "Cache mis à jour pour %s"
debug.cache_skipped = "Mise à jour du cache ignorée pour %s (aucun changement détecté)"
blog.cache_loading = "Chargement de l'index du blog depuis le cache"
blog.cache_stale = "Cache du blog obsolète, reconstruction..."
blog.cache_fresh = "Le cache du blog est à jour"
blog.post_updated = "Article de blog mis à jour : %s"
blog.post_skipped = "Ignoré (aucun changement) : %s"
# Blog Messages
blog.not_found = "Aucun fichier de blog trouvé."
blog.generating = "Génération du blog"
blog.no_template = "Impossible de trouver le modèle de blog : %s"
blog.cache_updated = "Cache du blog mis à jour"
blog.cache_loading = "Chargement de l'index du blog depuis le cache"
blog.cache_stale = "Cache du blog obsolète, reconstruction..."
blog.cache_fresh = "Le cache du blog est à jour"
blog.post_updated = "Article de blog mis à jour : %s"
blog.post_skipped = "Ignoré (aucun changement) : %s"
blog.post_error = "Erreur lors du traitement de l'article de blog : %s"
# Messages de Génération de Blog
blog.hello_world_title = "Bonjour le monde !"
blog.published_on = "Publié le"
blog.welcome_message = "Bienvenue sur votre nouveau blog ! Ceci est un exemple d'article de blog."
blog.getting_started = "Pour commencer"
blog.edit_this_post = "Vous pouvez modifier cet article à l'emplacement %s"
blog.features = "Fonctionnalités"
blog.feature_markdown = "Prise en charge du Markdown"
blog.feature_easy_customize = "Facile à personnaliser"
blog.feature_fast_lightweight = "Rapide et léger"
blog.next_steps = "Prochaines étapes"
blog.step_edit_post = "Modifier cet article"
blog.step_add_posts = "Ajouter plus d'articles"
blog.step_customize_theme = "Personnaliser votre thème"
blog.step_publish_site = "Publier votre site"
blog.happy_blogging = "Bon blogage !"
blog.latest_posts = "Derniers articles"
blog.sample_post = "Article de blog"
blog.categories = "Catégories"
blog.sample_category = "Catégorie"
blog.archives = "Archives"
blog.tags = "Étiquettes"
blog.about = "À propos"
blog.about_text = "Ceci est une page d'index de blog exemple. Vous pouvez la modifier à l'emplacement %s"
# Messages de Génération de Pages
page.about_me_title = "À propos de moi"
page.welcome_title = "Bienvenue sur mon site"
page.welcome_message = "Ceci est une page À propos exemple. Vous pouvez la modifier à l'emplacement %s"
page.my_story_title = "Mon histoire"
page.my_story_content = "Je suis un développeur passionné qui adore créer des sites web incroyables avec qsgen2 !"
page.skills_title = "Compétences"
page.skill_webdev = "Développement Web"
page.skill_design = "Design"
page.skill_opensource = "Logiciel Libre"
page.contact_title = "Contact"
page.contact_content = "Vous pouvez me contacter à : email@exemple.com"
page.about_site_title = "À propos de ce site"
page.about_site_content = "Ce site a été construit avec [qsgen2](https://github.com/kekePower/qsgen2)."
# Messages de Succès
success.config_loaded = "Configuration chargée avec succès"
success.build_complete = "Construction terminée avec succès"
success.blog_index_created = "Index du blog créé à l'emplacement : %s"
success.sample_post_created = "Exemple d'article de blog créé à l'emplacement : %s"
success.sample_page_created = "Page exemple créée à l'emplacement : %s"
success.project_initialized = "Projet initialisé avec succès !"
success.theme_initialized = "Thème initialisé avec succès !"
success.config_initialized = "Fichier de configuration créé avec succès !"
# Messages Système
system.created_by = "- Créé par kekePower - 2018-%s"
system.see_help = "- Voir '%s help' pour plus d'informations."
# Messages de Liste
list.pages_not_found = "_list_pages : Aucune page trouvée avec l'extension %s"
list.pages_adding = "_list_pages : Ajout du fichier au tableau : %s"
list.blogs_not_found = "_list_blogs : Aucun fichier de blog trouvé."
list.blogs_adding = "_list_blogs : Ajout du fichier au tableau : %s"
# Navigation
nav.home = "Accueil"
nav.blog = "Blog"
nav.about = "À propos"
# Pied de page
footer.all_rights_reserved = "Tous droits réservés."
# Configuration
config.site_config_title = "Configuration du Site"
config.theme_config_title = "Configuration du Thème"
config.site_name_default = "Mon Super Site"
config.site_tagline_default = "Un site statique généré avec qsgen2"
config.site_description_default = "Voici mon super site statique"
config.your_name = "Votre Nom"
config.theme_description = "Un thème personnalisé pour qsgen2"
config.theme_files_title = "Fichiers du thème (relatif au répertoire du thème)"
# CSS et JavaScript
css.main_styles = "Styles Principaux"
js.main_javascript = "JavaScript Principal"
js.console_message = "Bonjour depuis qsgen2 !"
js.add_custom_javascript = "Ajoutez votre code JavaScript personnalisé ici"
js.your_code_here = "Votre code ici"
# Messages de Dernière Mise à Jour
last_updated.setting = "_last_updated : Définition de la date et de la version dans le pied de page"
last_updated.file_not_found = "_f_last_updated : Fichier %s non trouvé."
# Pages Messages
pages.generating = "Génération des Pages"
pages.none = "* Vous n'avez aucune page *"
pages.no_template = "Impossible de trouver le modèle de page : %s"
# Messages Pandoc
pandoc.install = "Veuillez installer Pandoc."
pandoc.download = "https://github.com/jgm/pandoc/releases"
# Messages du Générateur
generator.not_found = "Aucun générateur valide trouvé. Êtes-vous sûr d'avoir sélectionné le bon générateur dans 'config' ?"
generator.using = "Utilisation du générateur : %s"
generator.not_found = "Générateur introuvable : %s"
generator.execution_failed = "Échec de l'exécution du générateur : %s"
generator.execution_success = "Générateur exécuté avec succès : %s"
# Messages de Construction
build.forced = "- Mise à jour forcée : Génération complète"
build.using_engine = "Utilisation du moteur %s pour les fichiers :"

View File

@ -1,217 +0,0 @@
# Quick Site Generator 2 - Norsk språkfil
# Denne filen inneholder alle brukervendte strenger for applikasjonen
# Feilmeldinger
error.missing_dependencies = "Mangler påkrevde avhengigheter: %s"
error.config_validation_failed = "Validering av konfigurasjon feilet. Vennligst sjekk konfigurasjonsfilene dine."
error.config_missing_key = "Mangler påkrevd konfigurasjon: %s"
error.invalid_url = "site_url må starte med http:// eller https://"
error.directory_not_found = "Mappen finnes ikke: %s"
error.theme_not_found = "Temamappe ikke funnet: %s"
error.theme_config_not_found = "Temakonfigurasjon ikke funnet: %s"
error.theme_config_creation_failed = "Kunne ikke opprette temakonfigurasjon: %s"
error.config_parse = "Kunne ikke tolke konfigurasjonsfil: %s"
error.invalid_path = "Ugyldig sti: %s"
error.write_failed = "Kunne ikke skrive til midlertidig fil: %s"
error.move_failed = "Kunne ikke flytte midlertidig fil til: %s"
error.config_load_failed = "Kunne ikke laste konfigurasjonsfil: %s"
error.config_not_found = "Ingen gyldig konfigurasjonsfil funnet."
error.create_blog_index_failed = "Kunne ikke opprette bloggindeks på: %s"
error.create_sample_post_failed = "Kunne ikke opprette eksempelinnlegg på: %s"
error.create_sample_page_failed = "Kunne ikke opprette eksempelside på: %s"
error.engine_not_found = "Motor ikke funnet eller ikke kjørbar: %s"
error.unknown_generator = "Ukjent generator: %s"
error.unknown_option = "Ukjent alternativ: %s"
error.directory_not_empty = "Mappen '%s' finnes allerede og er ikke tom."
error.theme_creation_failed = "Kunne ikke opprette tema: %s"
error.config_creation_failed = "Kunne ikke opprette konfigurasjonsfil: %s"
error.directory_creation_failed = "Kunne ikke opprette mappe: %s"
error.file_creation_failed = "Kunne ikke opprette fil: %s"
error.layout_creation_failed = "Kunne ikke opprette layoutfil: %s"
error.stylesheet_creation_failed = "Kunne ikke opprette stilark: %s"
error.script_creation_failed = "Kunne ikke opprette scriptfil: %s"
# Advarselsmeldinger
warning.optional_dependency = "Valgfritt verktøy '%s' kreves for %s, men ble ikke funnet"
warning.dependency_version = "%s versjon %s er lavere enn anbefalt versjon %s"
warning.legacy_config = "Bruker gammel konfigurasjonsfil. Vurder å endre navn på '%s' til 'site.conf'"
warning.git_repo = "Advarsel: Kjører i en git-mappe. Forsikre deg om at dette er meningen."
warning.outdated_dependencies = "Noen avhengigheter er utdaterte:"
# Informasjonsmeldinger
info.legacy_config = "Advarsel: Bruker gammel '%s'-fil. Vurder å endre navn til 'site.conf'"
info.legacy_config_used = "Bruker gammel konfigurasjonsfil. Vurder å endre navn fra 'config' til 'site.conf'"
info.config_help = "Vennligst opprett 'site.conf' i prosjektmappen din."
info.config_template = "Du kan bruke 'config.example' som en mal."
info.git_repo_help = "Hvis du vil generere nettsiden, kjør fra prosjektets rotmappe."
info.usage = "Bruk: %s <kommando> [alternativer]"
info.engine_usage = "Bruk: _run_engine <inndata>"
info.creating_blog_index = "Oppretter bloggindeksfil..."
info.creating_sample_post = "Oppretter eksempelinnlegg..."
info.creating_sample_page = "Oppretter eksempelside..."
info.setting_up_project = "Setter opp prosjektstruktur..."
info.creating_directories = "Oppretter prosjektmapper..."
info.initializing_blog = "Initialiserer blogg..."
info.initializing_pages = "Initialiserer sider..."
info.initializing_theme = "Initialiserer tema..."
info.initializing_config = "Initialiserer konfigurasjon..."
info.initializing_complete = "Initialisering fullført!"
info.initializing_aborted = "Initialisering avbrutt."
info.use_force_option = "Bruk --force for å overskrive den eksisterende mappen."
info.get_started_instructions = "For å komme i gang"
info.happy_coding = "Lykke til med kodingen!"
info.initializing_project = "Initialiserer prosjekt..."
info.initializing_blog_cache = "Initialiserer blogg-mellomlager..."
info.initializing_pages_cache = "Initialiserer side-mellomlager..."
# Feilsøkingsmeldinger
debug.loading_config = "Laster konfigurasjonsfil: %s"
debug.loaded_config = "=== Lastet Konfigurasjon ==="
debug.config_value = "%s: %s"
debug.config_end = "=========================="
debug.raw_config = "=== Rå Konfigurasjonsfil ==="
debug.raw_config_end = "========================"
debug.blog_cache_update = "Oppdaterer blogg-mellomlager på %s"
debug.blog_cache_bytes = "Blogg-mellomlager oppdatert med %d byte"
debug.blog_cache_loading = "Laster bloggindeks fra mellomlager"
debug.blog_cache_stale_new = "Blogg-mellomlager utdatert: Nye eller oppdaterte blogger oppdaget"
debug.blog_cache_stale_missing = "Blogg-mellomlager utdatert: Mellomlagerfilen finnes ikke"
debug.blog_cache_stale_old = "Blogg-mellomlager utdatert: Mellomlager er eldre enn 1 time"
debug.blog_cache_fresh = "Blogg-mellomlager er oppdatert"
debug.pages_cache_update = "Oppdaterer side-mellomlager på %s"
debug.pages_cache_bytes = "Side-mellomlager oppdatert med %d byte"
debug.pages_cache_loading = "Laster sideindeks fra mellomlager"
debug.pages_cache_stale_new = "Side-mellomlager utdatert: Nye eller oppdaterte sider oppdaget"
debug.pages_cache_stale_missing = "Side-mellomlager utdatert: Mellomlagerfilen finnes ikke"
debug.pages_cache_stale_old = "Side-mellomlager utdatert: Mellomlager er eldre enn 1 time"
debug.pages_cache_fresh = "Side-mellomlager er oppdatert"
# Bloggmeldinger
blog.not_found = "Ingen bloggfiler funnet."
blog.generating = "Genererer blogg"
blog.no_template = "Kunne ikke finne bloggmalen: %s"
blog.cache_updated = "Blogg-mellomlager oppdatert"
blog.cache_loading = "Laster blogg-mellomlager"
blog.cache_stale = "Blogg-mellomlager er utdatert, bygger på nytt..."
blog.cache_fresh = "Blogg-mellomlager er oppdatert"
blog.post_updated = "Oppdatert blogginnlegg: %s"
blog.post_skipped = "Hoppet over (ingen endringer): %s"
blog.post_error = "Feil ved behandling av blogginnlegg: %s"
# Blogg-genereringsmeldinger
blog.hello_world_title = "Hallo, verden!"
blog.published_on = "Publisert den"
blog.welcome_message = "Velkommen til din nye blogg! Dette er et eksempel på et blogginnlegg."
blog.getting_started = "Kom i gang"
blog.edit_this_post = "Du kan redigere dette innlegget på %s"
blog.features = "Funksjoner"
blog.feature_markdown = "Støtte for Markdown"
blog.feature_easy_customize = "Lett å tilpasse"
blog.feature_fast_lightweight = "Rask og lettvektig"
blog.next_steps = "Neste steg"
blog.step_edit_post = "Rediger dette innlegget"
blog.step_add_posts = "Legg til flere innlegg"
blog.step_customize_theme = "Tilpass temaet ditt"
blog.step_publish_site = "Publiser nettstedet ditt"
blog.happy_blogging = "Lykke til med bloggingen!"
blog.latest_posts = "Siste innlegg"
blog.sample_post = "Blogginnlegg"
blog.categories = "Kategorier"
blog.sample_category = "Kategori"
blog.archives = "Arkiv"
blog.tags = "Emneknagger"
blog.about = "Om"
blog.about_text = "Dette er en eksempelindeksside for bloggen. Du kan redigere den på %s"
# Sidegenereringsmeldinger
page.about_me_title = "Om meg"
page.welcome_title = "Velkommen til nettstedet mitt"
page.welcome_message = "Dette er en eksempel 'om'-side. Du kan redigere den på %s"
page.my_story_title = "Min historie"
page.my_story_content = "Jeg er en lidenskapelig utvikler som elsker å lage fantastiske nettsteder med qsgen2!"
page.skills_title = "Ferdigheter"
page.skill_webdev = "Nettutvikling"
page.skill_design = "Design"
page.skill_opensource = "Åpen kildekode"
page.contact_title = "Kontakt"
page.contact_content = "Du kan nå meg på: epost@eksempel.no"
page.about_site_title = "Om dette nettstedet"
page.about_site_content = "Dette nettstedet er bygget med [qsgen2](https://github.com/kekePower/qsgen2)."
# Suksessmeldinger
success.config_loaded = "Konfigurasjon lastet inn vellykket"
success.build_complete = "Bygging fullført vellykket"
success.blog_index_created = "Opprettet bloggindeks på: %s"
success.sample_post_created = "Opprettet eksempelblogginnlegg på: %s"
success.sample_page_created = "Opprettet eksempelside på: %s"
success.project_initialized = "Prosjektet er initialisert!"
success.theme_initialized = "Temaet er initialisert!"
success.config_initialized = "Konfigurasjonsfil opprettet!"
# Blogg-mellomlager meldinger
blog_cache.hash = "_blog_cache: HASH VERDI:"
blog_cache.current = "1. _blog_cache:"
blog_cache.cache_file = "2. _blog_cache: current_cache:"
blog_cache.new_cache = "3. _blog_cache: new_cache_file:"
blog_cache.new_current = "4. _blog_cache: new_current_cache:"
# Sider-mellomlager meldinger
page_cache.hash = "SIDER HASH VERDI:"
page_cache.current = "1. pages_cache:"
page_cache.cache_file = "2. _pages_cache: current_cache:"
page_cache.pages_file = "2. _pages_cache: pages_file:"
# Systemmeldinger
system.created_by = "- Laget av kekePower - 2018-%s"
system.see_help = "- Se '%s help' for mer informasjon."
# Listemeldinger
list.pages_not_found = "_list_pages: Ingen sider funnet med filendelse %s"
list.pages_adding = "_list_pages: Legger til fil i tabell: %s"
list.blogs_not_found = "_list_blogs: Ingen bloggfiler funnet."
list.blogs_adding = "_list_blogs: Legger til fil i tabell: %s"
# Navigasjon
nav.home = "Hjem"
nav.blog = "Blogg"
nav.about = "Om"
# Bunntekst
footer.all_rights_reserved = "Alle rettigheter reservert."
# Konfigurasjon
config.site_config_title = "Nettstedsinnstillinger"
config.theme_config_title = "Temainnstillinger"
config.site_name_default = "Mitt fantastiske nettsted"
config.site_tagline_default = "Et statisk nettsted generert med qsgen2"
config.site_description_default = "Dette er mitt fantastiske statiske nettsted"
config.your_name = "Ditt navn"
config.theme_description = "Et egendefinert tema for qsgen2"
config.theme_files_title = "Temafiler (relativ til temamappe)"
# CSS og JavaScript
css.main_styles = "Hovedstiler"
js.main_javascript = "Hoved-JavaScript"
js.console_message = "Hallo fra qsgen2!"
js.add_custom_javascript = "Legg til egendefinert JavaScript her"
js.your_code_here = "Din kode her"
# Sist oppdatert-meldinger
last_updated.setting = "_last_updated: Setter dato og versjon i bunntekst"
last_updated.file_not_found = "_f_last_updated: Filen %s ble ikke funnet."
# Pages Messages
pages.generating = "Genererer sider"
pages.none = "* Du har ingen sider *"
pages.no_template = "Kunne ikke finne sidemalen: %s"
# Pandoc Messages
pandoc.install = "Please install Pandoc."
pandoc.download = "https://github.com/jgm/pandoc/releases"
# Generator Messages
generator.not_found = "No valid generator found. Are you sure you've selected the correct generator in 'config'?"
# Build Messages
build.forced = "- Forced Update: Generating Everything"
build.using_engine = "Using the %s -engine for files:"

47
layouts/index.html Normal file
View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>$site_name$ - $site_tagline$</title>
$for(css)$
<link rel="stylesheet" href="$css$">
$endfor$
$if(site_rss_url)$
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$site_rss_url$">
$endif$
</head>
<body>
<header>
<h1><a href="$site_url$">$site_name$</a></h1>
<p>$site_tagline$</p>
</header>
<main>
<section id="posts-list">
<h2>Latest Posts</h2>
$if(posts)$
<ul>
$for(posts)$
<li>
<h3><a href="$posts.url$">$posts.title$</a></h3>
$if(posts.date)$
<p class="date">$posts.date$</p>
$endif$
$if(posts.summary)$
<p>$posts.summary$</p>
$endif$
</li>
$endfor$
</ul>
$else$
<p>No posts found.</p>
$endif$
</section>
</main>
<footer>
<p>&copy; $current_year$ $site_name$. Generated by qsgen3.</p>
</footer>
</body>
</html>

32
layouts/page.html Normal file
View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>$site_name$ - $title$</title>
<meta name="description" content="$description$"> <!-- Add description to frontmatter -->
<link rel="stylesheet" href="/static/css/style.css"> <!-- Assuming site served from root -->
$for(css)$
<link rel="stylesheet" href="$css$">
$endfor$
$if(math)$ $math$ $endif$
</head>
<body>
<header>
<h1><a href="/">$site_name$</a></h1>
<p>$site_tagline$</p>
</header>
<main>
<article>
<header>
<h1>$title$</h1>
</header>
$body$
</article>
</main>
<footer>
<p>&copy; $current_year$ $site_name$. Generated by qsgen3.</p>
<p><a href="$site_url$">$site_url$</a></p>
</footer>
</body>
</html>

39
layouts/post.html Normal file
View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>$site_name$ - $title$</title>
<meta name="author" content="$author$">
<meta name="description" content="$description$"> <!-- Add description to frontmatter -->
$if(date)$<meta name="date" content="$date$">$endif$
$for(css)$
<link rel="stylesheet" href="$css$">
$endfor$
$if(math)$ $math$ $endif$
</head>
<body>
<header>
<h1><a href="/">$site_name$</a></h1>
<p>$site_tagline$</p>
</header>
<main>
<article>
<header>
<h1>$title$</h1>
$if(author)$
<p class="author">By: $author$</p>
$endif$
$if(date)$
<p class="date">Published: $date$</p>
$endif$
</header>
$body$
</article>
</main>
<footer>
<p>&copy; $current_year$ $site_name$. Generated by qsgen3. </p>
<p><a href="$site_url$">$site_url$</a></p>
</footer>
</body>
</html>

24
layouts/rss.xml Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>$site_name$</title>
<link>$site_url$</link>
<description>$site_tagline$</description>
<language>en-us</language>
<lastBuildDate>$rfc_2822_date$</lastBuildDate>
<atom:link href="$site_url$/rss.xml" rel="self" type="application/rss+xml" />
$if(posts)$
$for(posts)$
<item>
<title>$it.post_title$</title>
<link>$it.post_url$</link>
<pubDate>$it.post_rfc_2822_date$</pubDate>
<guid isPermaLink="true">$it.post_url$</guid>
<description><![CDATA[$it.post_summary$]]></description>
</item>
$endfor$
$endif$
</channel>
</rss>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 KiB

2275
qsgen3

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,288 @@
import re
import argparse
from pathlib import Path
# Tags that will be kept as HTML as they don't have direct Markdown equivalents
HTML_PASSTHROUGH_TAGS = {
"#DV": "<div>", "#EDV": "</div>",
"#SPN": "<span>", "#ESPN": "</span>",
"#TBL": "<table>", "#ETBL": "</table>",
"#TR": "<tr>", "#ETR": "</tr>",
"#TD": "<td>", "#ETD": "</td>",
"#TH": "<th>", "#ETH": "</th>",
"#ART": "<article>", "#EART": "</article>",
"#SEC": "<section>", "#ESEC": "</section>",
"#ASIDE": "<aside>", "#EASIDE": "</aside>",
"#NAV": "<nav>", "#ENAV": "</nav>",
"#BTN": "<button>", "#EBTN": "</button>",
"#SEL": "<select>", "#ESEL": "</select>",
"#OPT": "<option>", "#EOPT": "</option>",
}
def sanitize_filename(name):
"""Sanitizes a string to be a valid filename."""
name = name.lower()
name = re.sub(r'\s+', '-', name) # Replace spaces with hyphens
name = re.sub(r'[^a-z0-9\-_.]', '', name) # Remove unwanted characters
name = re.sub(r'-+', '-', name) # Replace multiple hyphens with single
name = name.strip('-_')
return name if name else "untitled"
def convert_qstags_to_markdown(content):
"""Converts qstags in content to Markdown syntax."""
# Start with a copy to modify
md_content = content
# Links: #link URL¤TEXT¤ -> [TEXT](URL)
md_content = re.sub(r'#link\s+([^¤]+)¤([^¤]+)¤', r'[\2](\1)', md_content)
# Headings: #H1...#EH1 -> # ..., etc.
for i in range(6, 0, -1):
# Regex to capture content between #Hi and #EHi, case insensitive, dotall for newlines
# Makes #EHi optional if it's at the end of a section or file.
md_content = re.sub(r"#H{i}(.*?)(?:#EH{i}|$)".format(i=i),
r"{} \1".format("#"*i),
md_content, flags=re.IGNORECASE | re.DOTALL)
# Clean up potential multiple newlines left by DOTALL capture if content was multi-line
md_content = re.sub(r"({} .*?)\n\n".format("#"*i), r"\1\n", md_content)
# Blockquotes: #Q...#EQ -> > ...
# This is a simplified approach. For multi-line blockquotes, each line needs '>' prefix.
# We'll capture the content and then process it line by line.
def replace_blockquote(match):
inner_content = match.group(1).strip()
lines = inner_content.split('\n')
return '\n'.join([f"> {line}" for line in lines]) + '\n'
md_content = re.sub(r"#Q(.*?)(?:#EQ|$)", replace_blockquote, md_content, flags=re.IGNORECASE | re.DOTALL)
# Ordered Lists: #OL ... #LI ... #ELI ... #EOL
def replace_ordered_list(match_ol):
ol_content = match_ol.group(1).strip()
list_item_texts = re.findall(r"^[ \t]*#LI[ \t]*(.*?)[ \t]*(?:#ELI)?\s*$", ol_content, flags=re.IGNORECASE | re.MULTILINE)
processed_items = []
for i, item_text in enumerate(list_item_texts):
processed_items.append(f"{i + 1}. {item_text.strip()}")
return "\n".join(processed_items) + ("\n" if processed_items else "")
md_content = re.sub(r"^[ \t]*#OL[ \t]*\n(.*?)\n^[ \t]*#EOL[ \t]*$", replace_ordered_list, md_content, flags=re.IGNORECASE | re.DOTALL | re.MULTILINE)
# Unordered Lists: #UL ... #LI ... #ELI ... #EUL
def replace_unordered_list(match_ul):
ul_content = match_ul.group(1).strip()
list_item_texts = re.findall(r"^[ \t]*#LI[ \t]*(.*?)[ \t]*(?:#ELI)?\s*$", ul_content, flags=re.IGNORECASE | re.MULTILINE)
processed_items = []
for item_text in list_item_texts:
processed_items.append(f"- {item_text.strip()}")
return "\n".join(processed_items) + ("\n" if processed_items else "")
md_content = re.sub(r"^[ \t]*#UL[ \t]*\n(.*?)\n^[ \t]*#EUL[ \t]*$", replace_unordered_list, md_content, flags=re.IGNORECASE | re.DOTALL | re.MULTILINE)
# Remove any stray #ELI tags if they weren't consumed by the #LI regex (unlikely but for cleanup)
md_content = re.sub(r"^[ \t]*#ELI[ \t]*$", "", md_content, flags=re.IGNORECASE | re.MULTILINE)
# Paragraphs: Remove #P, replace #EP with a newline to help separate blocks.
# Markdown relies on blank lines between paragraphs.
md_content = re.sub(r"#P\s*", "", md_content, flags=re.IGNORECASE)
md_content = re.sub(r"\s*#EP", "\n", md_content, flags=re.IGNORECASE)
# Inline elements
md_content = re.sub(r"#BD(.*?)#EBD", r"**\1**", md_content, flags=re.IGNORECASE)
md_content = re.sub(r"#STRONG(.*?)#ESTRONG", r"**\1**", md_content, flags=re.IGNORECASE)
md_content = re.sub(r"#I(.*?)#EI", r"*\1*", md_content, flags=re.IGNORECASE)
md_content = re.sub(r"#EM(.*?)#SEM", r"*\1*", md_content, flags=re.IGNORECASE) # Assuming #SEM is end tag for emphasis
md_content = re.sub(r"#C(.*?)#EC", r"`\1`", md_content, flags=re.IGNORECASE)
md_content = re.sub(r"#UD(.*?)#EUD", r"\1", md_content, flags=re.IGNORECASE) # Markdown has no underline, strip tags
# Images: #showimg IMAGE_PATH¤ALT_TEXT¤ -> ![ALT_TEXT](PROCESSED_IMAGE_PATH)
def process_image_path_for_markdown(raw_path):
if raw_path.startswith(('http://', 'https://', '/')):
return raw_path
else:
return f"/images/{raw_path}"
def replace_showimg_to_markdown(match):
raw_path = match.group(1)
alt_text = match.group(2)
processed_path = process_image_path_for_markdown(raw_path)
return f"![{alt_text}]({processed_path})"
md_content = re.sub(r'#showimg\s+([^¤]+)¤([^¤]+)¤', replace_showimg_to_markdown, md_content)
# Linked Images: #linkimg IMAGE_PATH¤ALT_TEXT¤ -> [![ALT_TEXT](PROCESSED_IMAGE_PATH)](PROCESSED_IMAGE_PATH)
def replace_linkimg_to_markdown(match):
raw_path = match.group(1)
alt_text = match.group(2)
processed_path = process_image_path_for_markdown(raw_path) # Reusing the same path processor
return f"[![{alt_text}]({processed_path})]({processed_path})"
md_content = re.sub(r'#linkimg\s+([^¤]+)¤([^¤]+)¤', replace_linkimg_to_markdown, md_content)
# YouTube Videos: #ytvideo YOUTUBE_ID -> HTML iframe
def replace_ytvideo_to_html(match):
video_id = match.group(1)
return f'<iframe width="560" height="315" src="https://www.youtube.com/embed/{video_id}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>'
md_content = re.sub(r'#ytvideo\s+([A-Za-z0-9_\-]+)', replace_ytvideo_to_html, md_content)
# Line break: #BR -> two spaces + newline
md_content = md_content.replace("#BR", " \n")
# HTML Entities (these are fine as is, Markdown supports them)
md_content = md_content.replace("#LT", "&lt;")
md_content = md_content.replace("#GT", "&gt;")
md_content = md_content.replace("#NUM", "&num;")
# Passthrough HTML for tags without direct Markdown equivalents
for qstag, html_tag in HTML_PASSTHROUGH_TAGS.items():
md_content = md_content.replace(qstag, html_tag)
# Final cleanup:
# Normalize multiple blank lines to a single blank line (Markdown standard for paragraph separation)
md_content = re.sub(r"\n\s*\n", "\n\n", md_content)
# Remove leading/trailing whitespace from the whole content
md_content = md_content.strip()
return md_content
def process_blog_file(file_path, output_dir_base):
"""Processes a .blog file and creates a new Markdown file."""
print(f"Processing blog file: {file_path}")
content_lines = file_path.read_text().splitlines()
metadata = {
"title": "Untitled Post",
"date": "",
"layout": "post",
"author": "Anonymous"
}
body_content = []
# Extract date from filename (e.g., 20250530-3.blog)
match_date_filename = re.match(r'(\d{8})-\d+\.blog', file_path.name)
if match_date_filename:
date_str = match_date_filename.group(1)
metadata['date'] = f"{date_str[:4]}-{date_str[4:6]}-{date_str[6:8]}"
else:
print(f" [WARN] Could not parse date from filename: {file_path.name}. Skipping date.")
parsing_ingress = False
parsing_body = False
for line in content_lines:
if line.startswith("DATE "):
# DATE field in file is secondary to filename date for posts
pass
elif line.startswith("BLOG_TITLE "):
metadata['title'] = line.replace("BLOG_TITLE ", "", 1).strip()
elif line.strip() == "#INGRESS_START":
parsing_ingress = True
continue
elif line.strip() == "#INGRESS_STOP":
parsing_ingress = False
continue
elif line.strip() == "#BODY_START":
parsing_body = True
continue
elif line.strip() == "#BODY_STOP":
parsing_body = False
continue
if parsing_ingress or parsing_body:
body_content.append(line)
markdown_body = convert_qstags_to_markdown("\n".join(body_content))
escaped_title = metadata['title'].replace('"', '\\"') # Escape for YAML
frontmatter = [
"---",
f'title: "{escaped_title}"', # Use single quotes for f-string, double for YAML value
f"date: {metadata['date']}",
f"layout: {metadata['layout']}",
f"author: {metadata['author']}",
"---",
""
]
output_content = "\n".join(frontmatter) + markdown_body
sanitized_title = sanitize_filename(metadata['title'])
if not metadata['date']:
# Fallback if date couldn't be parsed, though unlikely for .blog files
output_subdir = Path(output_dir_base) / "blog" / "unknown_date"
else:
year, month, day = metadata['date'].split('-')
output_subdir = Path(output_dir_base) / "blog" / year / month / day
output_subdir.mkdir(parents=True, exist_ok=True)
output_file_path = output_subdir / f"{sanitized_title}.md"
output_file_path.write_text(output_content)
print(f" -> Created: {output_file_path}")
def process_qst_file(file_path, output_dir_base):
"""Processes a .qst file and creates a new Markdown file."""
print(f"Processing page file: {file_path}")
content_lines = file_path.read_text().splitlines()
metadata = {
"title": "Untitled Page",
"layout": "page",
"author": "Anonymous" # Added for consistency
}
body_content_lines = []
if content_lines and content_lines[0].startswith("#title="):
metadata['title'] = content_lines[0].replace("#title=", "", 1).strip()
body_content_lines = content_lines[1:]
else:
print(f" [WARN] No #title= found in {file_path.name}. Using filename as title.")
metadata['title'] = file_path.stem
body_content_lines = content_lines
markdown_body = convert_qstags_to_markdown("\n".join(body_content_lines))
escaped_title = metadata['title'].replace('"', '\\"') # Escape for YAML
frontmatter = [
"---",
f'title: "{escaped_title}"', # Use single quotes for f-string, double for YAML value
f"layout: {metadata['layout']}",
f"author: {metadata['author']}",
"---",
""
]
output_content = "\n".join(frontmatter) + markdown_body
sanitized_title = sanitize_filename(metadata['title'])
# Pages go into the root of the output_dir_base (e.g. content/)
output_file_path = Path(output_dir_base) / f"{sanitized_title}.md"
output_file_path.write_text(output_content)
print(f" -> Created: {output_file_path}")
def main():
parser = argparse.ArgumentParser(description="Migrate qsgen2 (.blog, .qst) files to qsgen3 Markdown format.")
parser.add_argument("--source-dir", required=True, help="Directory containing old .blog and .qst files.")
parser.add_argument("--output-dir", required=True, help="Directory to save new Markdown files (e.g., your qsgen3 'content' directory).")
args = parser.parse_args()
source_path = Path(args.source_dir)
output_path = Path(args.output_dir)
if not source_path.is_dir():
print(f"Error: Source directory '{source_path}' not found or not a directory.")
return
output_path.mkdir(parents=True, exist_ok=True)
print(f"Source directory: {source_path.resolve()}")
print(f"Output directory: {output_path.resolve()}")
for item in source_path.rglob('*'): # rglob to find in subdirectories too, if any
if item.is_file():
if item.name.endswith(".blog"):
process_blog_file(item, output_path)
elif item.name.endswith(".qst"):
process_qst_file(item, output_path)
print("\nMigration complete.")
if __name__ == "__main__":
main()

19
site.conf Normal file
View File

@ -0,0 +1,19 @@
# Site Configuration for qsgen3
# --- Site Metadata ---
site_name="My Awesome Site"
site_tagline="A brief description of my site"
site_url="http://localhost:8000"
site_theme="minimal"
site_theme_css_file="css/minimaltemplate-v1.css"
# --- Paths ---
paths_content_dir="content"
paths_output_dir="output"
paths_layouts_dir="layouts"
paths_static_dir="static"
# --- Build Options ---
build_options_generate_rss=true
build_options_generate_sitemap=true
build_options_process_drafts=false

View File

@ -1,26 +1,30 @@
; Place this file in your project directory # Example Site Configuration for qsgen3
# Copy this file to 'site.conf' in your project root and customize it.
[site] # --- Site Metadata ---
; This is the name of your site # These settings define general information about your site.
name = "The Site Name" site_name="My Example Site" # The main title of your website, used in page titles, headers, and RSS feed.
; This is the tagline site_tagline="An example site generated by qsgen3" # A short description or subtitle for your site, often used in meta tags or headers.
tagline = "The Site Tagline" site_url="http://localhost:8000" # Full base URL of your site (e.g., https://www.example.com). Essential for generating correct absolute links in RSS feeds, sitemaps, etc.
; This is the URL of your site site_theme="minimal" # Name of the theme directory located under your project's 'themes/' folder (e.g., "minimal", "custom-theme").
url = "https://www.example.com" site_theme_css_file="css/minimaltemplate-v1.css" # Path to the theme's main CSS file, relative to the THEME'S 'static/' directory (e.g., "css/style.css", "main.css").
; This is where your HTML files go
root = /path/to/www/dir
; The theme of your site
theme = theme_name
; sitemap or not: true or false
sitemap = true
; Do you want the blog to appear on the front page
; true = yes and false = no
blog = true
[project] # --- Paths ---
; This is where you work before you generate the output # Define the directory structure for your project.
root = /path/to/working/project # Paths are relative to your project's root directory (where site.conf is) unless an absolute path (starting with '/') is provided.
; Languages: en_US, en_UK, es_ES, nb_NO, fr_FR paths_content_dir="content" # Directory containing your Markdown content files (posts, pages).
lang = en_US paths_output_dir="output" # Directory where the generated static website will be written.
; Use QStags (native) or Markdown (markdown) paths_layouts_dir="layouts" # Directory containing global HTML layout templates (e.g., post.html, page.html, index.html) used by Pandoc.
generator = native paths_static_dir="static" # Project's root directory for global static assets (images, CSS, JS) that are not theme-specific.
# These are copied to the output's static folder. Theme static files take precedence in case of name conflicts.
# --- Build Options ---
# Control various aspects of the site generation process.
build_options_generate_rss=true # Generate an RSS feed for your posts. Set to 'true' to enable, 'false' to disable.
# The feed will be available at /rss.xml.
build_options_generate_sitemap=true # Generate a sitemap.xml. Set to 'true' to enable, 'false' to disable.
# Note: Sitemap generation is a basic implementation. The sitemap will be at /sitemap.xml.
build_options_process_drafts=false # Process draft posts/pages. Set to 'true' to include content marked as 'draft: true' in its frontmatter,
# 'false' to exclude them from the build.