@voodocs/cli 0.3.2 → 0.4.0

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.
@@ -0,0 +1,244 @@
1
+ """@darkarts
2
+ ⊢symbols:darkarts.vocabulary
3
+ ∂{typing,enum}
4
+ ⚠{unicode-support,symbols-unique}
5
+ ⊨{∀symbol→unique-meaning,bidirectional-mapping}
6
+ 🔒{no-implications}
7
+ ⚡{O(1)-lookup}
8
+
9
+ DarkArts Symbol Vocabulary
10
+
11
+ Defines all symbols used in DarkArts documentation language.
12
+ """
13
+
14
+ from typing import Dict, List, Optional, Set
15
+ from enum import Enum
16
+ from dataclasses import dataclass
17
+
18
+
19
+ class SymbolCategory(Enum):
20
+ """Categories of DarkArts symbols."""
21
+ META = "meta" # Documentation structure (⊢, ∂, ⚠, ⊨)
22
+ LOGIC = "logic" # Logical operators (∀, ∃, ∧, ∨, ¬, ⇒)
23
+ SET = "set" # Set theory (∈, ⊂, ∪, ∩, ∅)
24
+ COMPARISON = "comparison" # Comparisons (=, ≠, <, >, ≤, ≥)
25
+ NUMBER_SET = "number_set" # Number sets (ℕ, ℤ, ℝ, ℂ)
26
+ STATE = "state" # State/flow (++, --, ⊳, ⊲)
27
+ ARROW = "arrow" # Arrows (→, ←, ⇒, ⇔)
28
+
29
+
30
+ @dataclass
31
+ class Symbol:
32
+ """Represents a DarkArts symbol."""
33
+ unicode: str # Unicode character
34
+ name: str # Human-readable name
35
+ category: SymbolCategory
36
+ meaning: str # What it means
37
+ ascii: Optional[str] = None # ASCII equivalent (if any)
38
+
39
+ def __repr__(self) -> str:
40
+ return f"{self.unicode} ({self.name})"
41
+
42
+
43
+ class DarkArtsVocabulary:
44
+ """
45
+ Complete vocabulary of DarkArts symbols.
46
+
47
+ Provides bidirectional mapping between symbols and meanings.
48
+ """
49
+
50
+ def __init__(self):
51
+ """Initialize the symbol vocabulary."""
52
+ self.symbols: Dict[str, Symbol] = {}
53
+ self.by_category: Dict[SymbolCategory, List[Symbol]] = {}
54
+ self.by_name: Dict[str, Symbol] = {}
55
+
56
+ self._init_meta_symbols()
57
+ self._init_logic_symbols()
58
+ self._init_set_symbols()
59
+ self._init_comparison_symbols()
60
+ self._init_number_sets()
61
+ self._init_state_symbols()
62
+ self._init_arrow_symbols()
63
+
64
+ def _add_symbol(self, unicode: str, name: str, category: SymbolCategory,
65
+ meaning: str, ascii: Optional[str] = None):
66
+ """Add a symbol to the vocabulary."""
67
+ symbol = Symbol(unicode, name, category, meaning, ascii)
68
+ self.symbols[unicode] = symbol
69
+ self.by_name[name] = symbol
70
+
71
+ if category not in self.by_category:
72
+ self.by_category[category] = []
73
+ self.by_category[category].append(symbol)
74
+
75
+ def _init_meta_symbols(self):
76
+ """Initialize meta/documentation structure symbols."""
77
+ self._add_symbol('⊢', 'turnstile', SymbolCategory.META,
78
+ 'Module/component declaration', '|-')
79
+ self._add_symbol('∂', 'partial', SymbolCategory.META,
80
+ 'Dependencies', 'd')
81
+ self._add_symbol('⚠', 'warning', SymbolCategory.META,
82
+ 'Assumptions/preconditions', '!')
83
+ self._add_symbol('⊨', 'models', SymbolCategory.META,
84
+ 'Invariants (must always be true)', '|=')
85
+ self._add_symbol('🔒', 'lock', SymbolCategory.META,
86
+ 'Security model', '[lock]')
87
+ self._add_symbol('⚡', 'lightning', SymbolCategory.META,
88
+ 'Performance model', '[perf]')
89
+ self._add_symbol('📊', 'chart', SymbolCategory.META,
90
+ 'Complexity analysis', '[chart]')
91
+ self._add_symbol('🎯', 'target', SymbolCategory.META,
92
+ 'Objectives/goals', '[goal]')
93
+ self._add_symbol('⚙️', 'gear', SymbolCategory.META,
94
+ 'Configuration', '[config]')
95
+
96
+ def _init_logic_symbols(self):
97
+ """Initialize logical operator symbols."""
98
+ self._add_symbol('∀', 'forall', SymbolCategory.LOGIC,
99
+ 'For all', 'forall')
100
+ self._add_symbol('∃', 'exists', SymbolCategory.LOGIC,
101
+ 'There exists', 'exists')
102
+ self._add_symbol('∧', 'and', SymbolCategory.LOGIC,
103
+ 'Logical AND', 'and')
104
+ self._add_symbol('∨', 'or', SymbolCategory.LOGIC,
105
+ 'Logical OR', 'or')
106
+ self._add_symbol('¬', 'not', SymbolCategory.LOGIC,
107
+ 'Logical NOT', 'not')
108
+ self._add_symbol('⇒', 'implies', SymbolCategory.LOGIC,
109
+ 'Implies (if...then)', '=>')
110
+ self._add_symbol('⇐', 'implied_by', SymbolCategory.LOGIC,
111
+ 'Implied by', '<=')
112
+ self._add_symbol('⇔', 'iff', SymbolCategory.LOGIC,
113
+ 'If and only if', '<=>')
114
+ self._add_symbol('⊕', 'xor', SymbolCategory.LOGIC,
115
+ 'Exclusive OR', 'xor')
116
+ self._add_symbol('⊤', 'top', SymbolCategory.LOGIC,
117
+ 'Always true / Success', 'true')
118
+ self._add_symbol('⊥', 'bottom', SymbolCategory.LOGIC,
119
+ 'Always false / Error', 'false')
120
+
121
+ def _init_set_symbols(self):
122
+ """Initialize set theory symbols."""
123
+ self._add_symbol('∈', 'in', SymbolCategory.SET,
124
+ 'Element of / Member of', 'in')
125
+ self._add_symbol('∉', 'notin', SymbolCategory.SET,
126
+ 'Not element of', 'notin')
127
+ self._add_symbol('⊂', 'subset', SymbolCategory.SET,
128
+ 'Proper subset', 'subset')
129
+ self._add_symbol('⊃', 'supset', SymbolCategory.SET,
130
+ 'Proper superset', 'supset')
131
+ self._add_symbol('⊆', 'subseteq', SymbolCategory.SET,
132
+ 'Subset or equal', 'subseteq')
133
+ self._add_symbol('⊇', 'supseteq', SymbolCategory.SET,
134
+ 'Superset or equal', 'supseteq')
135
+ self._add_symbol('∪', 'union', SymbolCategory.SET,
136
+ 'Set union', 'union')
137
+ self._add_symbol('∩', 'intersect', SymbolCategory.SET,
138
+ 'Set intersection', 'intersect')
139
+ self._add_symbol('∅', 'emptyset', SymbolCategory.SET,
140
+ 'Empty set', 'emptyset')
141
+
142
+ def _init_comparison_symbols(self):
143
+ """Initialize comparison operator symbols."""
144
+ self._add_symbol('=', 'equals', SymbolCategory.COMPARISON,
145
+ 'Equals', '=')
146
+ self._add_symbol('≠', 'ne', SymbolCategory.COMPARISON,
147
+ 'Not equals', '!=')
148
+ self._add_symbol('<', 'lt', SymbolCategory.COMPARISON,
149
+ 'Less than', '<')
150
+ self._add_symbol('>', 'gt', SymbolCategory.COMPARISON,
151
+ 'Greater than', '>')
152
+ self._add_symbol('≤', 'le', SymbolCategory.COMPARISON,
153
+ 'Less than or equal', '<=')
154
+ self._add_symbol('≥', 'ge', SymbolCategory.COMPARISON,
155
+ 'Greater than or equal', '>=')
156
+ self._add_symbol('≈', 'approx', SymbolCategory.COMPARISON,
157
+ 'Approximately equal', '~=')
158
+ self._add_symbol('≡', 'equiv', SymbolCategory.COMPARISON,
159
+ 'Identical / Definitionally equal', '==')
160
+
161
+ def _init_number_sets(self):
162
+ """Initialize number set symbols."""
163
+ self._add_symbol('ℕ', 'naturals', SymbolCategory.NUMBER_SET,
164
+ 'Natural numbers', 'N')
165
+ self._add_symbol('ℤ', 'integers', SymbolCategory.NUMBER_SET,
166
+ 'Integers', 'Z')
167
+ self._add_symbol('ℚ', 'rationals', SymbolCategory.NUMBER_SET,
168
+ 'Rational numbers', 'Q')
169
+ self._add_symbol('ℝ', 'reals', SymbolCategory.NUMBER_SET,
170
+ 'Real numbers', 'R')
171
+ self._add_symbol('ℂ', 'complex', SymbolCategory.NUMBER_SET,
172
+ 'Complex numbers', 'C')
173
+ self._add_symbol('ℙ', 'primes', SymbolCategory.NUMBER_SET,
174
+ 'Prime numbers', 'P')
175
+
176
+ def _init_state_symbols(self):
177
+ """Initialize state/flow operator symbols."""
178
+ self._add_symbol('++', 'increment', SymbolCategory.STATE,
179
+ 'Increment by 1', '++')
180
+ self._add_symbol('--', 'decrement', SymbolCategory.STATE,
181
+ 'Decrement by 1', '--')
182
+ self._add_symbol('+=', 'add_assign', SymbolCategory.STATE,
183
+ 'Add and assign', '+=')
184
+ self._add_symbol('-=', 'sub_assign', SymbolCategory.STATE,
185
+ 'Subtract and assign', '-=')
186
+ self._add_symbol('⊳', 'precondition', SymbolCategory.STATE,
187
+ 'Precondition (must hold before)', '|>')
188
+ self._add_symbol('⊲', 'postcondition', SymbolCategory.STATE,
189
+ 'Postcondition (must hold after)', '<|')
190
+
191
+ def _init_arrow_symbols(self):
192
+ """Initialize arrow symbols."""
193
+ self._add_symbol('→', 'arrow_right', SymbolCategory.ARROW,
194
+ 'Maps to / Leads to', '->')
195
+ self._add_symbol('←', 'arrow_left', SymbolCategory.ARROW,
196
+ 'Comes from', '<-')
197
+ self._add_symbol('↔', 'arrow_both', SymbolCategory.ARROW,
198
+ 'Bidirectional', '<->')
199
+ self._add_symbol('↦', 'mapsto', SymbolCategory.ARROW,
200
+ 'Element maps to', '|->')
201
+
202
+ def get_symbol(self, unicode: str) -> Optional[Symbol]:
203
+ """Get symbol by Unicode character."""
204
+ return self.symbols.get(unicode)
205
+
206
+ def get_by_name(self, name: str) -> Optional[Symbol]:
207
+ """Get symbol by name."""
208
+ return self.by_name.get(name)
209
+
210
+ def get_category(self, category: SymbolCategory) -> List[Symbol]:
211
+ """Get all symbols in a category."""
212
+ return self.by_category.get(category, [])
213
+
214
+ def is_symbol(self, char: str) -> bool:
215
+ """Check if character is a DarkArts symbol."""
216
+ return char in self.symbols
217
+
218
+ def get_all_symbols(self) -> List[Symbol]:
219
+ """Get all symbols."""
220
+ return list(self.symbols.values())
221
+
222
+ def get_meta_symbols(self) -> Set[str]:
223
+ """Get set of meta symbols (⊢, ∂, ⚠, ⊨, etc.)."""
224
+ return {s.unicode for s in self.get_category(SymbolCategory.META)}
225
+
226
+
227
+ # Global vocabulary instance
228
+ VOCABULARY = DarkArtsVocabulary()
229
+
230
+
231
+ # Convenience functions
232
+ def get_symbol(unicode: str) -> Optional[Symbol]:
233
+ """Get symbol by Unicode character."""
234
+ return VOCABULARY.get_symbol(unicode)
235
+
236
+
237
+ def is_darkarts_symbol(char: str) -> bool:
238
+ """Check if character is a DarkArts symbol."""
239
+ return VOCABULARY.is_symbol(char)
240
+
241
+
242
+ def get_meta_symbols() -> Set[str]:
243
+ """Get set of meta symbols."""
244
+ return VOCABULARY.get_meta_symbols()
@@ -0,0 +1,386 @@
1
+ """@darkarts
2
+ ⊢translator:darkarts↔natural-lang
3
+ ∂{re,typing,symbols,darkarts_parser}
4
+ ⚠{bidirectional,preserves-meaning}
5
+ ⊨{∀translate→reversible,readable,accurate}
6
+ 🔒{no-implications}
7
+ ⚡{O(n)|n=text-length}
8
+
9
+ DarkArts Bidirectional Translator
10
+
11
+ Translates between DarkArts symbolic notation and natural language.
12
+ """
13
+
14
+ import re
15
+ from typing import Dict, List, Optional
16
+ from .symbols import VOCABULARY
17
+ from .darkarts_parser import DarkArtsAnnotation, DarkArtsParser
18
+
19
+
20
+ class DarkArtsTranslator:
21
+ """
22
+ Bidirectional translator between DarkArts symbols and natural language.
23
+
24
+ Supports:
25
+ - Symbols → Natural Language (for humans)
26
+ - Natural Language → Symbols (for writing)
27
+ """
28
+
29
+ def __init__(self):
30
+ """Initialize the translator."""
31
+ self.vocab = VOCABULARY
32
+
33
+ # Symbol → English mappings
34
+ self.symbol_to_english = {
35
+ '⊢': 'Module',
36
+ '∂': 'Dependencies',
37
+ '⚠': 'Assumptions',
38
+ '⊨': 'Invariants',
39
+ '🔒': 'Security Model',
40
+ '⚡': 'Performance',
41
+ '📊': 'Complexity',
42
+ '🎯': 'Objectives',
43
+ '⚙️': 'Configuration',
44
+ '∀': 'for all',
45
+ '∃': 'there exists',
46
+ '∧': 'and',
47
+ '∨': 'or',
48
+ '¬': 'not',
49
+ '⇒': 'implies',
50
+ '⇐': 'implied by',
51
+ '⇔': 'if and only if',
52
+ '∈': 'in',
53
+ '∉': 'not in',
54
+ '⊂': 'subset of',
55
+ '⊆': 'subset or equal to',
56
+ '∪': 'union',
57
+ '∩': 'intersection',
58
+ '∅': 'empty set',
59
+ '→': 'leads to',
60
+ '←': 'comes from',
61
+ '↔': 'bidirectional',
62
+ '⊤': 'success',
63
+ '⊥': 'failure',
64
+ '≤': 'less than or equal to',
65
+ '≥': 'greater than or equal to',
66
+ '≠': 'not equal to',
67
+ '≈': 'approximately',
68
+ '≡': 'identical to',
69
+ '++': 'increment',
70
+ '--': 'decrement',
71
+ '⊳': 'precondition',
72
+ '⊲': 'postcondition',
73
+ 'ℕ': 'natural numbers',
74
+ 'ℤ': 'integers',
75
+ 'ℚ': 'rationals',
76
+ 'ℝ': 'real numbers',
77
+ 'ℂ': 'complex numbers',
78
+ 'ℙ': 'prime numbers',
79
+ }
80
+
81
+ # English → Symbol mappings (reverse)
82
+ self.english_to_symbol = {v: k for k, v in self.symbol_to_english.items()}
83
+
84
+ # Add common variations
85
+ self.english_to_symbol.update({
86
+ 'for every': '∀',
87
+ 'for each': '∀',
88
+ 'exists': '∃',
89
+ 'then': '⇒',
90
+ 'if': '⇒',
91
+ 'iff': '⇔',
92
+ 'element of': '∈',
93
+ 'member of': '∈',
94
+ 'not element of': '∉',
95
+ 'true': '⊤',
96
+ 'false': '⊥',
97
+ 'error': '⊥',
98
+ 'less or equal': '≤',
99
+ 'greater or equal': '≥',
100
+ 'not equal': '≠',
101
+ 'approximately equal': '≈',
102
+ 'equal': '=',
103
+ })
104
+
105
+ def symbols_to_natural(self, annotation: DarkArtsAnnotation) -> str:
106
+ """
107
+ Translate DarkArts annotation to natural language.
108
+
109
+ Args:
110
+ annotation: Parsed DarkArts annotation
111
+
112
+ Returns:
113
+ Natural language description
114
+ """
115
+ lines = []
116
+
117
+ # Module
118
+ if annotation.module:
119
+ lines.append(f"**Module**: {annotation.module}")
120
+ lines.append("")
121
+
122
+ # Dependencies
123
+ if annotation.dependencies:
124
+ lines.append("**Dependencies**:")
125
+ for dep in annotation.dependencies:
126
+ # Check if dep has description (format: "name:description")
127
+ if ':' in dep:
128
+ name, desc = dep.split(':', 1)
129
+ lines.append(f" - {name}: {desc}")
130
+ else:
131
+ lines.append(f" - {dep}")
132
+ lines.append("")
133
+
134
+ # Assumptions
135
+ if annotation.assumptions:
136
+ lines.append("**Assumptions**:")
137
+ for assumption in annotation.assumptions:
138
+ translated = self._translate_expression(assumption)
139
+ lines.append(f" - {translated}")
140
+ lines.append("")
141
+
142
+ # Invariants
143
+ if annotation.invariants:
144
+ lines.append("**Invariants**:")
145
+ for invariant in annotation.invariants:
146
+ translated = self._translate_expression(invariant)
147
+ lines.append(f" - {translated}")
148
+ lines.append("")
149
+
150
+ # Security
151
+ if annotation.security:
152
+ lines.append(f"**Security Model**: {self._translate_expression(annotation.security)}")
153
+ lines.append("")
154
+
155
+ # Performance
156
+ if annotation.performance:
157
+ lines.append(f"**Performance**: {self._translate_expression(annotation.performance)}")
158
+ lines.append("")
159
+
160
+ # Complexity
161
+ if annotation.complexity:
162
+ lines.append(f"**Complexity**: {self._translate_expression(annotation.complexity)}")
163
+ lines.append("")
164
+
165
+ # Objectives
166
+ if annotation.objectives:
167
+ lines.append(f"**Objectives**: {self._translate_expression(annotation.objectives)}")
168
+ lines.append("")
169
+
170
+ # Configuration
171
+ if annotation.configuration:
172
+ lines.append(f"**Configuration**: {self._translate_expression(annotation.configuration)}")
173
+ lines.append("")
174
+
175
+ return '\n'.join(lines).strip()
176
+
177
+ def _translate_expression(self, expr: str) -> str:
178
+ """
179
+ Translate a symbolic expression to natural language.
180
+
181
+ Args:
182
+ expr: Symbolic expression
183
+
184
+ Returns:
185
+ Natural language translation
186
+ """
187
+ result = expr
188
+
189
+ # Replace symbols with English
190
+ for symbol, english in self.symbol_to_english.items():
191
+ result = result.replace(symbol, f" {english} ")
192
+
193
+ # Clean up spacing
194
+ result = re.sub(r'\s+', ' ', result).strip()
195
+
196
+ # Capitalize first letter
197
+ if result:
198
+ result = result[0].upper() + result[1:]
199
+
200
+ return result
201
+
202
+ def natural_to_symbols(self, text: str) -> str:
203
+ """
204
+ Translate natural language to DarkArts symbols.
205
+
206
+ Args:
207
+ text: Natural language description
208
+
209
+ Returns:
210
+ Symbolic notation
211
+ """
212
+ result = text.lower()
213
+
214
+ # Replace English phrases with symbols
215
+ # Sort by length (longest first) to avoid partial matches
216
+ phrases = sorted(self.english_to_symbol.items(),
217
+ key=lambda x: len(x[0]), reverse=True)
218
+
219
+ for english, symbol in phrases:
220
+ result = result.replace(english, symbol)
221
+
222
+ return result
223
+
224
+ def translate_file(self, file_path: str, to_natural: bool = True) -> str:
225
+ """
226
+ Translate all @darkarts annotations in a file.
227
+
228
+ Args:
229
+ file_path: Path to source file
230
+ to_natural: If True, translate to natural language;
231
+ if False, translate to symbols
232
+
233
+ Returns:
234
+ Translated content
235
+ """
236
+ parser = DarkArtsParser()
237
+ annotations = parser.parse_file(file_path)
238
+
239
+ if to_natural:
240
+ # Translate to natural language
241
+ results = []
242
+ for i, annotation in enumerate(annotations, 1):
243
+ results.append(f"## Annotation {i}\n")
244
+ results.append(self.symbols_to_natural(annotation))
245
+ results.append("\n---\n")
246
+ return '\n'.join(results)
247
+ else:
248
+ # Already in symbols, just return raw text
249
+ return '\n\n'.join(a.raw_text for a in annotations)
250
+
251
+ def translate_annotation_text(self, text: str) -> str:
252
+ """
253
+ Translate a @darkarts annotation text to natural language.
254
+
255
+ Args:
256
+ text: Annotation text (without @darkarts marker)
257
+
258
+ Returns:
259
+ Natural language translation
260
+ """
261
+ parser = DarkArtsParser()
262
+ annotation = parser.parse_annotation(text)
263
+ return self.symbols_to_natural(annotation)
264
+
265
+ def create_darkarts_from_voodocs(self, voodocs_dict: Dict) -> str:
266
+ """
267
+ Create @darkarts annotation from @voodocs dictionary.
268
+
269
+ Args:
270
+ voodocs_dict: Dictionary with keys like 'module_purpose',
271
+ 'dependencies', 'assumptions', 'invariants', etc.
272
+
273
+ Returns:
274
+ DarkArts annotation text
275
+ """
276
+ lines = ['"""@darkarts']
277
+
278
+ # Module
279
+ if 'module_purpose' in voodocs_dict:
280
+ purpose = voodocs_dict['module_purpose']
281
+ # Extract key parts (simplified)
282
+ lines.append(f"⊢{purpose}")
283
+
284
+ # Dependencies
285
+ if 'dependencies' in voodocs_dict:
286
+ deps = voodocs_dict['dependencies']
287
+ if isinstance(deps, list):
288
+ # Simplify dependencies
289
+ simplified = []
290
+ for dep in deps:
291
+ if ':' in dep:
292
+ name, _ = dep.split(':', 1)
293
+ simplified.append(name.strip())
294
+ else:
295
+ simplified.append(dep.strip())
296
+ lines.append(f"∂{{{','.join(simplified)}}}")
297
+
298
+ # Assumptions
299
+ if 'assumptions' in voodocs_dict:
300
+ assumptions = voodocs_dict['assumptions']
301
+ if isinstance(assumptions, list):
302
+ # Simplify assumptions
303
+ simplified = [self._simplify_assumption(a) for a in assumptions]
304
+ lines.append(f"⚠{{{','.join(simplified)}}}")
305
+
306
+ # Invariants
307
+ if 'invariants' in voodocs_dict:
308
+ invariants = voodocs_dict['invariants']
309
+ if isinstance(invariants, list):
310
+ # Convert to symbolic notation
311
+ symbolic = [self._convert_invariant(inv) for inv in invariants]
312
+ lines.append(f"⊨{{{','.join(symbolic)}}}")
313
+
314
+ # Security
315
+ if 'security_model' in voodocs_dict:
316
+ security = self._simplify_text(voodocs_dict['security_model'])
317
+ lines.append(f"🔒{{{security}}}")
318
+
319
+ # Performance
320
+ if 'performance_model' in voodocs_dict:
321
+ perf = voodocs_dict['performance_model']
322
+ lines.append(f"⚡{{{perf}}}")
323
+
324
+ lines.append('"""')
325
+ return '\n'.join(lines)
326
+
327
+ def _simplify_assumption(self, assumption: str) -> str:
328
+ """Simplify an assumption to compact form."""
329
+ # Remove common prefixes
330
+ assumption = assumption.lower()
331
+ for prefix in ['assume', 'assumes', 'assuming', 'we assume']:
332
+ if assumption.startswith(prefix):
333
+ assumption = assumption[len(prefix):].strip()
334
+
335
+ # Convert to symbolic notation where possible
336
+ assumption = self.natural_to_symbols(assumption)
337
+
338
+ return assumption
339
+
340
+ def _convert_invariant(self, invariant: str) -> str:
341
+ """Convert an invariant to symbolic notation."""
342
+ # Convert "must" patterns
343
+ invariant = invariant.lower()
344
+
345
+ # "all X must Y" → "∀X→Y"
346
+ invariant = re.sub(r'all (\w+) must (\w+)', r'∀\1→\2', invariant)
347
+
348
+ # "X must Y" → "X→Y"
349
+ invariant = re.sub(r'(\w+) must (\w+)', r'\1→\2', invariant)
350
+
351
+ # Convert common phrases to symbols
352
+ invariant = self.natural_to_symbols(invariant)
353
+
354
+ return invariant
355
+
356
+ def _simplify_text(self, text: str) -> str:
357
+ """Simplify text to compact form."""
358
+ # Remove articles
359
+ text = re.sub(r'\b(a|an|the)\b', '', text, flags=re.IGNORECASE)
360
+
361
+ # Remove extra spaces
362
+ text = re.sub(r'\s+', ' ', text).strip()
363
+
364
+ # Convert to symbols
365
+ text = self.natural_to_symbols(text)
366
+
367
+ return text
368
+
369
+
370
+ # Convenience functions
371
+ def translate_to_natural(annotation: DarkArtsAnnotation) -> str:
372
+ """Translate DarkArts annotation to natural language."""
373
+ translator = DarkArtsTranslator()
374
+ return translator.symbols_to_natural(annotation)
375
+
376
+
377
+ def translate_to_symbols(text: str) -> str:
378
+ """Translate natural language to DarkArts symbols."""
379
+ translator = DarkArtsTranslator()
380
+ return translator.natural_to_symbols(text)
381
+
382
+
383
+ def convert_voodocs_to_darkarts(voodocs_dict: Dict) -> str:
384
+ """Convert @voodocs dictionary to @darkarts annotation."""
385
+ translator = DarkArtsTranslator()
386
+ return translator.create_darkarts_from_voodocs(voodocs_dict)
@@ -1,4 +1,11 @@
1
- """
1
+ """@darkarts
2
+ ⊢ai-instructions:ctx.templates
3
+ ∂{typing}
4
+ ⚠{ai:cursor∨claude,project:voodocs-enabled,templates:markdown}
5
+ ⊨{∀gen→valid-markdown,∀gen→include-cmds,∀gen→teach-best-practices}
6
+ 🔒{no-implications}
7
+ ⚡{O(1)|template-generation}
8
+
2
9
  AI instruction templates for VooDocs Context System.
3
10
 
4
11
  This module provides templates for generating AI assistant instructions