スキップしてメイン コンテンツに移動

Making LLMs Read Word Files with Equations: Developing eqword2llm

 As a researcher, I frequently work with Word files in my daily work. When I want to have AI assistants analyze technical documents containing mathematical equations, I encountered a problem.

When you pass Word files directly to LLMs, equations are not correctly recognized.

To solve this challenge, I developed eqword2llm.

The Challenge: Why Existing Tools Are Insufficient

Limitations of Pandoc

Pandoc is an excellent conversion tool, but it cannot fully handle Word-specific issues.

For example, when converting a document that uses Word's equation numbering feature:


Equation with Field Code

$$\begin{array}{r}
\mathbf{E = m}\mathbf{c}^{\mathbf{2}}\mathbf{\#}\left( \mathbf{}\mathbf{\ SEQ\ Equation\ \backslash*\ ARABIC\ }\mathbf{}\mathbf{1}\mathbf{} \right)
\end{array}$$

Another Equation

$$\begin{array}{r}
\mathbf{F = ma\#}\left( \mathbf{}\mathbf{\ SEQ\ Equation\ \backslash*\ ARABIC\ }\mathbf{}\mathbf{2}\mathbf{} \right)
\end{array}$$

The internal Word field code SEQ Equation is output as-is. This prevents LLMs from correctly understanding the equations.

Limitations of Mammoth

Mammoth completely ignores equations. While it preserves heading structure, the essential equations disappear, making it unusable for scientific and technical documents.

Features of eqword2llm

1. Clean LaTeX Output

When converting the same document with eqword2llm:

Equation with Field Code

$$
E=mc^{2}
$$

Another Equation

$$
F=ma
$$

Field codes are removed, and only pure LaTeX equations are output.

2. Use of Standard LaTeX Environments

Let's compare the conversion of determinants.


Pandoc:

$$|A| = \left| \begin{matrix}
a & b \\
c & d
\end{matrix} \right| = ad - bc$$

eqword2llm:

$$
\left|A\right|=\begin{vmatrix}a & b \\ c & d\end{vmatrix}=ad-bc
$$

eqword2llm uses the standard determinant environment \begin{vmatrix}. The code is 27% shorter and the intent is clearer.

3. LLM-Ready Output Formats (v0.4.0+)

Starting from v0.4.0, output formats designed for LLM input are supported.

Structured Format (with YAML Frontmatter)

eqword2llm document.docx --format structured

Output:

---
format: eqword2llm/v1
source: document.docx
stats:
  sections: 3
  equations: 5
  headings: 8
equations:
  - id: 1
    latex: "E = mc^{2}"
    type: block
  - id: 2
    latex: "F = ma"
    type: block
---

# Document content...

A list of equations and statistics are attached as metadata. This makes it easier for LLMs to understand the document structure.

Prompt Format (LLM Prompt Generation)

eqword2llm document.docx --format prompt

Outputs in a format that can be directly passed to LLM APIs:

# Document for Analysis

## Document Information
- Source: document.docx
- Equations: 5
- Sections: 3

## Content

[Converted Markdown]

---

## Instructions

This document was converted from a Word file using eqword2llm.
Mathematical equations are formatted in LaTeX:
- Block equations: `$$...$$`
- Inline equations: `$...$`

Please analyze the content. If you need clarification about any equation or
concept, ask the user.

Usage

Installation

pip install eqword2llm

Zero dependencies. Works with Python standard library only.

CLI

# Basic conversion
eqword2llm paper.docx -o paper.md

# Without equation numbers
eqword2llm paper.docx -o paper.md --no-equation-numbers

# With metadata
eqword2llm paper.docx -o paper.md --format structured

# LLM prompt format
eqword2llm paper.docx --format prompt | pbcopy  # Copy to clipboard

Python API

from eqword2llm import WordToMarkdownConverter

# Basic conversion
converter = WordToMarkdownConverter("paper.docx")
markdown = converter.convert()

# Conversion with metadata
result = converter.convert_structured()
print(f"Number of equations: {result.metadata.equation_count}")
for eq in result.metadata.equations:
    print(f"  [{eq.id}] {eq.latex}")

# LLM prompt generation
prompt = converter.to_llm_prompt()
# Add custom instructions
prompt = converter.to_llm_prompt(
    instructions="Please explain the main equations in this document."
)

Integration with Claude API

import anthropic
from eqword2llm import WordToMarkdownConverter

# Convert Word document to LLM prompt
converter = WordToMarkdownConverter("research_paper.docx")
prompt = converter.to_llm_prompt()

# Send to Claude
client = anthropic.Anthropic()
response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=4096,
    messages=[{"role": "user", "content": prompt}]
)

print(response.content[0].text)

How Conversion Works

Word documents (.docx) are actually ZIP files containing XML internally. Equations are written in OMML (Office Math Markup Language) format.

Conversion Flow

eqword2llm parses this OMML and converts it to LaTeX format. During conversion:

  1. Word field codes (such as SEQ Equation) are removed
  2. Appropriate LaTeX environments are selected (vmatrixbmatrixpmatrix, etc.)
  3. Mathematical functions are converted to standard form (lim → \limsin → \sin)
  4. Heading structure is preserved in Markdown format

Comparison with Pandoc

FeaturePandoceqword2llm
Equation conversion△ Partial
Field code processing
Markdown headings
Determinant environment\left|...\right|\begin{vmatrix}
Vector notation\overset{\rightarrow}{v}\vec{v}
Metadata output
LLM prompt generation
DependenciesManyZero

For detailed comparison, see comparison-details.md.

Future Plans

Features currently under consideration:

  • Table conversion: Word tables → Markdown tables
  • Image extraction: External file export of embedded images
  • Cross-references: Maintaining equation references

Summary

eqword2llm is a tool focused on one thing: "making LLMs accurately read Word documents containing equations."

I hope you'll find it useful when you want AI assistants to analyze documents containing equations, such as research papers, technical reports, and lecture materials.


Repositoryhttps://github.com/manabelab/eqword2llm 

PyPIhttps://pypi.org/project/eqword2llm/ 

License: MIT

コメント

このブログの人気の投稿

Sourcetreeを使って、特定のブランチやタグをローカルに再現する方法 - フェッチ(fetch)を使おう -

今や、プログラミング開発に欠かせない存在となったGit。上司や同僚から「修正版をブランチ"devlop"にプッシュしたから、それを反映させてね」「安定版はタグ”v1.2”だから、よろしくね」と言われることもあるでしょう。その時に「どうやってブランチやタグって変えたらいいかわからない」「そもそも言われたブランチやタグが見当たらないんだけど…」となったら、とても困ってしまいます。そんなときにどうしたらいいか、本記事では Sourcetree を使用している環境を想定して、おすすめの手順を紹介します。環境によって具体的な操作は異なるものの、手順自体は一緒です。基本的には、 フェッチ(fetch)をしてリモートリポジトリをちゃんと確認 すればよいのです。 1. コミットしていないファイルをなくそう まず、Sourcetreeのコミット一覧に「コミットされていない変更があります」とあるかどうか確認します(下記図赤下線参照)。「コミット」の箇所に青マークでコミットされてないファイル数も表示されます(下記図赤枠参照)。その変更をコミットするか、破棄するかを行い、コミットされていない変更がない、きれいな状態にしましょう。そうしないと、後の作業中にエラー等が発生して進まなくなってしまいます。 2. フェッチしよう フェッチとは、 リモートリポジトリの最新の履歴の取得だけを行う 操作です。これによって、自分から見えていなかったブランチ・タグが見えるようになります。ブランチへのマージが伴うプッシュやプルと異なり、単に履歴を取得するだけなので、意図しないコミットが発生しません。安心して実施しましょう。Sourcetreeでは下記図赤枠部分をクリックすれば、フェッチを行うことができます。 その際出てくるポップアップで「すべてのリモートからフェッチ」「全てのタグを取得」をチェックしてください(下図赤下線参照)。 3. 目的のブランチ・タグを見つけよう 目的のブランチ・タグを見つけるのに便利なのが、Sourcetreeの左側領域にある「ブランチ」「タグ」「リモート」「スタッシュ」です。目的のブランチを探したい場合は「リモート」をクリックして現れる「origin」をさらにクリックしましょう。これでリモート上にあるブランチの一覧を見ることができます。タグの場合は「タグ」をクリック...

SourcetreeでGitHubのプライベートリポジトリをクローンする

Sourcetree は、初心者でも操作しやすいgitのGUIツールです。基本無料のソフトなので、あらゆる人が導入・利用しやすいという利点を持ちます。ですが、GitHubで非公開、つまりプライベートのリポジトリを取り扱う場合には、初期設定に一工夫が必要です。 本記事で紹介する設定の流れは以下の通りです。前提として、1)GitHubのアカウントとプライベートリポジトリを既に所有しているが、2)Sourcetreeを自身のPCにまだインストールしていない状態を想定しています。 GitHubのPersonal access tokenを作成する Sourcetreeを自身のPCにインストールする SourcetreeにGitHubのアカウントを登録する プライベートリポジトリをクローンする 今回はPersonal access tokenという手法を用います。秘密鍵や公開鍵が必要なSSH接続とは異なり、アカウント名とパスワードのみで認証できます。そのため、アカウント管理がより重要となりますので、 2段階認証 でより強力なアカウント保護をおこなうことをお勧めします。また、本記事で紹介するのはWindowsでの利用です。Macでもほぼ同じ流れになるかと思いますが、試してはいませんのでご了承ください。 1. GitHubのPersonal access tokenを作成する GitHubのPersonal access tokenとは、GitHub API またはコマンドラインを使用するときに GitHub への認証でパスワードの代わりに使用できる機能です。このトークンを自身のGitHubアカウントで作成することで、Sourcetreeからプライベートリポジトリにアクセスすることができるようになります。具体的な作り方は下記のGitHub公式ページををご参考ください。 Personal access tokenの作成方法: https://docs.github.com/ja/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token ポイントは手順8に書かれているS ...

GitHubのプライベートリポジトリからクローンできてもプッシュできないときの対処法 - Write権限の有無を確認しよう -

 以前、 SourceTreeを使って、GitHubのプライベートリポジトリにアクセスする方法 を記事にしました。その際、プライベートリポジトリからクローンできても、プッシュできない!という現象に遭遇するときがあります。下記のように、”そんなリポジトリは存在しないよ”というエラーが表示されます。 remote: Repository not found. もし、そのリポジトリがOrganaizationに属するものならば、 あなたのアカウントの権限が”Read”のみで、”Write”になっていない 可能性があります。権限に関してOrganaizationの管理者に確認してもらいましょう。 管理者がどういうルールで権限を決定しているのかによって、対応が変わるかと思います。一番手っ取り早い対応は、全てのメンバーのデフォルト権限を”Write”に変えてしまえばよいでしょう。Organaizationのページの右上にある「Settings」をクリックし、左に表示されるメニューから「Member privileges」を選択します。すると、左下のような画面が表示されますので、赤枠で囲っている「Base permissions」のプルダウン部分を"Write"に変更してください。 その他に、リポジトリ毎にアクセスできるメンバーを管理したい場合もあるかと思います。その際にはリポジトリの「Settings」→「Manage access」を選択し、設定等を変更してください。