in2lambda 0.3.2__py3-none-any.whl → 0.3.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
in2lambda/api/module.py CHANGED
@@ -112,10 +112,13 @@ class Module:
112
112
  ... module.to_json(temp_dir)
113
113
  ... # Check the contents of the directory
114
114
  ... sorted(os.listdir(temp_dir))
115
+ ... # Check the contents of the set directory
116
+ ... sorted(os.listdir(f"{temp_dir}/set"))
115
117
  ... # Check the title of the first question
116
- ... with open(f"{temp_dir}/question_1/question_1.json") as file:
118
+ ... with open(f"{temp_dir}/set/question_1.json") as file:
117
119
  ... print(f"Question 1's title: {json.load(file)['title']}")
118
- ['question_1', 'question_1.zip', 'question_2', 'question_2.zip']
120
+ ['set', 'set.zip']
121
+ ['media', 'question_1.json', 'question_2.json']
119
122
  Question 1's title: Question 1
120
123
 
121
124
  """
Binary file
Binary file
Binary file
@@ -32,12 +32,12 @@ def image_directories(tex_file: str) -> list[str]:
32
32
  >>> temp_dir = tempfile.mkdtemp()
33
33
  >>> tex_file = os.path.join(temp_dir, 'test.tex')
34
34
  >>> with open(tex_file, 'w') as f:
35
- ... f.write("\graphicspath{{subdir1/}{subdir2/}{subdir3/}}")
35
+ ... f.write("\\graphicspath{{subdir1/}{subdir2/}{subdir3/}}")
36
36
  45
37
37
  >>> image_directories(tex_file)
38
38
  ['subdir1/', 'subdir2/', 'subdir3/']
39
39
  >>> with open(tex_file, 'w') as f:
40
- ... f.write("\graphicspath{ { subdir1/ }, { subdir2/ }, { subdir3/ } }")
40
+ ... f.write("\\graphicspath{ { subdir1/ }, { subdir2/ }, { subdir3/ } }")
41
41
  57
42
42
  >>> image_directories.cache_clear()
43
43
  >>> image_directories(tex_file)
@@ -78,7 +78,7 @@ def image_path(image_name: str, tex_file: str) -> Optional[str]:
78
78
  >>> temp_dir = tempfile.mkdtemp()
79
79
  >>> tex_file = os.path.join(temp_dir, 'test.tex')
80
80
  >>> with open(tex_file, 'w') as f:
81
- ... f.write("\graphicspath{{./subdir1/}{./subdir2/}{./subdir3/}}")
81
+ ... f.write("\\graphicspath{{./subdir1/}{./subdir2/}{./subdir3/}}")
82
82
  51
83
83
  >>> # Example image in a relative subdirectory
84
84
  >>> sub_dir = os.path.join(temp_dir, 'subdir3')
@@ -24,6 +24,15 @@ def converter(
24
24
  """
25
25
  # Create output by copying template
26
26
 
27
+ # create directory to put the questions
28
+ os.makedirs(output_dir, exist_ok=True)
29
+ output_question = os.path.join(output_dir, "set")
30
+ os.makedirs(output_question, exist_ok=True)
31
+
32
+ # create directory to put images - should be in set
33
+ output_image = os.path.join(output_question, "media")
34
+ os.makedirs(output_image, exist_ok=True)
35
+
27
36
  for i in range(len(ListQuestions)):
28
37
  output = deepcopy(template)
29
38
 
@@ -39,28 +48,20 @@ def converter(
39
48
  # add parts to the question file
40
49
  if ListQuestions[i].parts:
41
50
  output["parts"][0]["content"] = ListQuestions[i].parts[0].text
42
- output["parts"][0]["workedSolution"][0]["content"] = (
51
+ output["parts"][0]["workedSolution"]["content"] = (
43
52
  ListQuestions[i].parts[0].worked_solution
44
53
  )
45
54
  for j in range(1, len(ListQuestions[i].parts)):
46
55
  output["parts"].append(deepcopy(template["parts"][0]))
47
56
  output["parts"][j]["content"] = ListQuestions[i].parts[j].text
48
- output["parts"][j]["workedSolution"][0]["content"] = (
57
+ output["parts"][j]["orderNumber"] = j
58
+ output["parts"][j]["workedSolution"]["content"] = (
49
59
  ListQuestions[i].parts[j].worked_solution
50
60
  )
51
61
 
52
62
  # Output file
53
63
  filename = "question_" + str(i + 1)
54
64
 
55
- # create directory to put the questions
56
- os.makedirs(output_dir, exist_ok=True)
57
- output_question = os.path.join(output_dir, filename)
58
- os.makedirs(output_question, exist_ok=True)
59
-
60
- # create directory to put image
61
- output_image = os.path.join(output_question, "media")
62
- os.makedirs(output_image, exist_ok=True)
63
-
64
65
  # write questions into directory
65
66
  with open(f"{output_question}/{filename}.json", "w") as file:
66
67
  json.dump(output, file)
@@ -1,26 +1,23 @@
1
1
  {
2
+ "displayFinalAnswer": true,
3
+ "displayStructuredTutorial": true,
4
+ "displayWorkedSolution": true,
2
5
  "masterContent": "Top level question here",
3
6
  "parts": [
4
7
  {
5
8
  "answer": "",
6
9
  "content": "Part text here",
7
- "responseArea": [],
10
+ "orderNumber": 0,
11
+ "responseAreas": [],
8
12
  "tutorial": [],
9
13
  "universalPartId": "N/A",
10
- "workedSolution": [
11
- {
12
- "content": "Part worked solution here",
13
- "id": "N/A",
14
- "title": ""
15
- }
16
- ]
14
+ "workedSolution": {
15
+ "content": "Part worked solution here",
16
+ "id": "N/A",
17
+ "title": ""
18
+ }
17
19
  }
18
20
  ],
19
21
  "publish": false,
20
- "questionSettings": {
21
- "displayFinalAnswer": true,
22
- "displayStructuredTutorial": true,
23
- "displayWorkedSolution": true
24
- },
25
22
  "title": "Question title here"
26
23
  }
in2lambda/main.py CHANGED
@@ -1,7 +1,14 @@
1
1
  """The main input for in2lambda, defining both the CLT and main library function."""
2
2
 
3
+ # This commented block makes it run the local files rather than the pip library (I think, I don't understand it. Kevin wrote it.)
4
+ #
5
+ # import sys
6
+ # import os
7
+ # sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
8
+
3
9
  import importlib
4
10
  import pkgutil
11
+ import subprocess
5
12
  from typing import Optional
6
13
 
7
14
  import panflute as pf
@@ -11,6 +18,19 @@ import in2lambda.filters
11
18
  from in2lambda.api.module import Module
12
19
 
13
20
 
21
+ def docx_to_md(docx_file: str) -> str:
22
+ """Converts .docx files to markdown.
23
+
24
+ Args:
25
+ docx_file: A file path with the file extension included.
26
+
27
+ Returns:
28
+ the contents of the .docx file in markdown formatting
29
+ """
30
+ md_output = subprocess.check_output(["pandoc", docx_file, "-t", "markdown"])
31
+ return md_output.decode("utf-8")
32
+
33
+
14
34
  def file_type(file: str) -> str:
15
35
  """Determines which pandoc file format to use for a given file.
16
36
 
@@ -52,7 +72,7 @@ def file_type(file: str) -> str:
52
72
  ):
53
73
  return "markdown"
54
74
  case "docx":
55
- return "docx" # Pandoc doesn't seem to support doc
75
+ return "docx" # Pandoc doesn't seem to support .doc, and panflute doesn't like .docx.
56
76
  raise RuntimeError(f"Unsupported file extension: .{extension}")
57
77
 
58
78
 
@@ -90,15 +110,20 @@ def runner(
90
110
  # Dynamically import the correct pandoc filter depending on the subject.
91
111
  filter_module = importlib.import_module(f"in2lambda.filters.{chosen_filter}.filter")
92
112
 
93
- with open(question_file, "r", encoding="utf-8") as file:
94
- text = file.read()
113
+ if file_type(question_file) == "docx":
114
+ # Convert .docx to md using Pandoc and proceed
115
+ text = docx_to_md(question_file)
116
+ input_format = "markdown"
117
+ else:
118
+ with open(question_file, "r", encoding="utf-8") as file:
119
+ text = file.read()
120
+
121
+ input_format = file_type(question_file)
95
122
 
96
123
  # Parse the Pandoc AST using the relevant panflute filter.
97
124
  pf.run_filter(
98
125
  filter_module.pandoc_filter,
99
- doc=pf.convert_text(
100
- text, input_format=file_type(question_file), standalone=True
101
- ),
126
+ doc=pf.convert_text(text, input_format=input_format, standalone=True),
102
127
  module=module,
103
128
  tex_file=question_file,
104
129
  parsing_answers=False,
@@ -106,13 +131,20 @@ def runner(
106
131
 
107
132
  # If separate answer TeX file provided, parse that as well.
108
133
  if answer_file:
109
- with open(answer_file, "r", encoding="utf-8") as file:
110
- answer_text = file.read()
134
+
135
+ if file_type(answer_file) == "docx":
136
+
137
+ answer_text = docx_to_md(answer_file)
138
+ answer_format = "markdown"
139
+ else:
140
+ with open(answer_file, "r", encoding="utf-8") as file:
141
+ answer_text = file.read()
142
+ answer_format = file_type(answer_file)
111
143
 
112
144
  pf.run_filter(
113
145
  filter_module.pandoc_filter,
114
146
  doc=pf.convert_text(
115
- answer_text, input_format=file_type(answer_file), standalone=True
147
+ answer_text, input_format=answer_format, standalone=True
116
148
  ),
117
149
  module=module,
118
150
  tex_file=answer_file,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: in2lambda
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Converts content ready for import into Lambda Feedback
5
5
  Home-page: https://lambda-feedback.github.io/in2lambda
6
6
  License: MIT
@@ -1,10 +1,13 @@
1
1
  in2lambda/__init__.py,sha256=VvbVGkrakfqTIqnYUuv95_LFxitkMODRYr161R9128U,492
2
2
  in2lambda/api/__init__.py,sha256=uh1WA1JIIYmjaWXms3JR5LOlnizv-ozW4ijBHQxi9QA,103
3
- in2lambda/api/module.py,sha256=YDV2NWejxg3duEzVjn6er05OiCGBihI7fUDJP16RuD0,5046
3
+ in2lambda/api/module.py,sha256=frAU0m6dJceXiVlGKiny_1UJGowwO0Q6p6RAlKjKqME,5173
4
4
  in2lambda/api/part.py,sha256=Y-W0sd5mJQifA8V8nZNTYk_HPhxhRQq5mUCdlYKioXw,204
5
5
  in2lambda/api/question.py,sha256=is-Bmx85GFAV7Jf8mblP2ZtkDgfbRcVbMhh9Tmy2hmk,6173
6
6
  in2lambda/example_questions.tex,sha256=kvcuUUoQXTJYqrAlUMfibzGsL9qFgqbKS57JIg1YhkA,9491
7
7
  in2lambda/example_solutions.tex,sha256=0idJQV9Q8VhMO_dB5RYzYkZzyEMSA594sqnPdl4wlLA,22164
8
+ in2lambda/figures/O2_potential.png,sha256=AxDizIID24J20wqVUAneGIN_WWr6Vfra3xoBdkgJbK0,64855
9
+ in2lambda/figures/activated_complex.png,sha256=6AQuS6lftVMX0GkAR5WpOQnSgzvhNA3Pb2c2iteUieE,265793
10
+ in2lambda/figures/rocket-momentum.png,sha256=EXsR7k_WehhSBfnsh4fssCTEKHpu6q3lCa4csHAFGHI,397693
8
11
  in2lambda/filters/PartPartSolSol/__init__.py,sha256=YJCnCoGJfXt7jrMdgcsEfkI7Su9WK-VOvUwwefQ8zog,124
9
12
  in2lambda/filters/PartPartSolSol/example.tex,sha256=TK4JyjYj_wFfi9bkV8uKfXdFIBYPsvgMng5x1XdE_oU,667
10
13
  in2lambda/filters/PartPartSolSol/filter.py,sha256=vttP0_RNjLuLu2GSUudzv2qk-AQHuRb172JAwf_0mmA,2383
@@ -18,18 +21,18 @@ in2lambda/filters/PartsSepSol/__init__.py,sha256=yAIUC3oJVob1R7Rrvn0sXGpK_-pXfF4
18
21
  in2lambda/filters/PartsSepSol/example.tex,sha256=w7mJIcWCqKzJE_sJG4bg0J-V9kXSfe6doKWXgTd1nF8,687
19
22
  in2lambda/filters/PartsSepSol/filter.py,sha256=9cV6HhSqOQGTk5bIS36pgBbB-5UWO3mPI2s8l9ZsNeE,3206
20
23
  in2lambda/filters/__init__.py,sha256=tla_1d85db2MAT-fgc5sNoScuYZJeTgKedzFn3NXT2c,69
21
- in2lambda/filters/markdown.py,sha256=FhbGHziVCHirhssCpMnSkyC0alMsOIxnInxvLMdaNek,7153
24
+ in2lambda/filters/markdown.py,sha256=6c0Q89CCtVhJ5F7of-eueUs9WqXXhMZNFq0uZr-ZxMQ,7156
22
25
  in2lambda/json_convert/__init__.py,sha256=2X3SLn6H449zXFprtZZU7M20elsOJ09mQr7EDnv04ow,87
23
- in2lambda/json_convert/json_convert.py,sha256=VPigakcUYvZCm2PPRm0umrA0BIvEOFNfwl-NLfcr4lM,3625
24
- in2lambda/json_convert/minimal_template.json,sha256=ctwpbvOqIs_okToSCRkRB3z5CRn1GNbrUegu6PuLngM,551
26
+ in2lambda/json_convert/json_convert.py,sha256=3C8Aa0RU1zRUXDvpvL6wV16jcGTuwVI0A1NfDcQg8fg,3662
27
+ in2lambda/json_convert/minimal_template.json,sha256=o83cZbhabXqeJiTCkLqdhijrJiiAfv1_I6HLT_QunZ8,516
25
28
  in2lambda/katex_convert/__init__.py,sha256=D0X21-NQXNrWwu_klZeCaQaqtV9vHfFv1PlrtuVAHlI,96
26
29
  in2lambda/katex_convert/delete_list.txt,sha256=Ywx8ltUbrvSxGaQVoTSXfXAe4FfPSCuRchkSCICYjHU,1753
27
30
  in2lambda/katex_convert/katex_convert.py,sha256=3UUw84432lOBnPLJwAw68MMyFPrD6ijxyYR-qVhJhnw,4909
28
31
  in2lambda/katex_convert/replace_list.txt,sha256=y5ciG4orj64eqEKsOVaQ95Zx7Xx0y4Awa4JIS27HVSw,611
29
- in2lambda/main.py,sha256=RSoHtn9e1y34xHxScwjMUshrP5RAuGJayqX_WXveajA,6006
32
+ in2lambda/main.py,sha256=IifSQfMn1ARYlrvowYYcYLGo6b5sMOxxz-nnELk56_k,7068
30
33
  in2lambda/py.typed,sha256=gN7aphE6U0Jj-OffDD7hw1OkRs9gg6OPOrVpN5eAnCA,56
31
- in2lambda-0.3.2.dist-info/LICENSE,sha256=vEyoprnh_ic_ZQ-woDohxEIE8GJOyXqbYZ-5cH42FG4,1072
32
- in2lambda-0.3.2.dist-info/METADATA,sha256=7DjyXejaoAtbgGr2kItJ-1I_5xHiNv_y8BKrOcODtCE,1833
33
- in2lambda-0.3.2.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
34
- in2lambda-0.3.2.dist-info/entry_points.txt,sha256=xhkZ_lmsx7SgdhjJC-DvkFFqu-Ff-wD4Poir55bdUSM,48
35
- in2lambda-0.3.2.dist-info/RECORD,,
34
+ in2lambda-0.3.3.dist-info/LICENSE,sha256=vEyoprnh_ic_ZQ-woDohxEIE8GJOyXqbYZ-5cH42FG4,1072
35
+ in2lambda-0.3.3.dist-info/METADATA,sha256=ROh8P1bkW2CWV73U1g6zrvEhvtz5Pc_iceFsqp2e5wI,1833
36
+ in2lambda-0.3.3.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
37
+ in2lambda-0.3.3.dist-info/entry_points.txt,sha256=xhkZ_lmsx7SgdhjJC-DvkFFqu-Ff-wD4Poir55bdUSM,48
38
+ in2lambda-0.3.3.dist-info/RECORD,,