Skip to content

Getting started

Installation

A translate script is provided to facilitate working with pandoc and deepl translation services.

  1. To install development version use:

    pip install git+https://github.com/jodygarnett/translate.git
    
  2. Install script requirements, and check it runs:

    mkdocs_translate --help
    
  3. This script requires pandoc be installed:

    Ubuntu:

    apt-get install pandoc
    

    macOS:

    brew install pandoc
    

Project setup

  1. A working example is provided to be adapted for your project.

  2. Create requirements.txt with mkdocs plugins required.

    mkdocs-material>=9.5.9
    mkdocs-include-markdown-plugin>=6.0.4
    mkdocs-exclude>=1.0.2
    mkdocs-macros-plugin>=1.0.4
    
  3. Create mkdocs.yml, the navigation tree is initially empty.

    # Project information
    site_name: MkDocs Translate
    site_description: Example sphinx-build documentation project for use with mkdocs_translate script.
    
    site_dir: build/html
    site_url: http://jodygarnett.github.io/translate
    
    # Repository
    repo_name: translate
    repo_url: https://github.com/jodygarnett/translate
    edit_uri: edit/main/example/docs
    
    # Copyright
    copyright: Copyright © 2024 Open Source Geospatial Foundation
    
    extra_css:
      - assets/stylesheets/extra.css
    
    # Configuration
    theme:
      name: material
      language: en
      custom_dir: overrides
      # logo: assets/images/geoserver_mark.png
      # favicon: assets/images/geoserver_mark.png
      icon:
        repo: fontawesome/brands/github
      palette:
        # Palette toggle for light mode
        - media: "(prefers-color-scheme: light)"
          scheme: default
          primary: blue
          toggle:
            icon: material/weather-night
            name: Switch to dark mode
        # Palette toggle for dark mode
        - media: "(prefers-color-scheme: dark)"
          scheme: slate
          toggle:
            icon: material/weather-sunny
            name: Switch to light mode
      features:
        - content.action.view
        - content.action.edit
        - content.code.copy
        - content.tabs.link
        - navigation.tracking
        - navigation.prune
        - navigation.indexes
        - toc.follow
        - navigation.top
        - navigation.footer
        - announce.dismiss
    
    # Plugins - install using: pip3 install -r requirements.txt
    plugins:
      - exclude:
          glob:
            - '**/download/download.txt'
      - include-markdown:
          preserve_includer_indent: true
          dedent: true
          comments: false
      - macros:
          render_by_default: false
          on_error_fail: true
          on_undefined: strict
          j2_block_start_string: '[[%'
          j2_block_end_string: '%]]'
      - search
    
    # Customizations
    hooks:
      - download.py
    extra:
      homepage: http://jodygarnett.github.io/translate
      social:
        - icon: fontawesome/brands/github
          link: ttps://github.com/jodygarnett/translate
      version: '0.9'
      release: '0.9.5'
    
    # Extensions
    # - These are carefully chosen to work with pandoc markdown support for whole document translation
    markdown_extensions:
      - admonition
      - attr_list
      - def_list
      - pymdownx.details
      - pymdownx.emoji:
          emoji_index: !!python/name:material.extensions.emoji.twemoji
          emoji_generator: !!python/name:material.extensions.emoji.to_svg
          options:
            custom_icons:
              - overrides/.icons
      - pymdownx.highlight:
          anchor_linenums: true
          line_spans: __span
          pygments_lang_class: true
      - pymdownx.inlinehilite
      - pymdownx.keys
      - pymdownx.smartsymbols
      - pymdownx.superfences:
      - pymdownx.tabbed:
          alternate_style: true
      - tables
      - md_in_html
    
    # Validation
    validation:
      nav:
        omitted_files: info
        not_found: warn
        absolute_links: info
      links:
        not_found: warn
        absolute_links: info
        unrecognized_links: info
    
    not_in_nav: |
      **/download/*.md
    
    # Page tree
    nav:
    - Home: index.md
    
  4. Create build/ folder for temporary files during migration.

    mkdir build
    

    Note

    If converting a maven project use of the existing target/ folder can be configured below.

  5. Define .gitingore to avoid adding generated artifacts to version control.

    __pycache__
    target
    build
    !.gitignore
    
  6. The resulting directory structure is:

    docs/
    source/
    .gitignore
    download.py
    mkdocs.yml
    requirements.txt
    

Download Hook

Optional: If your content uses download directive to include external content, there is a mkdocs hook for processing of download.txt files.

  1. Create download.py.

    import glob
    import logging
    import mkdocs.plugins
    import os
    import shutil
    
    log = logging.getLogger('mkdocs')
    
    
    @mkdocs.plugins.event_priority(-50)
    def on_pre_build(config, **kwargs):
        docs_dir = config['docs_dir']
        # print(docs_dir)
    
        pattern = os.path.normpath(os.path.join(docs_dir, '**', 'download', 'download.txt'))
    
        for download_txt in glob.glob(pattern, recursive=True):
            download_folder = os.path.dirname(download_txt)
            donload_txt_path = os.path.relpath(download_txt,docs_dir)
            log.debug(f"Download {donload_txt_path} ...")
            with open(download_txt, 'r') as file:
                path_list = file.read()
    
            downloads=['download.txt','.gitignore']
            for path in path_list.splitlines():
                if len(path.strip()) == 0 or path.startswith('#'):
                    continue
                resolved = os.path.normpath(os.path.join(download_folder, path))
                if os.path.exists(resolved):
                    dest = os.path.normpath(os.path.join(download_folder, os.path.basename(path)))
                    if not os.path.exists(dest) or (os.stat(resolved).st_mtime - os.stat(dest).st_mtime > 1):
                        log.info(f"Download '{dest}' updated")
                        shutil.copyfile(resolved, dest, follow_symlinks=True)
                    else:
                        log.info(f"Download '{resolved}' up to date")
                    downloads.append(os.path.basename(dest))
                else:
                    log.warning(f"Download '{resolved}' not found")
    
            for file in os.listdir(download_folder):
                if os.path.basename(file) not in downloads:
                    log.warning(f"Download '{os.path.basename(file)}' removed")
                    os.remove(file)
    
  2. Register hook with mkdocs.yml:

    # Customizations
    hooks:
    - download.py
    

    Note

    See writing guide Download of external file for example on how to use this hook.

  3. The resulting directory structure is:

    docs/
    source/
    download.py
    mkdocs.yml
    requirements.txt
    

Configuration

For simple python sphinx-build setup and directory structure no configuration is required.

Optional: To provide configuration for your project:

  1. Create a translate.yml to configure script for your project.

    # translate script configuration python project
    project_folder: "."
    docs_folder: "docs"
    build_folder: "build"
    
    # mkdocs migration
    rst_folder: "source"
    anchor_file: 'anchors.txt'
    convert_folder: "migrate"
    substitutions:
      project: MkDocs Translation Example
      author: Open Source Geospatial Foundation
      copyright: 2024, Open Source Geospatial Foundation
      project_copyright: 2024, Open Source Geospatial Foundation
    extlinks:
      github: https://github.com/jodygarnett/translate/blob/main/%s
      release: https://github.com/jodygarnett/translate/releases/tag/{{ release }}|Release {{ release }}
      squidfunk: https://squidfunk.github.io/mkdocs-material/%s
    macro_ignore:
      - setup/index.md
    nav:
      index.md: Home
      'translate/index.md': Translate
      'translate/migrate.md': Migrate
      guide/index.md: Guide
    
    # markdown internationalization
    deepl_base_url: "https://api-free.deepl.com"
    upload_folder: "upload"
    download_folder: "download"
    

    Note

    The example above is for the example project, with project and author substitutions. This project also has extlinks defined that need to be known upfront during migration.

  2. Optional: Maven project translate.yml configuration recommendations.

    # translate script configuration maven project
    project_folder: "."
    docs_folder: "docs"
    build_folder: "target"
    
    # mkdocs migration
    rst_folder: "source"
    anchor_file: 'anchors.txt'
    convert_folder: "migrate"
    
    # markdown internationalization
    deepl_base_url: "https://api-free.deepl.com"
    upload_folder: "translate"
    download_folder: "translate"
    
  3. The resulting directory structure is:

    docs/
    source/
    .gitignore
    translate.yml
    mkdocs.yml
    requirements.txt
    

The configuration settings are:

project_folder: .

Default assumes you are running from the current directory.

docs_folder: docs

mkdocs convention.

build_folder: build

The use of build follows sphinx-build and mkdocs convention, maven projects may wish to use target.

rst_folder: source

Location of sphinx-build documentation to migrate to mkdocs.

anchor_file: anchors.txt

Name of index file used to lookup anchor and title information during migration.

convert_folder: migrate

Combined with build_folder for rst conversion temporary files (example: build/migrate). Temporary files are required for use by pandoc.

upload_folder: upload

Combined with build_folder to stage html files for internationalization (example: build/upload)

deepl_base_url: https://api-free.deepl.com

Customize if you have a subscription to deepl.

download_folder: download

Combined with build_folder to retrieve internationalization results (example: build/download) Temporary files are required for use by pandoc.

substitutions:

dictionary of |substitutions| to use when converting config.py rst_epilog common substitutions.

project: GeoServer
author: Open Source Geospatial Foundation
copyright: 2023, Open Source Geospatial Foundation
project_copyright: 2023, Open Source Geospatial Foundation

The built-in substitutions for {{ version }} and {{ release }} are changed to {{ version }} and {{ release }} variables for use with mkdocs-macros-plugin variable substitution:

Use mkdocs.yml to define these variable substitutions:

extra:
  homepage: https://geoserver.org/
  version: '2.24'
  release: '2.24.2'
extlinks:

dictionary of config.py extlinks substitutions taking the form:

extlinks:
  wiki: https://github.com/geoserver/geoserver/wiki/%s
  user: https://docs.geoserver.org/{{ branch }}/en/user/%s
  geos: https://osgeo-org.atlassian.net/browse/GEOS-%s|GEOS-%s
  download_release: https://sourceforge.net/projects/geoserver/files/GeoServer/{{ release }}/geoserver-{{ release }}-%s.zip|geoserver-{{ release }}-%s.zip

Note

Use of mkdocs-macros-plugin for variable substitution of release above.

Use of |GEOS-%s to override default link text %s.

This handles the sphinx-build config.py extlinks during migration:

extlinks = {
   'wiki': ('https://github.com/geoserver/geoserver/wiki/%s', '%s'),
   'user': ('https://docs.geoserver.org/'+branch+'/en/user/%s', '%s'),
   'geos': ('https://osgeo-org.atlassian.net/browse/GEOS-%s','GEOS-%s'),
   'download_release': ('https://sourceforge.net/projects/geoserver/files/GeoServer/' + release + '/geoserver-' + release + '-%s.zip', 'geoserver-' + release + '-%s.zip )
}
macro_ignore:

Use of mkdocs-macros-plugin can conflict with code examples.

This script adds the YAML header to enable macros to better support the use {{ version }} and {{ release }}. If you find this accidentially is triggered by code examples you can add an ignore.

nav:

Provide simplified title for navigation, incase toctree title is too long. Most often used to override top-level index.rst title as "Home".