Newer
Older
AI_Lab_SCRUME_Co / skills / ailab / om-documentation-review / references / review-verdict-docx.md

Итоговая ведомость заказчику: docx-сверка на 4 колонки

When to Use

Когда просят «проверку тома ИОС1.1 / ЭОМ», «сверку проверок» или просит внести замечания в существующую docx-таблицу сверки (шаблон вида «ВОПРОС | МАСТЕРМАЙНД | …»). Это финальный формат результата — не заменяется markdown-отчётом.

Формат, который принимается как результат проверки тома — не markdown-отчёт, а docx-таблица сверки: «ВОПРОС | МАСТЕРМАЙНД | AI_Lab_SCRUM Co | РАСХОЖДЕНИЯ».

Правила оформления

  • 4 колонки; первые три — вопрос и два независимых заключения, четвёртая — расхождения.
  • Несоответствия — красным (RGBColor(0xC0, 0, 0) в python-docx; в исходных файлах встречается FF0000).
  • В колонке «Расхождения» — готовая отредактированная формулировка. Схему «было → отредактировано» не применять — колонку «было» не оставлять.
  • Новые находки (шаги 1–3) добавляются дополнительными строками целиком красным, в первой колонке — суть со пометкой источника: «(шаг 1, код)» или «(шаг 3, аудитор)». Так видно, какой этап методики что дал — это и есть оценка метода.
  • В конце — одно примечание: что проверено, чем, и что графическая часть не проверялась.

Техника сборки (python-docx)

Скрипт: scripts/build_review_docx.py.

  1. Читать существующий docx-шаблон и дописывать его, а не создавать с нуля: у шаблона уже есть стили, заливка шапки и прежние пометки.
  2. Новую колонку добавлять копированием последней ячейки (copy.deepcopy(cell._tc)
    • cell._tc.addnext(...)) — в шапке и в каждой строке.
  3. Новые строки — копированием строки-образца (copy.deepcopy(t.rows[1]._tr) + t._tbl.append(...)), затем заполнять ячейки 0..3.
  4. Обязательно дописать w:gridCol в w:tblGrid под новую колонку. Без этого table.columns показывает 4, ячейки читаются, но Word рисует таблицу с ломаными ширинами — внешний дефект, который видно сразу. После — задать cell.width.
  5. Удалять устаревшее примечание из шаблона: при дописывании остаются два противоречащих друг другу. Проверять len(d.paragraphs) до и после.
  6. Тексты ячеек задавать через cell.text = "" + p.add_run(text) с font.size = Pt(9); просто cell.text = ... теряет формат и даёт огромный шрифт.

Логотип и колонтитулы AI_Lab_SCRUM_Co

Требование: на итоговой ведомости — логотип и колонтитул AI_Lab_SCRUM_Co сверху и снизу. Логотип — logo AI Lab SCRUM ENGINEERING, присылается пользователем как PNG с прозрачным фоном и БЕЛЫМ текстом (проверка: РГБА + getchannel("A"), у белой части нейтральные каналы).

Перекраска логотипа под светлый фон

На белой бумаге белый текст исчезает — нейтральные (белые/серые) пиксели нужно перекрасить в тёмный, не трогая оранжевый градиент:

if a == 0: continue
if abs(r-g) < 28 and abs(g-b) < 28 and abs(r-b) < 28:   # нейтральный (белый текст)
    po[x,y] = (0x1F, 0x24, 0x2B, a)                     # тёмный, альфу сохранить
else:
    po[x,y] = (r, g, b, a)                              # оранжевый — как есть

Затем crop(alpha.getbbox()) и ресайз до ~900 px по ширине. Результат проверять на белом фоне (Image.alpha_composite с белым) — белых ореолов быть не должно, оранжевый градиент сохраняется.

Вставка колонтитулов (python-docx)

  • Логотип — в верхний колонтитул, а не в тело: sec.header, is_linked_to_previous = False, run.add_picture(path, width=Cm(3.6)). В теле при этом картинок оставаться не должно.
  • ЛОВУШКА: фиксированный таб-стоп. Том бывает форматом A3 landscape (page_width 42 см), поэтому таб на 17 см не работает — текст встаёт по центру. Стоп считать от фактической области: Emu(sec.page_width - sec.left_margin - sec.right_margin). Проверять по PDF не по блокам, а по спанам (get_text("dict") → lines[].spans[]), блоки дают всю ширину и создают ложное впечатление смещения.
  • paragraph_format.tab_stops.clear_all() перед добавлением своего стопа — в шаблоне.
  • Разделительная линия — w:pBdr (bottom у хедера, top у футера), цветом E06000.
  • Ширины колонок таблицы тоже зависят от формата: для A3 брать ~9,5 / 10 / 11,5 / 11,5 см.
  • Проверка результата — рендер в PDF через Word COM (doc.SaveAs(path, FileFormat=17)) и просмотр страниц; полезно проверить и первую, и последнюю страницу.

Проверка после сборки

Пройтись по всем строкам и собрать множество колонок, где есть красные run'ы:

red_cols = set()
for ci, cell in enumerate(row.cells):
    for para in cell.paragraphs:
        for r in para.runs:
            if r.font.color and r.font.color.rgb and str(r.font.color.rgb) == "C00000" and r.text.strip():
                red_cols.add(ci)

Ожидание: в старых строках красные — колонки 2 и/или 3; в новых — 0, 2, 3. Если в старой строке нет ни одного красного — там просто нет расхождений («—»).