Add AC/BC RTCP programs and 3D machine manager
This commit is contained in:
54
scripts/verify_rtcp_teaching_pdf.py
Normal file
54
scripts/verify_rtcp_teaching_pdf.py
Normal file
@@ -0,0 +1,54 @@
|
||||
"""Verify the standalone PDF, embedded fonts, text, page dimensions and evidence."""
|
||||
import hashlib
|
||||
import json
|
||||
import unicodedata
|
||||
from pathlib import Path
|
||||
from pypdf import PdfReader
|
||||
|
||||
root = Path(__file__).resolve().parents[1]
|
||||
output = root / 'docs/teaching/rtcp-five-axis'
|
||||
pdf = output / '五轴机床与RTCP-教学课件.pdf'
|
||||
reader = PdfReader(pdf)
|
||||
outline = json.loads((output / 'outline.json').read_text())
|
||||
layout = json.loads((output / 'verification/layout.json').read_text())
|
||||
numerics = json.loads((output / 'numeric-evidence.json').read_text())
|
||||
assert len(reader.pages) == len(outline) == 31
|
||||
assert numerics['status'] == 'verified' and not layout['errors']
|
||||
assert all(not p['clipped'] and not p['content_overflow'] for p in layout['pages'])
|
||||
pages = []
|
||||
fonts = {}
|
||||
for index, page in enumerate(reader.pages):
|
||||
text = unicodedata.normalize('NFKC', page.extract_text())
|
||||
assert len(text) > 100, (index, len(text))
|
||||
assert abs(float(page.mediabox.width) / float(page.mediabox.height) - 16/9) < .001
|
||||
assert str(index+1).zfill(2) in text
|
||||
assert '\ufffd' not in text
|
||||
for font in page['/Resources'].get('/Font', {}).values():
|
||||
value = font.get_object()
|
||||
descendants = value.get('/DescendantFonts', [value])
|
||||
for item in descendants:
|
||||
descriptor = item.get_object().get('/FontDescriptor')
|
||||
if descriptor:
|
||||
descriptor = descriptor.get_object()
|
||||
# Chrome embeds CFF CJK glyphs as Type 3 CharProcs instead of
|
||||
# a FontFile stream; both forms are self-contained PDF fonts.
|
||||
type3 = item.get_object().get('/Subtype') == '/Type3' and bool(item.get_object().get('/CharProcs'))
|
||||
embedded = type3 or any(key in descriptor for key in ['/FontFile', '/FontFile2', '/FontFile3'])
|
||||
name = str(descriptor.get('/FontName'))
|
||||
fonts[name] = embedded
|
||||
pages.append({'page': index+1, 'characters': len(text), 'width_pt': float(page.mediabox.width), 'height_pt': float(page.mediabox.height)})
|
||||
assert fonts and all(fonts.values()), fonts
|
||||
assert any('CJK' in font for font in fonts), fonts
|
||||
assert len(reader.outline) >= 31
|
||||
report = {
|
||||
'report_id': 'rtcp-teaching-pdf-v1', 'status': 'verified', 'pages': pages,
|
||||
'pdf': pdf.name, 'bytes': pdf.stat().st_size,
|
||||
'sha256': hashlib.sha256(pdf.read_bytes()).hexdigest(),
|
||||
'bookmarks': len(reader.outline), 'embedded_fonts': fonts,
|
||||
'numeric_report_id': numerics['report_id'], 'wasm_sha256': numerics['wasm_sha256'],
|
||||
'layout_report': 'verification/layout.json',
|
||||
'evidence': [{'path': str(p.relative_to(output)), 'sha256': hashlib.sha256(p.read_bytes()).hexdigest()}
|
||||
for p in [output/'course.html', output/'numeric-evidence.json', output/'outline.json', output/'verification/layout.json', *sorted((output/'assets').glob('*.png'))]],
|
||||
}
|
||||
(output / 'verification/acceptance.json').write_text(json.dumps(report, ensure_ascii=False, indent=2)+'\n')
|
||||
print(json.dumps({'report_id':report['report_id'], 'status':report['status'], 'pages':len(pages), 'bytes':report['bytes'], 'fonts':len(fonts), 'bookmarks':report['bookmarks']},ensure_ascii=False))
|
||||
Reference in New Issue
Block a user