stupa-pdf-api/backend/scripts/make_fields_readonly.py

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()