Source code for langchain_community.document_loaders.bibtex
import logging
import re
from pathlib import Path
from typing import Any, Iterator, List, Mapping, Optional
from langchain_core.documents import Document
from langchain_community.document_loaders.base import BaseLoader
from langchain_community.utilities.bibtex import BibtexparserWrapper
logger = logging.getLogger(__name__)
[docs]class BibtexLoader(BaseLoader):
"""加载一个`bibtex`文件。
每个文档代表`bibtex`文件中的一个条目。
如果在`file` bibtex字段中存在PDF文件,则将原始PDF加载到文档文本中。如果不存在这样的文件条目,则使用`abstract`字段。"""
[docs] def __init__(
self,
file_path: str,
*,
parser: Optional[BibtexparserWrapper] = None,
max_docs: Optional[int] = None,
max_content_chars: Optional[int] = 4_000,
load_extra_metadata: bool = False,
file_pattern: str = r"[^:]+\.pdf",
):
"""初始化BibtexLoader。
参数:
file_path: bibtex文件的路径。
parser: 要使用的解析器。如果为None,则使用默认解析器。
max_docs: 要加载的关联文档的最大数量。使用-1表示没有限制。
max_content_chars: 从PDF中加载的最大字符数。
load_extra_metadata: 是否从PDF中加载额外的元数据。
file_pattern: 用于匹配bibtex中文件名的正则表达式模式。
"""
self.file_path = file_path
self.parser = parser or BibtexparserWrapper()
self.max_docs = max_docs
self.max_content_chars = max_content_chars
self.load_extra_metadata = load_extra_metadata
self.file_regex = re.compile(file_pattern)
def _load_entry(self, entry: Mapping[str, Any]) -> Optional[Document]:
import fitz
parent_dir = Path(self.file_path).parent
# regex is useful for Zotero flavor bibtex files
file_names = self.file_regex.findall(entry.get("file", ""))
if not file_names:
return None
texts: List[str] = []
for file_name in file_names:
try:
with fitz.open(parent_dir / file_name) as f:
texts.extend(page.get_text() for page in f)
except FileNotFoundError as e:
logger.debug(e)
content = "\n".join(texts) or entry.get("abstract", "")
if self.max_content_chars:
content = content[: self.max_content_chars]
metadata = self.parser.get_metadata(entry, load_extra=self.load_extra_metadata)
return Document(
page_content=content,
metadata=metadata,
)
[docs] def lazy_load(self) -> Iterator[Document]:
"""使用bibtexparser加载bibtex文件,并获取文章文本以及文章元数据。
参见https://bibtexparser.readthedocs.io/en/master/
返回:
一个包含文档文本格式的文档列表
"""
try:
import fitz # noqa: F401
except ImportError:
raise ImportError(
"PyMuPDF package not found, please install it with "
"`pip install pymupdf`"
)
entries = self.parser.load_bibtex_entries(self.file_path)
if self.max_docs:
entries = entries[: self.max_docs]
for entry in entries:
doc = self._load_entry(entry)
if doc:
yield doc