o
    Y4i/                      @   sP   d Z ddlmZ ddlmZ ddlZddlZG dd dejZ	G dd dZ
dS )	u   文档清洗器    )Optional)loggerNc                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )TaxMarkdownConverteru   
    税务文档专用 Markdown 转换器
    - 表格保留为原始 HTML（避免 pipe 格式被分片器截断）
    - 其余节点按标准 markdownify 规则处理
    c                 C   s   dt | d S )N

)strselfeltextconvert_as_inline r   ^/lsinfo/ai/hellotax_ai/data_center/backend/app/services/tax_data_processor/document_cleaner.pyconvert_table   s   z"TaxMarkdownConverter.convert_tablec                 C      dS N r   r   r   r   r   
convert_tr      zTaxMarkdownConverter.convert_trc                 C   r   r   r   r   r   r   r   
convert_td   r   zTaxMarkdownConverter.convert_tdc                 C   r   r   r   r   r   r   r   
convert_th   r   zTaxMarkdownConverter.convert_thc                 C      d| dS Nz<strong>z	</strong>r   r   r   r   r   convert_strong      z#TaxMarkdownConverter.convert_strongc                 C   r   r   r   r   r   r   r   	convert_b   r   zTaxMarkdownConverter.convert_bN)
__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r   r   r   	   s    r   c                   @   s   e Zd ZdZdd ZdedefddZdedefd	d
ZdedefddZdedefddZ	dedefddZ
ededefddZdedefddZdedefddZdS )DocumentCleanerud   
    文档清洗器
    - HTML转Markdown
    - 移除特定噪声文本
    - 格式规范化
    c                 C   r   )u   初始化文档清洗器Nr   )r   r   r   r   __init__+   s   zDocumentCleaner.__init__html_contentreturnc              
   C   s   zt ddddgd|}| |}|W S  ty@ } z td|  ddlm} ||d	}|jd
ddW  Y d}~S d}~ww )uJ   
        HTML 转 Markdown（表格保留为 HTML 原始格式）
        ATX-scriptstyle)heading_stylebulletsstripu   HTML 转 Markdown 失败: r   BeautifulSouplxml
T	separatorr)   N)	r   convertclean_markdown	Exceptionr   errorbs4r+   get_text)r   r!   markdown_contenter+   soupr   r   r   html_to_markdown/   s"   

z DocumentCleaner.html_to_markdownr6   c                 C   s   t dd|}dd |dD }d|}g d}|D ]	}t |d|}qt jdd|t jd	}| |}| |}t dd|}| S )
u   
        清洗 Markdown 内容

        Args:
            markdown_content: Markdown 内容

        Returns:
            清洗后的 Markdown
        \n{3,}r   c                 S   s   g | ]}|  qS r   )r)   ).0liner   r   r   
<listcomp>Q   s    z2DocumentCleaner.clean_markdown.<locals>.<listcomp>r-   )z$!\[.*?\]\(.*?huibiao.*?\)\s*\S+.*?\nu   \[下载文字版\]\(.*?\)\n?u   \[下载图片版\]\(.*?\)\n?u-   字体：\s*【大】\s*【中】\s*【小】u   分享到：.*u   全文有效u   成文日期：.*u   【打印】u   【下载】u   纠错或建议z [^\n]*\{[^\n]*font[^\n]*\}[^\n]*r   z[^\n]*\{[^}]*font[^}]*\}flags)resubsplitjoinDOTALL_normalize_headings_normalize_listsr)   )r   r6   linesnoise_patternspatternr   r   r   r1   C   s   


zDocumentCleaner.clean_markdowncontentc                 C   sf   | d}g }|D ]$}|dr(|r|d dkr|d || |d q	|| q	d|S )u   
        规范化标题格式

        Args:
            content: Markdown 内容

        Returns:
            规范化后的内容
        r-   #r   )rB   
startswithappendrC   )r   rJ   rG   normalized_linesr<   r   r   r   rE   t   s   





z#DocumentCleaner._normalize_headingsc                 C   s,   t jdd|t jd}t jdd|t jd}|S )u   
        规范化列表格式

        Args:
            content: Markdown 内容

        Returns:
            规范化后的内容
        z^\s*[\*\+]\s+z- r>   z^\s*(\d+)\.\s+z\1. )r@   rA   	MULTILINE)r   rJ   r   r   r   rF      s   z DocumentCleaner._normalize_listsr
   c                 C   s$   t dd|}t dd|}| S )u   
        清洗纯文本

        Args:
            text: 文本内容

        Returns:
            清洗后的文本
        z\s+ z&[\x00-\x08\x0b-\x0c\x0e-\x1f\x7f-\x9f]r   )r@   rA   r)   )r   r
   r   r   r   
clean_text   s   zDocumentCleaner.clean_textmarkdownc                 C   s*   t jdd| t jd} t dd| } |  S )u5   移除 content_markdown 中的 OCR 图片内容段落u$   \n\n---\n\n## 正文图片内容\b.*r   r>   u   <!-- 图片\d* OCR -->\n?)r@   rA   rD   r)   )rS   r   r   r   strip_ocr_content   s   z!DocumentCleaner.strip_ocr_contentc                    s  |sdS g   fdd}t jd||t jd}t dd|}t dd|}t jd	d|t jd}t d
d|}t jdd|t jt jB d}t jdd|t jt jB d}t jdd|t jt jB d}t jdd|t jd}t dd|}t D ]\}}|d| d|}qqt dd|}| S )u  
        将 content_markdown 转换为 RAG 专用纯文本：
        - 去掉 Markdown 格式符号（标题 #、加粗 **、图片 ![]()、链接 []()、分隔线 ---）
        - 表格保留原始 HTML 格式（<table>...</table>）
        - <strong> 标签还原为纯文本
        - 压缩多余空行

        Args:
            markdown: content_markdown 内容

        Returns:
            RAG 专用纯文本
        r   c                    s$     | d dt d  dS )Nr   z


__TABLE_   z__

)rN   grouplen)mtablesr   r   _save_table   s   z9DocumentCleaner.markdown_to_rag_text.<locals>._save_tablez<table[\s\S]*?</table>r>   z!\[.*?\]\(.*?\)z\[([^\]]*)\]\([^)]*\)z\1z
^#{1,6}\s+z\*{1,2}([^*]+)\*{1,2}z<strong>(.*?)</strong>z<b>(.*?)</b>z<em>(.*?)</em>z^\s*---+\s*$z	`([^`]*)`__TABLE___r:   r   )r@   rA   
IGNORECASErP   rD   	enumeratereplacer)   )r   rS   r[   r
   itabler   rY   r   markdown_to_rag_text   s$   z$DocumentCleaner.markdown_to_rag_textc                 C   sL   ddl m} ||d}|ddgD ]}|  q|jddd}| |}|S )	u   
        从 HTML 提取纯文本

        Args:
            html_content: HTML 内容

        Returns:
            纯文本
        r   r*   r,   r%   r&   r-   Tr.   )r4   r+   	decomposer5   rR   )r   r!   r+   r8   r%   r
   r   r   r   extract_plain_text   s   



z"DocumentCleaner.extract_plain_textN)r   r   r   r   r    r   r9   r1   rE   rF   rR   staticmethodrT   rc   re   r   r   r   r   r   #   s    16r   )r   typingr   logurur   r@   markdownify_markdownifyMarkdownConverterr   r   r   r   r   r   <module>   s    