{"id":18031866,"url":"https://github.com/benzbrake/aaeditor","last_synced_at":"2026-03-08T21:33:36.093Z","repository":{"id":214150698,"uuid":"693178358","full_name":"benzBrake/AAEditor","owner":"benzBrake","description":"一款简约而不简单 Typecho Markdown 编辑器 ","archived":false,"fork":false,"pushed_at":"2024-12-24T03:46:06.000Z","size":4581,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-23T04:51:10.249Z","etag":null,"topics":["markdown","typecho","typecho-plugin"],"latest_commit_sha":null,"homepage":"https://xiamp.net/archives/aaeditor-is-another-typecho-editor-plugin.html","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benzBrake.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-18T14:00:45.000Z","updated_at":"2025-02-14T16:41:28.000Z","dependencies_parsed_at":"2024-08-19T16:59:28.188Z","dependency_job_id":null,"html_url":"https://github.com/benzBrake/AAEditor","commit_stats":null,"previous_names":["benzbrake/aaeditor"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benzBrake%2FAAEditor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benzBrake%2FAAEditor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benzBrake%2FAAEditor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benzBrake%2FAAEditor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benzBrake","download_url":"https://codeload.github.com/benzBrake/AAEditor/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245791343,"owners_count":20672665,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["markdown","typecho","typecho-plugin"],"created_at":"2024-10-30T10:11:35.150Z","updated_at":"2026-03-08T21:33:36.088Z","avatar_url":"https://github.com/benzBrake.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AAEditor\n\n## 功能自定义\n\n### 自定义按钮/自定义短代码渲染\n\n1.比如你想增加一个 QQ 卡片的功能\n\n2.进入`Modules`目录，随便复制一份可以用的目录，并改名为`QQ`\n\n3.修改`Modules\\QQ\\index.php`，这个文件前边的格式类似下面这样的，我这个是`Tabs`模块的范例，你要把备注信息修改一下，然后把类名`ModulesTab`改为`ModuleQQ`\n\n```php\n\u003c?php\n\n/** 包引用 */\nuse Typecho\\Config;\nuse TypechoPlugin\\AAEditor\\Module;\nuse TypechoPlugin\\AAEditor\\Util;\nuse Utils\\Helper;\n\n/**\n * 以多标签形式排版正文\n *\n * @package 多标签卡片\n * @author Ryan\n * @version 0.0.1\n * @link https://doufu.ru\n *\n */\nclass ModuleTabs implements Module\n```\n\n这个文件里有4个必须实现的函数\n\n```php\n    /**\n     * 编辑器页面插入静态资源\n     * @return void\n     */\n    public static function editorStatic(): void;\n\n    /**\n     * 前台插入静态资源\n     * @param {Widget_Archive} $archive 页面对象\n     * @return mixed\n     */\n    public static function archiveStatic($archive): void;\n\n    /**\n     * 正文内容处理\n     *\n     * @param {string} $text 处理前的 html\n     * @return string 处理后的 html\n     */\n    public static function parseContent($text, $archive): string;\n\n    /**\n     * 摘要内容处理\n     *\n     * @param {string} $text 处理前的 html\n     * @return string 处理后的 html\n     */\n    public static function parseExcerpt($text, $archive): string;\n```\n\n### editorStatic\n\n这是编辑器初始化以后执行的脚本，一般用于添加按钮，增加编辑实时渲染代码。\n\n```php+HTML\npublic static function editorStatic(): void {\n?\u003e\n\u003cscript\u003e\n// 增加按钮，触发 XEditorAddButton 事件可以用于增加按钮，该事件只接受一个参数，该参数指定按钮配置\n$('body').trigger('XEditorAddButton', [{\n    id: 'wmd-tabs-button', // 按钮 id\n    name: '\u003c?php _e(\"多标签\"); ?\u003e', // 鼠标在按钮上悬浮时显示的文字\n    icon: '\u003csvg viewBox=\"0 0 1024 1024\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\u003e\u003cpath d=\"M202.667 149.333c-52.651 0-96 43.35-96 96v533.334c0 52.65 43.349 96 96 96h618.666c52.651 0 96-43.35 96-96V245.333c0-52.65-43.349-96-96-96h-448a32 32 0 0 0-5.504.427c-2.816-.213-5.653-.427-8.49-.427H202.667zm0 64h156.672a53.32 53.32 0 0 1 37.696 15.616l102.997 103.019a32 32 0 0 0 22.635 9.365h298.666c18.048 0 32 13.952 32 32v405.334c0 18.048-13.952 32-32 32H202.667c-18.048 0-32-13.952-32-32V245.333c0-18.048 13.952-32 32-32zm269.248 0h349.418c18.048 0 32 13.952 32 32v37.974a94.016 94.016 0 0 0-32-5.974H535.915l-64-64z\"\u003e\u003c/path\u003e\u003c/svg\u003e', // 图标，推荐 SVG，建议设定 width 和 height 防止 css 未加载是图标过大\n    insertBefore: '#wmd-spacer4', // 插入到哪个 HTMLElement 前边\n    shortcut: 'ctrl+alt+t', // 快捷键，如果不需要就别用这项\n    command({ target }) {\n        // 点击按钮或按下快捷键运行的函数，target 是按钮 DOM\n        // 这里的 this 绑定的是 assets/src/main.js 定义的 XEditor 的实例，具体函数请查看 XEditor，常用的有 openModal, insertText, replaceSelection, getSelectedText, wrapText\n        // this.insertText(123); // 往光标处插入文本 123\n        // this.replaceSelection('哈哈哈') // 替换选中文本为哈哈哈\n        // this.getSelectedText() // 获取选中文本\n        // 新版 XEditor 针对 textarea 写了一个工具类，可以通过 this.textarea 获取改工具类，具体有什么函数可以查看 assets/src/utils/textarea.js\n        this.openModal({\n            title: '\u003c?php _e(\"插入多标签卡片\"); ?\u003e',\n            innerHTML: `\u003cx-custom-tabs\u003e\u003c/x-custom-tabs\u003e`,\n            checkEmptyOnConfirm: false,\n            confirm(modal) {\n                // 这里可以通过 this 拿到 XEditor实例，modal 是模态框 HTMLELement\n                // confirm 是点击确定后运行的函数，需要返回 true 关闭模态框，返回 false 保持模态框\n                let items = [];\n                $(modal).find('.x-custom-tabs-nav-item').each(function () {\n                    let tab = $(this);\n                    let tabId = tab.attr('data-id'),\n                        content = $('.x-custom-tabs-content-item[data-id=\"' + tabId + '\"]', modal);\n                    if (content) {\n                        let tabTitle = $('input[name=\"title\"]', content),\n                            tabContent = $('textarea[name=\"content\"]', content),\n                            isDefault = $('input[name=\"is-default\"]', content)[0].checked;\n                        items.push(`[tab name=\"${tabTitle.val()}\"${isDefault ? ' active=\"true\"' : ''}]${tabContent.val()}[/tab]`);\n                    }\n                });\n                if (items.length) {\n                    this.replaceSelection((this.textarea.isAtLineStart() ? '' : '\\n') + '[tabs]\\n' + items.join('\\n') + '\\n[/tabs]' + (this.textarea.isAtLineEnd() ? '' : '\\n'));\n                }\n                return true;\n            },\n            handle(modal) {\n                // 创建模态框后会运行的函数\n                $(modal).find('.aa-modal-frame').css({\n                    'width': '100%',\n                    'max-width': '640px'\n                });\n            }\n        });\n    }\n}])\n\u003c/script\u003e\n\u003cscript\u003e\n// 触发 XEditorAddHtmlProcessor 事件，增加实时渲染处理器，该事件只接受一个函数参数\n$('body').trigger('XEditorAddHtmlProcessor', [\n    function (html) {\n        // 只有一个参数，html 是上个渲染函数处理后的 html 文本，如果无需处理\n        // this 是 assets/src/previewUtils.js的实例\n        // this.getShortCodeRegex 用户获取短代码的正则表达式\n        if (html.indexOf(\"[tabs\")) {\n            html = html.replace(this.getShortCodeRegex(\"tabs\"), `\u003cdiv class=\"x-tabs-wrapper\"\u003e\u003cx-tabs$3\u003e$5\u003c/x-tabs\u003e\u003c/div\u003e`);\n        }\n        if (html.indexOf(\"[x-tabs\")) {\n            html = html.replace(this.getShortCodeRegex(\"x-tabs\"), `\u003cdiv class=\"x-tabs-wrapper\"\u003e\u003cx-tabs$3\u003e$5\u003c/x-tabs\u003e\u003c/div\u003e`);\n        }\n        if (html.indexOf(\"[tab\")) {\n            html = html.replace(this.getShortCodeRegex(\"tab\"), `\u003cdiv class=\"x-tab\"$3\u003e$5\u003c/div\u003e`);\n        }\n        if (html.indexOf(\"[x-tab\")) {\n            return html.replace(this.getShortCodeRegex(\"x-tab\"), `\u003cdiv class=\"x-tab\"$3\u003e$5\u003c/div\u003e`);\n        }\n    }\n]);\n\u003c/script\u003e\n\u003cscript\u003e\n\t// 你还可以增加渲染后处理代码，编辑器渲染完成后触发 XEditorPreviewEnd 事件\n\t$('body').on('XEditorPreviewEnd', function() {\n        \n    });\n\u003c/script\u003e\n\u003c?php \n}\n```\n\n这里也许会需要插入模块目录里的 css/js，相对路径请自行修改\n\n```php+HTML\n\u003clink rel=\"stylesheet\" href=\"\u003c?php echo TypechoPlugin\\AAEditor\\Util::pluginUrl('Modules/Tabs/index.css'); ?\u003e\"\u003e\n```\n\n\n\n### archiveStatic\n\n这是前台页面底部增加静态资源用的\n\n### parseContent\n\n正文处理，如果不需要处理，直接返回`$text`即可\n\n```php\npublic static function parseContent($text, $archive): string {\n    return $text;\n}\n```\n\n如果需要处理短代码\n\n```php\npublic static function parseContent($text, $archive): string {\n    /*\n     * 获取短代码正则表达式\n     * 下面获取的表达式能匹配[tabs active='1']xxx[/tabs]和[x-tabs active='1']xxx[/x-tabs]这两种，get_shortcode_regex需要的参数是数组\n     */\n    $pattern = TypechoPlugin\\AAEditor\\Util::get_shortcode_regex(['tabs', 'x-tabs']); \n    /*\n     * $1 $2 $3 $4 $5，对于[tabs active='1']xxx[/tabs]，$3对应 active='1' 这部分，$5 对应于 xxx 这部分\n     */\n    return preg_replace(\"/$patter/\", '\u003cx-tabs$3\u003e$5\u003c/x-tabs\u003e', $html);\n}\n```\n\n### parseExcerpt\n\n摘要处理，同上边一样的\n\n## 编译核心JS\n1.需要 nodejs 环境\n2.在插件目录运行 CMD\n```\nnpm install --legacy-peer-deps# 安装依赖\nnpm run prod # 编译\n```\n3.如果需要实时编译\n```\nnpm run watch\n```\n\n\n## 授权\n\n[Mozilla Public License Version 2.0](LICENSE)\n\n学习可以，禁止直接改名商用！！！\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenzbrake%2Faaeditor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenzbrake%2Faaeditor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenzbrake%2Faaeditor/lists"}