如何通过编程在Jinja中高亮字符串?HTML引语高亮实现方案
实现引语高亮的方案
一、在Python代码中嵌入<mark>标签
先编写一个辅助函数,遍历HTML文档的文本节点,将已识别的引语用带自定义类名的<mark>标签包裹,避免破坏原有HTML结构。
辅助函数代码:
from bs4 import BeautifulSoup def highlight_quotes(soup, quotes): # 遍历所有有效文本节点 for text_node in soup.find_all(text=True): content = text_node.strip() if not content: continue # 逐个匹配引语并替换 for quote in quotes: if quote in content: # 用带类名的<mark>包裹引语,方便后续样式控制 highlighted_content = content.replace(quote, f'<mark class="highlighted-quote">{quote}</mark>') # 解析为HTML节点再替换,防止字符串拼接破坏原有结构 new_content = BeautifulSoup(highlighted_content, 'html.parser') text_node.replace_with(new_content) return soup
修改原有render_doc函数:
def render_doc(doc_id, quotes): # 加载并解析HTML文档 data = dl.load_file(doc_id) soup = extract_soup(data) # 调用高亮函数处理引语 soup = highlight_quotes(soup, quotes) # 提取元数据 context = get_metadata(soup) # 将处理后的正文HTML传入模板,而非纯文本 context['body_html'] = str(soup.body) if soup.body else "" # 渲染Jinja模板 path = './' filename = 'ln_template.html' rendered = Environment( loader=FileSystemLoader(path), autoescape=True # 开启自动转义,规避XSS风险 ).get_template(filename).render(context) # 保存并打开生成的HTML文件 file_name = f"{doc_id}.html" with open(file_name, "w+") as f: f.write(rendered) os.system(f"open {file_name}")
二、通过CSS自定义高亮样式
在Jinja模板(ln_template.html)中添加自定义CSS规则,让高亮效果更贴合需求,同时正确渲染处理后的正文HTML:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{{ title }}</title> <style> /* 自定义引语高亮样式 */ mark.highlighted-quote { background-color: #fff3cd; /* 柔和的暖黄色背景 */ padding: 1px 3px; border-radius: 2px; font-weight: 500; /* 轻微加粗突出 */ border-bottom: 1px solid #ffc107; /* 底部线条增强视觉区分 */ } </style> </head> <body> <h1>{{ title }}</h1> <p>作者: {{ author }}</p> <!-- 渲染处理后的正文,用safe过滤器避免HTML被转义 --> <div class="article-body"> {{ body_html|safe }} </div> </body> </html>
三、优化注意事项
- 若引语包含HTML特殊字符(如
<、>),需提前用html.escape()处理,避免破坏原有HTML结构 - 如需精确匹配引语(防止短引语误匹配到其他单词),可改用正则表达式的边界匹配,示例:
import re for quote in quotes: pattern = re.compile(re.escape(quote), re.IGNORECASE) highlighted_content = pattern.sub(f'<mark class="highlighted-quote">\\g<0></mark>', content) - 若引语跨多个文本节点,需调整遍历逻辑,确保完整包裹引语内容
内容的提问来源于stack exchange,提问作者steadynappin
相关产品推荐
相关产品推荐

