From ef2cbef7817dc15645c71528d659a59ae7a04c02 Mon Sep 17 00:00:00 2001 From: OrcaSlicerBot Date: Thu, 1 Jan 2026 16:08:26 +0000 Subject: [PATCH] Updated Wiki content --- .github/workflows/deploy-wiki.yml | 70 +++++++ .gitignore | 2 + build.sh | 182 ++++++++++++++++++ generate_nav.py | 310 ++++++++++++++++++++++++++++++ mkdocs.yml | 140 ++++++++++++++ 5 files changed, 704 insertions(+) create mode 100644 .github/workflows/deploy-wiki.yml create mode 100644 .gitignore create mode 100755 build.sh create mode 100644 generate_nav.py create mode 100644 mkdocs.yml diff --git a/.github/workflows/deploy-wiki.yml b/.github/workflows/deploy-wiki.yml new file mode 100644 index 0000000..a14c591 --- /dev/null +++ b/.github/workflows/deploy-wiki.yml @@ -0,0 +1,70 @@ +name: Deploy Wiki to orca-website + +on: + push: + branches: + - main + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout OrcaSlicer_WIKI repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install mkdocs + run: pip install mkdocs + + - name: Build wiki content + run: | + chmod +x build.sh + ./build.sh -d + + - name: Generate GitHub App token + id: app-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + owner: OrcaSlicer + repositories: orca-website + + - name: Clone orca-website repository + run: | + git clone --depth 1 https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/OrcaSlicer/orca-website.git orca-website + + - name: Deploy wiki content + run: | + # Remove old wiki folder if it exists + rm -rf orca-website/wiki + + # Copy new wiki content + cp -r wiki orca-website/wiki + + # Configure git + cd orca-website + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + # Check if there are changes to commit + if git diff --quiet && git diff --staged --quiet; then + echo "No changes to deploy" + exit 0 + fi + + # Stage, commit and push + git add wiki + git commit -m "Update wiki content from OrcaSlicer_WIKI + + Source commit: ${{ github.sha }} + Triggered by: ${{ github.actor }}" + git push + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ca2a130 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +wiki/ +.DS_Store \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..1fc4300 --- /dev/null +++ b/build.sh @@ -0,0 +1,182 @@ +#!/bin/bash + +# Build script for OrcaSlicer WIKI using mkdocs +# Outputs HTML to the wiki/ folder + +set -e # Exit on error + +# Parse command-line arguments +DOWNLOAD_SVG=false +for arg in "$@"; do + case $arg in + --download-svg|-d) + DOWNLOAD_SVG=true + shift + ;; + *) + # Unknown option + ;; + esac +done + +# Check for required dependencies +command -v mkdocs >/dev/null 2>&1 || { echo "Error: mkdocs is required but not installed."; exit 1; } +command -v python3 >/dev/null 2>&1 || { echo "Error: python3 is required but not installed."; exit 1; } + +# python3 generate_nav.py --update + +echo "Building documentation with mkdocs..." + +# Clean previous build and prepare docs directory +rm -rf wiki +mkdir -p docs + +# Copy all markdown files and directories to docs, excluding wiki and docs itself +# This creates a structure mkdocs can work with +echo "Preparing documentation structure..." + +# Copy all directories and markdown files, excluding wiki, docs, and .git +rsync -av \ + --exclude='wiki' \ + --exclude='docs' \ + --exclude='.git' \ + --exclude='*.sh' \ + --exclude='*.py' \ + --exclude='*.yml' \ + --exclude='*.yaml' \ + --exclude='README.md' \ + --exclude='Home.md' \ + --exclude='.gitignore' \ + --exclude='infill-analysis' \ + . docs/ 2>/dev/null || { + # Fallback: manually copy directories and markdown files + echo "Using fallback copy method..." + # Copy root level markdown files, excluding Home.md and README.md + find . -maxdepth 1 -name "*.md" ! -name "README.md" ! -name "Home.md" -exec cp {} docs/ \; + # Copy all directories with markdown files + [ -d "images" ] && cp -r images docs/ 2>/dev/null || true + [ -d "calibration" ] && cp -r calibration docs/ 2>/dev/null || true + [ -d "developer-reference" ] && cp -r developer-reference docs/ 2>/dev/null || true + [ -d "general-settings" ] && cp -r general-settings docs/ 2>/dev/null || true + [ -d "material_settings" ] && cp -r material_settings docs/ 2>/dev/null || true + [ -d "print_prepare" ] && cp -r print_prepare docs/ 2>/dev/null || true + [ -d "print_settings" ] && cp -r print_settings docs/ 2>/dev/null || true + [ -d "printer_settings" ] && cp -r printer_settings docs/ 2>/dev/null || true +} + +# Copy Home.md as index.md so mkdocs generates index.html at root level +# (Home.md was excluded from rsync, so copy it directly from source) +if [ -f "Home.md" ]; then + cp Home.md docs/index.md +fi + +# Convert GitHub image URLs to relative local paths in all markdown files +echo "Converting GitHub image URLs to local paths..." + +# Download SVG icons if option is enabled +if [ "$DOWNLOAD_SVG" = true ]; then + # Create directory for OrcaSlicer main repo icons + mkdir -p docs/images/orcaslicer-icons + + # Extract and download unique SVG icons from OrcaSlicer main repo + echo "Downloading SVG icons from OrcaSlicer main repo..." + grep -roh "https://github.com/OrcaSlicer/OrcaSlicer/blob/main/resources/images/[^?)]*" docs/ 2>/dev/null | \ + sort -u | while read url; do + # Extract filename from URL + filename=$(basename "$url") + local_path="docs/images/orcaslicer-icons/$filename" + + # Download if not already cached + if [ ! -f "$local_path" ]; then + # Convert blob URL to raw URL + raw_url=$(echo "$url" | sed 's|github.com/OrcaSlicer/OrcaSlicer/blob/main|raw.githubusercontent.com/OrcaSlicer/OrcaSlicer/main|') + echo " Downloading: $filename" + curl -sL "$raw_url" -o "$local_path" 2>/dev/null || true + fi + done +else + echo "Skipping SVG icon download (use --download-svg or -d to enable)" +fi + +find docs -name "*.md" -type f | while read md_file; do + # Calculate relative path to images based on file depth + depth=$(echo "$md_file" | tr -cd '/' | wc -c) + depth=$((depth - 1)) # Subtract 1 for "docs/" + + prefix="" + for ((i=0; i/dev/null || \ + sed -i "s|https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/images/\([^?]*\)?raw=true|${prefix}images/\1|g" "$md_file" + + # Replace OrcaSlicer main repo icon URLs with local paths + sed -i '' "s|https://github.com/OrcaSlicer/OrcaSlicer/blob/main/resources/images/\([^?]*\)?raw=true|${prefix}images/orcaslicer-icons/\1|g" "$md_file" 2>/dev/null || \ + sed -i "s|https://github.com/OrcaSlicer/OrcaSlicer/blob/main/resources/images/\([^?]*\)?raw=true|${prefix}images/orcaslicer-icons/\1|g" "$md_file" +done + +# Build mkdocs and output to wiki folder +mkdocs build --site-dir wiki + +# Create redirect directories for GitHub wiki-style URLs (e.g., /wiki/quality_settings_layer_height) +echo "Creating redirect directories for wiki-style URLs..." +create_redirects() { + # Find all HTML files (except index.html) and create root-level redirects + find wiki -name "*.html" -type f ! -name "index.html" | while read html_file; do + # Get the relative path from wiki/ + rel_path="${html_file#wiki/}" + + # Extract the filename without .html extension + filename=$(basename "$rel_path" .html) + + # Skip files already at root level + dir_of_file=$(dirname "$rel_path") + if [ "$dir_of_file" = "." ]; then + continue + fi + + # Create redirect directory at root level (for clean URLs without .html) + redirect_dir="wiki/${filename}" + + # Skip if directory already exists (could be a real content directory) + if [ -d "$redirect_dir" ]; then + continue + fi + + mkdir -p "$redirect_dir" + redirect_file="${redirect_dir}/index.html" + + # Calculate relative path from redirect directory to target + # Redirect is at wiki/filename/, target is at wiki/rel_path + # So we need to go up one level (../) then to rel_path + relative_url="../${rel_path}" + + # URL encode spaces in the path + encoded_url=$(python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))" "${relative_url}" 2>/dev/null || echo "${relative_url}" | sed 's/ /%20/g') + + # Create redirect HTML content + cat > "$redirect_file" < + + + + + + + + +

Redirecting to ${filename}...

+ + +EOF + done +} + +create_redirects + +# Clean up docs directory after build +rm -rf docs + +echo "Build complete! HTML files are in the wiki/ folder." diff --git a/generate_nav.py b/generate_nav.py new file mode 100644 index 0000000..b3caf00 --- /dev/null +++ b/generate_nav.py @@ -0,0 +1,310 @@ +#!/usr/bin/env python3 +""" +Auto-generate mkdocs.yml navigation from folder structure. +Fully dynamic - scans all folders and markdown files automatically. + +Usage: + python3 generate_nav.py # Preview nav structure + python3 generate_nav.py --update # Update mkdocs.yml directly +""" + +import re +from pathlib import Path +from typing import Optional + + +# Folders to exclude from navigation (not documentation content) +EXCLUDED_FOLDERS = { + 'images', 'docs', 'wiki', 'html', 'custom_theme', + '.git', '.github', '__pycache__', 'node_modules', + 'venv', '.venv', 'infill-analysis', 'assets', 'static', +} + +# Optional: Override display names for specific folders +# If not specified, names are auto-generated from folder names +# Format: "folder_name": "Display Name" +DISPLAY_NAME_OVERRIDES = { + # Examples: + # "print_settings": "Process Settings", + # "developer-reference": "Developer Section", +} + + +def folder_to_title(name: str) -> str: + """Convert a folder name to a readable title.""" + # Replace separators with spaces + title = name.replace('_', ' ').replace('-', ' ') + + # Title case, preserving certain patterns + words = title.split() + result = [] + for word in words: + lower = word.lower() + if lower == 'gcode': + result.append('G-Code') + elif lower in ['api', 'stl', 'vfa', 'xy', 'semm']: + result.append(word.upper()) + elif lower in ['and', 'or', 'the', 'in', 'on', 'at', 'to', 'for', 'of']: + result.append(lower if result else word.title()) + else: + result.append(word.title()) + return ' '.join(result) + + +def get_display_name(folder_name: str) -> str: + """Get display name for a folder.""" + if folder_name in DISPLAY_NAME_OVERRIDES: + return DISPLAY_NAME_OVERRIDES[folder_name] + return folder_to_title(folder_name) + + +def extract_title_from_md(filepath: Path) -> Optional[str]: + """Extract the first H1 heading from a markdown file.""" + try: + content = filepath.read_text(encoding='utf-8') + match = re.search(r'^#\s+(.+)$', content, re.MULTILINE) + if match: + return match.group(1).strip() + except (UnicodeDecodeError, IOError, PermissionError): + # Silently skip files that can't be read + pass + return None + + +def filename_to_title(filename: str) -> str: + """Convert a filename to a readable title.""" + name = filename + + # Remove common prefixes (settings files often have category prefixes) + # This regex removes patterns like "printer_basic_information_", "quality_settings_", etc. + name = re.sub(r'^[a-z]+_(?:[a-z]+_)*(?=\w)', '', name) + + return folder_to_title(name) + + +def get_file_title(filepath: Path) -> str: + """Get the display title for a markdown file.""" + # Try to extract from file content first (most accurate) + extracted = extract_title_from_md(filepath) + if extracted: + return extracted + # Fall back to filename + return filename_to_title(filepath.stem) + + +def get_sort_key(path: Path) -> tuple: + """Generate a sort key for ordering files/folders.""" + name = path.name.lower() if path.is_dir() else path.stem.lower() + + # Priority ordering: basic/intro first, advanced/misc last + if any(x in name for x in ['index', 'home', 'intro', 'overview', 'guide']): + return (0, name) + if 'basic' in name: + return (1, name) + if 'advanced' in name: + return (8, name) + if any(x in name for x in ['other', 'misc', 'dependencies']): + return (9, name) + + return (5, name) # Default: middle priority, alphabetical + + +def scan_folder(folder: Path, base_path: Path) -> list: + """Recursively scan a folder and build nav structure.""" + nav_items = [] + + try: + items = list(folder.iterdir()) + except PermissionError: + return nav_items + + # Separate and sort files and folders + md_files = sorted( + [f for f in items if f.is_file() and f.suffix == '.md'], + key=get_sort_key + ) + subfolders = sorted( + [d for d in items if d.is_dir() + and not d.name.startswith('.') + and d.name.lower() not in EXCLUDED_FOLDERS], + key=get_sort_key + ) + + # Process markdown files + for md_file in md_files: + title = get_file_title(md_file) + rel_path = md_file.relative_to(base_path) + nav_items.append((title, str(rel_path))) + + # Process subfolders recursively + for subfolder in subfolders: + sub_items = scan_folder(subfolder, base_path) + if sub_items: + folder_title = get_display_name(subfolder.name) + nav_items.append((folder_title, sub_items)) + + return nav_items + + +def generate_nav(base_path: Path) -> list: + """Generate the complete navigation structure by scanning all folders.""" + nav = [] + + # Check for Home.md -> becomes index.md + if (base_path / 'Home.md').exists(): + nav.append(("Home", "index.md")) + + # Scan all top-level folders that contain markdown files + top_level_folders = sorted( + [d for d in base_path.iterdir() + if d.is_dir() + and not d.name.startswith('.') + and d.name.lower() not in EXCLUDED_FOLDERS + and any(d.rglob('*.md'))], # Only include if has .md files + key=get_sort_key + ) + + # Build nav from each folder + for folder in top_level_folders: + items = scan_folder(folder, base_path) + if items: + section_title = get_display_name(folder.name) + nav.append((section_title, items)) + + return nav + + +def escape_yaml_string(s: str) -> str: + """Escape special YAML characters in a string.""" + # Characters that need quoting in YAML + special_chars = set(':{}[],&*#?|-<>=!%@\\') + if any(c in s for c in special_chars) or ' ' in s or s.startswith('"') or s.startswith("'"): + # Escape quotes and backslashes, then wrap in double quotes + escaped = s.replace('\\', '\\\\').replace('"', '\\"') + return f'"{escaped}"' + return s + + +def nav_to_yaml(nav: list, indent: int = 2) -> str: + """Convert nav structure to YAML string.""" + lines = [] + base_indent = " " * indent + + def format_item(item, level): + prefix = base_indent * level + "- " + title, value = item + + # Escape title to handle special characters + escaped_title = escape_yaml_string(title) + + if isinstance(value, list): + lines.append(f"{prefix}{escaped_title}:") + for sub_item in value: + format_item(sub_item, level + 1) + else: + # Escape path value + escaped_value = escape_yaml_string(value) + lines.append(f"{prefix}{escaped_title}: {escaped_value}") + + for item in nav: + format_item(item, 0) + + return '\n'.join(lines) + + +def update_mkdocs_yml(mkdocs_path: Path, nav_yaml: str) -> None: + """Update the nav section in mkdocs.yml.""" + content = mkdocs_path.read_text(encoding='utf-8') + + # Find and replace the nav section + # Match nav: followed by indented content until next top-level key or EOF + nav_pattern = re.compile( + r'^nav:\s*\n((?:[ \t]+.*\n)*?)(?=^[a-zA-Z]|\Z)', + re.MULTILINE | re.DOTALL + ) + + match = nav_pattern.search(content) + if match: + new_content = content[:match.start()] + f"nav:\n{nav_yaml}\n" + content[match.end():] + else: + new_content = content.rstrip() + f"\n\nnav:\n{nav_yaml}\n" + + # Validate YAML before writing (basic check - try importing yaml if available) + try: + import yaml + yaml.safe_load(new_content) + except ImportError: + # yaml module not available, skip validation + pass + except yaml.YAMLError as e: + raise ValueError(f"Generated YAML is invalid: {e}") from e + + mkdocs_path.write_text(new_content, encoding='utf-8') + print(f"āœ… Updated {mkdocs_path}") + + +def print_nav_tree(nav: list, indent: int = 0) -> None: + """Pretty print the navigation structure.""" + for title, value in nav: + prefix = " " * indent + if isinstance(value, list): + print(f"{prefix}šŸ“ {title}") + print_nav_tree(value, indent + 1) + else: + print(f"{prefix}šŸ“„ {title}") + + +def count_items(nav: list) -> int: + """Count total navigation items.""" + count = 0 + for _, value in nav: + if isinstance(value, list): + count += count_items(value) + else: + count += 1 + return count + + +def main(): + import argparse + + parser = argparse.ArgumentParser( + description='Generate mkdocs.yml navigation from folder structure (fully dynamic)' + ) + parser.add_argument( + '--update', '-u', action='store_true', + help='Update mkdocs.yml directly (default: preview only)' + ) + args = parser.parse_args() + + script_dir = Path(__file__).parent + mkdocs_path = script_dir / 'mkdocs.yml' + + if not mkdocs_path.exists(): + print(f"āŒ Error: {mkdocs_path} not found") + return 1 + + print(f"šŸ“‚ Scanning: {script_dir}\n") + nav = generate_nav(script_dir) + nav_yaml = nav_to_yaml(nav) + + print("šŸ“‹ Navigation Structure:\n") + print_nav_tree(nav) + print(f"\nšŸ“Š Total pages: {count_items(nav)}") + print(f"šŸ“ Total sections: {len(nav) - 1}") # -1 for Home + + if args.update: + print() + update_mkdocs_yml(mkdocs_path, nav_yaml) + else: + print("\n" + "=" * 60) + print("Generated YAML (use --update to apply):\n") + print("nav:") + print(nav_yaml) + print("=" * 60) + + return 0 + + +if __name__ == '__main__': + exit(main()) diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..86755bc --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,140 @@ +site_name: OrcaSlicer WIKI +site_description: Official Wiki for OrcaSlicer - A powerful open source slicer for FFF (FDM) 3D Printers +site_url: https://www.orcaslicer.com/wiki + +# MkDocs requires docs_dir to be a subdirectory +# The build script will handle the file structure +docs_dir: docs +site_dir: html + +# Use flat URLs (page.html) instead of directory URLs (page/index.html) +use_directory_urls: false + +# Theme configuration +theme: + name: readthedocs + +# Markdown extensions (using built-in extensions to avoid extra dependencies) +markdown_extensions: + - codehilite: + guess_lang: false + - fenced_code + - tables + - toc: + permalink: true + - attr_list + - md_in_html + +# Navigation structure based on Home.md +nav: +- Home: index.md +- Calibration: + - "Adaptive Pressure Advance": "calibration/adaptive-pressure-advance-calib.md" + - "Calibration Guide": calibration/Calibration.md + - Cornering: "calibration/cornering-calib.md" + - "Flow Rate Calibration": "calibration/flow-rate-calib.md" + - "Input Shaping": "calibration/input-shaping-calib.md" + - "Pressure Advance": "calibration/pressure-advance-calib.md" + - "Retraction test": "calibration/retraction-calib.md" + - "Temp Calibration": "calibration/temp-calib.md" + - "Filament Tolerance Calibration": "calibration/tolerance-calib.md" + - VFA: "calibration/vfa-calib.md" + - "Max Volumetric Speed (FlowRate) Calibration": "calibration/volumetric-speed-calib.md" +- "Developer Reference": + - "Localization and translation guide": "developer-reference/Localization_guide.md" + - "Placeholders Variables": "developer-reference/Built-in-placeholders-variables.md" + - "How to Build": "developer-reference/How-to-build.md" + - "Guide: Develop Profiles for OrcaSlicer": "developer-reference/How-to-create-profiles.md" + - "How to Test": "developer-reference/How-to-test.md" + - "How to Contribute to the Wiki": "developer-reference/How-to-wiki.md" + - "Application Structure Overview": "developer-reference/plater-sidebar-tab-combobox.md" + - "Preset and Bundle": "developer-reference/Preset-and-bundle.md" + - "Slicing Hierarchy": "developer-reference/slicing-hierarchy.md" +- "General Settings": + - "Keyboard Shortcuts": "general-settings/keyboard-shortcuts.md" +- "Material Settings": + - Cooling: + - "Material Cooling": material_settings/cooling/material_cooling.md + - Filament: + - "Material Basic Information": material_settings/filament/material_basic_information.md + - "Material Flow Ratio and Pressure Advance": material_settings/filament/material_flow_ratio_and_pressure_advance.md + - "Material Temperatures": material_settings/filament/material_temperatures.md + - "Material Volumetric Speed Limitation": material_settings/filament/material_volumetric_speed_limitation.md + - Multimaterial: + - "Material Multimaterial Settings": material_settings/multimaterial/material_multimaterial.md + - "Setting Overrides": + - "Material Setting Overrides": "material_settings/setting overrides/material_setting_overrides.md" + - Advanced: + - "Advanced Material Settings": material_settings/advanced/material_advanced.md + - Dependencies: + - "Material Dependencies": material_settings/dependencies/material_dependencies.md +- "Print Prepare": + - "STL Transformation": "print_prepare/stl-transformation.md" +- "Print Settings": + - Multimaterial: + - "Filament for Features": print_settings/multimaterial/multimaterial_settings_filament_for_features.md + - "Flush Options": print_settings/multimaterial/multimaterial_settings_flush_options.md + - "Ooze prevention": print_settings/multimaterial/multimaterial_settings_ooze_prevention.md + - "Prime Tower": print_settings/multimaterial/multimaterial_settings_prime_tower.md + - "Multimaterial Advanced": print_settings/multimaterial/multimaterial_settings_advanced.md + - Quality: + - Bridging: print_settings/quality/quality_settings_bridging.md + - Ironing: print_settings/quality/quality_settings_ironing.md + - "Layer Height": print_settings/quality/quality_settings_layer_height.md + - "Line Width": print_settings/quality/quality_settings_line_width.md + - Overhangs: print_settings/quality/quality_settings_overhangs.md + - Precision: print_settings/quality/quality_settings_precision.md + - Seam: print_settings/quality/quality_settings_seam.md + - "Wall and surfaces": print_settings/quality/quality_settings_wall_and_surfaces.md + - "Wall Generator": print_settings/quality/quality_settings_wall_generator.md + - Speed: + - Acceleration: print_settings/speed/speed_settings_acceleration.md + - "Initial layer speed": print_settings/speed/speed_settings_initial_layer_speed.md + - "Jerk XY": print_settings/speed/speed_settings_jerk_xy.md + - "Overhang Speed": print_settings/speed/speed_settings_overhang_speed.md + - Travel: print_settings/speed/speed_settings_travel.md + - "Speed Advanced - Extrusion Rate Smoothing": print_settings/speed/speed_settings_advanced.md + - "Other layers speed": print_settings/speed/speed_settings_other_layers_speed.md + - Strength: + - Infill: print_settings/strength/strength_settings_infill.md + - "Infill rotation template metalanguage": print_settings/strength/strength_settings_infill_rotation_template_metalanguage.md + - Patterns: print_settings/strength/strength_settings_patterns.md + - "Top and Bottom Shells": print_settings/strength/strength_settings_top_bottom_shells.md + - Walls: print_settings/strength/strength_settings_walls.md + - "Strength Advanced": print_settings/strength/strength_settings_advanced.md + - Support: + - "Support Filament": print_settings/support/support_settings_filament.md + - "Support Ironing": print_settings/support/support_settings_ironing.md + - Raft: print_settings/support/support_settings_raft.md + - Support: print_settings/support/support_settings_support.md + - "Tree Support": print_settings/support/support_settings_tree.md + - "Support Advanced": print_settings/support/support_settings_advanced.md + - Others: + - Brim: print_settings/others/others_settings_brim.md + - "Fuzzy Skin": print_settings/others/others_settings_fuzzy_skin.md + - "G-Code Output": print_settings/others/others_settings_g_code_output.md + - Notes: print_settings/others/others_settings_notes.md + - "Post-Processing Scripts": print_settings/others/others_settings_post_processing_scripts.md + - Skirt: print_settings/others/others_settings_skirt.md + - "Special Mode": print_settings/others/others_settings_special_mode.md +- "Printer Settings": + - "Basic Information": + - "Printer Accessory": "printer_settings/basic information/printer_basic_information_accessory.md" + - "Adaptive Bed Mesh": "printer_settings/basic information/printer_basic_information_adaptive_bed_mesh.md" + - "Advanced Printer Settings": "printer_settings/basic information/printer_basic_information_advanced.md" + - "Cooling Fan": "printer_settings/basic information/printer_basic_information_cooling_fan.md" + - "Extruder Clearance": "printer_settings/basic information/printer_basic_information_extruder_clearance.md" + - "Printable Space": "printer_settings/basic information/printer_basic_information_printable_space.md" + - Extruder: + - "Basic Extruder Information": printer_settings/extruder/printer_extruder_basic_information.md + - Retraction: printer_settings/extruder/printer_extruder_retraction.md + - "Z Hop": printer_settings/extruder/printer_extruder_z_hop.md + - "Machine G-Code": + - "Machine G-code": "printer_settings/machine gcode/printer_machine_gcode.md" + - "Motion Ability": + - "Motion Ability": "printer_settings/motion ability/printer_motion_ability.md" + - Multimaterial: + - "Single Extruder Multi-Material Parameters": printer_settings/multimaterial/printer_multimaterial_semm_parameters.md + - "Multimaterial setup": printer_settings/multimaterial/printer_multimaterial_setup.md + - "Wipe Tower": printer_settings/multimaterial/printer_multimaterial_wipe_tower.md + - "Advanced Multi-Material Settings": printer_settings/multimaterial/printer_multimaterial_advanced.md