fabricatio 0.2.13.dev2__cp312-cp312-manylinux_2_34_x86_64.whl → 0.2.13.dev3__cp312-cp312-manylinux_2_34_x86_64.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.
- fabricatio/actions/article_rag.py +38 -18
- fabricatio/models/extra/article_base.py +27 -2
- fabricatio/models/extra/article_outline.py +5 -36
- fabricatio/rust.cpython-312-x86_64-linux-gnu.so +0 -0
- fabricatio/rust.pyi +65 -1
- {fabricatio-0.2.13.dev2.dist-info → fabricatio-0.2.13.dev3.dist-info}/METADATA +1 -1
- {fabricatio-0.2.13.dev2.dist-info → fabricatio-0.2.13.dev3.dist-info}/RECORD +11 -11
- {fabricatio-0.2.13.dev2.data → fabricatio-0.2.13.dev3.data}/scripts/tdown +0 -0
- {fabricatio-0.2.13.dev2.data → fabricatio-0.2.13.dev3.data}/scripts/ttm +0 -0
- {fabricatio-0.2.13.dev2.dist-info → fabricatio-0.2.13.dev3.dist-info}/WHEEL +0 -0
- {fabricatio-0.2.13.dev2.dist-info → fabricatio-0.2.13.dev3.dist-info}/licenses/LICENSE +0 -0
@@ -20,7 +20,13 @@ from fabricatio.models.extra.article_main import Article, ArticleChapter, Articl
|
|
20
20
|
from fabricatio.models.extra.article_outline import ArticleOutline
|
21
21
|
from fabricatio.models.extra.rule import RuleSet
|
22
22
|
from fabricatio.models.kwargs_types import ChooseKwargs, LLMKwargs
|
23
|
-
from fabricatio.rust import
|
23
|
+
from fabricatio.rust import (
|
24
|
+
convert_all_block_tex,
|
25
|
+
convert_all_inline_tex,
|
26
|
+
convert_to_block_formula,
|
27
|
+
convert_to_inline_formula,
|
28
|
+
fix_misplaced_labels,
|
29
|
+
)
|
24
30
|
from fabricatio.utils import ok
|
25
31
|
|
26
32
|
TYPST_CITE_USAGE = (
|
@@ -28,8 +34,10 @@ TYPST_CITE_USAGE = (
|
|
28
34
|
"Legal citing syntax examples(seperated by |): [[1]]|[[1,2]]|[[1-3]]|[[12,13-15]]|[[1-3,5-7]]\n"
|
29
35
|
"Illegal citing syntax examples(seperated by |): [[1],[2],[3]]|[[1],[1-2]]\n"
|
30
36
|
"You SHALL not cite a single reference more than once!"
|
31
|
-
"Those reference mark shall not be omitted during the extraction\n"
|
32
37
|
"It's recommended to cite multiple references that supports your conclusion at a time.\n"
|
38
|
+
)
|
39
|
+
|
40
|
+
TYPST_MATH_USAGE = (
|
33
41
|
"Wrap inline expression with '\\(' and '\\)',like '\\(>5m\\)' '\\(89%\\)', and wrap block equation with '\\[' and '\\]'.\n"
|
34
42
|
"In addition to that, you can add a label outside the block equation which can be used as a cross reference identifier, the label is a string wrapped in `<` and `>` like `<energy-release-rate-equation>`.Note that the label string should be a summarizing title for the equation being labeled and should never be written within the formula block.\n"
|
35
43
|
"you can refer to that label by using the syntax with prefix of `@eqt:`, which indicate that this notation is citing a label from the equations. For example ' @eqt:energy-release-rate-equation ' DO remember that the notation shall have both suffixed and prefixed space char which enable the compiler to distinguish the notation from the plaintext."
|
@@ -44,7 +52,7 @@ TYPST_CITE_USAGE = (
|
|
44
52
|
)
|
45
53
|
|
46
54
|
|
47
|
-
class WriteArticleContentRAG(Action,
|
55
|
+
class WriteArticleContentRAG(Action, Extract, AdvancedRAG):
|
48
56
|
"""Write an article based on the provided outline."""
|
49
57
|
|
50
58
|
ctx_override: ClassVar[bool] = True
|
@@ -56,13 +64,16 @@ class WriteArticleContentRAG(Action, RAG, Extract):
|
|
56
64
|
"""The threshold of relevance"""
|
57
65
|
extractor_model: LLMKwargs
|
58
66
|
"""The model to use for extracting the content from the retrieved references."""
|
59
|
-
query_model:
|
67
|
+
query_model: ChooseKwargs
|
60
68
|
"""The model to use for querying the database"""
|
61
69
|
supervisor: bool = False
|
62
70
|
"""Whether to use supervisor mode"""
|
63
71
|
result_per_query: PositiveInt = 4
|
64
72
|
"""The number of results to be returned per query."""
|
65
|
-
|
73
|
+
cite_req: str = TYPST_CITE_USAGE
|
74
|
+
"""The req of the write article content."""
|
75
|
+
|
76
|
+
math_req: str = TYPST_MATH_USAGE
|
66
77
|
"""The req of the write article content."""
|
67
78
|
tei_endpoint: Optional[str] = None
|
68
79
|
|
@@ -105,21 +116,25 @@ class WriteArticleContentRAG(Action, RAG, Extract):
|
|
105
116
|
cm = CitationManager()
|
106
117
|
await self.search_database(article, article_outline, chap, sec, subsec, cm)
|
107
118
|
|
108
|
-
|
109
|
-
r_print(
|
119
|
+
raw_paras = await self.write_raw(article, article_outline, chap, sec, subsec, cm)
|
120
|
+
r_print(raw_paras)
|
110
121
|
|
111
122
|
while not await confirm("Accept this version and continue?").ask_async():
|
112
123
|
if inst := await text("Search for more refs for additional spec.").ask_async():
|
113
124
|
await self.search_database(article, article_outline, chap, sec, subsec, cm, extra_instruction=inst)
|
114
125
|
|
115
126
|
if instruction := await text("Enter the instructions to improve").ask_async():
|
116
|
-
|
117
|
-
if edt := await text("Edit", default=
|
118
|
-
|
127
|
+
raw_paras = await self.write_raw(article, article_outline, chap, sec, subsec, cm, instruction)
|
128
|
+
if edt := await text("Edit", default=raw_paras).ask_async():
|
129
|
+
raw_paras = edt
|
130
|
+
|
131
|
+
raw_paras = fix_misplaced_labels(raw_paras)
|
132
|
+
raw_paras = convert_all_inline_tex(raw_paras)
|
133
|
+
raw_paras = convert_all_block_tex(raw_paras)
|
119
134
|
|
120
|
-
r_print(
|
135
|
+
r_print(raw_paras)
|
121
136
|
|
122
|
-
return await self.extract_new_subsec(subsec,
|
137
|
+
return await self.extract_new_subsec(subsec, raw_paras, cm)
|
123
138
|
|
124
139
|
async def _inner(
|
125
140
|
self,
|
@@ -137,6 +152,10 @@ class WriteArticleContentRAG(Action, RAG, Extract):
|
|
137
152
|
|
138
153
|
raw_paras = "\n".join(p for p in raw_paras.splitlines() if p and not p.endswith("**") and not p.startswith("#"))
|
139
154
|
|
155
|
+
raw_paras = fix_misplaced_labels(raw_paras)
|
156
|
+
raw_paras = convert_all_inline_tex(raw_paras)
|
157
|
+
raw_paras = convert_all_block_tex(raw_paras)
|
158
|
+
|
140
159
|
return await self.extract_new_subsec(subsec, raw_paras, cm)
|
141
160
|
|
142
161
|
async def extract_new_subsec(
|
@@ -148,12 +167,13 @@ class WriteArticleContentRAG(Action, RAG, Extract):
|
|
148
167
|
ArticleSubsection,
|
149
168
|
raw_paras,
|
150
169
|
f"Above is the subsection titled `{subsec.title}`.\n"
|
151
|
-
f"I need you to extract the content to
|
152
|
-
f"
|
170
|
+
f"I need you to extract the content to construct a new `{ArticleSubsection.__class__.__name__}`,"
|
171
|
+
f"Do not attempt to change the original content, your job is ONLY content extraction",
|
153
172
|
**self.extractor_model,
|
154
173
|
),
|
155
174
|
"Failed to propose new subsection.",
|
156
175
|
)
|
176
|
+
|
157
177
|
for p in new_subsec.paragraphs:
|
158
178
|
p.content = cm.apply(p.content)
|
159
179
|
p.description = cm.apply(p.description)
|
@@ -177,7 +197,7 @@ class WriteArticleContentRAG(Action, RAG, Extract):
|
|
177
197
|
f"{article_outline.finalized_dump()}\n\nAbove is my article outline, I m writing graduate thesis titled `{article.title}`. "
|
178
198
|
f"More specifically, i m witting the Chapter `{chap.title}` >> Section `{sec.title}` >> Subsection `{subsec.title}`.\n"
|
179
199
|
f"Please help me write the paragraphs of the subsec mentioned above, which is `{subsec.title}`.\n"
|
180
|
-
f"{self.
|
200
|
+
f"{self.cite_req}\n{self.math_req}\n"
|
181
201
|
f"You SHALL use `{article.language}` as writing language.\n{extra_instruction}\n"
|
182
202
|
f"Do not use numbered list to display the outcome, you should regard you are writing the main text of the thesis.\n"
|
183
203
|
f"You should not copy others' works from the references directly on to my thesis, we can only harness the conclusion they have drawn.\n"
|
@@ -206,11 +226,11 @@ class WriteArticleContentRAG(Action, RAG, Extract):
|
|
206
226
|
await self.clued_search(
|
207
227
|
search_req,
|
208
228
|
cm,
|
209
|
-
refinery_kwargs=self.
|
229
|
+
refinery_kwargs=self.query_model,
|
210
230
|
expand_multiplier=self.search_increment_multiplier,
|
211
231
|
base_accepted=self.ref_limit,
|
212
|
-
result_per_query=self.
|
213
|
-
similarity_threshold=self.
|
232
|
+
result_per_query=self.result_per_query,
|
233
|
+
similarity_threshold=self.threshold,
|
214
234
|
tei_endpoint=self.tei_endpoint,
|
215
235
|
)
|
216
236
|
|
@@ -2,9 +2,12 @@
|
|
2
2
|
|
3
3
|
from abc import ABC
|
4
4
|
from enum import StrEnum
|
5
|
+
from pathlib import Path
|
5
6
|
from typing import ClassVar, Generator, List, Optional, Self, Tuple, Type
|
6
7
|
|
8
|
+
from fabricatio.fs import dump_text, safe_text_read
|
7
9
|
from fabricatio.fs.readers import extract_sections
|
10
|
+
from fabricatio.journal import logger
|
8
11
|
from fabricatio.models.generic import (
|
9
12
|
AsPrompt,
|
10
13
|
Described,
|
@@ -19,10 +22,12 @@ from fabricatio.models.generic import (
|
|
19
22
|
Titled,
|
20
23
|
WordCount,
|
21
24
|
)
|
22
|
-
from fabricatio.rust import split_out_metadata, to_metadata, word_count
|
23
|
-
from fabricatio.utils import fallback_kwargs
|
25
|
+
from fabricatio.rust import extract_body, inplace_update, split_out_metadata, to_metadata, word_count
|
26
|
+
from fabricatio.utils import fallback_kwargs, ok
|
24
27
|
from pydantic import Field
|
25
28
|
|
29
|
+
ARTICLE_WRAPPER = "// =-=-=-=-=-=-=-=-=-="
|
30
|
+
|
26
31
|
|
27
32
|
class ReferringType(StrEnum):
|
28
33
|
"""Enumeration of different types of references that can be made in an article."""
|
@@ -397,3 +402,23 @@ class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, FromTypstCode, To
|
|
397
402
|
def avg_wordcount_recursive[S: "ArticleBase"](self: S) -> S:
|
398
403
|
"""Set all chap, sec, subsec have same word count sum up to be `self.expected_word_count`."""
|
399
404
|
return self.avg_chap_wordcount().avg_sec_wordcount().avg_subsec_wordcount()
|
405
|
+
|
406
|
+
def update_article_file(self, file: str | Path) -> Self:
|
407
|
+
"""Update the article file."""
|
408
|
+
file = Path(file)
|
409
|
+
string = safe_text_read(file)
|
410
|
+
if updated := inplace_update(string, ARTICLE_WRAPPER, self.to_typst_code()):
|
411
|
+
dump_text(file, updated)
|
412
|
+
logger.success(f"Successfully updated {file.as_posix()}.")
|
413
|
+
else:
|
414
|
+
logger.warning(f"Failed to update {file.as_posix()}. Please make sure there are paired `{ARTICLE_WRAPPER}`")
|
415
|
+
return self
|
416
|
+
|
417
|
+
@classmethod
|
418
|
+
def from_article_file(cls, file: str | Path, title: str) -> Self:
|
419
|
+
"""Load article from file."""
|
420
|
+
file = Path(file)
|
421
|
+
string = safe_text_read(file)
|
422
|
+
return cls.from_typst_code(
|
423
|
+
title, ok(extract_body(string, ARTICLE_WRAPPER), "Failed to extract body from file.")
|
424
|
+
)
|
@@ -1,8 +1,7 @@
|
|
1
1
|
"""A module containing the ArticleOutline class, which represents the outline of an academic paper."""
|
2
2
|
|
3
|
-
from typing import Dict,
|
3
|
+
from typing import ClassVar, Dict, Type
|
4
4
|
|
5
|
-
from fabricatio.fs.readers import extract_sections
|
6
5
|
from fabricatio.models.extra.article_base import (
|
7
6
|
ArticleBase,
|
8
7
|
ChapterBase,
|
@@ -20,33 +19,13 @@ class ArticleSubsectionOutline(SubSectionBase):
|
|
20
19
|
class ArticleSectionOutline(SectionBase[ArticleSubsectionOutline]):
|
21
20
|
"""A slightly more detailed research component specification for academic paper generation, Must contain subsections."""
|
22
21
|
|
23
|
-
|
24
|
-
def from_typst_code(cls, title: str, body: str, **kwargs) -> Self:
|
25
|
-
"""Parse the given Typst code into an ArticleSectionOutline instance."""
|
26
|
-
return super().from_typst_code(
|
27
|
-
title,
|
28
|
-
body,
|
29
|
-
subsections=[
|
30
|
-
ArticleSubsectionOutline.from_typst_code(*pack)
|
31
|
-
for pack in extract_sections(body, level=3, section_char="=")
|
32
|
-
],
|
33
|
-
)
|
22
|
+
child_type: ClassVar[Type[SubSectionBase]] = ArticleSubsectionOutline
|
34
23
|
|
35
24
|
|
36
25
|
class ArticleChapterOutline(ChapterBase[ArticleSectionOutline]):
|
37
26
|
"""Macro-structural unit implementing standard academic paper organization. Must contain sections."""
|
38
27
|
|
39
|
-
|
40
|
-
def from_typst_code(cls, title: str, body: str, **kwargs) -> Self:
|
41
|
-
"""Parse the given Typst code into an ArticleChapterOutline instance."""
|
42
|
-
return super().from_typst_code(
|
43
|
-
title,
|
44
|
-
body,
|
45
|
-
sections=[
|
46
|
-
ArticleSectionOutline.from_typst_code(*pack)
|
47
|
-
for pack in extract_sections(body, level=2, section_char="=")
|
48
|
-
],
|
49
|
-
)
|
28
|
+
child_type: ClassVar[Type[SectionBase]] = ArticleSectionOutline
|
50
29
|
|
51
30
|
|
52
31
|
class ArticleOutline(
|
@@ -56,21 +35,11 @@ class ArticleOutline(
|
|
56
35
|
):
|
57
36
|
"""Outline of an academic paper, containing chapters, sections, subsections."""
|
58
37
|
|
38
|
+
child_type: ClassVar[Type[ChapterBase]] = ArticleChapterOutline
|
39
|
+
|
59
40
|
def _as_prompt_inner(self) -> Dict[str, str]:
|
60
41
|
return {
|
61
42
|
"Original Article Briefing": self.referenced.referenced,
|
62
43
|
"Original Article Proposal": self.referenced.display(),
|
63
44
|
"Original Article Outline": self.display(),
|
64
45
|
}
|
65
|
-
|
66
|
-
@classmethod
|
67
|
-
def from_typst_code(cls, title: str, body: str, **kwargs) -> Self:
|
68
|
-
"""Parse the given Typst code into an ArticleOutline instance."""
|
69
|
-
return super().from_typst_code(
|
70
|
-
title,
|
71
|
-
body,
|
72
|
-
chapters=[
|
73
|
-
ArticleChapterOutline.from_typst_code(*pack)
|
74
|
-
for pack in extract_sections(body, level=1, section_char="=")
|
75
|
-
],
|
76
|
-
)
|
Binary file
|
fabricatio/rust.pyi
CHANGED
@@ -16,6 +16,7 @@ from typing import Any, Dict, List, Optional, Tuple, overload
|
|
16
16
|
|
17
17
|
from pydantic import JsonValue
|
18
18
|
|
19
|
+
|
19
20
|
class TemplateManager:
|
20
21
|
"""Template rendering engine using Handlebars templates.
|
21
22
|
|
@@ -26,7 +27,7 @@ class TemplateManager:
|
|
26
27
|
"""
|
27
28
|
|
28
29
|
def __init__(
|
29
|
-
|
30
|
+
self, template_dirs: List[Path], suffix: Optional[str] = None, active_loading: Optional[bool] = None
|
30
31
|
) -> None:
|
31
32
|
"""Initialize the template manager.
|
32
33
|
|
@@ -58,8 +59,10 @@ class TemplateManager:
|
|
58
59
|
|
59
60
|
@overload
|
60
61
|
def render_template(self, name: str, data: Dict[str, Any]) -> str: ...
|
62
|
+
|
61
63
|
@overload
|
62
64
|
def render_template(self, name: str, data: List[Dict[str, Any]]) -> List[str]: ...
|
65
|
+
|
63
66
|
def render_template(self, name: str, data: Dict[str, Any] | List[Dict[str, Any]]) -> str | List[str]:
|
64
67
|
"""Render a template with context data.
|
65
68
|
|
@@ -76,8 +79,10 @@ class TemplateManager:
|
|
76
79
|
|
77
80
|
@overload
|
78
81
|
def render_template_raw(self, template: str, data: Dict[str, Any]) -> str: ...
|
82
|
+
|
79
83
|
@overload
|
80
84
|
def render_template_raw(self, template: str, data: List[Dict[str, Any]]) -> List[str]: ...
|
85
|
+
|
81
86
|
def render_template_raw(self, template: str, data: Dict[str, Any] | List[Dict[str, Any]]) -> str | List[str]:
|
82
87
|
"""Render a template with context data.
|
83
88
|
|
@@ -89,6 +94,7 @@ class TemplateManager:
|
|
89
94
|
Rendered template content as string or list of strings
|
90
95
|
"""
|
91
96
|
|
97
|
+
|
92
98
|
class BibManager:
|
93
99
|
"""BibTeX bibliography manager for parsing and querying citation data."""
|
94
100
|
|
@@ -197,6 +203,7 @@ class BibManager:
|
|
197
203
|
Field value if found, None otherwise
|
198
204
|
"""
|
199
205
|
|
206
|
+
|
200
207
|
def blake3_hash(content: bytes) -> str:
|
201
208
|
"""Calculate the BLAKE3 cryptographic hash of data.
|
202
209
|
|
@@ -207,9 +214,11 @@ def blake3_hash(content: bytes) -> str:
|
|
207
214
|
Hex-encoded BLAKE3 hash string
|
208
215
|
"""
|
209
216
|
|
217
|
+
|
210
218
|
def detect_language(string: str) -> str:
|
211
219
|
"""Detect the language of a given string."""
|
212
220
|
|
221
|
+
|
213
222
|
def split_word_bounds(string: str) -> List[str]:
|
214
223
|
"""Split the string into words based on word boundaries.
|
215
224
|
|
@@ -220,6 +229,7 @@ def split_word_bounds(string: str) -> List[str]:
|
|
220
229
|
A list of words extracted from the string.
|
221
230
|
"""
|
222
231
|
|
232
|
+
|
223
233
|
def split_sentence_bounds(string: str) -> List[str]:
|
224
234
|
"""Split the string into sentences based on sentence boundaries.
|
225
235
|
|
@@ -230,6 +240,7 @@ def split_sentence_bounds(string: str) -> List[str]:
|
|
230
240
|
A list of sentences extracted from the string.
|
231
241
|
"""
|
232
242
|
|
243
|
+
|
233
244
|
def split_into_chunks(string: str, max_chunk_size: int, max_overlapping_rate: float = 0.3) -> List[str]:
|
234
245
|
"""Split the string into chunks of a specified size.
|
235
246
|
|
@@ -242,6 +253,7 @@ def split_into_chunks(string: str, max_chunk_size: int, max_overlapping_rate: fl
|
|
242
253
|
A list of chunks extracted from the string.
|
243
254
|
"""
|
244
255
|
|
256
|
+
|
245
257
|
def word_count(string: str) -> int:
|
246
258
|
"""Count the number of words in the string.
|
247
259
|
|
@@ -252,51 +264,67 @@ def word_count(string: str) -> int:
|
|
252
264
|
The number of words in the string.
|
253
265
|
"""
|
254
266
|
|
267
|
+
|
255
268
|
def is_chinese(string: str) -> bool:
|
256
269
|
"""Check if the given string is in Chinese."""
|
257
270
|
|
271
|
+
|
258
272
|
def is_english(string: str) -> bool:
|
259
273
|
"""Check if the given string is in English."""
|
260
274
|
|
275
|
+
|
261
276
|
def is_japanese(string: str) -> bool:
|
262
277
|
"""Check if the given string is in Japanese."""
|
263
278
|
|
279
|
+
|
264
280
|
def is_korean(string: str) -> bool:
|
265
281
|
"""Check if the given string is in Korean."""
|
266
282
|
|
283
|
+
|
267
284
|
def is_arabic(string: str) -> bool:
|
268
285
|
"""Check if the given string is in Arabic."""
|
269
286
|
|
287
|
+
|
270
288
|
def is_russian(string: str) -> bool:
|
271
289
|
"""Check if the given string is in Russian."""
|
272
290
|
|
291
|
+
|
273
292
|
def is_german(string: str) -> bool:
|
274
293
|
"""Check if the given string is in German."""
|
275
294
|
|
295
|
+
|
276
296
|
def is_french(string: str) -> bool:
|
277
297
|
"""Check if the given string is in French."""
|
278
298
|
|
299
|
+
|
279
300
|
def is_hindi(string: str) -> bool:
|
280
301
|
"""Check if the given string is in Hindi."""
|
281
302
|
|
303
|
+
|
282
304
|
def is_italian(string: str) -> bool:
|
283
305
|
"""Check if the given string is in Italian."""
|
284
306
|
|
307
|
+
|
285
308
|
def is_dutch(string: str) -> bool:
|
286
309
|
"""Check if the given string is in Dutch."""
|
287
310
|
|
311
|
+
|
288
312
|
def is_portuguese(string: str) -> bool:
|
289
313
|
"""Check if the given string is in Portuguese."""
|
290
314
|
|
315
|
+
|
291
316
|
def is_swedish(string: str) -> bool:
|
292
317
|
"""Check if the given string is in Swedish."""
|
293
318
|
|
319
|
+
|
294
320
|
def is_turkish(string: str) -> bool:
|
295
321
|
"""Check if the given string is in Turkish."""
|
296
322
|
|
323
|
+
|
297
324
|
def is_vietnamese(string: str) -> bool:
|
298
325
|
"""Check if the given string is in Vietnamese."""
|
299
326
|
|
327
|
+
|
300
328
|
def tex_to_typst(string: str) -> str:
|
301
329
|
"""Convert TeX to Typst.
|
302
330
|
|
@@ -307,6 +335,7 @@ def tex_to_typst(string: str) -> str:
|
|
307
335
|
The converted Typst string.
|
308
336
|
"""
|
309
337
|
|
338
|
+
|
310
339
|
def convert_all_inline_tex(string: str) -> str:
|
311
340
|
"""Convert all inline TeX code in the string.
|
312
341
|
|
@@ -317,6 +346,7 @@ def convert_all_inline_tex(string: str) -> str:
|
|
317
346
|
The converted string with inline TeX code replaced.
|
318
347
|
"""
|
319
348
|
|
349
|
+
|
320
350
|
def convert_all_block_tex(string: str) -> str:
|
321
351
|
"""Convert all block TeX code in the string.
|
322
352
|
|
@@ -327,6 +357,7 @@ def convert_all_block_tex(string: str) -> str:
|
|
327
357
|
The converted string with block TeX code replaced.
|
328
358
|
"""
|
329
359
|
|
360
|
+
|
330
361
|
def fix_misplaced_labels(string: str) -> str:
|
331
362
|
"""A func to fix labels in a string.
|
332
363
|
|
@@ -337,6 +368,7 @@ def fix_misplaced_labels(string: str) -> str:
|
|
337
368
|
The fixed string with labels properly placed.
|
338
369
|
"""
|
339
370
|
|
371
|
+
|
340
372
|
def comment(string: str) -> str:
|
341
373
|
"""Add comment to the string.
|
342
374
|
|
@@ -347,6 +379,7 @@ def comment(string: str) -> str:
|
|
347
379
|
The string with each line prefixed by '// '.
|
348
380
|
"""
|
349
381
|
|
382
|
+
|
350
383
|
def uncomment(string: str) -> str:
|
351
384
|
"""Remove comment from the string.
|
352
385
|
|
@@ -357,6 +390,7 @@ def uncomment(string: str) -> str:
|
|
357
390
|
The string with comments (lines starting with '// ' or '//') removed.
|
358
391
|
"""
|
359
392
|
|
393
|
+
|
360
394
|
def split_out_metadata(string: str) -> Tuple[Optional[JsonValue], str]:
|
361
395
|
"""Split out metadata from a string.
|
362
396
|
|
@@ -367,6 +401,7 @@ def split_out_metadata(string: str) -> Tuple[Optional[JsonValue], str]:
|
|
367
401
|
A tuple containing the metadata as a Python object (if parseable) and the remaining string.
|
368
402
|
"""
|
369
403
|
|
404
|
+
|
370
405
|
def to_metadata(data: JsonValue) -> str:
|
371
406
|
"""Convert a Python object to a YAML string.
|
372
407
|
|
@@ -377,8 +412,37 @@ def to_metadata(data: JsonValue) -> str:
|
|
377
412
|
The YAML string representation of the input data.
|
378
413
|
"""
|
379
414
|
|
415
|
+
|
380
416
|
def convert_to_inline_formula(string: str) -> str:
|
381
417
|
r"""Convert `$...$` to inline formula `\(...\)` and trim spaces."""
|
382
418
|
|
419
|
+
|
383
420
|
def convert_to_block_formula(string: str) -> str:
|
384
421
|
r"""Convert `$$...$$` to block formula `\[...\]` and trim spaces."""
|
422
|
+
|
423
|
+
|
424
|
+
def inplace_update(string: str, wrapper: str, new_body: str) -> Optional[str]:
|
425
|
+
"""Replace content between wrapper strings.
|
426
|
+
|
427
|
+
Args:
|
428
|
+
string: The input string containing content wrapped by delimiter strings.
|
429
|
+
wrapper: The delimiter string that marks the beginning and end of the content to replace.
|
430
|
+
new_body: The new content to place between the wrapper strings.
|
431
|
+
|
432
|
+
Returns:
|
433
|
+
A new string with the content between wrappers replaced.
|
434
|
+
|
435
|
+
"""
|
436
|
+
|
437
|
+
|
438
|
+
def extract_body(string: str, wrapper: str) -> Optional[str]:
|
439
|
+
"""
|
440
|
+
Extract the content between two occurrences of a wrapper string.
|
441
|
+
|
442
|
+
Args:
|
443
|
+
string: The input string containing content wrapped by delimiter strings.
|
444
|
+
wrapper: The delimiter string that marks the beginning and end of the content to extract.
|
445
|
+
|
446
|
+
Returns:
|
447
|
+
The content between the first two occurrences of the wrapper string if found, otherwise None.
|
448
|
+
"""
|
@@ -1,6 +1,6 @@
|
|
1
|
-
fabricatio-0.2.13.
|
2
|
-
fabricatio-0.2.13.
|
3
|
-
fabricatio-0.2.13.
|
1
|
+
fabricatio-0.2.13.dev3.dist-info/METADATA,sha256=Dns3zHDS0D06YJFNSLlN-J4QhN9RujbuX_n-7IBw0Cc,5169
|
2
|
+
fabricatio-0.2.13.dev3.dist-info/WHEEL,sha256=7FgAcpQES0h1xhfN9Ugve9FTUilU6sRAr1WJ5ph2cuw,108
|
3
|
+
fabricatio-0.2.13.dev3.dist-info/licenses/LICENSE,sha256=yDZaTLnOi03bi3Dk6f5IjhLUc5old2yOsihHWU0z-i0,1067
|
4
4
|
fabricatio/capabilities/check.py,sha256=TLtkUIR6tX73qR_V5TkXpdmplrmqFt4dZj32PBy81H0,8409
|
5
5
|
fabricatio/capabilities/propose.py,sha256=vOJvmmnMBHUQB6N1AmZNFw42jf7Bl2mBRNlBK15TpNI,1942
|
6
6
|
fabricatio/capabilities/correct.py,sha256=Et3Ud-oLZlwTVSy2XyT5UX2shT_OJ9j4HWP9b5Hntvk,10192
|
@@ -15,11 +15,11 @@ fabricatio/capabilities/review.py,sha256=EPL8IlxSKO0XStBkXdW7FJMbPztDQMv9w7tHgu6
|
|
15
15
|
fabricatio/capabilities/__init__.py,sha256=skaJ43CqAQaZMH-mCRzF4Fps3x99P2SwJ8vSM9pInX8,56
|
16
16
|
fabricatio/parser.py,sha256=rMXd9Lo5TjxUkI0rocYigF9d1kC0rSySenuMW8uqXm8,6483
|
17
17
|
fabricatio/models/action.py,sha256=_8iwX7BJWUOUKzM0Zn6B7jSrjRPJgzr88vTiYVHxRgE,10330
|
18
|
-
fabricatio/models/extra/article_outline.py,sha256=
|
18
|
+
fabricatio/models/extra/article_outline.py,sha256=K3Ajb86JQSsjo61briVCkIJkqRwvJ46uNU94NCrW-cY,1584
|
19
19
|
fabricatio/models/extra/article_essence.py,sha256=zUfZ2_bX3h__RaVPwJlxQ-tkFyfSV8SdX8DsmFX6v_w,2649
|
20
20
|
fabricatio/models/extra/article_main.py,sha256=RT4GRywxbR_ExOpYufe8j320EWT4nbnd7ASfcWIK-l0,10928
|
21
21
|
fabricatio/models/extra/article_proposal.py,sha256=4G2qLkMxtK54G1ANgPW0G3w4Pahxgk2lhGPU5KMxuzw,1818
|
22
|
-
fabricatio/models/extra/article_base.py,sha256=
|
22
|
+
fabricatio/models/extra/article_base.py,sha256=KSAAtShI1sSgpc8JxKxz4eLDBhquGABedsZUuwHX0_4,16338
|
23
23
|
fabricatio/models/extra/rag.py,sha256=RWv_YJhDX6UL4t3sRtQt-LYMtxN-K-t931nmyiJXkKM,3857
|
24
24
|
fabricatio/models/extra/rule.py,sha256=b756_XmWeDoJ1qOFEGy6ZfP8O7rBjOZs4XvfZvWKXXI,2574
|
25
25
|
fabricatio/models/extra/problem.py,sha256=1Sd8hsThQK6pXMXhErRhP1ft58z4PvqeB8AV8VcXiaI,7051
|
@@ -39,12 +39,12 @@ fabricatio/config.py,sha256=WL7lGN_XD98NHXuPYi95HWUY-xnGxXJxxqSFk0xVPRA,17696
|
|
39
39
|
fabricatio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
40
40
|
fabricatio/core.py,sha256=MaEKZ6DDmbdScAY-7F1gwGA6fr7ADX6Mz5rNVi2msFA,6277
|
41
41
|
fabricatio/constants.py,sha256=JxtaKGTf0IQhM-MNCHtr6x85Ejg8FWYcie-Z_RupCBg,557
|
42
|
-
fabricatio/rust.pyi,sha256=
|
42
|
+
fabricatio/rust.pyi,sha256=14jXpVNtxBGq5Yez6SNQG5mGWkjayAnOSGiF76xdQ2k,12192
|
43
43
|
fabricatio/actions/article.py,sha256=7N2TJARtN7iBWagmrtTI7Zqcp7U_8yxzKP6eB0t4PiM,12241
|
44
44
|
fabricatio/actions/rules.py,sha256=07ILsiwR250AUcKLPHTUPpWD_mPhPCfWKSkEAKcPv3A,3557
|
45
45
|
fabricatio/actions/output.py,sha256=lTvMgXzY-fwA_kNrivdFZkk3kT8DMpjBSIWLyav2B1k,8089
|
46
46
|
fabricatio/actions/rag.py,sha256=-bA7KkZEFfWEanAPHzYwRHG7zRlTZcNDI7HL3n-lDuE,3496
|
47
|
-
fabricatio/actions/article_rag.py,sha256=
|
47
|
+
fabricatio/actions/article_rag.py,sha256=6y-GnaBQ36I2y2LM3MnU9JFppFFNXo3IsOBbbfAH6rs,18009
|
48
48
|
fabricatio/actions/fs.py,sha256=nlTmk-tYDW158nz_fzlsNfuYJwj7j4BHn_MFY5hxdqs,934
|
49
49
|
fabricatio/actions/__init__.py,sha256=ZMa1LeM5BNeqp-J-D32W-f5bD53-kdXGyt0zuueJofM,47
|
50
50
|
fabricatio/fs/curd.py,sha256=x7Je9V1ydv-BdZTjlLc3syZ6380gkOhpfrfnhXstisg,4624
|
@@ -61,7 +61,7 @@ fabricatio/rust_instances.py,sha256=i5fIt6XkE8UwUU4JarmPt50AZs8aJW6efaypSLGLl0I,
|
|
61
61
|
fabricatio/utils.py,sha256=ocQMezvAiLxV7FyHrPi-H4Wp5xKJymuyntPGpHyOHCc,10044
|
62
62
|
fabricatio/journal.py,sha256=Op0wC-JlZumnAc_aDmYM4ljnSNLoKEEMfcIRbCF69ow,455
|
63
63
|
fabricatio/__init__.py,sha256=OXoMMHJKHEB_vN97_34U4I5QpAKL9xnVQEVcBCvwBCg,986
|
64
|
-
fabricatio/rust.cpython-312-x86_64-linux-gnu.so,sha256=
|
65
|
-
fabricatio-0.2.13.
|
66
|
-
fabricatio-0.2.13.
|
67
|
-
fabricatio-0.2.13.
|
64
|
+
fabricatio/rust.cpython-312-x86_64-linux-gnu.so,sha256=70ZYQcZMvFooMDJQe-ty67zN8ohGRmOt4mi8jQ4dcYU,4748624
|
65
|
+
fabricatio-0.2.13.dev3.data/scripts/tdown,sha256=4Liv9ixP-750aUzsZzKrvF76ZyJRG3Ay8mKPFdUe-6k,4592872
|
66
|
+
fabricatio-0.2.13.dev3.data/scripts/ttm,sha256=GA53bWxU6I-xNgtBMtulVwlCN5rcKLSrq0ddEK2N2Nc,3921584
|
67
|
+
fabricatio-0.2.13.dev3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|