329 lines
9.0 KiB
TypeScript
329 lines
9.0 KiB
TypeScript
import { Component } from 'react';
|
||
import { Input } from 'antd';
|
||
// import Taro from "@tarojs/taro";
|
||
// import {
|
||
// View,
|
||
// Text,
|
||
// Image,
|
||
// Button,
|
||
// Input,
|
||
// Editor,
|
||
// Textarea,
|
||
// } from "@tarojs/components";
|
||
import './APP.scss';
|
||
// import { AtTabBar } from "taro-ui";
|
||
import React, { useCallback, useEffect, useState } from 'react';
|
||
// import { AtGrid } from "taro-ui";
|
||
// import { Swiper, SwiperItem } from "@tarojs/components";
|
||
// import { AtCard } from "taro-ui";
|
||
// import { AtImagePicker } from "taro-ui";
|
||
// import { AtButton } from "taro-ui";
|
||
// import { AtSearchBar } from "taro-ui";
|
||
// import { Picker } from "@tarojs/components";
|
||
// import { AtList, AtListItem } from "taro-ui";
|
||
// import { AtNavBar } from "taro-ui";
|
||
// import { AtModal, AtModalHeader, AtModalContent, AtModalAction } from "taro-ui";
|
||
// import { AtToast } from "taro-ui";
|
||
// import { AtIcon } from "taro-ui";
|
||
import see from '../../images/see.png';
|
||
import group from '../../images/group.png';
|
||
import { marked } from 'marked';
|
||
// import _ from "lodash";
|
||
import OriginMark from './conpoments/OriginMark/index';
|
||
import TextArea from 'antd/es/input/TextArea';
|
||
|
||
// marked.use(`marked-code-jsx-renderer`);
|
||
// marked.use(`marked-extended-tables`);
|
||
|
||
// 
|
||
|
||
const markTextStr = `
|
||
## 标题
|
||
> 测试引用桔子的样子
|
||
随便测试普通的文本,要不要来个\`内敛\`的字符串
|
||
---
|
||
- 无序列表1
|
||
个人有看看
|
||
- 无序列表2
|
||
- [ ] 任务列表
|
||
- [x] 完成任务
|
||
1. 测试111
|
||
恶魔女哪里的请
|
||
2. 你好啊
|
||
3. iefw4t43t43t
|
||
永远不要相信一个
|
||
---
|
||
相信我
|
||
`;
|
||
|
||
let tablecellArr = [];
|
||
let tableRowArr = [];
|
||
let maxLengthCell = null;
|
||
let bodydata = null;
|
||
let headerdata = null;
|
||
let maxWidths = null;
|
||
|
||
marked.setOptions({
|
||
breaks: true, // 是否回车换行
|
||
gfm: true, //使用经批准的 GitHub Flavored Markdown (GFM) 规范
|
||
// pedantic: true, //严格模式
|
||
// highlight(code:any, lang:any) {
|
||
// // 语法高亮
|
||
// let val = code;
|
||
// if (lang) {
|
||
// val = hljs.highlight(lang, code).value;
|
||
// } else {
|
||
// val = hljs.highlightAuto(code).value;
|
||
// }
|
||
// return val;
|
||
// },
|
||
});
|
||
// 符号
|
||
// 🔥❓👉
|
||
// 0️⃣1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣🔟
|
||
// ©️⭐🔍〰️➖
|
||
|
||
// 修改 marked 的解析规则
|
||
const block = marked.Lexer.rules.block;
|
||
// block.gfm.hr = /^( *[-*_]){3,} *(?:\n+|$)/;
|
||
// 自定义水平线规则,确保它们在文档中被正确识别
|
||
block.gfm.hr =
|
||
/^ {0,3}(?:(?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
|
||
|
||
const renderer = new marked.Renderer();
|
||
// const originRenderer = _.cloneDeep(renderer);
|
||
|
||
// 图片调整300px
|
||
renderer.image = function (href, title, text) {
|
||
// console.log("href, title, text", href, title, text);
|
||
// <div class="desc">${text}</div>
|
||
return `<img width="300px" src="${href}" alt="${text}"/>`;
|
||
};
|
||
|
||
// let listSinbal="▫️ "
|
||
let listSinbal = '🔸';
|
||
|
||
// 有序列表
|
||
renderer.list = function (body, ordered, start) {
|
||
// console.log("body,ordered, start", body, ordered, start);
|
||
const type = ordered ? 'ol' : 'ul';
|
||
// console.log("type===>", type);
|
||
const startatt = ordered && start !== 1 ? ' start="' + start + '"' : '';
|
||
// 正则取值
|
||
// const regex = /▫️\s*(.*?)<br\/?>/g;
|
||
const regex = /([^<]*)<br\/?>/g;
|
||
const input = body;
|
||
const matches = [...input.matchAll(regex)];
|
||
const texts = matches.map((match) => match[1]);
|
||
// 不含▫️的元素数量
|
||
// const diffcCount=texts.length-texts.filter(item => item.includes('▫️')).length;
|
||
// console.log("texts===>", texts); // 输出: ["测试111", "测试222", "if"]
|
||
const newArray = texts.filter((item) => item.includes(listSinbal));
|
||
// 0️⃣',
|
||
const numbers = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟'];
|
||
const string = texts
|
||
.map((value, index) => {
|
||
// console.log("value, index==>", value, index);
|
||
// ${ value.indexOf("▫️ ") === -1 ? '<br/><span>111</sapn>' : ""}
|
||
return value.indexOf(listSinbal) !== -1
|
||
? `<div>${
|
||
type === 'ol' ? numbers[newArray.indexOf(value)] : listSinbal
|
||
}${value.replace(listSinbal, '')} </div>`
|
||
: `<div style="white-space:pre;">\t${value}</div>`;
|
||
})
|
||
.join('');
|
||
// return `1️⃣`
|
||
// console.log("string===>", string);
|
||
|
||
return `${string}`;
|
||
};
|
||
|
||
// 无序列表 ▫️
|
||
renderer.listitem = function (text, task, checked) {
|
||
// return `<li>${text}</li>\n`;
|
||
return `${listSinbal}${text}<br/>`;
|
||
// return `➖${text}<br/>`;
|
||
};
|
||
|
||
// 任务列表
|
||
renderer.checkbox = function (checked) {
|
||
// ✅❌
|
||
return !!checked ? '✅' : '❌';
|
||
return (
|
||
'<input ' + (checked ? 'checked="" ' : '') + 'disabled="" type="checkbox">'
|
||
);
|
||
};
|
||
|
||
// 标题
|
||
renderer.heading = function (text, level, raw) {
|
||
console.log('text, level, raw', text, level, raw);
|
||
// ignore IDs
|
||
// return `📋<span>${text}</span> <br/>`;
|
||
return `🔥<span>${text}</span> <br/>`;
|
||
// return `<h${level}>🔥<span>${text}</span></h${level}>\n`;
|
||
// return `<h${level}>🔥${text}</h${level}><br/>`;
|
||
};
|
||
|
||
renderer.text = function (text) {
|
||
return text;
|
||
};
|
||
|
||
// 分隔符
|
||
renderer.hr = function () {
|
||
// return '<hr>\n';
|
||
// return '➖➖➖➖➖<br/>';
|
||
return '➖➖➖➖➖';
|
||
|
||
};
|
||
|
||
// 自定义分隔线解析规则
|
||
// marked.Lexer.rules.block.gfm.hr = /^(\*{3,}|-{3,}|_{3,})(?:\s*)$/;
|
||
// hr = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
|
||
|
||
// 内联样式,使用直角引号「」
|
||
renderer.codespan = function (text) {
|
||
// return `「${text}」`;
|
||
return `『${text}』`;
|
||
};
|
||
|
||
// 引用符号
|
||
renderer.blockquote = function (quote) {
|
||
// console.log("quote", quote);
|
||
let content = null;
|
||
var regex = /<p>(.*?)<\/p>/;
|
||
var str = quote;
|
||
var match = regex.exec(str);
|
||
if (match != null) {
|
||
content = match[1]; // 获取第一个捕获组的内容
|
||
// console.log(content);
|
||
}
|
||
// <pre></pre>
|
||
//
|
||
return `<span style="white-space:pre;" class="blockquote">\t 👉${content}</span><br/> `;
|
||
};
|
||
|
||
renderer.table = function (header, body) {
|
||
if (body) body = `<tbody>${body}</tbody>`;
|
||
|
||
return (
|
||
'📊 表格 📊<br/><table>\n' +
|
||
'<thead>\n' +
|
||
header +
|
||
'</thead>\n' +
|
||
body +
|
||
'</table>\n'
|
||
);
|
||
};
|
||
|
||
renderer.tablerow = function (content) {
|
||
return `<tr>\n${content}</tr>\n`;
|
||
};
|
||
|
||
renderer.tablecell = function (content, flags) {
|
||
const type = flags.header ? 'th' : 'td';
|
||
const tag = flags.align ? `<${type} align="${flags.align}">` : `<${type}>`;
|
||
return tag + `|${content}` + `</${type}>\n`;
|
||
};
|
||
|
||
function cleanUrl(href: any) {
|
||
try {
|
||
href = encodeURI(href).replace(/%25/g, '%');
|
||
} catch (e) {
|
||
return null;
|
||
}
|
||
return href;
|
||
}
|
||
|
||
renderer.link = function (href, title, text) {
|
||
const cleanHref = cleanUrl(href);
|
||
if (cleanHref === null) {
|
||
return text;
|
||
}
|
||
href = cleanHref;
|
||
let out = '<a href="' + href + '"';
|
||
if (title) {
|
||
out += ' title="' + title + '"';
|
||
}
|
||
out += '>' + `🌐` + text + '</a>';
|
||
// out += ">" +`🌐`+ text + "</a>"+`(${href})`;
|
||
|
||
return out;
|
||
};
|
||
|
||
renderer.paragraph = function (text) {
|
||
return `<p>${text}</p>\n`;
|
||
// return `<p>${text}</p>`;
|
||
|
||
};
|
||
renderer.br = function () {
|
||
return '<br>';
|
||
};
|
||
renderer.html = function (html, block) {
|
||
return html;
|
||
};
|
||
|
||
// 使用拓展
|
||
marked.use({ renderer });
|
||
|
||
// export default class Index extends Component {
|
||
const Index = () => {
|
||
const [inputValue, setinputValue] = useState('');
|
||
const [markText, setmarkText] = useState(``);
|
||
|
||
const [oldmarkText, setoldmarkText] = useState(null);
|
||
const [currentRender, setcurrentRender] = useState(null);
|
||
const [markdownTable, setmarkdownTable] = useState();
|
||
const [tablecellArr, settablecellArr] = useState([]);
|
||
|
||
const onConfirm = (onConfirmtxt: any) => {
|
||
console.log('onConfirmtxt--->', onConfirmtxt.detail.value);
|
||
};
|
||
const onBlur = (onBlurtxt: any) => {
|
||
console.log('onBlurtxt--->', onBlurtxt.detail.value);
|
||
if (onBlurtxt.detail.value) {
|
||
setmarkText(onBlurtxt.detail.value);
|
||
}
|
||
};
|
||
const onInput = (onInputtxt: any) => {
|
||
console.log('onInputtxt--->', onInputtxt?.target?.value);
|
||
setinputValue(onInputtxt.target.value);
|
||
// console.log('inputValue',inputValue)
|
||
let value = onInputtxt?.target?.value;
|
||
if (value) {
|
||
setmarkText(value);
|
||
}
|
||
};
|
||
|
||
useEffect(() => {}, []);
|
||
|
||
return (
|
||
<div className="index">
|
||
<div className="left">
|
||
<TextArea
|
||
// styles="background:#fff;width:100%;min-height:80px;padding:0 30rpx;"
|
||
className="TextArea"
|
||
autoFocus
|
||
allowClear
|
||
onChange={onInput}
|
||
showCount
|
||
/>
|
||
</div>
|
||
<div className="right">
|
||
<div className="rightHtml" dangerouslySetInnerHTML={{ __html: marked(markText) }}></div>
|
||
</div>
|
||
|
||
{/* {markText ? (
|
||
<div
|
||
className="right"
|
||
dangerouslySetInnerHTML={{ __html: marked(markText) }}
|
||
></div>
|
||
) : null} */}
|
||
{/* <div className="origin">
|
||
<OriginMark markText={markText} />
|
||
</div> */}
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default Index;
|