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>

显示页面 :

相关推荐
赵广陆1 小时前
SSM+Vue社区物业管理系统
java·前端·javascript·vue.js·maven
m0_689087071 小时前
9.26 C++杂项
开发语言·c++
鸽芷咕1 小时前
【Python报错已解决】[notice] A new release of pip available: 22.2 -> 22.2.2
开发语言·python·bug·pip
边疆.1 小时前
C++入门基础 (超详解)
c语言·开发语言·c++
wjs20241 小时前
Scala 字符串
开发语言
jyl_sh2 小时前
CMake教程:第一步:一个基本的起点
开发语言·c++·客户端·cmake
ac-er88882 小时前
php的urlencode和rawurlencode区别
开发语言·php
zyhomepage2 小时前
科技的成就(六十三)
linux·开发语言·人工智能·科技·算法·游戏·内容运营
前端开发菜鸟的自我修养2 小时前
elementUi / elementPlus自定义上传方法 Upload自定义文件上传
前端·javascript·vue.js·阿里云·elementui·七牛云存储
勿语&2 小时前
多级侧边菜单(递归)
前端·javascript·vue.js