document

package
v0.1.53 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 16, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package document — единая точка чтения документов: PDF и книг EPUB.

Форматы разбираются разными пакетами, но пользуются ими одинаково: прочитать текст, узнать, сколько там рисунков, вытащить сами рисунки. Этот слой прячет различия, чтобы инструмент read_file и команды /add и /addimg не разбирались в устройстве каждого формата и не дублировали одну и ту же обвязку.

Index

Constants

View Source
const MaxTextLines = 65535

MaxTextLines — предел длины текстового документа в строках.

Номер строки хранится в двоичной записи куска как uint16 (internal/kb), то есть больше 65 535 не помещается. Молча обрезать нельзя: ссылки на конец файла показывали бы 65 535 у каждого куска, и проверить их стало бы невозможно — а непроверяемая ссылка хуже отсутствующей.

Variables

View Source
var ErrTooManyLines = errors.New("файл длиннее предела строк")

ErrTooManyLines — файл длиннее предела. Отдельная ошибка, чтобы вызывающий мог отличить «слишком длинный» от «нечитаемый» и сказать человеку, что с этим делать.

Functions

func CodeExt added in v0.1.32

func CodeExt(path string) bool

CodeExt — файл с исходным кодом: берётся как текст, но заголовком куска служит объявление, а не заголовок раздела.

**Зачем код в базе знаний.** Знание проекта живёт не только в `docs/`: правило бывает записано только в скрипте обвязки, а почему сделано так — в комментарии над функцией. 25.09.2026 разбор сторожа карты, обёртки `graph` и пакетов `internal/` шёл `grep`'ом, потому что искать по ним было нечем. Цена замерена в тот же день: весь код проекта — около 6 350 кусков против 94 171 в коллекции документации, то есть прибавка 7 % и две минуты карты на векторы.

func IndexExt added in v0.1.32

func IndexExt(path string) bool

IndexExt — можно ли положить файл в коллекцию базы знаний.

Шире TextExt ровно на код: искать по своему коду вопросом полезно, а вот считать его чужим документом при чтении — нет (см. TextExt).

func Parts

func Parts(path string, maxBytes int64) (*Doc, []Part, error)

Parts читает документ поединично: метаданные плюс страницы или разделы по отдельности. Поле Doc.Text при этом пустое — склеивать текст незачем, вызывающий код разбивает его на куски сам.

func ServiceUnits added in v0.1.25

func ServiceUnits(path string, maxBytes int64) ([]int, error)

ServiceUnits — номера служебных единиц документа: у книги EPUB это разделы с оглавлением и указателем (epub.Section.Service). У PDF и текстовых файлов таких нет: там оглавление узнаётся по строению куска при нарезке. Нужен проходу по уже проиндексированным книгам, где разделы не помечены.

func TextExt

func TextExt(path string) bool

TextExt сообщает, берём ли мы файл с таким расширением как ДОКУМЕНТ-текст.

Код сюда не входит намеренно. Первая редакция правки 25.09.2026 добавила к нему `.go`, и это молча поменяло совсем другое поведение: `read_file` на собственном исходнике пошёл путём документа и стал помечать вывод как ЧУЖОЙ текст (`Plan.Foreign`) — то есть код проекта подавался модели так же, как страница из сети. Поймали три чужих теста, которые это решение стерегли. Отсюда разделение: TextExt — «документ», IndexExt — «можно положить в базу знаний». Вопросы разные, и смешивать их нельзя.

func YearFromCopyright

func YearFromCopyright(text string) int

YearFromCopyright ищет год в начале текста книги.

text — первые страницы: дальше первых страниц копирайт не встречается, а «© 2011» в ссылке из середины книги — это чужой год.

func YearFromFilename

func YearFromFilename(path string) int

YearFromFilename достаёт год из имени файла. 0 — не нашёлся.

Когда чисел несколько («Книга 2-е издание (2019) 2021.pdf»), берётся наибольшее: переиздание новее оригинала, а номер издания в диапазон лет не попадает.

func YearNote

func YearNote(year int, now time.Time) string

YearNote — оговорка о давности книги, годная для показа модели. Пустая строка означает, что оговорка не нужна.

Порог в три года выбран так: за меньший срок в книгах по нашим темам мало что успевает устареть настолько, чтобы оговорка окупала место в контексте.

Types

type Doc

type Doc struct {
	Kind    Kind
	Title   string
	Author  string
	Units   int    // страниц у PDF, разделов у книги
	Unit    string // как называть единицу: «страниц», «разделов»
	Text    string // текст с заголовками единиц
	Figures int    // сколько в тексте меток рисунков

	// Year — год издания, YearSrc — откуда он взят. 0 — не определился.
	// Зачем это нужно и почему источников три — в year.go.
	Year    int
	YearSrc YearSource
}

Doc — прочитанный документ.

func Probe

func Probe(path string, maxBytes int64, units int) (*Doc, error)

Probe быстро определяет, годится ли документ для чтения: формат, метаданные и есть ли вообще текстовый слой. Разбирает не больше units единиц, поэтому на скане отвечает за миллисекунды вместо полного разбора всех страниц.

Нужен при обходе тысяч книг: скан отличается от книги только тем, что текста в нём нет, и узнать это дешевле заранее.

func Read

func Read(path string, maxBytes int64) (*Doc, error)

Read читает документ целиком. Предел maxBytes — на файл: в контекст идёт извлечённый текст, но сам файл всё же читается в память.

func (*Doc) Header

func (d *Doc) Header(canView bool) string

Header — строка сведений о документе, которую видит модель.

canView говорит, включён ли инструмент view_image. Звать к выключенному инструменту нельзя: модель принимает его имя за программу и пробует запустить через оболочку — проверено на живом сеансе.

type Image

type Image struct {
	Label  string // обозначение, то же что в метке текста: «44.1»
	Width  int
	Height int
	Format string // "jpeg" или "png"
	Data   []byte
}

Image — картинка из документа.

func Images

func Images(path string, maxBytes int64, opt ImageOptions) ([]Image, error)

Images достаёт картинки документа.

type ImageOptions

type ImageOptions struct {
	First     int // первая страница или раздел, начиная с 1
	Count     int // сколько их взять; 0 — все
	MinWidth  int
	MinHeight int
	MaxCount  int
}

ImageOptions ограничивает выборку картинок.

type Kind

type Kind string

Kind — формат документа.

const (
	KindNone     Kind = ""         // не документ
	KindPDF      Kind = "PDF"      //
	KindEPUB     Kind = "EPUB"     //
	KindText     Kind = "текст"    // .txt: единица ссылки — строка
	KindMarkdown Kind = "markdown" // .md: то же плюс заголовки разделов
)

func Detect

func Detect(head []byte) Kind

Detect определяет формат по началу файла.

func DetectFile

func DetectFile(path string) Kind

DetectFile определяет формат файла по содержимому, а не по расширению.

Для EPUB одного заголовка мало: строка типа бывает сжата, и признаком служит имя обязательного файла внутри архива. Поэтому читается начало файла, а у архивов — ещё и их оглавление (zipHasContainer).

func (Kind) Text

func (k Kind) Text() bool

Text сообщает, что документ текстовый: ссылка на него идёт по строкам, а не по страницам, и нарезается он иначе (internal/kb/textchunk.go).

type Part

type Part struct {
	Number int    // номер страницы или раздела, начиная с 1
	Title  string // заголовок раздела; у PDF пусто
	Text   string
	// Service — раздел служебный: оглавление или указатель книги EPUB
	// (epub.Section.Service). Нарезка помечает его куски служебными:
	// в оглавлении EPUB нет номеров страниц, и по строению куска его
	// не отличить от списка (18.09.2026).
	Service bool
}

Part — одна единица документа: страница PDF или раздел книги EPUB.

Нужна базе знаний: куски текста обязаны знать точный номер страницы, иначе ссылку в ответе модели нельзя проверить. Разбирать для этого заголовки «── страница N ──» из Doc.Text нельзя по двум причинам: такая строка может встретиться в тексте книги о вёрстке, а сами заголовки при индексации становятся мусорным термом — проверка на живой книге показала слово «страниц» в двадцатке самых частых.

type YearSource

type YearSource string

YearSource — откуда взялся год.

const (
	YearNone     YearSource = ""           // года нет
	YearFromName YearSource = "имя файла"  //
	YearFromText YearSource = "копирайт"   //
	YearFromMeta YearSource = "метаданные" //
)

func PickYear

func PickYear(path, head string, meta int) (int, YearSource)

PickYear выбирает год издания из трёх источников и говорит, откуда он взят.

head — начало текста документа (первые страницы), meta — год из метаданных файла, path — путь к нему.

func (YearSource) Approximate

func (s YearSource) Approximate() bool

Approximate сообщает, что году верить можно не вполне: он взят из даты файла.

Directories

Path Synopsis
Пакет probe — посмотреть глазами, что наш разбор достаёт из файла книги: хвост текста, прочитанного до нужной единицы, или одну страницу с признаками порчи.
Пакет probe — посмотреть глазами, что наш разбор достаёт из файла книги: хвост текста, прочитанного до нужной единицы, или одну страницу с признаками порчи.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL