支持代码高亮
This commit is contained in:
parent
f93d65abe6
commit
d0cb25240b
@ -1,4 +1,4 @@
|
|||||||
page {
|
page {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
}
|
}
|
||||||
@ -1,4 +1,6 @@
|
|||||||
{
|
{
|
||||||
"component": true,
|
"component": true,
|
||||||
"usingComponents": {}
|
"usingComponents": {
|
||||||
|
"wemark": "../wemark/wemark"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
<wxs src="../../tools.wxs" module="tools" />
|
||||||
<view wx:if="{{chatList.length == 0}}" style="text-align:center;color: rgb(180, 187, 196);font-size: 28rpx;">输入问题开始和New Bing聊天吧~</view>
|
<view wx:if="{{chatList.length == 0}}" style="text-align:center;color: rgb(180, 187, 196);font-size: 28rpx;">输入问题开始和New Bing聊天吧~</view>
|
||||||
<scroll-view class="chat" scroll-y="true" scroll-into-view="{{scrollId}}" style="height:{{systemInfo.windowHeight - 70}}px;" enable-back-to-top="{{true}}" scroll-anchoring="{{true}}" enhanced="{{true}}" enable-flex="{{true}}">
|
<scroll-view class="chat" scroll-y="true" scroll-into-view="{{scrollId}}" style="height:{{systemInfo.windowHeight - 70}}px;" enable-back-to-top="{{true}}" scroll-anchoring="{{true}}" enhanced="{{true}}" enable-flex="{{true}}">
|
||||||
<view wx:for="{{chatList}}" wx:key="index" wx:for-item="item" id="{{'item'+index}}">
|
<view wx:for="{{chatList}}" wx:key="index" wx:for-item="item" id="{{'item'+index}}">
|
||||||
@ -5,7 +6,7 @@
|
|||||||
<image class="avatar" src="{{item.avatarUrl}}" style="display: flex;" bindlongpress="clearChat" data-index="{{index}}"></image>
|
<image class="avatar" src="{{item.avatarUrl}}" style="display: flex;" bindlongpress="clearChat" data-index="{{index}}"></image>
|
||||||
<view class="chat-box" style="margin-left: 20rpx;">
|
<view class="chat-box" style="margin-left: 20rpx;">
|
||||||
<text class="dt">{{item.dt}}</text>
|
<text class="dt">{{item.dt}}</text>
|
||||||
<view class="content bg-white" bindlongpress="copyContent" data-index="{{index}}"><view class="{{item.blink ? 'blinking': ''}}">{{item.originContent}}</view></view>
|
<view class="content bg-white" bindlongpress="copyContent" data-index="{{index}}"><view class="{{item.blink ? 'blinking': ''}}"><wemark md="{{item.originContent}}" link="{{false}}" highlight type="wemark" wx:if="{{tools.indexOf(item.originContent, '```') || tools.indexOf(item.originContent, '**')}}"></wemark><view wx:else>{{item.originContent}}</view></view></view>
|
||||||
<view class="suggest" >
|
<view class="suggest" >
|
||||||
<text class="suggest-item" bindtap="suggestSubmit" data-suggest="{{suggest}}" wx:for="{{item.suggests}}" wx:for-item="suggest">{{suggest}}</text>
|
<text class="suggest-item" bindtap="suggestSubmit" data-suggest="{{suggest}}" wx:for="{{item.suggests}}" wx:for-item="suggest">{{suggest}}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
262
bingchat/components/wemark/parser.js
Normal file
262
bingchat/components/wemark/parser.js
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
var Remarkable = require('./remarkable');
|
||||||
|
var parser = new Remarkable({
|
||||||
|
html: true
|
||||||
|
});
|
||||||
|
var prism = require('./prism');
|
||||||
|
|
||||||
|
function parse(md, options){
|
||||||
|
if(!options) options = {};
|
||||||
|
var tokens = parser.parse(md, {});
|
||||||
|
|
||||||
|
// markdwon渲染列表
|
||||||
|
var renderList = [];
|
||||||
|
|
||||||
|
var env = [];
|
||||||
|
// 记录当前list深度
|
||||||
|
var listLevel = 0;
|
||||||
|
// 记录第N级ol的顺序
|
||||||
|
var orderNum = [0, 0];
|
||||||
|
var tmp;
|
||||||
|
|
||||||
|
// 获取inline内容
|
||||||
|
var getInlineContent = function(inlineToken){
|
||||||
|
var ret = [];
|
||||||
|
var env;
|
||||||
|
var tokenData = {};
|
||||||
|
|
||||||
|
if(inlineToken.type === 'htmlblock'){
|
||||||
|
// 匹配video
|
||||||
|
// 兼容video[src]和video > source[src]
|
||||||
|
var videoRegExp = /<video.*?src\s*=\s*['"]*([^\s^'^"]+).*?(poster\s*=\s*['"]*([^\s^'^"]+).*?)?(?:\/\s*>|<\/video>)/g;
|
||||||
|
|
||||||
|
var match;
|
||||||
|
var html = inlineToken.content.replace(/\n/g, '');
|
||||||
|
while(match = videoRegExp.exec(html)){
|
||||||
|
if(match[1]){
|
||||||
|
var retParam = {
|
||||||
|
type: 'video',
|
||||||
|
src: match[1]
|
||||||
|
};
|
||||||
|
|
||||||
|
if(match[3]) {
|
||||||
|
retParam.poster = match[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.push(retParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
// console.log(inlineToken);
|
||||||
|
inlineToken.children && inlineToken.children.forEach(function(token, index){
|
||||||
|
if(['text', 'code'].indexOf(token.type) > -1){
|
||||||
|
ret.push({
|
||||||
|
type: env || token.type,
|
||||||
|
content: token.content,
|
||||||
|
data: tokenData
|
||||||
|
});
|
||||||
|
env = '';
|
||||||
|
tokenData = {};
|
||||||
|
}else if(token.type === 'del_open'){
|
||||||
|
env = 'deleted';
|
||||||
|
}else if (token.type === 'softbreak') {
|
||||||
|
// todo:处理li的问题
|
||||||
|
/* ret.push({
|
||||||
|
type: 'text',
|
||||||
|
content: ' '
|
||||||
|
}); */
|
||||||
|
}else if (token.type === 'hardbreak') {
|
||||||
|
ret.push({
|
||||||
|
type: 'text',
|
||||||
|
content: '\n'
|
||||||
|
});
|
||||||
|
}else if(token.type === 'strong_open'){
|
||||||
|
if(env === 'em') {
|
||||||
|
env = 'strong_em';
|
||||||
|
}else {
|
||||||
|
env = 'strong';
|
||||||
|
}
|
||||||
|
}else if (token.type === 'em_open') {
|
||||||
|
if(env === 'strong') {
|
||||||
|
env = 'strong_em';
|
||||||
|
}else {
|
||||||
|
env = 'em';
|
||||||
|
}
|
||||||
|
}else if (token.type === 'link_open') {
|
||||||
|
if(options.link){
|
||||||
|
env = 'link';
|
||||||
|
tokenData = {
|
||||||
|
href: token.href
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}else if(token.type === 'image'){
|
||||||
|
ret.push({
|
||||||
|
type: token.type,
|
||||||
|
src: token.src
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
var getBlockContent = function(blockToken, index, firstInLi){
|
||||||
|
|
||||||
|
if(blockToken.type === 'htmlblock'){
|
||||||
|
return getInlineContent(blockToken);
|
||||||
|
}else if(blockToken.type === 'heading_open'){
|
||||||
|
return {
|
||||||
|
type: 'h' + blockToken.hLevel,
|
||||||
|
content: getInlineContent(tokens[index+1])
|
||||||
|
};
|
||||||
|
}else if(blockToken.type === 'paragraph_open'){
|
||||||
|
// var type = 'p';
|
||||||
|
var prefix = '';
|
||||||
|
if(env.length){
|
||||||
|
prefix = env.join('_') + '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
var content = getInlineContent(tokens[index+1]);
|
||||||
|
|
||||||
|
// 处理ol前的数字
|
||||||
|
if(env[env.length - 1] === 'li' && env[env.length - 2] === 'ol'){
|
||||||
|
let prefix = ' ';
|
||||||
|
if (firstInLi){
|
||||||
|
prefix = orderNum[listLevel - 1] + '. ';
|
||||||
|
}
|
||||||
|
content.unshift({
|
||||||
|
type:'text',
|
||||||
|
content: prefix
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: prefix + 'p',
|
||||||
|
content: content
|
||||||
|
};
|
||||||
|
}else if(blockToken.type === 'fence' || blockToken.type === 'code'){
|
||||||
|
content = blockToken.content;
|
||||||
|
var highlight = false;
|
||||||
|
if(options.highlight && blockToken.params && prism.languages[blockToken.params]){
|
||||||
|
content = prism.tokenize(content, prism.languages[blockToken.params]);
|
||||||
|
highlight = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const flattenTokens = (tokensArr, result = [], parentType = '') => {
|
||||||
|
if (Array.isArray(tokensArr)) {
|
||||||
|
tokensArr.forEach(el => {
|
||||||
|
if (typeof el === 'object') {
|
||||||
|
// el.type = parentType + ' wemark_inline_code_' + el.type;
|
||||||
|
if(Array.isArray(el.content)){
|
||||||
|
flattenTokens(el.content, result, el.type);
|
||||||
|
}else{
|
||||||
|
flattenTokens(el, result, el.type);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const obj = {};
|
||||||
|
obj.type = parentType || 'text';
|
||||||
|
// obj.type = parentType + ' wemark_inline_code_';
|
||||||
|
obj.content = el;
|
||||||
|
result.push(obj);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
result.push(tokensArr)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(highlight){
|
||||||
|
var tokenList = content;
|
||||||
|
content = [];
|
||||||
|
tokenList.forEach((token) => {
|
||||||
|
// let contentListForToken = [];
|
||||||
|
if(Array.isArray(token.content)){
|
||||||
|
content = content.concat(flattenTokens(token.content, [], ''));
|
||||||
|
}else{
|
||||||
|
content.push(token);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// flatten nested tokens in html
|
||||||
|
// if (blockToken.params === 'html') {
|
||||||
|
// content = flattenTokens(content)
|
||||||
|
// }
|
||||||
|
// console.log(content);
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'code',
|
||||||
|
highlight: highlight,
|
||||||
|
content: content
|
||||||
|
};
|
||||||
|
}else if(blockToken.type === 'bullet_list_open'){
|
||||||
|
env.push('ul');
|
||||||
|
listLevel++;
|
||||||
|
}else if(blockToken.type === 'ordered_list_open'){
|
||||||
|
env.push('ol');
|
||||||
|
listLevel++;
|
||||||
|
}else if(blockToken.type === 'list_item_open'){
|
||||||
|
env.push('li');
|
||||||
|
if(env[env.length - 2] === 'ol' ){
|
||||||
|
orderNum[listLevel - 1]++;
|
||||||
|
}
|
||||||
|
}else if(blockToken.type === 'list_item_close'){
|
||||||
|
env.pop();
|
||||||
|
}else if(blockToken.type === 'bullet_list_close'){
|
||||||
|
env.pop();
|
||||||
|
listLevel--;
|
||||||
|
}else if(blockToken.type === 'ordered_list_close'){
|
||||||
|
env.pop();
|
||||||
|
listLevel--;
|
||||||
|
orderNum[listLevel] = 0;
|
||||||
|
}else if(blockToken.type === 'blockquote_open'){
|
||||||
|
env.push('blockquote');
|
||||||
|
}else if(blockToken.type === 'blockquote_close'){
|
||||||
|
env.pop();
|
||||||
|
}else if(blockToken.type === 'tr_open'){
|
||||||
|
tmp = {
|
||||||
|
type: 'table_tr',
|
||||||
|
content:[]
|
||||||
|
};
|
||||||
|
return tmp;
|
||||||
|
}else if(blockToken.type === 'th_open'){
|
||||||
|
tmp.content.push({
|
||||||
|
type: 'table_th',
|
||||||
|
content: getInlineContent(tokens[index+1]).map(function(inline){return inline.content;}).join('')
|
||||||
|
});
|
||||||
|
}else if(blockToken.type === 'td_open'){
|
||||||
|
tmp.content.push({
|
||||||
|
type: 'table_td',
|
||||||
|
content: getInlineContent(tokens[index+1]).map(function(inline){return inline.content;}).join('')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
tokens.forEach(function(token, index){
|
||||||
|
// 标记是否刚进入li,如果刚进入,可以加符号/序号,否则不加
|
||||||
|
var firstInLi = false;
|
||||||
|
if(token.type === 'paragraph_open' && tokens[index-1] && tokens[index-1].type === 'list_item_open'){
|
||||||
|
firstInLi = true;
|
||||||
|
}
|
||||||
|
var blockContent = getBlockContent(token, index, firstInLi);
|
||||||
|
if(!blockContent) return;
|
||||||
|
if(!Array.isArray(blockContent)){
|
||||||
|
blockContent = [blockContent];
|
||||||
|
}
|
||||||
|
blockContent.forEach(function(block){
|
||||||
|
if(Array.isArray(block.content)){
|
||||||
|
block.isArray = true;
|
||||||
|
}else{
|
||||||
|
block.isArray = false;
|
||||||
|
}
|
||||||
|
renderList.push(block);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return renderList;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
parse: parse
|
||||||
|
};
|
||||||
16
bingchat/components/wemark/prism.js
Normal file
16
bingchat/components/wemark/prism.js
Normal file
File diff suppressed because one or more lines are too long
81
bingchat/components/wemark/prism.wxss
Normal file
81
bingchat/components/wemark/prism.wxss
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* PrismJS 1.15.0
|
||||||
|
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+basic+markup-templating+go+java+json+php+sql+python+typescript */
|
||||||
|
/**
|
||||||
|
* prism.js default theme for JavaScript, CSS and HTML
|
||||||
|
* Based on dabblet (http://dabblet.com)
|
||||||
|
* @author Lea Verou
|
||||||
|
*/
|
||||||
|
|
||||||
|
.wemark_inline_code_comment,
|
||||||
|
.wemark_inline_code_prolog,
|
||||||
|
.wemark_inline_code_doctype,
|
||||||
|
.wemark_inline_code_cdata {
|
||||||
|
color: slategray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wemark_inline_code_punctuation,
|
||||||
|
.wemark_inline_code_interpolation-punctuation {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wemark_inline_code_namespace {
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wemark_inline_code_property,
|
||||||
|
.wemark_inline_code_tag,
|
||||||
|
.wemark_inline_code_boolean,
|
||||||
|
.wemark_inline_code_number,
|
||||||
|
.wemark_inline_code_constant,
|
||||||
|
.wemark_inline_code_symbol,
|
||||||
|
.wemark_inline_code_deleted {
|
||||||
|
color: #905;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wemark_inline_code_selector,
|
||||||
|
.wemark_inline_code_attr-name,
|
||||||
|
.wemark_inline_code_string,
|
||||||
|
.wemark_inline_code_char,
|
||||||
|
.wemark_inline_code_builtin,
|
||||||
|
.wemark_inline_code_inserted {
|
||||||
|
color: #690;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wemark_inline_code_operator,
|
||||||
|
.wemark_inline_code_entity,
|
||||||
|
.wemark_inline_code_url,
|
||||||
|
.language-css .wemark_inline_code_string,
|
||||||
|
.style .wemark_inline_code_string {
|
||||||
|
color: #9a6e3a;
|
||||||
|
background: hsla(0, 0%, 100%, .5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wemark_inline_code_atrule,
|
||||||
|
.wemark_inline_code_attr-value,
|
||||||
|
.wemark_inline_code_keyword {
|
||||||
|
color: #07a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wemark_inline_code_function,
|
||||||
|
.wemark_inline_code_class-name {
|
||||||
|
color: #DD4A68;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wemark_inline_code_regex,
|
||||||
|
.wemark_inline_code_important,
|
||||||
|
.wemark_inline_code_variable,
|
||||||
|
.wemark_inline_code_interpolation {
|
||||||
|
color: #e90;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wemark_inline_code_important,
|
||||||
|
.wemark_inline_code_bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.wemark_inline_code_italic {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wemark_inline_code_entity {
|
||||||
|
cursor: help;
|
||||||
|
}
|
||||||
4
bingchat/components/wemark/remarkable.js
Normal file
4
bingchat/components/wemark/remarkable.js
Normal file
File diff suppressed because one or more lines are too long
155
bingchat/components/wemark/richtext.js
Normal file
155
bingchat/components/wemark/richtext.js
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
exports.getRichTextNodes = function(parsedData){
|
||||||
|
|
||||||
|
var richTextNodes = [];
|
||||||
|
|
||||||
|
var getNodeName = (function(){
|
||||||
|
var stack = [];
|
||||||
|
return function(type, nodeType = 'inline'){
|
||||||
|
if(type === 'table_tr'){
|
||||||
|
return 'tr';
|
||||||
|
}else{
|
||||||
|
// 有多级的,block返回第一级,inline返回最后一级
|
||||||
|
if(type.indexOf('_') > -1){
|
||||||
|
var typePart = type.split('_');
|
||||||
|
if(nodeType === 'inline'){
|
||||||
|
return typePart.pop();
|
||||||
|
}else{
|
||||||
|
return typePart[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
var getBlockNode = function(node){
|
||||||
|
var nodeType = node.type;
|
||||||
|
// console.log('nodeType:', nodeType);
|
||||||
|
var richTextNode = {
|
||||||
|
name: getNodeName(nodeType, 'inline'),
|
||||||
|
attrs: {
|
||||||
|
class: 'wemark_block_' + nodeType
|
||||||
|
},
|
||||||
|
children: []
|
||||||
|
};
|
||||||
|
if(node.isArray){
|
||||||
|
node.content.forEach((childNode) => {
|
||||||
|
if(['text','code','strong','deleted','em'].indexOf(childNode.type) > -1){
|
||||||
|
richTextNode.children.push({
|
||||||
|
name: 'span',
|
||||||
|
attrs: {
|
||||||
|
class: 'wemark_inline_' + childNode.type
|
||||||
|
},
|
||||||
|
children:[{
|
||||||
|
type: 'text',
|
||||||
|
text: childNode.content
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}else if(node.highlight){
|
||||||
|
if(typeof childNode === 'string'){
|
||||||
|
richTextNode.children.push({
|
||||||
|
name: 'span',
|
||||||
|
attrs: {
|
||||||
|
class: 'wemark_inline_code_text'
|
||||||
|
},
|
||||||
|
children: [{
|
||||||
|
type: 'text',
|
||||||
|
text: childNode
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
richTextNode.children.push({
|
||||||
|
name: 'span',
|
||||||
|
attrs: {
|
||||||
|
class: 'wemark_inline_code_' + childNode.type
|
||||||
|
},
|
||||||
|
children: [{
|
||||||
|
type: 'text',
|
||||||
|
text: childNode.content
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}else if(childNode.type === 'link'){
|
||||||
|
richTextNode.children.push({
|
||||||
|
name: 'a',
|
||||||
|
attrs: {
|
||||||
|
class: 'wemark_inline_link',
|
||||||
|
href: childNode.data.href
|
||||||
|
},
|
||||||
|
children:[{
|
||||||
|
type: 'text',
|
||||||
|
text: childNode.content
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}else if(childNode.type === 'image'){
|
||||||
|
richTextNode.children.push({
|
||||||
|
name: 'img',
|
||||||
|
attrs: {
|
||||||
|
mode: 'widthFix',
|
||||||
|
class: 'wemark_inline_image',
|
||||||
|
src: childNode.src
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}else if(childNode.type === 'table_th'){
|
||||||
|
richTextNode.children.push({
|
||||||
|
name: 'th',
|
||||||
|
attrs: {
|
||||||
|
class: 'wemark_inline_table_th',
|
||||||
|
},
|
||||||
|
children: [{
|
||||||
|
type: 'text',
|
||||||
|
text: childNode.content
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}else if(childNode.type === 'table_td'){
|
||||||
|
richTextNode.children.push({
|
||||||
|
name: 'td',
|
||||||
|
attrs: {
|
||||||
|
class: 'wemark_inline_table_td',
|
||||||
|
},
|
||||||
|
children: [{
|
||||||
|
type: 'text',
|
||||||
|
text: childNode.content
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}else if(node.type === 'code'){
|
||||||
|
|
||||||
|
richTextNode.children = [{
|
||||||
|
name: 'code',
|
||||||
|
children: [{
|
||||||
|
type: 'text',
|
||||||
|
text: node.content
|
||||||
|
}]
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
return richTextNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i=0; i<parsedData.length;i++){
|
||||||
|
var node = parsedData[i];
|
||||||
|
if(node.type === 'table_tr'){
|
||||||
|
var tableNode = {
|
||||||
|
name: 'table',
|
||||||
|
attrs: {
|
||||||
|
class: 'wemark_block_table'
|
||||||
|
},
|
||||||
|
children: []
|
||||||
|
};
|
||||||
|
var tmpNode = node;
|
||||||
|
while(tmpNode.type === 'table_tr'){
|
||||||
|
tableNode.children.push(getBlockNode(tmpNode));
|
||||||
|
tmpNode = parsedData[++i];
|
||||||
|
}
|
||||||
|
richTextNodes.push(tableNode);
|
||||||
|
}else{
|
||||||
|
richTextNodes.push(getBlockNode(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return richTextNodes;
|
||||||
|
|
||||||
|
}
|
||||||
71
bingchat/components/wemark/wemark.js
Normal file
71
bingchat/components/wemark/wemark.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
const parser = require('./parser');
|
||||||
|
const getRichTextNodes = require('./richtext').getRichTextNodes;
|
||||||
|
|
||||||
|
Component({
|
||||||
|
properties: {
|
||||||
|
md: {
|
||||||
|
type: String,
|
||||||
|
value: '',
|
||||||
|
observer(){
|
||||||
|
this.parseMd();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
value: 'wemark'
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
highlight: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
parsedData: {},
|
||||||
|
richTextNodes: []
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
parseMd(){
|
||||||
|
if (this.data.md) {
|
||||||
|
var parsedData = parser.parse(this.data.md, {
|
||||||
|
link: this.data.link,
|
||||||
|
highlight: this.data.highlight
|
||||||
|
});
|
||||||
|
// console.log('parsedData:', parsedData);
|
||||||
|
if(this.data.type === 'wemark'){
|
||||||
|
this.setData({
|
||||||
|
parsedData
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
// var inTable = false;
|
||||||
|
var richTextNodes = getRichTextNodes(parsedData);
|
||||||
|
|
||||||
|
// console.log('richTextNodes:', richTextNodes);
|
||||||
|
|
||||||
|
this.setData({
|
||||||
|
richTextNodes
|
||||||
|
});
|
||||||
|
|
||||||
|
/* // 分批更新
|
||||||
|
var update = {};
|
||||||
|
var batchLength = 1000;
|
||||||
|
console.log(batchLength);
|
||||||
|
for(var i=0; i<richTextNodes.length; i++){
|
||||||
|
update['richTextNodes.' + i] = richTextNodes[i];
|
||||||
|
if(i%batchLength === batchLength - 1){
|
||||||
|
console.log(update);
|
||||||
|
this.setData(update);
|
||||||
|
update = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.setData(update);
|
||||||
|
update = {}; */
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
3
bingchat/components/wemark/wemark.json
Normal file
3
bingchat/components/wemark/wemark.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"component": true
|
||||||
|
}
|
||||||
19
bingchat/components/wemark/wemark.wxml
Normal file
19
bingchat/components/wemark/wemark.wxml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<view class="wemark_wrapper">
|
||||||
|
<block wx:if="{{type === 'wemark'}}" wx:for="{{parsedData}}" wx:key="blockIndex" wx:for-index="blockIndex" wx:for-item="renderBlock">
|
||||||
|
<view class="wemark_block_{{renderBlock.type}}">
|
||||||
|
<block wx:if="{{renderBlock.isArray}}" wx:for="{{renderBlock.content}}" wx:key="inlineIndex" wx:for-index="inlineIndex" wx:for-item="renderInline">
|
||||||
|
<text class="wemark_inline_{{renderInline.type}}" wx:if="{{renderInline.type === 'text' || renderInline.type === 'code' || renderInline.type === 'strong' || renderInline.type === 'strong_em' || renderInline.type === 'deleted' || renderInline.type === 'em' || renderInline.type === 'table_th' || renderInline.type === 'table_td'}}">{{renderInline.content}}</text>
|
||||||
|
<!-- 代码高亮 -->
|
||||||
|
<text class="wemark_inline_code_{{renderInline.type}}" wx:if="{{renderInline.type&&renderBlock.highlight}}">{{renderInline.content}}</text>
|
||||||
|
<text class="wemark_inline_code_text" wx:if="{{!renderInline.type}}">{{renderInline}}</text>
|
||||||
|
<navigator class="wemark_inline_link" url="{{renderInline.data.href}}" wx:if="{{renderInline.type === 'link'}}">{{renderInline.content}}</navigator>
|
||||||
|
<image mode="widthFix" class="wemark_inline_image" src="{{renderInline.src}}" wx:if="{{renderInline.type === 'image'}}"></image>
|
||||||
|
</block>
|
||||||
|
<block wx:if="{{!renderBlock.isArray}}">
|
||||||
|
<view wx:if="{{renderBlock.type === 'code'}}">{{renderBlock.content}}</view>
|
||||||
|
<video wx:if="{{renderBlock.type == 'video'}}" class="wemark_block_video" src="{{renderBlock.src}}" poster="{{renderBlock.poster}}" controls></video>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<rich-text class="wemark_wrapper_richtext" wx:if="{{type === 'rich-text'}}" nodes="{{richTextNodes}}"></rich-text>
|
||||||
|
</view>
|
||||||
148
bingchat/components/wemark/wemark.wxss
Normal file
148
bingchat/components/wemark/wemark.wxss
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
@import "prism.wxss";
|
||||||
|
|
||||||
|
.wemark_wrapper{
|
||||||
|
/* margin:10px 0;
|
||||||
|
font-size:32rpx;
|
||||||
|
line-height: 1.8em; */
|
||||||
|
}
|
||||||
|
.wemark_block_h1{
|
||||||
|
font-size:40rpx;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom:1em;
|
||||||
|
}
|
||||||
|
.wemark_block_h2{
|
||||||
|
font-size:40rpx;
|
||||||
|
padding-bottom:.5em;
|
||||||
|
margin-top:1em;
|
||||||
|
margin-bottom:1em;
|
||||||
|
border-bottom:1px solid #f8f8f8;
|
||||||
|
}
|
||||||
|
.wemark_block_h3{
|
||||||
|
font-size:36rpx;
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
.wemark_block_h4,
|
||||||
|
.wemark_block_h5,
|
||||||
|
.wemark_block_h6{
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
.wemark_block_p{
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
.wemark_block_video{
|
||||||
|
margin-top:1em;
|
||||||
|
margin-bottom:1em;
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
.wemark_block_blockquote_p{
|
||||||
|
margin-top:1em;
|
||||||
|
margin-bottom:1em;
|
||||||
|
padding:10px 0 10px 1em;
|
||||||
|
font-size:28rpx;
|
||||||
|
background:#f8f8f8;
|
||||||
|
border-left:5px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
.wemark_block_ul_li_p::before{
|
||||||
|
content:'• ';
|
||||||
|
}
|
||||||
|
.wemark_block_ul_li_ul_li_p::before,
|
||||||
|
.wemark_block_ol_li_ul_li_p::before{
|
||||||
|
content:'◦ ';
|
||||||
|
}
|
||||||
|
.wemark_block_ul_li_ul_li_p,
|
||||||
|
.wemark_block_ul_li_ol_li_p,
|
||||||
|
.wemark_block_ol_li_ul_li_p,
|
||||||
|
.wemark_block_ol_li_ol_li_p{
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
.wemark_block_ul_li_p:last{
|
||||||
|
margin-bottom:1em;
|
||||||
|
}
|
||||||
|
.wemark_block_code{
|
||||||
|
display: block;
|
||||||
|
padding:10px;
|
||||||
|
font-size:28rpx;
|
||||||
|
line-height: 1.5em;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
white-space: pre;
|
||||||
|
overflow: auto;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
}
|
||||||
|
.wemark_block_table{
|
||||||
|
width: 100%;
|
||||||
|
border-spacing: 0;
|
||||||
|
border-collapse: collapse;
|
||||||
|
/* border-left: 1px solid #e0e0e0; */
|
||||||
|
/* border-top: 1px solid #e0e0e0; */
|
||||||
|
}
|
||||||
|
.wemark_block_table_tr{
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.wemark_wrapper_richtext .wemark_block_table_tr{
|
||||||
|
display: table-row;
|
||||||
|
}
|
||||||
|
.wemark_inline_table_th,
|
||||||
|
.wemark_inline_table_td{
|
||||||
|
flex:1;
|
||||||
|
padding:5px;
|
||||||
|
font-size:28rpx;
|
||||||
|
word-break: break-all;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
.wemark_wrapper_richtext .wemark_inline_table_th,
|
||||||
|
.wemark_wrapper_richtext .wemark_inline_table_td{
|
||||||
|
display: table-cell;
|
||||||
|
/* background:red;
|
||||||
|
border-right:1px solid #e0e0e0;
|
||||||
|
border-bottom:1px solid #e0e0e0; */
|
||||||
|
}
|
||||||
|
.wemark_inline_table_td:last{
|
||||||
|
/* border-top:1px solid #e0e0e0; */
|
||||||
|
}
|
||||||
|
.wemark_inline_table_th{
|
||||||
|
background:#f8f8f8;
|
||||||
|
/* border-top:1px solid #e0e0e0; */
|
||||||
|
}
|
||||||
|
.wemark_inline_strong{
|
||||||
|
font-weight: bold;
|
||||||
|
padding:0 5px;
|
||||||
|
word-wrap:break-word;
|
||||||
|
}
|
||||||
|
.wemark_inline_em{
|
||||||
|
font-style: italic;
|
||||||
|
padding:0 5px;
|
||||||
|
word-wrap:break-word;
|
||||||
|
}
|
||||||
|
.wemark_inline_strong_em{
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: bold;
|
||||||
|
padding:0 5px;
|
||||||
|
word-wrap:break-word;
|
||||||
|
}
|
||||||
|
.wemark_inline_deleted{
|
||||||
|
text-decoration: line-through;
|
||||||
|
padding:0 5px;
|
||||||
|
word-wrap:break-word;
|
||||||
|
}
|
||||||
|
.wemark_inline_image{
|
||||||
|
width:100%;
|
||||||
|
height:auto;
|
||||||
|
}
|
||||||
|
.wemark_inline_code{
|
||||||
|
background-color: #fff5f5;
|
||||||
|
padding: 3px;
|
||||||
|
word-wrap:break-word;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: #ff502c;
|
||||||
|
}
|
||||||
|
.wemark_inline_text{
|
||||||
|
word-wrap:break-word;
|
||||||
|
}
|
||||||
|
.wemark_inline_link{
|
||||||
|
display: inline;
|
||||||
|
color: blue;
|
||||||
|
word-wrap:break-word;
|
||||||
|
}
|
||||||
@ -48,7 +48,7 @@ Page({
|
|||||||
InputBlur(e) {
|
InputBlur(e) {
|
||||||
this.setData({
|
this.setData({
|
||||||
InputBottom: 24,
|
InputBottom: 24,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
processContent(content) {
|
processContent(content) {
|
||||||
return content.replace(/\\n/g, "\n");
|
return content.replace(/\\n/g, "\n");
|
||||||
|
|||||||
8
bingchat/tools.wxs
Normal file
8
bingchat/tools.wxs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
function indexOf(s, value) {
|
||||||
|
if (s.indexOf(value) < 0) {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports.indexOf = indexOf
|
||||||
Loading…
Reference in New Issue
Block a user