-
-
Notifications
You must be signed in to change notification settings - Fork 122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
语法树提供源码映射 #187
Comments
这个应该很难做到,Markdown 和 HTML 相互转换本身是存在一些损失的。 对于编辑器层面,需要在细节处理上进行改进,但是我不太确定你目前遇到的问题到底是哪方面的,能否举个具体的例子我们分析一下,谢谢。 |
当一个被git管理的文件,在使用编辑器打开后,编辑或者新增了一点内容,重新获取markdown保存时,整个文件都被格式化了,这个在多人协同时体验有点差,相关的issues: shuzijun/markdown-editor#69, 在类似编辑marktext也存在这个问题marktext/marktext#2189 |
我看了下目前markdown解析成语法树的代码,Node与markdown文本很难一一对应,很难做到还原成原格式。一个比较折中的方案就是,在目前语法树中,在顶级的块级节点上保存这一块内容的源码信息,在生成html和反解析html时,能够优先获取保存的源码信息,当然这个也需要编辑器能够在这一块内容发生更改事件时,直接移除携带的源码信息。 这样能够在一定程度上保留原格式。 |
编辑器需要有个 “Spin” 过程,将输入的 DOM 转换为 Markdown 然后再转换输出为 DOM,这个过程中需要格式化 Markdown,之前我们考虑过源码映射来实现,但是太复杂所以放弃了。 节点中保留的话可能会有问题,比如无法在 Markdown 文本上持久化,因为 Markdown 没这语法;对性能会有较大影响,因为需要解析这段元信息;就算以上两个问题解决了,还是无法解决解析上遇到的问题,比如对于输入能够打断行文本来生成块级节点的情况: foo
* 输入 所以,Lute 对于格式化这个问题估计是无解了,这是目前技术方案的局限。 |
对于这几个问题,可能和我理解的有点出入,我描述一下目前编辑器的整体流程和相关改动点
// 例如列表新增了一个,则清除
<h1 data-block="0"
class="vditor-ir__node"
id="ir-标题"
data-marker="#" source="# 标题">
<span class="vditor-ir__marker vditor-ir__marker--heading"
data-type="heading-marker"># </span>标题
</h1>
<p data-block="0" source="文本">文本</p>
<ul data-tight="true"
data-marker="*"
data-block="0"
>
<li data-marker="*">* 列表1</li>
<li data-marker="*">* 列表2</li>
<li data-marker="*">* 列表3</li>
</ul>
以上是对提到问题的解释,不知道是否正确?对于HTML上的修改事件可能会有问题,那块的代码没怎么理解。 |
|
去看了下SpinVditorDOM,过程是先把HTML解析成Markdown,然后再把Markdown转成HTML,如果输入的HTML是已经把编辑区域的source去掉了,整体流程应该是不受影响的。 这个方案有没有可行性? |
我没理解你的意思,去掉的话后面怎么在 spin 内部使用源 md 文本? |
这个又回到前面提出的问题了,这种情况前端 DOM 里不会产生块的: <p>
foo
*
</p> 如果要在前端区分的话,细节处理可能会比较多,如果这个能实现的话,实际上 spin 就没有必要了,直接在前端实现就好了 😂 |
我好像理解了,就是输入了新的文本,要追加到上一个节点,这时候HTML的内容是 <h1 data-block="0"
class="vditor-ir__node"
id="ir-标题"
data-marker="#" source="# 标题">
<span class="vditor-ir__marker vditor-ir__marker--heading"
data-type="heading-marker"># </span>标题
</h1>
<p data-block="0" source="文本">文本</p>
<ul data-tight="true"
data-marker="*"
data-block="0"
source="* 列表1\n* 列表2"
>
<li data-marker="*">* 列表1</li>
<li data-marker="*">* 列表2</li>
</ul>
<p>
* 列表3
</p> 在解析时做的事情是要把<p></p>的内容追加到上一个列表中。 不知道理解的对不对,我先按这种解释一下方案。
|
上面这个例子应该是生成两个列表,不是追加列表项。我意思就是类似的情况很多,不大可能在前端一一处理的,如果能一一处理的话,spin 就没有存在的必要了,也就是可以整体重构为新的方案了。 |
这些能不能在spin里处理哪? 😄是想能够尽量不破坏现有结构的情况下实现功能,还是已经有重构方案能够满足这个功能了? |
现在肯定是不能在 spin 中处理的,因为转换中间状态 Markdown 这个步骤没有对应的语法支持,会丢失元信息。如果要支持,需要使用能带属性的语法(比如 kramdown),这个工作量还是比较大的,编辑器前端也要做相应调整。 我们目前没有时间精力去改这个了,类似的方案可以参考思源笔记项目,它就是这样保留节点属性的。但是我个人还是建议你目前最好暂时不要在这个上面投入太多时间精力,因为如果只是为了解决全局格式化问题的话不太值得这么多投入,除非还有其他更有价值的需求可以一并解决。 |
👌还是等其他有价值的需求一起处理吧 |
以后看情况吧,我关闭了,感谢讨论。 |
你在什么场景下需要该功能? In what scenarios do you need this function?
在编辑时使用markdown转换到html,保存时从html转换到markdown,经过这层转化,即时在未进行修改的情况下,markdown文本也会发生变化。根据文章Markdown 解析原理详解和 Markdown AST 描述中介绍,ast.Node中没有保存源码信息,在生成html时无法带上源码。
描述最优的解决方案 Describe the optimal solution
根据目前语法树的层级,是否可以在块级容器节点中增加此节点下对应的源码信息,在生成html时以隐藏节点或者属性保存。
从html转化为markdown时,优先取保存的源码信息,当发生变化时,再解析转换此块的html到markdown
The text was updated successfully, but these errors were encountered: