latex.folders

Create and manage folders to house Obsidian.md notes correspnoding to parts divided by the latex.divide module.
import glob
import shutil
import tempfile


from fastcore.test import ExceptionExpected, test_eq
from pathvalidate import validate_filename

from trouver.helper.files_and_folders import text_from_file
from trouver.helper.tests import _test_directory

from trouver.markdown.obsidian.personal.reference import (
    delete_reference_folder
)

Identify sections and subsections to make folders for a reference.


source

section_and_subsection_titles_from_latex_parts

 section_and_subsection_titles_from_latex_parts
                                                 (parts:list[tuple[str,str
                                                 ]])

*Return a list of lists of titles for the sections and subsections in parts

Unnumbered sections get their own list. Unnumbered subsections are also included in lists. All the titles are striped (of leading and trailing whitespaces).*

Type Details
parts list An output of divide_latex_text
Returns list Each list corresponds to a section. The first entry of the list is the title of the section and the other entries are the titles of the subsections.

In the following example, the Environments are numbered Theorem 1, Corollary 2, Definition 3, etc. Also note that there is some content before the very first (explicitly defined) section, so there is a section given by the UNTITLED_SECTION_TITLE constant.

parts = [
    ['1', 'For this document, the `theorem` counter is not reset whenever a new section begins.\n\nA similar numbering scheme can be accomplished by importing \\verb|amsmath| and invoking the code \\verb|\\numberwithin{theorem}{part}| in the preamble.'],
    ['1. Introduction', '\\section{Introduction}'],
    ['Theorem 1.', '\\begin{theorem}\nThis is Theorem 1.\n\\end{theorem}'],
    ['Corollary 2.', '\\begin{corollary}\nThis is Corollary 2.\n\\end{corollary}'],
    ['Remark', '\\begin{remark*}\nThis is a remark. It is unnumbered and it does not affect the numberings of other environments.\n\\end{remark*}'],
    ['Definition 3.', '\\begin{definition}\nThis is Definition 3.\n\\end{definition}'],
    ['2. Another Section', '\\section{Another Section}'],
    ['Theorem 4.', '\\begin{theorem}\nThis is Theorem 4.\n\\end{theorem}'], ['2', 'And we might get a corollary!'],
    ['Corollary 5.', '\\begin{corollary}\nThis is Corollary 5.\n\\end{corollary}'],
    ['Definition 6.', '\\begin{definition}\nThis is Definition 6.\n\\end{definition}']]
sample_output = section_and_subsection_titles_from_latex_parts(parts)
test_eq(sample_output, [[UNTITLED_SECTION_TITLE], ['1. Introduction'], ['2. Another Section']])

In contrast, the following example has environments numbered by sections:

parts = [
    ['1', 'This document resets its `theorem` counter whenever a new section begins.'], 
    ['1. Introduction', '\\section{Introduction}'],
    ['Theorem 1.1.', '\\begin{theorem}\nThis is Theorem 1.1.\n\\end{theorem}'],
    ['Corollary 1.2.', '\\begin{corollary}\nThis is Corollary 1.2.\n\\end{corollary}'],
    ['Remark', '\\begin{remark*}\nThis is a remark. It is unnumbered and it does not affect the numberings of other environments.\n\\end{remark*}'],
    ['Definition 1.3.', '\\begin{definition}\nThis is Definition 1.3.\n\\end{definition}'],
    ['2. Another Section', '\\section{Another Section}'],
    ['Theorem 2.1.', '\\begin{theorem}\nThis is Theorem 2.1.\n\\end{theorem}'],
    ['Corollary 2.2.', '\\begin{corollary}\nThis is Corollary 2.2.\n\\end{corollary}'],
    ['Definition 2.3.', '\\begin{definition}\nThis is Definition 2.3.\n\\end{definition}']]
test_eq(sample_output, [[UNTITLED_SECTION_TITLE], ['1. Introduction'], ['2. Another Section']])

The below example is derived from a LaTeX document in which significant content is present before any particular sections. See the nbs\_tests\latex_examples\latex_example_with_content_before_sections folder. Also see https://arxiv.org/abs/1111.3607 for an example of a paper with significant content priori to any explicitly defined sections.

parts = [
    ['abstract', "\\begin{abstract}\nI'm an abstract\n\\end{abstract}"],
    ['1', '\\maketitle\n\nI want to talk about things but notice that this part does not belong to a section!'],
    ['Theorem 1.', "\\begin{theorem}\\label{th:some_theorem}\nI'm a theorem.\n\\end{theorem}"],
    ['2', 'Blah blah blah'],
    ['Theorem 2.', '\\begin{theorem}\\label{th:some_other_theorem}\nImpart me with mathematical knowledge!\n\\end{theorem}'],
    ['3', 'Maybe a corollary'],
    ['Corollary 3.', '\\begin{corollary}\\label{cor:a_corollary}\nI immediately follow from the above theorem.\n\\end{corollary}'],
    ['4', 'More stuff!'],
    ['Corollary 4.', '\\begin{corollary}\\label{cor:another_corollary}\nMore delicious mathematical knowledge.\n\\end{corollary}'],
    ['5', 'Maybe you could describe how we demonstrate this corollary.'],
    ['1. Proof of Theorem~\\ref{th:main}', '\\section{Proof of Theorem~\\ref{th:main}}'],
    ['6', 'Now this is finally in a section.'],
    ['Lemma 5.', '\\begin{lemma}\nSome lemma\n\\end{lemma}\\begin{proof}\nMaximum effort!\n\\end{proof}'],
    ['7', 'Blah blah blah.'],
    ['1.1. This is a subsection', '\\subsection{This is a subsection}'],
    ['8', "I'm about one thing."],
    ['1.2. This is another subsection', '\\subsection{This is another subsection}'],
    ['9', "I'm about another thing."]] 
sample_output = section_and_subsection_titles_from_latex_parts(parts)
test_eq(sample_output, [[UNTITLED_SECTION_TITLE], ['1. Proof of Theorem~\\ref{th:main}', '1.1. This is a subsection', '1.2. This is another subsection']])

The below example is derived from a LaTeX document with a \numberwithin{equation}{subsection} in which the theorem-like environments are numbered with the equation counter. In particular, theorem-like environments and subsections are counted together.

Also, note that the below example starts with an explicitly defined section, so there is no section given by the UNTITLED_SECTION_TITLE constant.

parts = [
    ['1. This is section 1', '\\section{This is section 1}'],
    ['1.1. Theorem.', '\\begin{thm}\nThis is 1.1. Theorem. Note that the \\verb|\\swapnumbers| command is invoked in the preamble.\n\\end{thm}'],
    ['1.2. This is 1.2. subsection.', '\\subsection{This is 1.2. subsection.}'],
    ['1', 'Note that the equation counter is numbered within the subsection counter and that the theorem-like environments are numbered with the equation counter.\n\n\\subsubsection{This is 1.2.1. Subsubsection}'],
    ['1. Remark.', '\\begin{remark}\nThis is an 1. Remark. Note that \\verb|\\remark| has a counter separate from those of many of the other theorem-like environments.\n\\end{remark}'],
    ['Remark', '\\begin{rem*}\nThis is an unnumbered Remark.\n\\end{rem*}'],
    ['1.3. Proposition.', '\\begin{prop}\nThis is 1.3. Proposition.\n\\end{prop}'],
    ['Unnumbered section', '\\section*{Unnumbered section}'],
    ['1.1. Theorem.', '\\begin{thm}\nThis is 1.4. Theorem.\n\\end{thm}'],
    ['2. This is Section 2', '\\section{This is Section 2}'],
    ['2.1. Theorem.', '\\begin{thm}\nThis is 2.1. Theorem\n\\end{thm}']]
sample_output = section_and_subsection_titles_from_latex_parts(parts)
test_eq(sample_output, [['1. This is section 1', '1.2. This is 1.2. subsection.'], ['Unnumbered section'], ['2. This is Section 2']])

The titles of the sections are stripped of their leading and trailing whitespaces (if available)

# The below example makes sure that titles are stripped
parts = [
    ['   1. Section with an unnumbered subsection   ', '\\section{Section with an unnumbered subsection}'],
    ['1', 'This is a section with an unnumbered subsection'],
    ['1.1. ', '\\subsection{}']
]
sample_output = section_and_subsection_titles_from_latex_parts(parts)
test_eq(sample_output, [['1. Section with an unnumbered subsection', '1.1.']])
dir = _test_directory() / 'latex_examples' / 'latex_example_with_plenty_of_sections_and_subsections'
file = dir / 'main.tex'
text = text_from_file(file)
parts = divide_latex_text(text, dir) 
print(parts)
sample_output = section_and_subsection_titles_from_latex_parts(parts)
test_eq(sample_output,
        [['1. This is section 1', '1.1. This is section 1.1', '1.2. This is section 1.2'],
         ['2. This is section 2'],
         ['3. This is section 3', '3.1. This is section 3.1', '3.2. This is section 3.2', '3.3. This is section 3.3', '3.4. This is section 3.4']])
[['1. This is section 1', '\\section{This is section 1}\n\n'], ['1.1. This is section 1.1', '\\subsection{This is section 1.1}\n\n'], ['1.2. This is section 1.2', '\\subsection{This is section 1.2}\n\n\n'], ['2. This is section 2', '\\section{This is section 2}\n\n\n'], ['3. This is section 3', '\\section{This is section 3}\n\n'], ['3.1. This is section 3.1', '\\subsection{This is section 3.1}\n\n'], ['3.2. This is section 3.2', '\\subsection{This is section 3.2}\n\n'], ['3.3. This is section 3.3', '\\subsection{This is section 3.3}\n\n'], ['3.4. This is section 3.4', '\\subsection{This is section 3.4}\n\n']]