]> git.lyx.org Git - lyx.git/blob - development/thorough_export_tests/lyxhtml_validity.py
Adding binary path for Homebrew on MacOS-arm64 (bug 12619).
[lyx.git] / development / thorough_export_tests / lyxhtml_validity.py
1 # Stricter version of the export tests: validate the XHTML code produced by
2 # LyX' lyxhtml output as HTML5. It also validates the CSS and MathML parts.
3 # Validation errors usually are mistakes in the generator.
4 #
5 # Call:
6 #     python lyxhtml_validity.py PATH_TO_LYX/lyx
7 #
8 # Written with Python 3.8.8.
9 # Requirements:
10 # - Python package: html5validator: at least v0.4.2
11 # - Java runtime engine (JRE): at least v8 (depending on html5validator)
12 # Run:
13 #     pip install html5validator>=0.4.2
14
15 import collections
16 import glob
17 import sys
18 import tempfile
19 import os
20
21 import html5validator
22
23
24 if len(sys.argv) != 2:
25     print('Expecting one argument, the path to the LyX binary to test')
26     sys.exit(-1)
27 if not os.path.exists(sys.argv[1]):
28     print('The given path does not point to an existing file')
29     sys.exit(-1)
30 if not os.access(sys.argv[1], os.X_OK):
31     print('The given path does not point to an executable file')
32     sys.exit(-1)
33
34
35 PATH_SCRIPT = os.path.dirname(os.path.realpath(__file__))
36 PATH_EXPORT_TESTS = os.path.realpath(PATH_SCRIPT + '/../../autotests/export/')
37 PATH_LYX = sys.argv[1]
38
39
40 TestFile = collections.namedtuple(
41     "TestFile", ["lyx_path", "lyx_file_name", "xhtml_path", "xhtml_file_name"]
42 )
43
44 validator = html5validator.Validator(format='text')
45
46
47 with tempfile.TemporaryDirectory() as out_dir_name:
48     all_lyx_files = glob.glob(PATH_EXPORT_TESTS + '/**/*.lyx', recursive=True)
49     all_files = [
50         TestFile(
51             lyx_path=path,
52             lyx_file_name=os.path.basename(path),
53             xhtml_path = os.path.join(out_dir_name, os.path.basename(path)),
54             xhtml_file_name=os.path.basename(path).replace('.lyx', '.html')
55         ) for path in all_lyx_files
56     ]
57     
58     # Generate XHTML files.
59     print(
60         f'Exporting {len(all_lyx_files)} LyX files to LyXHTML format in the ' +
61         f'directory {out_dir_name}'
62     )
63     
64     for file in all_files:
65         print(f'* Generating {file.lyx_file_name}...')
66         os.system(f'{PATH_LYX} --export-to xhtml "{file.xhtml_path}" "{file.lyx_path}"')
67         print(f'> Done generating {file.lyx_path} to {file.xhtml_path}')
68         
69         # print()
70         # print(open(file.xhtml_path, 'r').read())
71
72     print(f'Exported successfully all {len(all_lyx_files)} files!')
73
74     # Validate the XHTML files.
75     print(f'Validating {len(all_lyx_files)} XHTML files...')
76     
77     n_valid = 0
78     n_invalid = 0
79     for file in all_files:
80         print(f'* Validating {file.xhtml_file_name}...')
81         error_count = validator.validate([file.xhtml_file_name])
82         # Caution: this call outputs all validation errors to stdout!
83         # This line is equivalent to running vnu on the corresponding file.
84         # https://github.com/validator/validator
85         
86         if error_count == 0:
87             n_valid += 1
88             print(f'> Found no validation error!')
89         else:
90             n_invalid += 1
91             print(f'> Found {error_count} validation error{"" if error_count == 1 else "s"}!')
92
93     print(f'Validated all {len(all_lyx_files)} files! Among them:')
94     print(f'> {n_valid} were valid ({100.0 * n_valid / len(all_files)}%)')
95     print(f'> {n_invalid} were invalid ({100.0 * n_invalid / len(all_files)}%)')
96     
97     if n_invalid == 0:
98         print("That's excellent! Give yourself a pat on the back!")
99     elif 100.0 * n_invalid / len(all_files) <= 5.0:
100         print("That's a pretty good job!")