orzih / mkdocs-with-pdf

Generate a single PDF file from MkDocs repository.
MIT License
325 stars 76 forks source link

Cover page logo not displayed on Windows #86

Open jolekss opened 2 years ago

jolekss commented 2 years ago

I am running mkdocs-with-pdf 0.9.3 on Windows 10. The cover page logo (cover_logo) does not appear in the PDF. All other images work fine.

In the debug HTML, the image URL shows up as file://C:\dir1\dir2\dir3\pdf_cover.png, which does not even work in the browser (I use Chrome).

The only way I was able to work around this problem was by manually modifying the mkdocs_with_pdf\templates\filters\url.py file where I changed the following line: return 'file://' + path to the following: return 'file:///' + path.replace("\\", "/") Then the image appears correctly in the PDF.

Anything I am missing or is this indeed a bug in the plugin?

pyjoku commented 2 years ago

I am having the same issue. I used several approaches to solve issues with weasyprint. So i also started to try it inside WSL with ubuntu. So it am not sure this is a problem related to just windows. I downloaded the samples and tried to render those. no success either. The cover page image is missing.

Just did an experiment and used a weblink to an image. That is being rendered perfectly. just not the local files.

flavienbwk commented 2 years ago

I have the same problem. It works on Linux but not Windows.

Lexy2 commented 11 months ago

I worked around it by adding a pdf_event_hook.py with the following content:

import logging, re, os.path
from urllib.parse import urlparse, urlunparse
from bs4 import BeautifulSoup

def normalize_url(str_url):
    url = urlparse(str_url)
    if url.scheme == 'file' and '\\' in url.netloc:
        return urlunparse((url.scheme, url.netloc.replace('\\', '/'), url.path, url.params, url.query, url.fragment))
    elif not url.scheme:
        return urlunparse(('file', url.netloc, os.path.abspath(url.path).replace('\\', '/'), url.params, url.query, url.fragment))
    return str_url

def fix_urls(match):
    quote, str_url = match.groups()
    return f'url({quote}{normalize_url(str_url)}{quote})'

def pre_pdf_render(soup: BeautifulSoup, logger: logging) -> BeautifulSoup:
    logger.info('(hook on pre_pdf_render)')
    url_re = re.compile(r'\burl\(([\'"]?)(.*?)\1\)')
    logger.info('Replacing relative url links with absolute and Windows-style paths in CSS')
    for tag in soup.find_all(lambda t: 'style' in t.attrs or t.name == 'style'):
        if tag.name == 'style':
            for child in tag.children:
                child.replace_with(url_re.sub(fix_urls, child))
        else:
            tag['style'] = url_re.sub(fix_urls, tag['style'])
    logger.info('Replacing img src tags')
    for tag in soup('img'):
        src = tag.get('src')
        if src:
            tag['src'] = normalize_url(src)
    return soup

Of course, I had to replace my relative links with relative to mkdocs.yml.