为 Pelican 网站编辑带有图像的 Markdown 文件

问题描述 投票:0回答:5

是否有一种方法可以在 Markdown 文件中引用图像,使其 1) 在编辑时正确预览,2) 在使用 Pelican 处理时正确生成?

我尝试 Pelican 的全部原因是为了尽可能简单地使用各种编辑器本地/离线编辑文件,而无需运行本地服务器。这些编辑器了解常见的图像语法,如下所示:

![Pelican](images/pelican.jpg)

但是为了让 Pelican 生成正确的路径,我必须使用:

![Pelican]({filename}/images/pelican.jpg)

哪些编辑不明白,所以预览只显示损坏的图像。这不太理想。链接到具有完整地址的图像不起作用,因为我经常离线工作。

是否有一些设置组合(除了运行本地服务器之外,当我在 ipad/etc 上编辑文件时这对我没有一点帮助)可以让我使用相同的图像标记进行编辑和正确发布?

markdown pelican
5个回答
9
投票

考虑到您所描述的用例,我相信唯一的解决方案是本地和生产环境中的 URL 路径相同。例如,给定以下层次结构:

- content
    - images
        - dinosaur.jpg
    - posts
        - my-dinosaur.md

...您可以通过以下方式从

my-dinosaur.md
链接到图像:

Title: My Dinosaur
Date: 2013-03-28
URL: /posts/my-dinosaur.html
Save_as: posts/my-dinosaur.html

Here is an image of my dinosaur:

![Pelican](../images/dinosaur.jpg)

在这种情况下,生成的 HTML 将包含指向图像的链接,如下所示:

<img src="../images/dinosaur.jpg" />

只要之间的相对位置:

  • 源文件<->图片
  • 生成的 HTML <->图像

...是一样的,上述技术应该可以让你实现你的目标。

当然,根据您选择的生产 URL 结构,这可能可行,也可能不可行。如果您不想更改 URL 结构以匹配源内容组织结构,则在不运行本地服务器的情况下很难在两种环境中渲染图像。


5
投票

{文件名}方法似乎不适用于当前版本的 Pelican 中的图像。

具体操作方法如下:

从 Pelican 3.5 开始,您可以使用 {attach} 标签将任何文件类型附加到静态站点。 content 文件夹的相对路径约定保持不变。

![MyImage]({attach}images/MyImage.jpg)

只需在您想要链接图像的Markdown文章中插入上述短语即可。

让我知道结果如何!


4
投票

您可以在 Markdown 帖子中使用 Jinja

{{ SITEURL }}
变量来引用图像:

![Pelican]({{SITEURL}}/images/pelican.jpg)

这应该可以解决(2)。但是,如果没有有关您使用的编辑器以及它们如何将图像路径转换为渲染图像的更多信息,就不可能知道这是否能解决 (1)。


0
投票

我在使用 Pelican 时遇到了同样的问题。为了使 Markdown 文件中的链接和图像在编辑器中正确显示,同时也满足 Pelican 的要求,我编写了一个 Markdown 扩展。它可以通过pelicanconf.py直接集成到Pelican的Markdown配置中,允许它自动添加{filename}或{static}。 python代码如下:

# (C) - Debao Zhang
# SPDX-License-Identifier: MIT
import re
import typing
from markdown.preprocessors import Preprocessor
from markdown.extensions import Extension

# Regular expression to match markdown links with relative .md or .markdown
MD_LINK_RE = re.compile(r'\[(.*?)\]\(([^)\{][^):]+\.(md|markdown))\)')
# Regular expression to match markdown images, excluding external URLs
MD_IMAGE_RE = re.compile(r'!\[(.*?)\]\(([^)\{][^:)]+)\)')

# Regular expression to match code blocks:
# - Match multi-line code blocks first (` ``` ` or ` ~~~ ` with 3 or more, including optional language tag)
# - Then match inline code blocks, ensuring that both single (`) and double (``) backticks are matched symmetrically.
CODE_BLOCK_RE = re.compile(r'(`{3,}|~{3,})[\s\S]*?\1|(`+)[^`]*?\2', re.DOTALL)

def replace_md_links(text):
    """
    Replace markdown links with relative .md or .markdown paths with {filename} syntax,
    and replace image paths with {static} syntax.
    """
    text = MD_LINK_RE.sub(r'[\1]({filename}\2)', text)
    text = MD_IMAGE_RE.sub(r'![\1]({static}\2)', text)
    return text

def do_links_replace_all(all_text):
    """
    Modify markdown content by adding {filename} to relative .md or .markdown links,
    and {static} to image links, but skip code blocks (including inline code blocks).
    """
    result = []
    last_end = 0

    for match in CODE_BLOCK_RE.finditer(all_text):
        start, end = match.span()

        non_code_part = all_text[last_end:start]
        result.append(replace_md_links(non_code_part))

        code_block_part = all_text[start:end]
        result.append(code_block_part)

        last_end = end

    result.append(replace_md_links(all_text[last_end:]))

    return ''.join(result)


class DebaoModifyMdLinks(Preprocessor):
    """
    Custom Preprocessor to modify markdown links with relative .md or .markdown paths,
    and replace image links with {static} syntax.
    """
    BLOCK_CODE_FENCE_RE       = re.compile(r"^(\s*)(`{3,}|~{3,})")
    def _iter_lines(self, lines: list[str]) -> typing.Iterable[str]:
        is_in_code_fence          = False
        expected_code_fence_close = "```"

        for line in lines:
            if is_in_code_fence:
                # We should deal with any lines in normal fence
                yield line
                if line.rstrip() == expected_code_fence_close:
                    is_in_code_fence = False
            else:
                # Try to find the fence code or math block start flag
                code_fence_match      = self.BLOCK_CODE_FENCE_RE.match(line)
                if code_fence_match:
                    is_in_code_fence          = True
                    prefix               = code_fence_match.group(1)
                    expected_code_fence_close = prefix + code_fence_match.group(2)
                    yield line
                else:
                    ## Ok now, we don't live in any block now
                    yield do_links_replace_all(line)

    def run(self, lines: list[str]) -> list[str]:
        return list(self._iter_lines(lines))

class DebaoMdPreprocessExtension(Extension):
    """
    Custom Markdown extension that adds the DebaoModifyMdLinks to the Markdown parser.
    """
    def extendMarkdown(self, md):
        # Register the custom preprocessor
        md.preprocessors.register(DebaoModifyMdLinks(md), 'debao_md_preprocess', 25)

# Function to make the extension easily loadable
def makeExtension(**kwargs):
    return DebaoMdPreprocessExtension(**kwargs)

-1
投票

{filename}
指令用于在发布期间创建超链接,发布后您的图像应链接到输出文件夹中的图像文件夹。

取决于您在

pelicanconf.py
中如何配置静态路径,例如

# Path to static folders
STATIC_PATHS = ["images", "extra/SW.js"]

根据文档,正确的方法是

![Pelican]({static}/images/pelican.jpg)

其中

static
是包含图像的静态文件夹的路径。

© www.soinside.com 2019 - 2024. All rights reserved.