#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Test file for: check_float_order.py
import os
import sys
from pathlib import Path
# Add scripts/python to path for imports
ROOT_DIR = Path(__file__).resolve().parent.parent.parent
sys.path.insert(0, str(ROOT_DIR / "scripts" / "python"))
from check_float_order import ( # noqa: E402
check_order,
extract_number_and_name,
find_labels,
find_references,
)
# ====================================================================
# Tests for extract_number_and_name
# ====================================================================
def test_extract_number_and_name_basic():
"""Test basic numbered key extraction."""
num, name = extract_number_and_name("04_modules")
assert num == 4
assert name == "modules"
def test_extract_number_and_name_no_prefix():
"""Test key without numeric prefix."""
num, name = extract_number_and_name("no_number")
assert num is None
assert name == "no_number"
def test_extract_number_and_name_number_only():
"""Test key with only a number."""
num, name = extract_number_and_name("05")
assert num == 5
assert name == ""
def test_extract_number_and_name_two_digit():
"""Test two-digit numbered key."""
num, name = extract_number_and_name("12_results")
assert num == 12
assert name == "results"
def test_extract_number_and_name_leading_zero():
"""Test key with leading zero."""
num, name = extract_number_and_name("01_intro")
assert num == 1
assert name == "intro"
# ====================================================================
# Tests for find_references
# ====================================================================
def test_find_references_in_order(tmp_path):
"""Test finding references that are in correct order."""
content_dir = tmp_path / "contents"
content_dir.mkdir()
# Create introduction.tex with refs to 01, 02
intro_file = content_dir / "introduction.tex"
intro_file.write_text(
r"""
\section{Introduction}
See \ref{fig:01_first} for details.
Also see \ref{fig:02_second}.
"""
)
# Create results.tex with ref to 03
results_file = content_dir / "results.tex"
results_file.write_text(
r"""
\section{Results}
The results in \ref{fig:03_third} show this.
"""
)
refs = find_references(content_dir, "fig")
assert len(refs) == 3
assert refs[0][0] == "01_first"
assert refs[1][0] == "02_second"
assert refs[2][0] == "03_third"
def test_find_references_out_of_order(tmp_path):
"""Test finding references that are out of order."""
content_dir = tmp_path / "contents"
content_dir.mkdir()
# Create introduction.tex with refs in wrong order
intro_file = content_dir / "introduction.tex"
intro_file.write_text(
r"""
\section{Introduction}
See \ref{fig:03_third} first.
Then \ref{fig:01_first}.
Finally \ref{fig:02_second}.
"""
)
refs = find_references(content_dir, "fig")
assert len(refs) == 3
# Should preserve order of first appearance
assert refs[0][0] == "03_third"
assert refs[1][0] == "01_first"
assert refs[2][0] == "02_second"
def test_find_references_empty(tmp_path):
"""Test finding references when no refs exist."""
content_dir = tmp_path / "contents"
content_dir.mkdir()
# Create file without any refs
intro_file = content_dir / "introduction.tex"
intro_file.write_text(
r"""
\section{Introduction}
This section has no figure references.
"""
)
refs = find_references(content_dir, "fig")
assert len(refs) == 0
def test_find_references_multiple_types(tmp_path):
"""Test finding references for different float types (fig vs tab)."""
content_dir = tmp_path / "contents"
content_dir.mkdir()
intro_file = content_dir / "introduction.tex"
intro_file.write_text(
r"""
\section{Introduction}
See \ref{fig:01_figure} and \ref{tab:01_table}.
Also \ref{fig:02_another} and \ref{tab:02_more}.
"""
)
fig_refs = find_references(content_dir, "fig")
tab_refs = find_references(content_dir, "tab")
assert len(fig_refs) == 2
assert len(tab_refs) == 2
assert fig_refs[0][0] == "01_figure"
assert tab_refs[0][0] == "01_table"
def test_find_references_duplicate_refs(tmp_path):
"""Test that duplicate references are only counted once."""
content_dir = tmp_path / "contents"
content_dir.mkdir()
intro_file = content_dir / "introduction.tex"
intro_file.write_text(
r"""
\section{Introduction}
See \ref{fig:01_first}.
Again, see \ref{fig:01_first}.
And \ref{fig:02_second}.
"""
)
refs = find_references(content_dir, "fig")
# Should only count first appearance
assert len(refs) == 2
assert refs[0][0] == "01_first"
assert refs[1][0] == "02_second"
# ====================================================================
# Tests for find_labels
# ====================================================================
def test_find_labels_in_caption_files(tmp_path):
"""Test finding labels in caption files."""
content_dir = tmp_path / "contents"
figures_dir = content_dir / "figures" / "caption_and_media"
figures_dir.mkdir(parents=True)
# Create caption files with labels
caption1 = figures_dir / "01_first.tex"
caption1.write_text(r"\caption{First figure}\label{fig:01_first}")
caption2 = figures_dir / "02_second.tex"
caption2.write_text(r"\caption{Second figure}\label{fig:02_second}")
labels = find_labels(content_dir, "fig")
assert len(labels) == 2
assert "01_first" in labels
assert "02_second" in labels
assert labels["01_first"]["source"] == "caption_file"
assert labels["02_second"]["source"] == "caption_file"
def test_find_labels_inline(tmp_path):
"""Test finding labels inline in content tex files."""
content_dir = tmp_path / "contents"
content_dir.mkdir()
intro_file = content_dir / "introduction.tex"
intro_file.write_text(
r"""
\section{Introduction}
\begin{figure}
\includegraphics{image.png}
\caption{An inline figure}
\label{fig:01_inline}
\end{figure}
"""
)
labels = find_labels(content_dir, "fig")
assert len(labels) == 1
assert "01_inline" in labels
assert labels["01_inline"]["source"] == "inline"
def test_find_labels_tables(tmp_path):
"""Test finding table labels."""
content_dir = tmp_path / "contents"
tables_dir = content_dir / "tables" / "caption_and_media"
tables_dir.mkdir(parents=True)
caption1 = tables_dir / "01_results.tex"
caption1.write_text(r"\caption{Results table}\label{tab:01_results}")
labels = find_labels(content_dir, "tab")
assert len(labels) == 1
assert "01_results" in labels
assert labels["01_results"]["source"] == "caption_file"
# ====================================================================
# Tests for check_order
# ====================================================================
def test_check_order_passing(tmp_path, capsys):
"""Test check_order with sequential references."""
content_dir = tmp_path / "contents"
figures_dir = content_dir / "figures" / "caption_and_media"
figures_dir.mkdir(parents=True)
# Create content with refs in order
intro_file = content_dir / "introduction.tex"
intro_file.write_text(
r"""
\section{Introduction}
See \ref{fig:01_first} and \ref{fig:02_second}.
"""
)
# Create corresponding caption files
(figures_dir / "01_first.tex").write_text(r"\label{fig:01_first}")
(figures_dir / "02_second.tex").write_text(r"\label{fig:02_second}")
is_ok, refs, mapping = check_order(content_dir, "fig", "Figure Test")
assert is_ok is True
assert len(refs) == 2
assert len(mapping) == 0 # No remapping needed
def test_check_order_failing(tmp_path, capsys):
"""Test check_order with out-of-order references."""
content_dir = tmp_path / "contents"
figures_dir = content_dir / "figures" / "caption_and_media"
figures_dir.mkdir(parents=True)
# Create content with refs out of order
intro_file = content_dir / "introduction.tex"
intro_file.write_text(
r"""
\section{Introduction}
See \ref{fig:03_third} first, then \ref{fig:01_first}, then \ref{fig:02_second}.
"""
)
# Create corresponding caption files
(figures_dir / "01_first.tex").write_text(r"\label{fig:01_first}")
(figures_dir / "02_second.tex").write_text(r"\label{fig:02_second}")
(figures_dir / "03_third.tex").write_text(r"\label{fig:03_third}")
is_ok, refs, mapping = check_order(content_dir, "fig", "Figure Test")
assert is_ok is False
assert len(refs) == 3
# Should map to sequential order based on appearance
assert "03_third" in mapping
assert "01_first" in mapping
assert "02_second" in mapping
assert mapping["03_third"] == "01_third"
assert mapping["01_first"] == "02_first"
assert mapping["02_second"] == "03_second"
def test_check_order_no_references(tmp_path, capsys):
"""Test check_order when no references exist."""
content_dir = tmp_path / "contents"
content_dir.mkdir()
intro_file = content_dir / "introduction.tex"
intro_file.write_text(
r"""
\section{Introduction}
No figures here.
"""
)
is_ok, refs, mapping = check_order(content_dir, "fig", "Figure Test")
assert is_ok is True
assert len(refs) == 0
assert len(mapping) == 0
def test_check_order_non_numbered_refs(tmp_path, capsys):
"""Test check_order with non-numbered reference keys."""
content_dir = tmp_path / "contents"
content_dir.mkdir()
intro_file = content_dir / "introduction.tex"
intro_file.write_text(
r"""
\section{Introduction}
See \ref{fig:schematic} and \ref{fig:workflow}.
"""
)
is_ok, refs, mapping = check_order(content_dir, "fig", "Figure Test")
assert is_ok is True # Non-numbered refs pass
assert len(refs) == 2
assert len(mapping) == 0
def test_check_order_mixed_numbered_unnumbered(tmp_path, capsys):
"""Test check_order with mix of numbered and unnumbered refs."""
content_dir = tmp_path / "contents"
content_dir.mkdir()
intro_file = content_dir / "introduction.tex"
intro_file.write_text(
r"""
\section{Introduction}
See \ref{fig:01_intro}, \ref{fig:schematic}, and \ref{fig:02_results}.
"""
)
is_ok, refs, mapping = check_order(content_dir, "fig", "Figure Test")
assert is_ok is True # Sequential numbered refs (01, 02)
assert len(refs) == 3
if __name__ == "__main__":
import pytest
pytest.main([os.path.abspath(__file__), "-v"])
# --------------------------------------------------------------------------------
# Start of Source Code from: /home/ywatanabe/proj/scitex-writer/scripts/python/check_float_order.py
# --------------------------------------------------------------------------------
# #!/usr/bin/env python3
# # -*- coding: utf-8 -*-
# # File: scripts/python/check_float_order.py
# # Purpose: Validate and auto-renumber figure/table reference ordering in LaTeX manuscripts
# # Usage:
# # python check_float_order.py [project_dir] [--fix] [--doc-type manuscript|supplementary]
# #
# # Checks that figures and tables are referenced in numerical order in the text.
# # With --fix, renumbers files and updates all \ref{} and \label{} to match appearance order.
#
# import argparse
# import os
# import re
# import shutil
# import sys
# from collections import OrderedDict
# from pathlib import Path
#
# # ANSI colors
# GREEN = "\033[0;32m"
# YELLOW = "\033[1;33m"
# RED = "\033[0;31m"
# DIM = "\033[0;90m"
# BOLD = "\033[1m"
# NC = "\033[0m"
#
# --------------------------------------------------------------------------------
# End of Source Code from: /home/ywatanabe/proj/scitex-writer/scripts/python/check_float_order.py
# --------------------------------------------------------------------------------