14
14
from _pytask .nodes import FilePathNode
15
15
from _pytask .nodes import PythonFunctionTask
16
16
from _pytask .parametrize import _copy_func
17
- from _pytask .shared import to_list
18
17
19
18
20
19
DEFAULT_OPTIONS = ["--pdf" , "--interaction=nonstopmode" , "--synctex=1" , "--cd" ]
@@ -37,45 +36,9 @@ def latex(options: Optional[Union[str, Iterable[str]]] = None):
37
36
return options
38
37
39
38
40
- def compile_latex_document (depends_on , produces , latex ):
41
- """Compile a LaTeX document.
42
-
43
- This function replaces the dummy function of an LaTeX task. It is a nice wrapper
44
- around subprocess.
45
-
46
- The output folder needs to be declared as a relative path to the directory where the
47
- latex source lies.
48
-
49
- 1. It must be relative because bibtex / biber, which is necessary for
50
- bibliographies, does not accept full paths as a safety measure.
51
- 2. Due to the ``--cd`` flag, latexmk will change the directory to the one where the
52
- source files are. Thus, relative to the latex sources.
53
-
54
- See this `discussion on Github
55
- <https://github.com/James-Yu/LaTeX-Workshop/issues/1932#issuecomment-582416434>`_
56
- for additional information.
57
-
58
- """
59
- latex_document = to_list (depends_on )[0 ]
60
- compiled_document = to_list (produces )[0 ]
61
-
62
- if latex_document .stem != compiled_document .stem :
63
- latex .append (f"--jobname={ compiled_document .stem } " )
64
-
65
- # See comment in doc string.
66
- out_relative_to_latex_source = Path (
67
- os .path .relpath (compiled_document .parent , latex_document .parent )
68
- ).as_posix ()
69
-
70
- subprocess .run (
71
- [
72
- "latexmk" ,
73
- * latex ,
74
- f"--output-directory={ out_relative_to_latex_source } " ,
75
- f"{ latex_document .as_posix ()} " ,
76
- ],
77
- check = True ,
78
- )
39
+ def compile_latex_document (latex ):
40
+ """Replaces the dummy function provided by the user."""
41
+ subprocess .run (latex , check = True )
79
42
80
43
81
44
@hookimpl
@@ -88,52 +51,56 @@ def pytask_collect_task(session, path, name, obj):
88
51
89
52
"""
90
53
if name .startswith ("task_" ) and callable (obj ) and has_marker (obj , "latex" ):
91
- # Collect the task.
92
54
task = PythonFunctionTask .from_path_name_function_session (
93
55
path , name , obj , session
94
56
)
95
- latex_function = _copy_func (compile_latex_document )
96
- latex_function .pytaskmark = copy .deepcopy (task .function .pytaskmark )
97
-
98
- merged_mark = _merge_all_markers (task )
99
- args = latex (* merged_mark .args , ** merged_mark .kwargs )
100
- latex_function = functools .partial (latex_function , latex = args )
101
-
102
- task .function = latex_function
103
57
104
58
return task
105
59
106
60
107
61
@hookimpl
108
- def pytask_collect_task_teardown (task ):
109
- """Perform some checks.
110
-
111
- Remove check for task is none with pytask 0.0.9.
112
-
113
- """
114
- if task is not None and get_specific_markers_from_task (task , "latex" ):
115
- if (len (task .depends_on ) == 0 ) or (
116
- not (
117
- isinstance (task .depends_on [0 ], FilePathNode )
118
- and task .depends_on [0 ].value .suffix == ".tex"
119
- )
120
- ):
62
+ def pytask_collect_task_teardown (session , task ):
63
+ """Perform some checks."""
64
+ if get_specific_markers_from_task (task , "latex" ):
65
+ source = _get_node_from_dictionary (
66
+ task .depends_on , session .config ["latex_source_key" ]
67
+ )
68
+ if not (isinstance (source , FilePathNode ) and source .value .suffix == ".tex" ):
121
69
raise ValueError (
122
70
"The first or sole dependency of a LaTeX task must be the document "
123
71
"which will be compiled and has a .tex extension."
124
72
)
125
73
126
- if (len (task .produces ) == 0 ) or (
127
- not (
128
- isinstance (task .produces [0 ], FilePathNode )
129
- and task .produces [0 ].value .suffix in [".pdf" , ".ps" , ".dvi" ]
130
- )
74
+ document = _get_node_from_dictionary (
75
+ task .produces , session .config ["latex_document_key" ]
76
+ )
77
+ if not (
78
+ isinstance (document , FilePathNode )
79
+ and document .value .suffix in [".pdf" , ".ps" , ".dvi" ]
131
80
):
132
81
raise ValueError (
133
82
"The first or sole product of a LaTeX task must point to a .pdf, .ps "
134
83
"or .dvi file which is the compiled document."
135
84
)
136
85
86
+ latex_function = _copy_func (compile_latex_document )
87
+ latex_function .pytaskmark = copy .deepcopy (task .function .pytaskmark )
88
+
89
+ merged_mark = _merge_all_markers (task )
90
+ args = latex (* merged_mark .args , ** merged_mark .kwargs )
91
+ options = _prepare_cmd_options (session , task , args )
92
+ latex_function = functools .partial (latex_function , latex = options )
93
+
94
+ task .function = latex_function
95
+
96
+
97
+ def _get_node_from_dictionary (obj , key , fallback = 0 ):
98
+ if isinstance (obj , Path ):
99
+ pass
100
+ elif isinstance (obj , dict ):
101
+ obj = obj .get (key ) or obj .get (fallback )
102
+ return obj
103
+
137
104
138
105
def _merge_all_markers (task ):
139
106
"""Combine all information from markers for the compile latex function."""
@@ -142,3 +109,51 @@ def _merge_all_markers(task):
142
109
for mark_ in latex_marks [1 :]:
143
110
mark = mark .combined_with (mark_ )
144
111
return mark
112
+
113
+
114
+ def _prepare_cmd_options (session , task , args ):
115
+ """Prepare the command line arguments to compile the LaTeX document.
116
+
117
+ The output folder needs to be declared as a relative path to the directory where the
118
+ latex source lies.
119
+
120
+ 1. It must be relative because bibtex / biber, which is necessary for
121
+ bibliographies, does not accept full paths as a safety measure.
122
+ 2. Due to the ``--cd`` flag, latexmk will change the directory to the one where the
123
+ source files are. Thus, relative to the latex sources.
124
+
125
+ See this `discussion on Github
126
+ <https://github.com/James-Yu/LaTeX-Workshop/issues/1932#issuecomment-582416434>`_
127
+ for additional information.
128
+
129
+ """
130
+ latex_document = _get_node_from_dictionary (
131
+ task .depends_on , session .config ["latex_source_key" ]
132
+ ).value
133
+ compiled_document = _get_node_from_dictionary (
134
+ task .produces , session .config ["latex_document_key" ]
135
+ ).value
136
+
137
+ # Jobname controls the name of the compiled document. No suffix!
138
+ if latex_document .stem != compiled_document .stem :
139
+ jobname = [f"--jobname={ compiled_document .stem } " ]
140
+ else :
141
+ jobname = []
142
+
143
+ # The path to the output directory must be relative from the location of the source
144
+ # file. See docstring for more information.
145
+ out_relative_to_latex_source = Path (
146
+ os .path .relpath (compiled_document .parent , latex_document .parent )
147
+ ).as_posix ()
148
+
149
+ return (
150
+ [
151
+ "latexmk" ,
152
+ * args ,
153
+ ]
154
+ + jobname
155
+ + [
156
+ f"--output-directory={ out_relative_to_latex_source } " ,
157
+ latex_document .as_posix (),
158
+ ]
159
+ )
0 commit comments