markdown 中启用音频支持

markdown 中启用音频支持

markdown 默认不支持音频文件,我们通过 html 标签渲染

flask项目

其中音频文件放在 /static/audios/vad_example.wav

markdown 内容如下:

## 音频播放器示例
<audio controls  >
    <source src="vad_example.wav" type="audio/wav">
</audio>

预览显示为html

html 复制代码
<p>&lt;audio controls &gt;<br> &lt;source src="vad_example.wav" type="audio/wav"&gt;<br>&lt;/audio&gt;</p>

我们需要把上面代码变为如下html:

html 复制代码
<audio controls  >
    <source src="{{ url_for('static', filename='audios/vad_example.wav') }}" type="audio/wav">
</audio>

1编辑器预览区替换

markdown编辑器的html 代码:

html 复制代码
        <div id="create-editormd" class="editor">
            <textarea name="doc" id="doc">{{ request.form['doc'] or post['body'] if post else '' }}</textarea>
        </div>

js脚本:

预览区域默认html标签 editormd-preview

通过 onload 预览触发替换

js 复制代码
<script type="text/javascript">
    var testEditor;
    var textarea = document.getElementById('doc');

    $(function () {

        testEditor = editormd("create-editormd",
            {
                width: "90%",
                height: 640,
                syncScrolling: "single",
                path: "{{ url_for('static',filename='editormd/lib/') }}",
                imageUpload: true,
                imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
                imageUploadURL: "/upload/upload_image",  // 设置图片上传的服务器路径
                onload: function () {
                    console.log("onload");
                    // 动态替换音频文件路径
                    const audioPathPrefix = "{{ url_for('static', filename='audios/') }}";
                    const previewContainer = document.querySelector('.editormd-preview');

                    if (previewContainer) {
                        console.log("Found preview container:", previewContainer);

                        // 查找并替换 <p> 标签内的音频标签
                        const pElements = previewContainer.querySelectorAll('p');
                        pElements.forEach(pElement => {
                            const htmlContent = pElement.innerHTML;

                            // 使用正则表达式匹配 <p> 标签内的音频标签
                            const audioRegex = /&lt;audio\s+controls[^&gt;]*&gt;[\s\S]*&lt;source\s+src="([^"]+)"\s+type="audio\/wav"[^&gt;]*&gt;[\s\S]*&lt;\/audio&gt;/g;
                            const matches = htmlContent.match(audioRegex);

                            if (matches) {
                                matches.forEach(match => {
                                    // 替换 &lt; 和 &gt; 为 < 和 >
                                    let actualHtml = match.replace(/&lt;/g, '<').replace(/&gt;/g, '>');

                                    // 移除 <br> 标签
                                    actualHtml = actualHtml.replace(/<br>/g, '');

                                    // 替换 <p> 标签内的内容
                                    pElement.innerHTML = pElement.innerHTML.replace(match, actualHtml);
                                    console.log("Replaced audio tag:", actualHtml);
                                });
                            }else{
                                console.log("No audio tags found in p element.");
                            }
                        });

                        // 更新音频文件路径
                        const audioElements = previewContainer.querySelectorAll('audio source');

                        if (audioElements.length > 0) {
                            console.log("Found audio elements:", audioElements);
                            audioElements.forEach(element => {
                                const originalSrc = element.getAttribute('src');
                                const newSrc = audioPathPrefix + originalSrc;
                                element.setAttribute('src', newSrc);
                                console.log("Updated src from", originalSrc, "to", newSrc);
                            });
                        } else {
                            console.log("No audio elements found.");
                        }
                    } else {
                        console.log("No preview container found.");
                    }
                }
            });
    });

</script>

显示页面 :

2 显示页面替换

html:

html 复制代码
    <!-- 预览区域 -->
    <div id="preview-wrapper" class="markdown-body">
        <!-- 这里会显示Markdown的渲染内容 -->
    </div>

js 脚本:

html 复制代码
<script type="text/javascript">

    document.addEventListener("DOMContentLoaded", function () {

        const preview = document.getElementById("preview-wrapper")

	// 更新预览
	preview.innerHTML = '';
	editormd.markdownToHTML(preview.id, {
		markdown: docBody,
		htmlDecode: "style,script,iframe",
		emoji: true,
		taskList: true,
		tex: true,
		flowChart: true,
		sequenceDiagram: true,
	});

	// 动态替换音频文件路径
	// 假设 audio_path 是从 Flask 传递过来的变量
	const audioPathPrefix = "{{ url_for('static', filename='audios/') }}";
	const audioElements = preview.querySelectorAll('audio source');
	audioElements.forEach(element => {
		const originalSrc = element.getAttribute('src');
		const newSrc = audioPathPrefix + originalSrc;
		element.setAttribute('src', newSrc);
	});

    });

</script>

显示页面 :

相关推荐
paj123456789几秒前
JDK1.8新增特性
java·开发语言
木子02042 分钟前
前端VUE项目启动方式
前端·javascript·vue.js
IT古董8 分钟前
【人工智能】Python在机器学习与人工智能中的应用
开发语言·人工智能·python·机器学习
繁依Fanyi12 分钟前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
endingCode20 分钟前
45.坑王驾到第九期:Mac安装typescript后tsc命令无效的问题
javascript·macos·typescript
湫ccc32 分钟前
《Python基础》之pip换国内镜像源
开发语言·python·pip
fhvyxyci33 分钟前
【C++之STL】摸清 string 的模拟实现(下)
开发语言·c++·string
qq_4597300335 分钟前
C 语言面向对象
c语言·开发语言
菜鸟学Python44 分钟前
Python 数据分析核心库大全!
开发语言·python·数据挖掘·数据分析
一个小坑货1 小时前
Cargo Rust 的包管理器
开发语言·后端·rust