Skip to content
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

请求增加定理,引理,定义等环境的定义,并渲染 #425

Open
Jieli12 opened this issue Sep 24, 2024 · 4 comments
Open

请求增加定理,引理,定义等环境的定义,并渲染 #425

Jieli12 opened this issue Sep 24, 2024 · 4 comments
Labels
enhancement New feature or request

Comments

@Jieli12
Copy link

Jieli12 commented Sep 24, 2024

首先感谢作者提供如此好用的工具。我在VScode中用Markdown preview enhanced 来渲染markdown文件,这个插件提供了一个自定义的接口,用户可以自己定制环境并设置CSS样式。下面是 parser.js 文件内容:

({
  // Please visit the URL below for more information:
  // https://shd101wyy.github.io/markdown-preview-enhanced/#/extend-parser
  onWillParseMarkdown: async function (markdown) {

    // Define the regex to match the environments and references
    let environments = [
      { name: 'theorem', label: '#theorem:', color: '#ff8618', shape: '♥' },
      { name: 'postulate', label: '#postulate:', color: '#ff8618', shape: '♥' },
      { name: 'axiom', label: '#axiom:', color: '#ff8618', shape: '♥' },
      { name: 'assumption', label: '#assumption:', color: '#ff8618', shape: '♥' },
      { name: 'lemma', label: '#lemma:', color: '#ff8618', shape: '♥' },
      { name: 'corollary', label: '#corollary:', color: '#ff8618', shape: '♥' },
      { name: 'definition', label: '#definition:', color: '#4CAF50', shape: '♣' },
      { name: 'proposition', label: '#proposition:', color: '#00aef7', shape: '♠' }
    ];

    // Construct a regex pattern to match only the labels in the environments array
    let labels = environments.map(env => env.label.slice(1, -1)).join('|');
    let refRegex = new RegExp(`@(${labels}):(\\w*)`, 'g');

    // Store references and their numbers
    let references = {};
    let counts = {};

    environments.forEach(env => {
      counts[env.name] = 0;
    });

    // First pass: Assign numbers to each environment
    environments.forEach(env => {
      let regex = new RegExp(`::: ${env.name}\\s*(\\{${env.label}(.*?)\\})?\\n([\\s\\S]*?)\\n:::\\n`, 'g');
      markdown = markdown.replace(regex, function (match, id, key, body) {
        counts[env.name]++;
        let number = `${env.name.charAt(0).toUpperCase() + env.name.slice(1)} ${counts[env.name]}`;
        if (key) {
          references[`@${env.label.slice(1)}${key}`] = number;
        }
        return match.replace(new RegExp(`::: ${env.name}\\s*(\\{${env.label}(.*?)\\})?`), `::: ${number}`);
      });
    });

    markdown = markdown.replace(refRegex, function (match, id, key) {
      let reference = references[`@${id}:${key}`] || match;
      return `<span style="color: #3c71b7;">${reference}</span>`;
    });

    // Replace each environment with the appropriate HTML structure
    environments.forEach(env => {
      let regex = new RegExp(`::: ${env.name.charAt(0).toUpperCase() + env.name.slice(1)}\\s*(\\d+)\\n([\\s\\S]*?)\\n:::\\n`, 'g');
      markdown = markdown.replace(regex, function (match, key, body) {
        // Trim the body to remove any leading/trailing whitespace
        body = body.trim();
        let idd = `${env.name.charAt(0).toUpperCase() + env.name.slice(1)} ${key}`;
        // Function to find the key by value in the references object
        function getKeyByValue(object, value) {
          return Object.keys(object).find(key => object[key] === value);
        }

        // Find the key that matches the value 'Lemma 1'
        let key1 = getKeyByValue(references, idd);

        // Construct id_initial using the found key
        let id_initial = `${key1.slice(1)}`;

        // Return the HTML structure
        return "<div style=\"position: relative; border: 2px solid" + env.color + "; background-color: #f9f9f9; padding: 15px; margin: 20px 0; font-family: Arial, sans-serif; box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1); border-radius: 8px;\"><div style=\"position: absolute; top: -0.85em; left: 15px; background-color:" + env.color + "; padding: 0 5px; font-weight: bold; color: #f9f9f9; border: 2px solid" + env.color + ";\">" + "<span id=" + id_initial + ">" + env.name.charAt(0).toUpperCase() + env.name.slice(1) + " " + key + "</span >" + "</div><div style=\"font-style: italic; margin-top: 0.7em;\">" + body + "</div><div style=\"position: absolute; bottom: 10px; right: 10px; text-align: right; font-size: 20px; color:" + env.color + "; margin-top: 1px;\">" + env.shape + "</div></div>";
      });
    });
    // Return the modified markdown content
    return markdown;
  },

  onDidParseMarkdown: async function (html) {
    return html;
  },
})

渲染结果如下图:
Screenshot 2024-09-24 at 23 16 09

我设置的语法是:

// for environment:
::: theorem {#theorem:fisher_theorem}
Theorem body
:::

// for reference:
see [@theorem:fisher_theorem](#theorem:fisher_theorem)

我通过正则表达式查找并直接替换成html。

可以把类似的定理环境加到这个repository中吗?我写数学公式用会经常用公式和定理环境。当然我上面的方法肯定不是最优的,给出的style仅供参考。期待您的回复,谢谢!

@YangFong
Copy link
Member

若是你的想法是加入高亮块,比如下面这样的:

Note

Highlights information that users should take into account, even when skimming.

Tip

Optional information to help a user be more successful.

Important

Crucial information necessary for users to succeed.

Warning

Critical content demanding immediate user attention due to potential risks.

Caution

Negative potential consequences of an action.

那么我也是有想过的,有找到对应的库,可以快速实现,不过暂时还未落实。

参见:

@Jieli12
Copy link
Author

Jieli12 commented Sep 25, 2024

类似高亮块,但是我想要的效果是类似上面的定理截图。其实另一个思路是借用高亮块的class,然后再自己重新设置CSS即可,不知道这样是否可行?我不是非常熟悉Vue, JS, TS,所以只是泛泛而谈,谢谢回复,期待更新!

@YangFong
Copy link
Member

设定一个标记规则,并渲染高亮块,高亮块主要有标题、标识、主题背景或边框,还有内容。

而样式可以先不管,都是可以 div 的,主要是定好触发规则和渲染的基础内容。

我们可以支持该规则,并预设一套基础样式,有其他样式的需求,则可以自己手动修改。

@Jieli12
Copy link
Author

Jieli12 commented Sep 25, 2024

Thank you very much, well done!

@yanglbme yanglbme added the enhancement New feature or request label Sep 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants