doxygen使用: 跨平台方式让markdown文件包含另一个文件

news2024/10/7 10:24:52

在这里插入图片描述

文章目录

    • 1. 目的和问题
    • 2. 解决思路
      • 2.1 `FILTER_PATTERNS` 选项
      • 2.2 基于 Python 的 `FILTER_PATTERNS` 选项
      • 2.3 sledcpp.py 脚本
    • 3. 完整工程
      • 3.1 目录结构
      • 3.2 `hello.h` 文件内容
      • 3.3 `CHANGELOG.md` 文件内容
      • 3.4 `generate_doxyfile.py` 文件内容
      • 3.5 `docs/root.md`
      • 3.6 `docs/changelog.md`
      • 3.7 运行整个工程

1. 目的和问题

项目代码的 changelog.md 有特殊用处和格式, 用它生成 doxygen 的 html 网页时, 内容不足, 需要添加额外内容; 这些额外内容直接放在 changelog.md 里会导致整个工程的编译、打包出错。

解决思路是另外写一个 docs/changelog.md 文件, 让它包含根目录的 changelog.md:

ChangeLog {#changelog}
====
This page lists change logs for each released version.<br/>

#include "../CHANGELOG.md"

其中 #include "../CHANGELOG.md" 意思是要用 C/C++ 编译器(其实是C预处理器),把内容替换过来。

原本的 changelog.md 内容为 :
在这里插入图片描述

预期结果如下,其中头部的 ChangeLog 标题和 This page lists chagne logs for each released version. 是增加的内容
在这里插入图片描述

在 Windows 上则是得到了非预期结果:
在这里插入图片描述

2. 解决思路

2.1 FILTER_PATTERNS 选项

容易在 StackOverflow 找到解决方案的大致方向: 在 Doxyfile 里配置 FILTER_PATTERNS 选项:

FILTER_PATTERNS = *.md="cpp -P "

这样的写法可以在 Linux / MacOSX 系统上生成预期结果, 但在 Windows 下没有 cpp 这个预处理命令使用。

其中 -P 意思是把替换后的内容输出到屏幕。

尝试过一些方法, 不过失败了, 报错内容是一个 doxygen 警告:

explicit link request to ‘include’ could not be resolved

简单罗列这些失败的方法:

  1. 直接用 VS2022 的 cl.exe 的路径

失败: 可能是路径有空格,也可能是 cl.exe 的 /P 参数不支持导致的。

  1. 找到了 mcpp 这个开源项目和它的魔改版本(https://github.com/zeroc-ice/mcpp)

失败: mcpp 的魔改版本不支持 -P 参数

  1. 封装 VS2022 的 cl.exe 为 cpp.cmd 脚本

失败: 和方法1 差不多。

2.2 基于 Python 的 FILTER_PATTERNS 选项

cross platform FILTER_PATTERNS in doxygen 这个问答中提示, 可以用 Python 脚本作为 FILTER_PATTERNS 的参数。于是可以自行实现一个替代 cpp 命令的 Python 脚本, 让它支持 #include "xxx" 替换为 xxx 文件的具体内容即可。

2.3 sledcpp.py 脚本

我实现的替代 cpp 命令的脚本名为 sledcpp.py, 内容如下

# sledcpp:  a naive C Pre-Processor implementation
# Author:   Zhuo Zhang <imzhuo#foxmail.com>
#
# Currently only support expanding `#include` directive once
# Used in generating doxygen webpages from markdown files which include another file
#
# Created:  2023-05-30 10:38:29
# Modified: 2023-05-30 10:38:48

import sys
import os

def getLinesOfTextFile(filepath):
    lines = []
    with open(filepath, encoding='utf-8') as fin:
        for line in fin.readlines():
            lines.append(line.strip())
    return lines


def expand_file_once(filepath):
    fileDir = os.path.dirname(filepath)
    with open(filepath) as fin:
        for line in fin.readlines():
            line = line.strip()
            if line.startswith('#include'):
                startPos = len('#include')
                depfile = line[startPos:].strip().split('"')[1]
                deppath = os.path.join(fileDir, depfile)
                deplines = getLinesOfTextFile(deppath)
                for item in deplines:
                    print(item)
            else:
                print(line)


if __name__ == '__main__':
    if len(sys.argv) != 2:
        print('Usage: python {:s} filepath'.format(sys.argv[0]))
        exit(1)
    
    filepath = sys.argv[1]
    expand_file_once(filepath)

3. 完整工程

3.1 目录结构

➜  b tree
.
├── CHANGELOG.md
├── docs
│   ├── changelog.md
│   └── root.md
├── Doxyfile
├── generate_doxyfile.py
├── hello.h
├── html
└── sledcpp.py

3.2 hello.h 文件内容

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

void hello(const char* name);

#ifdef __cplusplus
}
#endif

3.3 CHANGELOG.md 文件内容

## 0.0.1
- [feat] Add `hello()`.
- [docs] Generate doxygen html website.

3.4 generate_doxyfile.py 文件内容

由于 Doxyfile 中需要配置 markdown 文件的绝对路径(尝试过相对路径,无法得到正确结果),而每个人电脑上的路径不一样, 这里提供 python 脚本 generate_doxyfile.py 来生成 Doxyfile 来解决路径问题。

此外还需要注意, 路径里不能带中文, 即使是 Linux 下也不能有中文。

generate_doxyfile.py 内容如下

import os

class CodeWriter(object):
    def __init__(self, indent_len):
        self.lines = []
        self.indent_num = 0
        self.indent_len = indent_len

    def write(self, content):
        padding = (self.indent_len * self.indent_num) * ' '
        line = padding + content
        self.lines.append(line)

    def save(self, filename):
        with open(filename, 'w') as fout:
            for line in self.lines:
                fout.write(line + "\n")

    def tab(self):
        self.indent_num += 1

    def backspace(self):
        if (self.indent_num > 0):
            self.indent_num -= 1


def generate_doxyfile():
    w = CodeWriter(8)
    w.write('PROJECT_NAME = "x"')
    w.write('GENERATE_TREEVIEW = YES')
    w.write('GENERATE_HTML = YES')
    w.write('GENERATE_LATEX = NO')
    w.write('')
    w.write('EXTRACT_ALL = YES')
    w.write('EXTRACT_STATIC = YES')
    w.write('')
    w.write('INPUT = hello.h \\')
    w.tab()

    curDir = os.getcwd().replace('\\', '/')
    line = '{:s}/docs/root.md \\'.format(curDir)
    w.write(line)

    line = '{:s}/docs/changelog.md'.format(curDir)
    w.write(line)

    w.backspace()

    w.write('# cpp command, the C Pre Processor, works on Linux/MacOSX, but failed on Windows')
    line = '# FILTER_PATTERNS = {:s}/docs/changelog.md="cpp -P "'.format(curDir)
    w.write(line)

    w.write('# Implement an alternative of cpp with Python wors for Windows, Linux and MacOSX')
    line = 'FILTER_PATTERNS = {:s}/docs/changelog.md="python {:s}/sledcpp.py "'.format(curDir, curDir)
    w.write(line)

    w.save("Doxyfile")


if __name__ == '__main__':
    generate_doxyfile()

例如我生成的 Doxyfile 内容为

PROJECT_NAME = "x"
GENERATE_TREEVIEW = YES
GENERATE_HTML = YES
GENERATE_LATEX = NO

EXTRACT_ALL = YES
EXTRACT_STATIC = YES

INPUT = hello.h \
        D:/dbg/a/docs/root.md \
        D:/dbg/a/docs/changelog.md
# cpp command, the C Pre Processor, works on Linux/MacOSX, but failed on Windows
# FILTER_PATTERNS = D:/dbg/a/docs/changelog.md="cpp -P "
# Implement an alternative of cpp with Python wors for Windows, Linux and MacOSX
FILTER_PATTERNS = D:/dbg/a/docs/changelog.md="python D:/dbg/a/sledcpp.py "

3.5 docs/root.md

是生成的网页的主页。

# MainPage

Hello, World!

3.6 docs/changelog.md

这个文件是关键文件。最关键一行是 #include "../CHANGELOG.md".

ChangeLog {#changelog}
====
This page lists change logs for each released version.<br/>

#include "../CHANGELOG.md"

3.7 运行整个工程

python generate_doxyfile.py
doxygen
cd html
python -m http.server 7080

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

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

相关文章

Redis 事务详细介绍

事务 注意&#xff1a;Redis单条命令是保证原子性的&#xff1b;但是事务不保证原子性&#xff01; Redis事务没有隔离级别的概念&#xff0c;所有的命令在事务中&#xff0c;并没有直接被执行&#xff0c;只有发起执行命令时才执行 Redis事务本质&#xff1a;一组命令的集合&…

API接口对接的流程和注意的事项

API接口对接是将两个应用程序或系统连接并进行数据交换的过程。在进行API接口对接时&#xff0c;需要确保两个系统具有相同的协议和格式&#xff0c;并且数据传输过程中不会出现错误或数据丢失。下面是API接口对接的流程和注意事项&#xff1a; 流程&#xff1a; 1.确认数据格…

【多目标优化算法】多目标蚱蜢优化算法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Linux——进程退出

目录 一.进程退出时有三种选择&#xff1a; 1.1 echo $?命令&#xff1a; 功能&#xff1a; 打印距离现在最近一次执行某进程的退出码 例2代码&#xff1a; 例3&#xff1a; 例4代码&#xff1a; 1.3 进程运行过程中可能会出现的错误种类&#xff1a; 二.总结&#xff…

神经网络学习小记录73——Pytorch CA(Coordinate attention)注意力机制的解析与代码详解

神经网络学习小记录73——Pytorch CA&#xff08;Coordinate attention&#xff09;注意力机制的解析与代码详解 学习前言代码下载CA注意力机制的概念与实现注意力机制的应用 学习前言 CA注意力机制是最近提出的一种注意力机制&#xff0c;全面关注特征层的空间信息和通道信息…

Unity随手问题记录(持续更新~~)

目录 1.将摄像机定位到模型实际中心点前边&#xff08;防止有些模型中心点和实际模型中心位置偏移很大的情况&#xff09; 2.获取当鼠标在RawImage上时&#xff0c;鼠标位置对应的图像坐标(简单粗暴方式) 3.设置脚本运行顺序 4.当plugins底下出现dll文件识别不到的情况&#xf…

LeetCode 1110. Delete Nodes And Return Forest【二叉树,DFS,哈希表】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

SKD240

SKD240 系列智能电力仪表 SKD240 系列智能电力仪表是陕西斯科德智能科技有限公司自主研发、生产的。 产品概述 - 点击了解详情 SKD240采用先进的微处理器和数字信号处理技术&#xff08;内置主芯片采用32位单片机, 采用32位浮点型真有效值处理数据&#xff09;&#xff0c;测量…

图像采集卡的基本原理、应用领域和发展趋势

图像采集卡是一种硬件设备&#xff0c;用于将模拟视频信号转换为数字信号&#xff0c;并将其传输到计算机中进行处理和存储。它通常用于监控、视频会议、医学图像等领域。本文将介绍图像采集卡的基本原理、应用领域和发展趋势。 一、图像采集卡的基本原理 图像采集卡的基本原…

视频里的声音怎么转换成音频?

视频里的声音怎么转换成音频&#xff1f;这样我们就能把视频里的想要的声音在其他音频平台播放或是用于其他视频。其实视频提取音频是一种将视频文件中的音频数据分离出来的技术。该技术可以将视频中的音频转换为不同的格式&#xff0c;让我们可以在无需视频的情况下使用音频文…

Web 应用程序防火墙 (WAF) 相关知识介绍

Web应用程序防火墙 (WAF) 如何工作&#xff1f; Web应用防护系统&#xff08;也称为&#xff1a;网站应用级入侵防御系统。英文&#xff1a;Web Application Firewall&#xff0c;简称&#xff1a;WAF&#xff09;。利用国际上公认的一种说法&#xff1a;Web应用防火墙是通过执…

【Zero to One系列】在WSL linux系统上,使用docker运行Mysql与Nacos,以及如何启动与停止WSL

前期回顾&#xff1a; 【Zero to One系列】window系统安装Linux、docker 1、下载docker-compose 1.下载&#xff1a; curl -SL https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose 2.授予权限&a…

大数据治理入门系列:元数据管理

在介绍数据治理一文中&#xff0c;我们曾用在图书馆找书的例子解释为什么需要进行数据治理。数据治理在某种程度上类似于图书管理。元数据管理作为数据治理的重要一环&#xff0c;也可以进行这种类比。 在图书管理过程中&#xff0c;需要根据相应的制度购买、记录、存放、借还…

【LeetCode: 486. 预测赢家 | 暴力递归=>记忆化搜索=>动态规划 】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

【T+】畅捷通T+设置收入成本配比结转

【问题需求】 收入成本配比原则是指&#xff1a; 取得的销售收入应与为取得该收入所发生的成本相匹配&#xff0c; 即先出库后销货时需要等收到销售发票才能确认成本&#xff0c; 先销货后出库时要先确认虚拟成本。 【解决方案】 重点&#xff1a;业务流程选择【单据立账】的情…

ArcGis系列-java发布空间表为地图服务(map)

1,实现思路 使用java调用cmd命令执行python脚本python环境使用arcgis pro安装目录下的 \ArcGIS\Pro\bin\Python\envs\arcgispro-py3作为地图服务应该可以支持添加样式文件发布表需要用到sde文件,使用java创建sde的代码可以看这里发布表时,先在本地的空项目模板中添加数据库表作…

vue模拟el-table演示插槽用法

vue模拟el-table演示插槽用法 转载自&#xff1a;www.javaman.cn 很多人知道插槽分为三种&#xff0c;但是实际到elementui当中为什么这么用&#xff0c;就一脸懵逼&#xff0c;接下来就跟大家聊一聊插槽在elementui中的应用&#xff0c;并且自己写一个类似el-table的组件 vue…

回归问题里的数学

假设一个简单的案例 投入的广告费越多&#xff0c;广告的点击量就越高&#xff0c;进而带来访问数的增加&#xff0c;不过点击量经常变化&#xff0c;投入同样的广告费未必能带来同样的点击量。根据广告费和实际点击量的对应关系数据&#xff0c;可以将两个变量用下面的图展示…

CASA模型:生态系统NPP及碳源、碳汇模拟、土地利用变化、未来气候变化、空间动态模拟

查看原文>>>生态系统NPP及碳源、碳汇模拟、土地利用变化、未来气候变化、空间动态模拟实践技术应用 目录 第一章 CASA模型介绍&#xff08;讲解案例实践&#xff09; 第二章 CASA初步操作 第三章 CASA数据制备&#xff08;一&#xff09; 第四章 CASA数据制备&am…

4_回归算法(算法原理推导+实践)

文章目录 1 线性回归1.1 定义1.2 题目分析1.3 误差项分析1.4 目标函数推导1.5 线性回归求解1.6 最小二乘法的参数最优解 2 目标函数&#xff08;loss/cost function&#xff09;3 模型效果判断4 机器学习调参5 梯度下降算法5.1 梯度方向5.2 批量梯度下降算法&#xff08;BGD&am…