Documentation
¶
Overview ¶
Package textdoc 把 OFD 页面中的文字对象提取为带位置的条目,供文本、Markdown 等编码器复用。它只依赖 OFD 模型与解析器,不感知任何输出格式。
Index ¶
- Variables
- func BodyFontSize(entries []Entry) float64
- func Count(documents []*parser.Document) int
- func DetectHeadingLevel(text string, fontSize, bodyFontSize float64) int
- func DisplayWidth(text string) int
- func EnsureUTF8(value string) string
- func Finite(value float64) bool
- func IsPageNumber(text string) bool
- func IsPageNumberRow(row []Entry, pageHeight float64) bool
- func JoinText(row []Entry) string
- func ParagraphStarts(rows [][]Entry, inTable []bool, rowInfos []RowInfo) []bool
- func RowLeft(row []Entry) float64
- func RowRight(row []Entry) float64
- func RowSize(row []Entry) float64
- func RowTolerance(a, b, unit float64) float64
- func RowTop(row []Entry) float64
- func Rows(entries []Entry) [][]Entry
- type Entry
- type EntrySource
- type Image
- type Page
- type RowInfo
- type Table
Constants ¶
This section is empty.
Variables ¶
var ( // NumberedHeaderRegex 匹配「1.」「1.2.」「1.2.3.」等形式的多级编号标题。 NumberedHeaderRegex = regexp.MustCompile(`^(\d+\.)(?:\d+\.)*`) // ParagraphMarkerRegex 匹配常见的中文段落起始标记。 ParagraphMarkerRegex = regexp.MustCompile( `^(第\s*[0-9一二三四五六七八九十百千零两]+\s*[条编]|[((][一二三四五六七八九十百0-9]+[))]|[一二三四五六七八九十百]+、)`) // PageNumberRegex 匹配纯页码,例如「12」。 PageNumberRegex = regexp.MustCompile(`^\d{1,3}$`) // DashPageNumberRegex 匹配带破折号的页码,例如「- 12 -」「— 12 —」。 DashPageNumberRegex = regexp.MustCompile(`^[—–\-]\s*\d+\s*[—–\-]$`) )
Functions ¶
func BodyFontSize ¶ added in v0.1.4
BodyFontSize 返回一页的正文基准字号:出现次数最多的字号,平票取较小值。 找不到有效字号时兜底 6mm。
func DetectHeadingLevel ¶ added in v0.1.4
DetectHeadingLevel 判断一行文字的标题层级,不是标题时返回 0。
编号标题优先于字号:「1.2 引言」无论字号多大都是标题。字号派生的层级还要过 两道否决——首字符必须是大写字母、数字或汉字(避免把以标点开头的正文误判), 且不能是正文形态(过长或以句末标点结尾)。
func DisplayWidth ¶
DisplayWidth 返回按终端显示列数计算的宽度:CJK 等全角字符占两列,其余字符 占一列,保证多栏文字的列位置对齐。
func EnsureUTF8 ¶
EnsureUTF8 保证输出文本是合法 UTF-8。OFD 规范要求文字为 UTF-8,但部分第三方 文档会写入 GBK 等本地编码的原始字节;这里先尝试按 GBK 解码,失败时再把无法 识别的字节替换为 U+FFFD,避免 .txt/.md 出现非法 UTF-8 导致乱码。
func IsPageNumber ¶ added in v0.1.4
IsPageNumber 判断文本是否为页码形式(纯数字或两侧带破折号的数字)。
func IsPageNumberRow ¶ added in v0.1.4
IsPageNumberRow 判断一行是否为页码行。只有页码形式的文本且位于页面顶部或 底部(页眉/页脚区域)时才认定为页码,避免把表格或数据中的纯数字行删掉。
func ParagraphStarts ¶ added in v0.1.4
ParagraphStarts 判断每个正文行是否为段落起点。段落边界按以下信号:
- 段首缩进:行左边缘比正文左边距多出约一个字符宽;
- 段落标记:第 X 条、第 X 编、(一)、一、 等;
- 纵向间距明显大于页内常见行距(部分文档使用段间距而非缩进)。
Types ¶
type Entry ¶
type Entry struct {
Text string
X float64
Y float64
Size float64
Width float64
// FontName 是字体资源里的字体名,解析不到时为空串。OFD 只在文字对象上给
// FontID,名字要查文档体的字体资源;结构化输出(DOCX 的 w:rFonts)需要它,
// 纯文本与 Markdown 则不关心。
FontName string
// Bold 与 Italic 供逐 run 还原字符形态,Weight 达到 boldWeight 即视为粗体。
Bold bool
Italic bool
// Source 记录该条目来自页面的哪一部分。同样的文字放在不同位置,含义差别
// 很大:页面图层是正文,模板层常放页眉页脚与页面装饰,批注层则是水印、
// 印章、签章这类叠加在正文上的标记。是否采信由输出格式决定,因此这里
// 只如实记录来源而不做过滤。
Source EntrySource
}
Entry 是一个待输出的文字对象及其在页面中的位置与尺寸(毫米,原点在页面左上角)。
type EntrySource ¶ added in v0.1.4
type EntrySource int
EntrySource 是文字条目的来源。
const ( // EntrySourcePage 是页面自身图层里的文字,即正文。 EntrySourcePage EntrySource = iota // EntrySourceTemplate 是页面模板里的文字,常是页眉页脚与页面边框装饰。 EntrySourceTemplate // EntrySourceAnnotation 是批注外观里的文字,即叠加在正文上的水印、印章与 // 签章标记。实测保密宣传册的整页「保密资料」水印就属于这一类:81 个文字 // 对象分布在批注里,而页面图层只有 5 个真实内容对象。 EntrySourceAnnotation )
func (EntrySource) String ¶ added in v0.1.4
func (s EntrySource) String() string
String 返回来源的短名称,供日志与测试断言使用。
type Image ¶ added in v0.1.4
type Image struct {
// Data 是原始编码字节(PNG/JPEG 等),按原样内嵌,不重新编码。
Data []byte
// Extension 是不含点的扩展名,决定 MIME 与文件名。
Extension string
// X 与 Y 是图片左上角位置(毫米,原点在页面左上角)。
X float64
Y float64
// Width 与 Height 是显示尺寸(毫米)。
Width float64
Height float64
}
Image 是页面里的一张可内嵌图片。
type Page ¶
type Page struct {
Entries []Entry
Width float64
Height float64
// Source 是提取来源,供需要非文字图元的输出格式(DOCX 内嵌图片)回到原页面
// 继续提取。纯文本与 Markdown 输出不使用这两个字段。
Source *parser.Page
Owner *parser.Document
}
Page 保存单页的文字条目以及该页物理尺寸,用于按列对齐和页眉页脚判定。
func ExtractPage ¶
ExtractPage 提取单个页面的文字条目和物理尺寸。
func (Page) WithoutSource ¶ added in v0.1.4
func (p Page) WithoutSource(drop EntrySource) Page
WithoutSource 返回剔除指定来源条目后的页面副本。批注里的水印与印章属于叠加 标记,不是正文,结构化输出通常要排除;模板层的页眉页脚则常是真内容, 是否剔除由调用方决定。
type RowInfo ¶ added in v0.1.4
type RowInfo struct {
Text string
MaxSize float64
// Level 是标题层级,1..6;0 表示不是标题。
Level int
// IsTitle 等价于 Level > 0。
IsTitle bool
// IsList 由 DOCX 的列表识别写入,其他输出格式不使用,保持 false。
IsList bool
}
RowInfo 保存页内一行的文本与标题判定结果。
type Table ¶
Table 描述一个已识别的表格。Start/End 是页内行索引(含),Header 为表头 单元格文本,Rows 为数据行。
func DetectTables ¶
DetectTables 在已按行分组的文字条目中识别表格。算法:
- 行内按水平间距切分单元格,含两个及以上单元格的行为候选网格行;
- 用候选网格行的单元格区间求并,间隔(白槽)处切分得到列;
- 每个候选行的单元格必须各自落在唯一列内且覆盖至少两列,才认定为表格行;
- 只有一个单元格且落在唯一列内的行作为续行,合并到最近的表格行;
- 被非表格行(标题、页脚等)隔开的多行网格行组成一个表格。