157 lines
4.7 KiB
Python
157 lines
4.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Make all form fields in LaTeX documents readonly by adding readonly=true attribute.
|
|
This script carefully parses LaTeX commands to avoid breaking the syntax.
|
|
"""
|
|
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def add_readonly_to_textfield(content):
|
|
"""Add readonly=true to CustomTextFieldDefault commands."""
|
|
# Pattern to match CustomTextFieldDefault{...}{...}{...}{params}
|
|
pattern = r'(\\CustomTextFieldDefault\{[^}]*\}\{[^}]*\}\{[^}]*\}\{)([^}]*)\}'
|
|
|
|
def replacer(match):
|
|
prefix = match.group(1)
|
|
params = match.group(2)
|
|
|
|
# Check if readonly is already present
|
|
if 'readonly=' in params:
|
|
return match.group(0)
|
|
|
|
# Add readonly=true to the parameters
|
|
if params.strip():
|
|
new_params = params + ',readonly=true'
|
|
else:
|
|
new_params = 'readonly=true'
|
|
|
|
return prefix + new_params + '}'
|
|
|
|
return re.sub(pattern, replacer, content)
|
|
|
|
|
|
def add_readonly_to_choicemenu(content):
|
|
"""Add readonly=true to CustomChoiceMenuDefault commands."""
|
|
# Pattern to match CustomChoiceMenuDefault{...}{...}{params}{...}
|
|
pattern = r'(\\CustomChoiceMenuDefault\{[^}]*\}\{[^}]*\}\{)([^}]*)\}(\{[^}]*\})'
|
|
|
|
def replacer(match):
|
|
prefix = match.group(1)
|
|
params = match.group(2)
|
|
suffix = match.group(3)
|
|
|
|
# Check if readonly is already present
|
|
if 'readonly=' in params:
|
|
return match.group(0)
|
|
|
|
# Add readonly=true to the parameters
|
|
if params.strip():
|
|
new_params = params + ',readonly=true'
|
|
else:
|
|
new_params = 'readonly=true'
|
|
|
|
return prefix + new_params + '}' + suffix
|
|
|
|
return re.sub(pattern, replacer, content)
|
|
|
|
|
|
def add_readonly_to_checkbox(content):
|
|
"""Add readonly=true to CheckBox commands."""
|
|
# Pattern to match CheckBox[params]
|
|
pattern = r'(\\CheckBox\[)([^\]]*)\]'
|
|
|
|
def replacer(match):
|
|
prefix = match.group(1)
|
|
params = match.group(2)
|
|
|
|
# Check if readonly is already present
|
|
if 'readonly=' in params:
|
|
return match.group(0)
|
|
|
|
# Add readonly=true to the parameters
|
|
params_lines = params.split('\n')
|
|
|
|
# Find a good place to insert readonly=true (after first parameter)
|
|
for i, line in enumerate(params_lines):
|
|
if line.strip() and not line.strip().startswith('%'):
|
|
# Insert after this line
|
|
params_lines.insert(i + 1, '\t\t\t\treadonly=true,')
|
|
break
|
|
|
|
new_params = '\n'.join(params_lines)
|
|
return prefix + new_params + ']'
|
|
|
|
return re.sub(pattern, replacer, content, flags=re.MULTILINE | re.DOTALL)
|
|
|
|
|
|
def add_readonly_to_textfield_multiline(content):
|
|
"""Add readonly=true to TextField commands (multiline text fields)."""
|
|
# Pattern to match TextField[params] for multiline fields
|
|
pattern = r'(\\TextField\[)([^\]]*name=pa-project-description[^\]]*)\]'
|
|
|
|
def replacer(match):
|
|
prefix = match.group(1)
|
|
params = match.group(2)
|
|
|
|
# Check if readonly is already present
|
|
if 'readonly=' in params:
|
|
return match.group(0)
|
|
|
|
# Add readonly=true to the parameters
|
|
params_lines = params.split('\n')
|
|
|
|
# Find a good place to insert readonly=true (after multiline parameter)
|
|
for i, line in enumerate(params_lines):
|
|
if 'multiline' in line:
|
|
# Insert after this line
|
|
params_lines.insert(i + 1, '\t\t\t\treadonly=true,')
|
|
break
|
|
|
|
new_params = '\n'.join(params_lines)
|
|
return prefix + new_params + ']'
|
|
|
|
return re.sub(pattern, replacer, content, flags=re.MULTILINE | re.DOTALL)
|
|
|
|
|
|
def process_file(filepath):
|
|
"""Process a single LaTeX file to make all fields readonly."""
|
|
print(f"Processing {filepath}...")
|
|
|
|
with open(filepath, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
# Apply transformations
|
|
content = add_readonly_to_textfield(content)
|
|
content = add_readonly_to_choicemenu(content)
|
|
content = add_readonly_to_checkbox(content)
|
|
content = add_readonly_to_textfield_multiline(content)
|
|
|
|
# Write back
|
|
with open(filepath, 'w', encoding='utf-8') as f:
|
|
f.write(content)
|
|
|
|
print(f"✓ Processed {filepath}")
|
|
|
|
|
|
def main():
|
|
"""Main function to process QSM and VSM LaTeX files."""
|
|
base_dir = Path(__file__).parent.parent
|
|
|
|
files_to_process = [
|
|
base_dir / "latex-qsm" / "Content" / "01_content.tex",
|
|
base_dir / "latex-vsm" / "Content" / "01_content.tex",
|
|
]
|
|
|
|
for filepath in files_to_process:
|
|
if filepath.exists():
|
|
process_file(filepath)
|
|
else:
|
|
print(f"✗ File not found: {filepath}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|