本地化csdn文章markdown链接

⌚Time: 2024-11-14 22:59:00

👨‍💻Author: Jack Ge

本地化markdown里面链接是简单的,只需要把里面的图片网络链接变成本地路径就行了。![描述](https://i-blog.csdnimg.cn/blog_migrate/abc.png)替换成![描述](markdown文件名/abc.png)

用自己不明白的lua脚本,用match函数匹配,用gsub函数替换,还有正则表达式。最后是替换成功的。但是中文编码问题导致乱码。我也知道是替换内容和原文的gbk和utf8编码的混乱。但是我不知道怎么统一化。在脚本里用iconv命令行也不能正确转换。知道怎么去做,却没有能力去做。

最后回到自己熟悉的cpp语言。用cpp转换。才实现了。

#include <iostream>
#include <fstream>
#include <string.h>
#include <iconv.h>//字符集转换库
//要替换的内容
const char *replacestr = "https://i-blog.csdnimg.cn/blog_migrate";
//将gbk转换成utf8编码
int gbk_convert_utf8(char *input_str,char output_str[]){
    // 定义输入字符串的长度
    size_t input_len = strlen(input_str);
    // 分配输出缓冲区
    size_t output_len = input_len * 2;  // 假设输出缓冲区需要的长度为输入长度的两倍
    // 定义转换句柄,gbk转utf-8
    iconv_t cd = iconv_open("utf-8", "gbk");
    if (cd == (iconv_t) -1) {
        perror("iconv_open");
        return 1;
    }
    // 调用 iconv() 函数进行转换
    char *inptr = input_str;
    char *outptr = output_str;
    if (iconv(cd, &inptr, &input_len, &outptr, &output_len) == (size_t) -1) {
        perror("iconv");
        return 1;
    }
    // 关闭转换句柄
    iconv_close(cd);
    return 0;
}
//获取文件名
void get_basename(char *fullname,char basename[]){
    bool hasSeparator = false;
    unsigned int separatorPos = 0;
    int i=0;
    for(i=0;i<strlen(fullname);i++){
        if(fullname[i]=='\\'||fullname[i]=='/'){
            separatorPos = i;
            hasSeparator = true;
        }
    }
    if(hasSeparator == true){
        strcpy(basename,fullname+separatorPos+1);
    }else{
        strcpy(basename,fullname);
    }
}
// 不带扩展名
void get_basename_no_ext(char *fullname,char basename[]){
    get_basename(fullname,basename);
    unsigned int pointpos = 0;
    bool haspoint = false;
    for(int i=0;i<strlen(basename);i++){
        if(basename[i]=='.'){
            haspoint = true;
            pointpos = i;
        }
    }
    if(haspoint){
        basename[pointpos] = '\0';
    }
}
int main(int argc,char* argv[]){
    //检测参数数量
    if(argc!=2){
        return 0;
    }
    char argvv[10240] = {0};
    char newstr[10240] = {0};
    //获取不带扩展的文件名
    get_basename_no_ext(argv[1],argvv);
    //转换中文字符的gbk成utf8编码
    gbk_convert_utf8(argvv,newstr);
    //
    std::ifstream iFile;
    std::ofstream oFile;
    //输出文件
    oFile.open("out.md",std::ios::out);
    //读取文件
    iFile.open(argv[1],std::ios::in);
    if(iFile.is_open()){
        //读取的文件内容位置
        char buff[10240] = {0};
        //替换后要写入新文件的内容
        char temp[10240] = {0};
        memset(buff,0,sizeof(buff));
        memset(temp,0,sizeof(temp));
        //循环读取文件
        while(iFile.getline(buff,sizeof(buff))){
            //复制字符串内容
            strcpy(temp,buff);
            //查找要替换的内容位置
            char *posb = strstr(buff,replacestr);
            char *post = strstr(temp,replacestr);
            if(posb&&post){
                //把文件名拷贝到要替换的内容起始位置并且覆盖
                strncpy(post,newstr,strlen(newstr));
                //掠过要替换的内容,从之后的位置继续拷贝
                strncpy(post+strlen(newstr),posb+strlen(replacestr),strlen(posb+strlen(replacestr)));
                //截断字符串,位置是之前的长度减去替换的字符长度加新增的字符长度
                post[strlen(post)-strlen(replacestr)+strlen(newstr)] = '\0';
            }
            //追加内容和换行
            oFile<<temp<<"\n";
            //清空缓存
            memset(buff,0,sizeof(buff));
            memset(temp,0,sizeof(temp));
        }
        iFile.close();
        oFile.close();
    }
    
    return 0;
}

cpp输出的中文路径链接内容会乱码的原因是中文字符用了gbk编码。而其它内容用了utf8编码。所以查看的时候在链接部分会乱码。用iconv库把中文路径转换成utf8编码就行了。

g++连接需要iconv库,加-liconv参数

g++ new.cpp -liconv -o a.exe

转换后能够正确显示本地化的链接了。

当然了,程序最后还是需要脚本调用。因为程序是精准的执行功能,脚本是控制。还得用lua调用这个程序执行转换。