Featured image of post ChatGPT帮我调整stack主题

ChatGPT帮我调整stack主题

刚开始搭建博客,看中了stack主题,但是还有一些需求无法满足,于是让ChatGPT辅助我调整stack主题。

Rblogdown使用stack-theme遇到了几个问题,应该是Rblogdown与原生hugo间的不太兼容。

我很快发现了问题是Rmd产生的md文件可能跟stack主题不太匹配,一开始想看看yaml文件能不能修改解决,但找了不少地方都没找到😭。

因为问题还比较确定,可以试试自己写脚本转换Rmd产生的md文件。

公式问题

rblogdown 渲染Rmd成md会把我写的公式语法改变:

例如: $a=sum_i^2$变成$a=sum_i^2$

但是stack主题识别不了后面那种语法,这个比较简单:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import re

# 定义一个正则表达式,匹配LaTeX数学公式中的起始和结束行内数学模式符号
pattern = r'\\\((.*?)\\\)'  

# 定义一个字符串,包含要处理的LaTeX字符串
latex_string = r'For the equation$\sum_{i=1}^n i^2$'

# 使用sub()函数替换匹配到的文本
processed_string = re.sub(pattern, r'$\1$', latex_string)

# 输出处理后的字符串
print(processed_string)

a=re.sub(r'`\\\((.*?)\\\)`',r'$\1$',$a=sum_i^2$jjjh$a=sum_i^2$")

图片大小调整

因为![from data to viz website](images/data2viz.png){width=60%}这种语法是stack主题不支持的, 但是

1
2
3
'<p style="text-align: center;">
    <img src="images/data2viz.png" width="60%" title="from data to viz website"/>
</p>'

这种语法是支持的,所以想写一个小脚本转换一下

自己不太熟悉正则(上面那个公式转换的也是他帮我写的,哈哈),所以试试问了ChatGPT :

可以帮我写一个将插入图片的markdown语法转换为html语法的小脚本吗? 比如:![A](B.png){width=60%}转换为<img src="B.png" width="60%" title="A"/>

它立马用python帮我写了:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import re

def convert_markdown_to_html(markdown_text):
    # 将插入图片的Markdown语法转换为HTML语法
    pattern = r"!\[(.*?)\]\((.*?)\){(.*?)}"
    matches = re.findall(pattern, markdown_text)
    for match in matches:
        title = match[0]
        src = match[1]
        attributes = match[2].split(",")
        attr_dict = dict([tuple(attribute.split("=")) for attribute in attributes])
        html_tag = f'<img src="{src}" title="{title}"'
        for key, value in attr_dict.items():
            html_tag += f' {key}="{value}"'
        html_tag += "/>"
        markdown_text = markdown_text.replace(f"![{title}]({src}){{{match[2]}}}", html_tag)
    return markdown_text

def convert_latex_to_md(markdown_text):
    html_text=re.sub(r'`\\\((.*?)\\\)`',r'$\1$',markdown_text)
    return html_text

def convert_markdown_file_to_html(file_path):
    # 读取Markdown文件
    with open(file_path, "r", encoding="utf-8") as f:
        markdown_text = f.read()
    # 将Markdown语法转换为HTML语法
    html_text = convert_markdown_to_html(markdown_text)
    html_text = convert_latex_to_md(html_text)
    # 将HTML文本写入文件
    with open(file_path, "w", encoding="utf-8") as f:
        f.write(html_text)

if __name__ == "__main__":
    file_path = "index.md"
    convert_markdown_file_to_html(file_path)

牛牛牛! 再问一下,可以用R语言写一下吗?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
convert_markdown_to_html <- function(markdown_text) {
  # 通过正则表达式匹配图片语法
  matches <- gregexpr("!\\[(.*?)\\]\\((.*?)\\){(.*?)}", markdown_text, perl = TRUE)
  
  # 遍历匹配结果,将Markdown语法替换为HTML语法
  for (i in seq_along(matches[[1]])) {
    # 判断匹配结果是否为空列表
    if (length(matches[[1]][i]) == 0) {
      next
    }
    
    match <- regmatches(markdown_text, matches[[1]][i])
    title <- match[[2]]
    src <- match[[3]]
    attributes <- strsplit(match[[4]], ",")[[1]]
    attr_dict <- setNames(sapply(strsplit(attributes, "="), "[", 2), sapply(strsplit(attributes, "="), "[", 1))
    
    # 构造HTML标签
    html_tag <- sprintf('<img src="%s" title="%s"', src, title)
    for (key in names(attr_dict)) {
      value <- attr_dict[[key]]
      html_tag <- paste(html_tag, sprintf('%s="%s"', key, value), sep = " ")
    }
    html_tag <- paste(html_tag, "/>", sep = "")
    
    # 将Markdown语法替换为HTML语法
    markdown_text <- sub("!\\[(.*?)\\]\\((.*?)\\){(.*?)}", html_tag, markdown_text, fixed = TRUE)
  }
  
  return(markdown_text)
}
markdown_text <- "![A](B.png){width=60%}"
html_text <- convert_markdown_to_html(markdown_text)
print(html_text)

唉,实际上这个代码没有用,我也不知道bug怎么搞,R的正则表达式一直感觉没有python好用。

还是用写好的python脚本吧。

修改新的md文件

我们还需要找到最新render出来的md文件按上述规则进行修改(否则一口气改全部的话,害怕会越来越慢,甚至损坏以前的md文件):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import os
import datetime

# 定义要查找的目录
directory = './content/post/'

# 存储所有的md文件
md_files = []

# 递归查找目录下的所有文件
for root, dirs, files in os.walk(directory):
    for file in files:
        if file.endswith('.md'):
            file_path = os.path.join(root, file)
            md_files.append((file_path, os.path.getmtime(file_path)))

# 找到最新修改的文件
latest_file = max(md_files, key=lambda x: x[1])[0]

print("最新保存的.md文件是:", latest_file)

再问问,可以找到目录下所有新保存的.md文件吗,就是修改时间与上次不一致的?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import os
import datetime

# 定义要查找的目录
directory = './content/'

# 存储所有新保存的md文件
new_md_files = []

# 读取上一次检查的时间戳
if os.path.isfile('last_check_time.txt'):
    with open('last_check_time.txt', 'r') as f:
        last_check_time = datetime.datetime.strptime(f.read(), '%Y-%m-%d %H:%M:%S.%f')
else:
    last_check_time = datetime.datetime.now()

# 递归查找目录下的所有文件
for root, dirs, files in os.walk(directory):
    for file in files:
        if file.endswith('.md'):
            file_path = os.path.join(root, file)
            mod_time = datetime.datetime.fromtimestamp(os.path.getmtime(file_path))
            if mod_time > last_check_time:
                new_md_files.append(file_path)

# 更新上一次检查的时间戳
last_check_time = datetime.datetime.now()

# 将上一次检查的时间戳保存到文件中
with open('last_check_time.txt', 'w') as f:
    f.write(last_check_time.strftime('%Y-%m-%d %H:%M:%S.%f'))

# 打印所有新保存的md文件
for file_path in new_md_files:
    print("新保存的.md文件:", file_path)
#更新所有新保存的md文件
for file_path in new_md_files:
    convert_markdown_file_to_html(latest_file)

这个思路真不错,哈哈

解决方法

调教了一下ChatGPT后,就得到了整个更新问题的方法了: 首先整理一个refresh_md_to_fit_stack.py放在网站根目录下, 然后在R文件夹的(如果你是用Rblogdown生成的网站,那就会有这个文件夹)的build2.R中加入一行:

system("python refresh_md_to_fit_stack.py")

即可。 因为Rblogdown会在每次实时渲染我们的网站后运行build2.R文件,相当于运行了refresh_md_to_fit_stack.py文件,而refresh_md_to_fit_stack.py文件将搜索所有更新的md文件并修改以上两个问题,这样hugo建立的网站就能够契合stack-theme。

看看结果: 如果调试成功的话,下面显示的即是正常的latex公式:

$y=\frac{1}{2} $

如果不是使用的Rblogdown生成的网站,这种思路的方法也可以帮助改变stack-theme。

此外,如果是Rblogdown生成的其他主题的网站有类似问题,也可以这样修改。

最后,ChatGPT真不错!再来一个攻略

其他调整参考

Licensed under CC BY-NC-SA 4.0
Email: pengchen2001@zju.edu.cn
Built with Hugo
Theme Stack designed by Jimmy