【imarkdown】一个轻量级markdown图片链接转换器

news2024/11/26 11:38:52

imarkdown

imarkdown是一个轻量级markdown图片链接转换器,你可以轻松地对图片链接进行本地到图片服务器、图片服务器到本地、图片服务器到图片服务器的转换。

因为语雀转markdown的时候图片存在防外链行为,如果想要把转出的markdown发表在其他平台,就需要把markdown中所有的图片地址改成本地图片地址或者自定义的图片服务器地址,才可以让别人正常查看。该项目旨在解决这个问题,提供了一个可以批量转换markdown中的图片链接转换器,并支持一些复杂场景下的定制化转换功能。

功能

  • 批量下载:对于markdown中的图片引用,imarkdown可以批量下载markdown中所有的图片到本地
  • 多种转换方式: 对于markdown中的图片链接,支持本地转图床、web url转本地、web url转图床等多种转换方式
  • 批量转换:支持单、多文件的批量转换,以及生成文件的格式化重命名等操作
  • 高度自定义: 只需要继承一个MdAdapter,就可以轻松实现自定义图床的url转换
  • 图床适配: 当前暂时只支持阿里云图床,欢迎pr提供更多类型图床

适用人群

  • 有批量转换markdown图片链接url的需求的人
  • 对于语雀导出markdown的用户,需要对图片外链进行转换的人
  • 需要开发第三扩展应用的人

技术架构

imarkdown采用模块化设计,对于每一个组件,你都可以方便地进行扩展,下图简单展示了imarkdown的技术架构,imarkdown由以下几个部分组成:

  • MdImageConverter Image图片转换器,负责转换markdown的图片地址并生成新的markdown文件。
  • MdAdapter Md适配器,Image需要转换成的类型,如LocalFileAdapter本地适配器、AliyunAdapter阿里云oss适配器,CustomAdapter自定义适配器,通过将适配器注入MdImageConverter,可以定义将Image转换成什么类型的地址。
  • MdMedium 包括MdFile和MdFolder,封装了一些特性,用于传入MdImageConverter进行数据转换。

imarkdown执行过程大致如下所示,在MdImageConverter执行convert方法后,imarkdown会根据传入的MdMedium构建一个虚拟MdTree,根据此树将文件进行批量图片url转换生成。

快速上手

该项目基于Python进行开发,使用Pypi进行发包,用户可以直接通过pip的方式轻松使用imarkdown。下面将会讲解imarkdown的几种使用场景以及使用方式。

  • 第三方包安装,打开终端命令行,运行如下命令。
pip install -U imarkdown

示例

  • web url转本地地址
  • web-url转图床
  • 多文件转换 web-url转本地
  • 多文件转换 本地转图床
  • 多文件转换 本地转图床

web url转本地地址

如果你的markdown文件里面的图片是其他网站的web url链接,而你想要将其批量下载到本地,并将markdown中的图片地址转换为本地图片地址,下面的示例将会解决你的问题。

假设你需要转换的文件为test.md,内容如下:

下面的示例如果初始markdown文件为web url,则都将基于该文档进行转换,下面不重复给出。

## 6.3 md图片地址转换
以下只支持本地传到图床

- [https://github.com/JyHu/useful_script.git](https://github.com/JyHu/useful_script.git)
- [https://github.com/JyHu/useful_script/blob/](https://github.com/JyHu/useful_script/blob/master/Scripts/md%E6%96%87%E4%BB%B6%E5%9B%BE%E7%89%87%E5%9B%BE%E5%BA%8A%E8%BD%AC%E6%8D%A2/%E8%87%AA%E5%8A%A8%E8%BD%AC%E6%8D%A2markdown%E6%96%87%E4%BB%B6%E4%B8%AD%E5%9B%BE%E7%89%87%E5%88%B0%E5%9B%BE%E5%BA%8A.md/)

罢了,折腾了这么久,又试了试这个,发现也不好用。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/26910220/1670091709979-52f8c3c4-a00f-4668-a236-29ad2c09d0da.png#averageHue=%23272c34&clientId=ubb991e0d-3414-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=928&id=u4a7a8376&margin=%5Bobject%20Object%5D&name=image.png&originHeight=928&originWidth=1050&originalType=binary&ratio=1&rotation=0&showTitle=false&size=201083&status=done&style=none&taskId=u27493dc0-9d78-4c07-929c-cc946d41409&title=&width=1050)

最后,还是PigGo最香,提供了快捷键上传,上传完之后直接xxxTODO

## 6.4 Pycasbin

在pycasbin看到一个经常参与pycasbin的同行,可以参考一些他的contribution:

- [https://github.com/Nekotoxin/nekotoxin.github.io/blob/gsoc_2022_summary/GSoC2022-summary.md](https://github.com/Nekotoxin/nekotoxin.github.io/blob/gsoc_2022_summary/GSoC2022-summary.md)


![image.png](https://cdn.nlark.com/yuque/0/2022/png/26910220/1670150012015-3a93ec6b-bb27-4ed3-b42f-252a0f70b65c.png#averageHue=%23fcfbf5&clientId=u86ce0a81-ec80-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=936&id=ube9c482c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=936&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=205691&status=done&style=none&taskId=u6a6825da-aaf4-471c-ad0e-2280c325c66&title=&width=1920)

该内容为本文语雀导出markdown之后的文件,其图片链接为语雀的防外链链接,需要将其图片转换到本地,并替换markdown中的链接。

from imarkdown import MdFile, LocalFileAdapter, MdImageConverter

def main():
    adapter = LocalFileAdapter()
    converter = MdImageConverter(adapter=adapter)
    
    md_file = MdFile(name="test.md")
    converter.convert(md_file)

if __name__ == '__main__':
    main()

imarkdown中有许多需要传入路径的地方,你可以传入相对路径或者绝对路径,路径分割符推荐使用/而不是\\

转换之后的结果如下,生成一个新的markdown文件,文件名为test_converted.md

## 6.3 md图片地址转换
以下只支持本地传到图床

- [https://github.com/JyHu/useful_script.git](https://github.com/JyHu/useful_script.git)
- [https://github.com/JyHu/useful_script/blob/](https://github.com/JyHu/useful_script/blob/master/Scripts/md%E6%96%87%E4%BB%B6%E5%9B%BE%E7%89%87%E5%9B%BE%E5%BA%8A%E8%BD%AC%E6%8D%A2/%E8%87%AA%E5%8A%A8%E8%BD%AC%E6%8D%A2markdown%E6%96%87%E4%BB%B6%E4%B8%AD%E5%9B%BE%E7%89%87%E5%88%B0%E5%9B%BE%E5%BA%8A.md/)

罢了,折腾了这么久,又试了试这个,发现也不好用。
![image.png](./images/20230713_1356451324.png)

最后,还是PigGo最香,提供了快捷键上传,上传完之后直接xxxTODO

## 6.4 Pycasbin

在pycasbin看到一个经常参与pycasbin的同行,可以参考一些他的contribution:

- [https://github.com/Nekotoxin/nekotoxin.github.io/blob/gsoc_2022_summary/GSoC2022-summary.md](https://github.com/Nekotoxin/nekotoxin.github.io/blob/gsoc_2022_summary/GSoC2022-summary.md)


![image.png](./images/20230713_1356469646.png)
  • 自定义文件名输出
    使用imarkdown进行转换,默认转换后生成的markown文件名为{markdown_file_name}_converted.md如果你想要自定义输出的文件名,你可以使用如下方式进行配置。
md_converter.convert(md_file, name_prefix="new_", name_suffix="_converted")

使用该方式进行转换,最终输出的文件名为new_test_converted.md。如果你想要完全自定义其转换后的名字,可以使用如下方式:

md_converter.convert(md_file, new_name="A new markdown.md")

通过上面的方式,会转换生成一个A new markdown.md的文件。

web url转图床

下面的示例,我们将使用上面给出的test.md进行图片地址的转换,将其web url转换为阿里云oss服务器的url地址,以此展示web url转图床的功能。

from imarkdown import MdImageConverter, AliyunAdapter, MdFile


def main():
    aliyun_config = {
        "access_key_id": "key_id",
        "access_key_secret": "key_secret",
        "bucket_name": "bucket_name",
        "place": "bucket_place",
        "storage_path_prefix": "prefix",
    }
    adapter = AliyunAdapter(**aliyun_config)
    md_converter = MdImageConverter(adapter=adapter)
    md_file = MdFile(name="markdown.md")
    md_converter.convert(md_file)


if __name__ == "__main__":
    main()

在上面的示例中,storage_path_prefix表示上传到oss之后图片在bucket中的文件前缀,如你想要将图片存储在/imarkdown目录下,则需要设置storage_path_prefix="/imarkdown"。而其余的配置内容属于aliyun oss相关的配置内容,请自行填写。

多文件转换: web url转本地

下面的示例展示了多markdown文件批量转换,将图片web链接地址转换为本地图片地址,的解决方案。

from imarkdown import LocalFileAdapter, MdFolder, MdImageConverter

def main():
    adapter = LocalFileAdapter()
    converter = MdImageConverter(adapter=adapter)
    
    # 文件名为mds
    md_folder = MdFolder(name="mds")
    # 将文件输出至converted_mds
    converter.convert(md_folder, output_directory="converted_mds")

使用上面的方式进行输出,将创建一个名为converted_mds的文件,转换后的文件都在保存到此,图片将保存在converted_mds/images中,如果你想要输出图片至指定文件,可以按照如下方式设置。

md_folder = MdFolder(name="mds", image_directory="mds/my_images")

多文件转换: 本地转图床

下面的示例展示了多markdown文件批量转换,将本地图片地址转换为图床图片地址的解决方案。

from imarkdown import LocalFileAdapter, MdFolder, MdImageConverter

def main():
    adapter = LocalFileAdapter()
    converter = MdImageConverter(adapter=adapter)
    
    # 文件名为local_mds,图片为本地类型,图片链接保存在"local_mds/images"
    md_folder = MdFolder(name="local_mds", image_type="local", image_directory="local_mds/images")
    # 将文件输出至converted_mds
    converter.convert(md_folder, output_directory="converted_mds")

自定义图床

下面的示例展示了如何使用imarkdown上传图片自定义的文件服务器,并获取url。

首先,你需要自定义一个适配器,并继承BaseMdAdapter;并实现upload, get_replaced_url两个方法。然后你就可以将其注入MdImageConverter中。

import os
import json

import requests
from imarkdown import BaseMdAdapter, MdImageConverter, MdFolder

class CustomMdAdapter(BaseMdAdapter):
    name = "custom"
    url = "https://server/upload/file/batch"
    headers = {
        "X-Upload-Token": "my_token"
    }
    cur_key = ""

    def upload(self, key: str, file):
        files = {"file": file}
        response = requests.post(self.url, headers=self.headers, files=files)
        if response.status_code == 200:
            res_data = json.loads(response.content.decode("utf-8"))
            self.cur_key = res_data["data"]["images"]["url"]
        else:
            raise Exception(response.content)

    def get_replaced_url(self, key):
        return self.cur_key

def get_all_folder_names():
    return os.listdir("my-blog")

    
def main():
    adapter = CustomMdAdapter()
    md_converter = MdImageConverter(adapter=adapter)

    md_folders = []
    for folder_name in get_all_folder_names():
        md_folders.append(
            MdFolder(
                name=f"my-blog/{folder_name}",
                image_directory=f"my-blog/{folder_name}/images",
                image_type="local",
            )
        )
    md_converter.convert(md_folders, output_directory="converted")


if __name__ == "__main__":
    main()

开发计划

  • 添加客户端支持
  • 支持腾讯云、七牛云等图床
  • 支持批量文件修改
  • 自定义适配器
  • 支持大图片压缩
  • 支持命令行
  • 支持pypi简化操作步骤
  • 提供文件自定义命名
  • 提供图片自定义格式化命名方式

FAQ

1. 如何扩展其他图床?

如果你想开发其他图床,你唯一需要做的就是实现像AliyunAdapter这样的适配器,在使用的时候注入MdImageConverter即可,参考自定义图床
。这就是你所需要做的。实际上,我已经把它包装好了,所以很容易扩展。

2. 文件地址的使用

在Python中,/\\都可以用作文件路径的分隔符。然而,它们在使用上有一些区别。

  • /(正斜杠):在大多数操作系统中(包括Windows,Linux和Mac),/被用作文件路径的分隔符。使用/作为分隔符可以使代码在不同操作系统上具有可移植性。例如:
path = "folder/file.txt"
  • \\(反斜杠):在Windows操作系统中,\\被用作文件路径的分隔符。这是因为在Windows上,\
    被用作转义字符,所以为了表示一个普通的反斜杠,需要使用两个连续的反斜杠。例如:
path = "folder\\file.txt"

在使用\\作为分隔符时,需要注意以下几点:

  • 在字符串中使用\\时,需要转义成\\\\,因为第一个\会被解释为转义字符。
  • 可以使用原始字符串(raw string)来避免转义的麻烦。在原始字符串中,\不会被解释为转义字符。例如:path = r"folder\file.txt"

总结起来,如果你的代码需要在不同的操作系统上运行,建议使用/
作为文件路径的分隔符,这样可以保持代码的可移植性。如果你只在Windows上运行代码,使用\\也是可以的。但是,在imarkdown
中,所有的\\都会被转换为/。在本项目中,所有的\\路径最后都会被转换为/

贡献

欢迎PRs!如果你想为这个项目做贡献,你可以提交pr或issue,开发计划中有一些可以扩展的功能,当前还有很多第三方图床需要适配,如果你在做这方面的工作,欢迎pr!我很高兴看到更多的人参与改进并优化它。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/750199.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电子电路基础知识--电阻

视频教程 薄膜电阻 (包括碳膜电阻、合成碳膜电阻、金属氧化膜电阻、玻璃釉膜电阻)… 碳膜电阻 气态碳氢化合物在高温和真空中分解,碳沉积在蜜挂或者瓷管上,形成一层结晶碳膜。改变碳膜厚度和用刻槽的方法变更碳膜的长度&#…

驱动 day10 作业

要求&#xff1a;platform驱动实现 现象&#xff1a; test.c应用程序 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #in…

Edge浏览器和Google浏览器占用内存情况

最近发现适用edge浏览器看视频时&#xff0c;或者打开多个网页&#xff0c;电脑就会变得非常卡顿&#xff0c;打开任务管理器发现内存占用较多&#xff0c;网上也有人说edge浏览器确实占用内存较多。但是给出的解决方案是更新windows系统&#xff0c;这个方法显然不能接受&…

Modbus tcp转ETHERCAT网关modbus tcp功能码

远创智控YC-ECT-TCP网关能够连接到Modbus tcp总线和ETHERCAT总线中&#xff0c;实现两种不同协议设备之间的通讯。这个网关能够大大提高工业生产的效率和生产效益&#xff0c;让生产变得更加智能化。远创智控YC-ECT-TCP 是自主研发的一款 ETHERCAT 从站功能的通讯网关。该产品主…

渗透专题丨Vulnhub-Tr0ll2靶机打靶

确认目标机IP&#xff1a;192.168.38.140 进行端口扫描&#xff1a; 查看一下版本&#xff1a; 没有查到关键信息&#xff0c;以80端口作为突破&#xff1a; 拿到提示信息&#xff1a; 接下来尝试ftp登录&#xff0c;根据提示信息&#xff1a; 登录之后&#xff0c;拿到lmao.z…

线性电源,开关电源

稳压器是如何工作的&#xff1f; 稳压器是这样一种电路&#xff1a;无论输入电压或负载条件如何变化&#xff0c;它都能产生并保持固定的输出电压。 稳压器&#xff08;VR&#xff09;将来自电源的电压保持在其他电气组件相容的范围之内。它最常用于DC / DC电源转换&#xff…

基于亚博K210开发板——串口中断以及开启双核任务

文章目录 开发板实验目的实验准备硬件原理图软件对应SDK对应的头文件 uart.huart.h接口函数高速通用异步收发传输器(UARTHS)对应的头文件 uarths.huarths.h接口函数板级对应的头文件 bsp.hbsp.h接口函数 实验代码实验结果效果 开发板 亚博K210开发板 实验目的 本实验配置串…

vue3中的excel表导出功能(选中导出或导出所有,也可支持vue2)

1.安装模块 npm install xlsx file-saver -S 2.文件导入 import * as XLSX from "xlsx"; import FileSaver from "file-saver" 3.整体代码(可选中导出或导出所有) <template><div><el-button type"warning" click"down&quo…

apt-get install命令

在Linux系统中&#xff0c;apt-get命令默认安装包的位置是在/usr目录下。具体来说&#xff0c;安装的可执行文件会存储在/usr/bin目录下&#xff0c;而库文件会存储在/usr/lib目录下。同时&#xff0c;相应的配置文件和文档等也会存储在/usr/share目录下。 举例&#xff0c;ap…

【计算机系统概论Yale.patt】第三章

文章目录 3.数字逻辑3.1 MOS管3.1.1 p型MOS晶体管3.1.2 n型MOS晶体管 3.2 逻辑门3.2.1 非门——反相器3.2.2 或非门、或门或非门或门 3.2.3 与非门、与门3.2.4 逻辑门符号表示逻辑门的数电表达式摩根定律 3.3 逻辑结构3.3.1 组合逻辑译码器多路复用器全加器可编程逻辑阵列 3.3.…

20230713-------通过platform实现阻塞IO来驱动按键控制LED灯的亮灭

需添加的设备树节点 myplatform{ compatible "hqyj,myplatform"; reg<0X12345678 0X400>; interrupt-parent<&gpiof>; interrupts<9 0>; //9表示引用中断父节点时的索引信息 0表示默认设置 led1<&gpioe 10 0>;pdev.c #include …

linux 安装pytorch3d的坑

事实上&#xff0c;只要按照官方文档的说明就可以完美安装。其中坑的地方在于conda的管理可能会导致下载的版本不符合你的要求&#xff08;例如下载成了cpu版本、下载的cuda版本&#xff09;而同样尝试使用源码编译以及其他方式下载库都会导致同样的问题&#xff0c;这里主要的…

【动手学深度学习】层和块

层和块 简单介绍 块&#xff1a;描述单个层&#xff0c;由多个层组成的组件或整个模型本身。使用块进行抽象的一个好处是可以将一些块组合成更大的组件&#xff0c;这一过程通常是递归的 简单入门 import torch from torch import nn from torch.nn import functional as F# …

【分布式系统案例课】计数服务之需求收集和总架构设计

面试题 对B站视频观看量进行实时的计数 技术问题是一个比较普遍的问题&#xff0c;比如对头条作者的粉丝或者是对获赞进行计数。或者是对企业的业务指标进行计数&#xff0c;例如注册登录下单数这些等。 需求澄清 问题一&#xff1a;用户点击观察视频之后&#xff0c;这个数量…

Gateway网关组件(在Spring Cloud整合Gateway(idea19版本))

Spring Cloud Gateway官网:Spring Cloud Gateway 局域网中就有网关这个概念&#xff0c;局域网接收数据或发送数据都要通过网关&#xff0c;比如使用VMware虚拟机软件搭建虚拟机集群的时候&#xff0c;往往我们需要选择IP段中的⼀个IP作为网关地址,网关可以对请求进行控制,提升…

Shell第三章——循环语句与函数

循环&#xff1a;重复执行一段代码的结构&#xff0c;通过循环可以在满足一定的条件之下多次执行相同的代码。 循环语句&#xff1a;包换循环体&#xff0c;代码的总结构&#xff0c;循环条件&#xff0c;当循环条件满足时&#xff0c;循环体的代码才会执行&#xff0c;条件不…

RabbitMQ-同步和异步通讯、安装和入门案例、SpringAMQP(5个消息发送接收Demo,jackson消息转换器)

文章目录 1.初识MQ1.1.同步和异步通讯1.1.1.同步通讯1.1.2.异步通讯 1.2.技术对比&#xff1a; 2.快速入门2.1.安装RabbitMQ2.2.RabbitMQ消息模型2.3.导入Demo工程2.4.入门案例2.4.1.publisher实现2.4.2.consumer实现 2.5.总结 3.SpringAMQP3.1.Basic Queue 简单队列模型3.1.1.…

【设计模式】23种设计模式——工厂模式(原理讲解+应用场景介绍+案例介绍+Java代码实现)

工厂模式 需求了解 看一个披萨的项目&#xff1a;要便于披萨种类的扩展&#xff0c;要便于维护 披萨的种类很多(比如 GreekPizz、CheesePizz 等)披萨的制作有 prepare&#xff08;准备材料&#xff09;,bake&#xff08;烘焙&#xff09;,cut&#xff08;切割&#xff09;,b…

Hive SQL 迁移 Flink SQL 在快手的实践

摘要&#xff1a;本文整理自快手数据架构工程师张芒&#xff0c;阿里云工程师刘大龙&#xff0c;在 Flink Forward Asia 2022 生产实践专场的分享。本篇内容主要分为四个部分&#xff1a; Flink 流批一体引擎 Flink Batch 生产实践 核心优化解读 未来规划 点击查看原文视频…

切换.net Framework 版本后,出现NuGet 包是使用不同于当前目标框架的目标框架安装的,可能需要重新安装

问题现象&#xff1a; 由于添加新的dll文件&#xff0c;依赖的.NET Framework版本与当前的不一致&#xff0c;在vs 中切换了目标框架版本后&#xff0c;运行程序&#xff0c;出现以下的warnning信息&#xff1a; 一些 NuGet 包是使用不同于当前目标框架的目标框架安装的&#…