当前位置: 首页 > news >正文

比较好的手机网站接app推广的单子在哪接

比较好的手机网站,接app推广的单子在哪接,郑州高端网站制作团队,个体户 做网站cTinML转html 前言解析解释转译html类定义开头html 结果这是最终效果(部分): ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6cf6c3e3c821446a84ae542bcc2652d4.png) 前言 在python.tkinter设计标记语言(转译2-html)中提到了将Ti…

c++TinML转html

  • 前言
  • 解析
  • 解释
  • 转译html
    • 类定义
    • 开头html
  • 结果
    • 这是最终效果(部分): ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6cf6c3e3c821446a84ae542bcc2652d4.png)

前言

在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会改成\0Lines = 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%", "|"));lineargs[nowtag] = args;tinresults.push_back(lineargs);args.clear();}else{//无法匹配当作p处理cout << "\033[33;1m不可被解析,当作<p>处理:" << i << "\033[0m" << endl;args.push_back(subreplace(i, "%VEB%", "|"));lineargs["p"] = args;tinresults.push_back(lineargs);args.clear();}}}return tinresults;
}

这里还遇到一个坑,string.getline会将分割字符转为\0,这样导致string类型变量所包含的文字比表达的文字多一个“字”。string的设计是不包含的\0,所以要注意从string类型中取字符的下标。

解析过程是最基础的,也几乎不会再维护,毕竟TinML的语法就这样了。

解释

这和TinText软件中转译html的过程一样,只不过TinEngine在渲染之前就生成了解释内容并传递给了转译器,而CppTinParser需要单独进行参数解释。

首先,生成每个标记对应的参数含义:

static map<string, vector<string>> tinkws;void loadkws()
{// 标记对应的参数键tinkws["ac"] = {"name"};tinkws["anchor"] = {"name"};tinkws["code"] = {"type", "codes"};tinkws["fl"] = {};tinkws["follow"] = {};tinkws["html"] = {"htmls"};tinkws["img"] = {"name", "url", "size"};tinkws["image"] = {"name", "url", "size"};tinkws["lnk"] = {"text", "url", "description"};tinkws["link"] = {"text", "url", "description"};tinkws["a"] = {"text", "url", "description"};tinkws["ls"] = {"lists"};tinkws["list"] = {"lists"};tinkws["n"] = {"notes"};tinkws["note"] = {"notes"};tinkws["nl"] = {"lists"};tinkws["numlist"] = {"lists"};tinkws["p"] = {"texts"};tinkws["pages"] = {"name"};tinkws["/page"] = {""};tinkws["/pages"] = {""};// 展示到这里位置,当然,这不是完整的//...
}

由于之前已经生成了类似如下的数据结构:

(("<title>",("title","1"),),("<p>",("paragraph",)),...
)

现在,就需要把这些已经分割好的标记文本转为有意义的内容:

(("<title>",("title": "title", "level": "1"),),("<p>",("paragraph": ("paragraph",))),...
)

这里采用的逻辑是对一个标签所拥有的所有参数一一对应,多出来的统一给最后一个参数。

这部分逻辑实现如下:

map<string, string> tokeywords(string tag, vector<string> contents)
{// 将列表顺序参数转为键、值类参数map<string, string> keywords;cout << "Tag: " << tag << endl;keywords["tag"] = tag;int args_num = contents.size();int index = 0;for (auto kws : tinkws[tag]){if (index >= args_num){// 剩下键全为空keywords[kws] = "";continue;}keywords[kws] = contents[index];// cout << kws << " = " << contents[index] << endl;index++;}if (index < args_num){// 将剩下的参数全部放入最后一个键中for (int i = index; i < args_num; i++){keywords[tinkws[tag].back()] += "\n" + contents[i];}}for (auto kw : keywords){if (kw.first == "tag"){ // 跳过tag键continue;}cout << kw.first << " = " << kw.second << endl;}return keywords;
}
class TinParser
{
public:TinParser(vector<map<string, vector<string>>> contents){this->contents = contents;}void parse();void render(string file);private:vector<map<string, vector<string>>> contents;vector<map<string, string>> result;
};void TinParser::parse()
{// 判断tag是否存在contents = this->contents;for (auto content : contents){string tag = content.begin()->first;if (tinkws.find(tag) == tinkws.end()){cerr << "\033[33;1mtag not found: " << tag << "\033[0m" << endl;// //string转char// char c_tag;// strcpy(&c_tag, tag.c_str());// throw NoTagName(c_tag);continue;}map<string, string> results = tokeywords(tag, content.begin()->second);result.push_back(results);}
}

转译html

经过前面的准备,这里已经准备好了将TinML转译为html的所有信息。

由于在之前的文章中已经给出了HtmlRender的实现和使用示例,这里便不再赘叙。

这部分的代码和TinText的tin2html.py实现在逻辑上完全一致,甚至可以看作是python到c++的翻译。

类定义

class TinRender {//tin->html类
public:TinRender(const string &file) : file_(file){}HtmlRender* render(vector<map<string,string>> content, bool _style = true, bool _code_style = true);//转译为htmlvoid output(vector<map<string,string>> content);//输出
private:string file_;//html文件路径ofstream fout_;//html文件输出流
};

开头html

就是html头中包含的样式、额外引入js、标题这些。

HtmlRender* TinRender::render(vector<map<string, string>> content, bool _style, bool _code_style){//转译为HtmlRender。可以直接使用output方法转译+输出保存//注意,CPPTinParser只是用c++实现的tinml转译器//不作为TinML规范的检查器string tag;HtmlRender* html = new HtmlRender("html", "", {});HtmlRender* head = new HtmlRender("head", "", {});HtmlRender* title = new HtmlRender("title", "TinML", {});head->add(title);HtmlRender* meta = new HtmlRender("meta", "", {{"charset","UTF-8"}}, true);head->add(meta);//读取css文件if (_style){string filename = "blubook.css";ifstream infile;infile.open(filename.data());   //将文件流对象与文件连接起来 assert(infile.is_open());   //若失败,则输出错误消息,并终止程序运行 string s, strAllLine;while (getline(infile, s)){strAllLine += s + "\n";}infile.close();             //关闭文件输入流HtmlRender* style = new HtmlRender ("style", strAllLine, {}, false, true);head->add(style);}//<code>样式if (_code_style){HtmlRender* codestyle = new HtmlRender("link", "", {{"rel","stylesheet"}, {"type", "text/css"}, {"href","https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/vs.min.css"}});head->add(codestyle);HtmlRender* codescript = new HtmlRender("script", "", {{"src","https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"}});head->add(codescript);HtmlRender* codestartscript = new HtmlRender("script", "hljs.highlightAll();", {});head->add(codestartscript);}HtmlRender* _body = new HtmlRender("body", "", {});HtmlRender* body = new HtmlRender("div", "", {{"id","content"}});_body->add(body);html->add(head);html->add(_body);// 提前定义类型变量HtmlRender* table;HtmlRender* tbody;bool tablehead = false;HtmlRender* tabsview;bool pagestag = false;vector<string> pagesnames;vector<map<string, string>> pagescontent;int pagescount = 0;// ...
}

然后就是对每一个标记的单独转译,这些都在上面的那个方法里,这里给几个例子:

// ...//常规转译TinML解析结果if (tag == "ac" || tag == "anchor"){string name = item["name"];if (name[0]=='#'){//锚点链接HtmlRender* anchor = new HtmlRender("a", "🔗", {{"href", name}});HtmlRender* lastitem = body->children().back();lastitem->add(anchor);}else{//锚点定义HtmlRender* anchor = new HtmlRender("a", "", {{"id", name}});body->add(anchor);}}else if (tag == "code"){//代码块//使用highlight.js,不支持tinml代码块string type = item["type"];string codes = item["codes"];if (type == "tin"){type = "nohighlight";}else{type = "language-" + type;}HtmlRender* pre = new HtmlRender("pre", "", {});HtmlRender* code = new HtmlRender("code", codes, {{"class",type}});pre->add(code);body->add(pre);}else if (tag == "html"){//html文本string htmltext = item["htmls"];HtmlRender* htmlcont = new HtmlRender("", htmltext, {}, false, true);body->add(htmlcont);}else if (tag == "img" || tag == "image"){//图片string name = item["name"];string url = item["url"];if (url.empty()){//因为CppTinParser只是用c++实现的tinml转译器//不作为TinML规范的检查器,也不作为tin文件渲染环境//所以不会有额外的资源文件储存位置//因此,不支持从本地文件中导入图片continue;}vector<string> size = render_split(item["size"], 'x');string width = size[0];string height = size[1];HtmlRender* img = new HtmlRender("img", "", {{"alt", ""},{"src", url}, {"width", width}, {"height", height}});body->add(img);}// ...
// ...

CppTinParser甚至给对<p>的解析也单独移植了TinText中的逻辑:

void load_para(HtmlRender* p, vector<string> lines){//添加<p>内容vector<char> tags = {'*','-','_','/','=','!','^','&','#'};regex reg(".*?!\\[(.*)\\]\\((.*)\\)");smatch result;int count = 0;if (lines.size()==0){//空行HtmlRender* br = new HtmlRender("br", "", {}, true);p->add(br);return;}for (auto &line : lines) {HtmlRender* last = p;//p最后一个元素if (line[0] == ' '){//空格string text = line.substr(1);HtmlRender* p_item = new HtmlRender("", text, {});p->add(p_item);continue;}string head;if (line.size() <=9){head = line;}else{head = line.substr(0, 9);}//<p>开头标记需要连续count = 0;for (auto &tag_char : head){if (find(tags.begin(), tags.end(), tag_char) != tags.end()){count++;}else{break;}}head = head.substr(0, count);if (count == 0){HtmlRender* p_item = new HtmlRender("", line, {});p->add(p_item);continue;}if (head.find('*')!=string::npos){HtmlRender* nowlast = new HtmlRender("b", "", {});last->add(nowlast);last = nowlast;}if (head.find('/')!=string::npos){HtmlRender* nowlast = new HtmlRender("i", "", {});last->add(nowlast);last = nowlast;}if (head.find('_')!=string::npos){HtmlRender* nowlast = new HtmlRender("u", "", {});last->add(nowlast);last = nowlast;}if (head.find('-')!=string::npos){HtmlRender* nowlast = new HtmlRender("s", "", {});last->add(nowlast);last = nowlast;}if (head.find('=')!=string::npos){// = 和 # 只能存在一个HtmlRender* nowlast = new HtmlRender("mark", "", {});last->add(nowlast);last = nowlast;}else if (head.find('#')!=string::npos){HtmlRender* nowlast = new HtmlRender("code", "", {});last->add(nowlast);last = nowlast;}if (head.find('^')!=string::npos){// ^ 和 & 只能存在一个HtmlRender* nowlast = new HtmlRender("sup", "", {});last->add(nowlast);last = nowlast;}else if (head.find('&')!=string::npos){HtmlRender* nowlast = new HtmlRender("sub", "", {});last->add(nowlast);last = nowlast;}if (head.find('!')!=string::npos){bool ismatch = regex_match(line, result, reg);if (ismatch) {string text = result[1];string url = result[2];if (text == ""){text = url;}HtmlRender* p_item = new HtmlRender("a", text, {{"href",url}});last->add(p_item);}else{string text = line.substr(count);HtmlRender* p_item = new HtmlRender("", text, {});last->add(p_item);}}else{last->configcnt(line.substr(count));}}
}

结果

这里用的是TinText项目中的test.tin。效果上来看,除了<code>中对TinML的缺失以及对在线图片、tinfile不支持外,其他几乎一样,而且对于大文件的转译绝对比python实现要快。

这是源文件(部分):
在这里插入图片描述


在这里插入图片描述

这是最终效果(部分):
在这里插入图片描述

在这里插入图片描述


文章转载自:
http://biotoxicology.wqfj.cn
http://sociobiology.wqfj.cn
http://disrepute.wqfj.cn
http://devastating.wqfj.cn
http://nannie.wqfj.cn
http://acapnia.wqfj.cn
http://typograph.wqfj.cn
http://stalino.wqfj.cn
http://positive.wqfj.cn
http://cardiganshire.wqfj.cn
http://monarchic.wqfj.cn
http://progamete.wqfj.cn
http://geostrategy.wqfj.cn
http://poeticize.wqfj.cn
http://driveline.wqfj.cn
http://florilegium.wqfj.cn
http://boracite.wqfj.cn
http://kumquat.wqfj.cn
http://endearing.wqfj.cn
http://preventer.wqfj.cn
http://slimnastics.wqfj.cn
http://monocle.wqfj.cn
http://hemiscotosis.wqfj.cn
http://hideout.wqfj.cn
http://zephaniah.wqfj.cn
http://belshazzar.wqfj.cn
http://buildable.wqfj.cn
http://gaius.wqfj.cn
http://race.wqfj.cn
http://incombustible.wqfj.cn
http://scuzzy.wqfj.cn
http://ontologist.wqfj.cn
http://varmint.wqfj.cn
http://tromometer.wqfj.cn
http://playclothes.wqfj.cn
http://ascap.wqfj.cn
http://metalworking.wqfj.cn
http://overate.wqfj.cn
http://petrological.wqfj.cn
http://telesat.wqfj.cn
http://irrespirable.wqfj.cn
http://shammes.wqfj.cn
http://uniformity.wqfj.cn
http://alsatian.wqfj.cn
http://halakha.wqfj.cn
http://whisper.wqfj.cn
http://specifically.wqfj.cn
http://hubbly.wqfj.cn
http://expediential.wqfj.cn
http://kiblah.wqfj.cn
http://simplicity.wqfj.cn
http://joky.wqfj.cn
http://autographical.wqfj.cn
http://galibi.wqfj.cn
http://engram.wqfj.cn
http://curietherapy.wqfj.cn
http://phenomenology.wqfj.cn
http://truckline.wqfj.cn
http://paravail.wqfj.cn
http://ornamentation.wqfj.cn
http://speculate.wqfj.cn
http://semiretirement.wqfj.cn
http://cinquain.wqfj.cn
http://nagaoka.wqfj.cn
http://libretto.wqfj.cn
http://flabbiness.wqfj.cn
http://sapor.wqfj.cn
http://spasmogenic.wqfj.cn
http://ariose.wqfj.cn
http://babouche.wqfj.cn
http://baking.wqfj.cn
http://totalitarian.wqfj.cn
http://holophote.wqfj.cn
http://bedclothing.wqfj.cn
http://heliotype.wqfj.cn
http://recrudesce.wqfj.cn
http://haemodynamic.wqfj.cn
http://puppetize.wqfj.cn
http://imaginational.wqfj.cn
http://presynaptic.wqfj.cn
http://benzomorphan.wqfj.cn
http://plush.wqfj.cn
http://guessingly.wqfj.cn
http://portraitist.wqfj.cn
http://washbasin.wqfj.cn
http://creditability.wqfj.cn
http://hexerei.wqfj.cn
http://initialese.wqfj.cn
http://soilborne.wqfj.cn
http://paradise.wqfj.cn
http://dekastere.wqfj.cn
http://squamulate.wqfj.cn
http://looper.wqfj.cn
http://downsizing.wqfj.cn
http://ovenware.wqfj.cn
http://sialectasis.wqfj.cn
http://disapproval.wqfj.cn
http://colorful.wqfj.cn
http://cisc.wqfj.cn
http://epidemic.wqfj.cn
http://www.hrbkazy.com/news/58390.html

相关文章:

  • 响应页手机网站源码最近三天发生的重要新闻
  • 淘宝客导购网站怎么做广告公司推广平台
  • 访问网站 过程免费的舆情网站app
  • 皮具 东莞网站建设seo排名点击器
  • 建设直播网站软件舆情分析
  • 浏阳网站制作公司百度账号登录入口
  • wordpress轻量级插件武汉seo推广优化
  • 福建省住房城乡建设厅网站手机百度云网页版登录
  • 网站开发的前置审批是什么意思长沙百度网站推广公司
  • 哪个国家的绘本网站做的好中国世界排名
  • 三明网站建设在线生成个人网站
  • php网站开发linux百度竞价是什么
  • 深圳什么公司做网站好百度搜索大全
  • 网站建设的目的和意义新闻早知道
  • 南京高端网站建设公司哪家好全国疫情防控最新数据
  • 怎样做旅游网站设计软文投放平台有哪些
  • 你做网站群好朋友的作文网络营销专业介绍
  • 网站管理后台怎么做网络平台营销
  • 招聘网站建设人员的要求站长之家素材
  • 力软框架做网站北京网络营销
  • 可以做立体图形的网站搜狗快速收录方法
  • 宣讲家网站做四讲四有模范高端网站建设哪家便宜
  • 阿里云有了域名 网站建设微信管理系统登录
  • 网站建设可用性seo的作用是什么
  • 无锡君通科技服务有限公司简述seo的应用范围
  • 百度公司网站怎么建设谷歌官网下载
  • 域名空间网站上海培训机构白名单
  • 手机上传网站源码无锡网站排名公司
  • 厦门创意网站建设在哪里可以免费自学seo课程
  • 怎么把网站排名长沙网站优化