npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

any-block-converter-markdown-it

v3.1.3-beta11

Published

```typescript import { ABConvertManager } from "ABConvertManager"

Downloads

60

Readme

Any Block Converter

使用

使用流程

// 转换器模块
import { ABConvertManager } from "ABConvertManager"
// 加载所有转换器 (都是可选的)
// (当然,如果A转换器依赖B转换器,那么你导入A必然导入B)
import {} from "./ABConverter/converter/abc_text"
import {} from "./ABConverter/converter/abc_list"
import {} from "./ABConverter/converter/abc_table"
import {} from "./ABConverter/converter/abc_deco"
import {} from "./ABConverter/converter/abc_ex"
import {} from "./ABConverter/converter/abc_mermaid" // 可选建议:7.1MB
import {} from "./ABConverter/converter/abc_markmap" // 可选建议:1.3MB

// 先注册默认渲染行为
ABConvertManager.getInstance().redefine_renderMarkdown((markdown: string, el: HTMLElement): void => {...})

// 然后按下面这个原型正常使用即可
ABConvertManager.autoABConvert(el:HTMLDivElement, header:string, content:string): HTMLElement

其中,回调函数设置详细说下

Obsidian 回调设置如下:

ABConvertManager.getInstance().redefine_renderMarkdown((markdown: string, el: HTMLElement): void => {
    /**
     * Renders markdown string to an HTML element.
     * @deprecated - use {@link MarkdownRenderer.render}
     * 
     * 原定义: 
     * @param markdown - The markdown source code
     * @param el - The element to append to
     * @param sourcePath - The normalized path of this markdown file, used to resolve relative internal links
     *     此标记文件的规范化路径,用于解析相对内部链接
     *     TODO 我可能知道为什么重渲染图片会出现bug了,原因应该在这里
     * @param component - A parent component to manage the lifecycle of the rendered child components, if any
     *     一个父组件,用于管理呈现的子组件(如果有的话)的生命周期
     * @public
     * 
     */
    //MarkdownRenderer.renderMarkdown(markdown, el, "", new MarkdownRenderChild(el))

    /**
     * Renders markdown string to an HTML element.
     * @param app - A reference to the app object
     * @param markdown - The markdown source code
     * @param el - The element to append to
     * @param sourcePath - The normalized path of this markdown file, used to resolve relative internal links
     * @param component - A parent component to manage the lifecycle of the rendered child components.
     * @public
     */
    // @ts-ignore 新接口,但旧接口似乎不支持
    MarkdownRenderer.render(app, markdown, el, "", new MarkdownRenderChild(el))
})

MarkdownIt 回调函数设置如下:

ABConvertManager.getInstance().redefine_renderMarkdown((markdown: string, el: HTMLElement): void => {
    const result: string = md.render(markdown)
    const el_child = document.createElement("div"); el.appendChild(el_child); el_child.innerHTML = result;
})

至于其他平台的可以参考上面两者进行设置

使用流程改良 (npm版)

作者上传npm:

$ npm adduser  # 先登录,在vscode里他会让我打开浏览器来登录
Username: ...
Password: ...

$ npm publish  # 上传 (注意不要重名、npm账号可能需要邮箱验证)

这里踩了很多坑:

  • 源码使用
    • 就是一开始的做法
    • 相关文件: 无
    • 使用结果: 成功
  • build_tsc
    • 使用结果: 成功,但上传npm后失败
    • NPM使用结果:[ERR_MODULE_NOT_FOUND]
  • build_tsup
    • 使用结果: Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'markdown-it' imported from ...
  • build_vite
    • 参考: https://github.com/ebullient/markdown-it-obsidian-callouts/
    • 相关文件: package.json、tsconfig.json、vite.config.ts
    • 构建结果: 成功
    • 使用结果: Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'markdown-it' imported from ... 安装mdit后:TypeError: Cannot read properties of undefined (reading 'prototype')
    • NPM使用结果:TypeError: Cannot read properties of undefined (reading 'prototype')
  • build_rollup

从npm下载并使用:

$pnpm install -D [email protected] # 我这里的vuepress环境统一用pnpm (实际上根据你的习惯使用npm也好)
# 后面的使用和前面类似

开发/设计/架构补充

(先读src下的README)

架构

也叫 Any Block Render (text->html时)

因为模块化内置了很多 Converter (text->text等),所以整体叫 Any Block Converter

该模块设计不应依赖于Ob插件

这个模块以前是依赖Ob插件接口的,后来才改成可复用的 AnyBlock 转化器。

为了高复用 (不仅仅在Ob插件上使用,还在md-it的等其他地方使用)

  1. 要与选择器解耦
  2. 相较于V2版本,为了不依赖于Ob底层,使用一个回调函数去替代 MarkdownRenderer 相关函数

程序缩写

  • AnyBlockAB
  • AnyBlockConvertABC
  • AnyBlockSelectorABS
  • AnyBlockRenderABR

格式转换所在位置

思考

例如我有两个格式:格式1(有格式1解析渲染、将自己格式转别人格式,将别人格式转自己格式)、格式2(有格式2解析渲染、将别人的格式转自己式、将自己的格式转别人的格式)。问题在于:1转2和2转1的功能,应该怎么设置?

  1. 都放在两个文件中
    • 优点:两模块互相独立
    • 缺点:造成冗余,而非复用 —— 只写一遍,两个程序都用一份
  2. 只放格式2
    • 思想:该方式视为先有的格式1后有的格式2扩展。或视为格式1是更通用更广泛的格式,格式2属于扩展格式,自然由格式2负责12的互转
    • 采用:abc_mermaid、abc_markmap 与 list 的转换属于此类,后期增加的新格式也属于此类
  3. 1转2由2实现,2转1则由1实现
    • 思想:该方式视为1和2是两个商业软件,他们乐意于让对方的用户转移到自己这边,但并不乐意让自己的用户转到对方那边
    • 采用:list、table 的互相转换属于此类
总结

按格式的通用性分为:(越往上通用级别越高)

  1. str
  2. html
  3. list、table
  4. mermaid、mindmap、……以后的扩展
策略
  1. 低通用级格式要实现对高通用级格式的互转
  2. 同通用级则实现其他同通用级格式对自己格式的转化

todo

  1. 别名模块,AnyBlockConverter 不应该最后强制输出html。最后补md的行为是ob的别名模块做的,不应该由abc来快
  2. PlantUML,感觉很多东西都好用多了

bug

mdit环境下onclick需要内嵌才生效

// TODO,onClick代码在mdit环境下按钮点击失效。测试代码如下
const btn = document.createElement("button"); table.appendChild(btn); btn.textContent = "测试按钮1";
btn.onclick = () => { console.log("btn.onclick") }
const btndiv = document.createElement("div"); table.appendChild(btndiv);
btndiv.innerHTML = `<button onclick="console.log('Button was clicked!')">测试按钮2</button>`
// 发现mdit环境下,按钮1无法正常按动,而按钮2可以
// 原因应该是:因为mdit环境下的document对象是jdsom创建的,假的。这个dom对象后面会被转化为html_str,onclick的信息就丢失了

mermaid找不到DOMPurify

mermaid的一个未定义行为的报错 (不过修复了这个之后又说BBox找不到了)

// 见:https://github.com/kkomelin/isomorphic-dompurify

// 用
import DOMPurify from "isomorphic-dompurify"
// 替换
import DOMPurify from "dompurify"

npm使用可能遇到的报错

Error [ERR_MODULE_NOT_FOUND]: Cannot find module

解决见:https://stackoverflow.com/questions/65384754/error-err-module-not-found-cannot-find-module

  1. 手动添加.js扩展名
  2. 设置别名, tsconfig.json:
    "paths": {
       "@theme-hope/*": ["./src/client/*.js"]
     }
  3. 设置环境变量 (windows设置麻烦点,见我个人网站的仓库的主repo那里写过一次,这里不写了) NODE_OPTIONS='--experimental-specifier-resolution=node'