c++TinML转html

前言

python.tkinter设计标记语言(转译2-html)中提到了将TinML转为静态html的python实现方法;在HtmlRender - c++实现的html生成类中又提供了我自己写的基于c++编辑html的简单方式,这篇笔记就是使用c++将tinml转为静态html。

本示例未使用任何第三方库(除了我之前提供的HtmlRender类),但是在html中代码高亮方面使用了在线的highlight.js

整套流程下来和基于python的TinText平台类似,都是先解析TinML标记文本段,再给每个标记赋以特定含义(解释过程),最后通过这些解释后的内容生成html结构,生成html文本。

项目示例:CppTinParser: TinML to html by c++

解析

这一部分是对TinML标记的语法解析。

class TinLexer{
   

public:
    TinLexer(string contents){
   
        this->content = '\n' + contents + '\n';
    }

    void run_test();
    vector<string> run();
    vector<map<string,vector<string>>> lex();

private:
    string content;

};

主要解析功能就是对每一行TinML标记文本段进行基于上下文标记的正则匹配和结构解析,这部分相当于TinText项目中的TinParser

  • 单行TinML标记,分为标记名称和标记参数组
  • 多行模式TinML,转为单行TinML标记解析后格式

部分代码如下:

vector<map<string,vector<string>>> TinLexer::lex(){
   
    // 预处理
    // tackle <tinfile>: add context of the specific TinML file into this->content
    // 此部分代码省略,可见程序源码
    // ...

    vector<map<string,vector<string>>> tinresults;//总结果
    
    vector<string> contents;
    string nowtag;//当前标签

    contents = split(this->content, '\n');

    bool Lines = false;//多行模式
    regex pattern("^<(.*?)>(.*)");
    smatch result;
    vector<string> args;//参数列表
    
    for (const auto &i : contents){
   
        if (size(i) == 1){
   
            // 实际上是empty,不过貌似写不对
            // 既有可能是因为getline将\n转为\0,导致该字符串截止
            continue;
        }
        
        if (size(i)>=2 && i.substr(0,2)=="|-"){
   
            //  cout << "Comment: " << i << endl;
            continue;
        }

        map<string,vector<string>> lineargs;//单行参数

        if (Lines){
   
            if (i[0]=='|'){
   
                if (size(i)>2 && i[i.length()-2]!='|'){
   
                    string content = i.substr(1,size(i)-2);
                    args.push_back(subreplace(content, "%VEB%", "|"));
                }else if (size(i)==2){
   
                    args.push_back("");
                }else{
   
                    string content = i.substr(1,size(i)-3);
                    args.push_back(subreplace(content, "%VEB%", "|"));
                    // for (auto const &j : args){
   
                    //     cout << "Arg: " << j << endl;
                    // }
                    lineargs[nowtag] = args;
                    tinresults.push_back(lineargs);
                    args.clear();
                    Lines = false;
                }
            }
        }else if (i[i.length()-2] == ';'){
   
            // getline最后一个为\0,因此-2
            // string本身不以\0结尾,但是getline会改成\0
            Lines = true;
            bool ismatch = regex_search(i, result, pattern);
            if (ismatch){
   
                // cout << "Tag: " << result[1] << endl;
                nowtag = result[1];
                string content = result[2];
                int lastindex = content.find_last_of(';');
                content = content.substr(0, lastindex);
                args.push_back(subreplace(content, "%VEB%", "|"));
            }else{
   
                cout << "\033[33;1m不可被解析,当作<p>处理:" << i << "\033[0m" << endl;
                args.push_back(subreplace(i, "%VEB%", "|"));
                lineargs["p"] = args;
                tinresults.push_back(lineargs);
                args.clear();
            }
        }else{
   
            bool ismatch = regex_search(i, result, pattern);
            if (ismatch){
   
                nowtag = result[1];
                string content = result[2];
                auto oargs = split(content, '|');
                for (auto const &j : oargs)
                    args.push_back(subreplace(j, "%VEB%", 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值