import fitz, re, json from pathlib import Path doc = fitz.open('/home/alexives/Desktop/newsources/Kuper_Dzh_Entsiklopedia_simvolov.pdf') figs = [] for pno in range(6, len(doc)-1): blocks = doc[pno].get_text('blocks') for b in blocks: t = b[4].strip() m = re.search(r'Рис\.\s*(\d+)[\.:]?\s*(.*?)(?=\n\n|\Z)', t, re.DOTALL) if m: num = int(m.group(1)) cap = re.sub(r'\s+', ' ', m.group(2)).strip() figs.append((num, pno+1, cap)) seen = {} for num, pno, cap in figs: if num not in seen or len(cap) > len(seen[num][1]): seen[num] = (pno, cap) print(f"Total unique figures in Cooper: {len(seen)}") # Precise manual/rule-based target mapping for every Cooper figure mapping = { 1: ['агнец', 'агнец божий'], 2: ['инь-ян'], 3: ['алтарь'], 4: ['ангел', 'ангелы'], 5: ['маат', 'жертвоприношение'], 6: ['архангел', 'гавриил'], 7: ['бабочка'], 8: ['барабан', 'шаман'], 9: ['ад', 'бес'], 10: ['пеликан'], 11: ['буйвол', 'лао-цзы'], 12: ['апис', 'бык'], 13: ['ваза', 'надгробие'], 14: ['весло', 'весла'], 16: ['дионис', 'виноград', 'лоза'], 17: ['ундина', 'вода'], 18: ['вол'], 19: ['волны', 'спираль'], 20: ['ворон', 'ложка'], 21: ['орел', 'полумесяц'], 22: ['вяз'], 23: ['геральдика', 'лев'], 24: ['гиацинт'], 25: ['голова', 'череп'], 26: ['голубь'], 27: ['горгона', 'медуза'], 28: ['гриф'], 29: ['гроб'], 30: ['гусь'], 31: ['дверь', 'врата'], 32: ['дева', 'богоматерь'], 34: ['дельфин'], 35: ['мировое дерево', 'древо жизни', 'иггдрасиль'], 36: ['диск', 'солнце'], 37: ['дракон'], 38: ['дуб'], 39: ['дуга', 'радуга'], 40: ['единорог'], 41: ['еж'], 42: ['жаба'], 43: ['жемчуг'], 44: ['женщина'], 45: ['журавль'], 46: ['заяц'], 47: ['звезда', 'пентаграмма'], 48: ['зверь'], 49: ['зеркало'], 50: ['зигзаг', 'молния'], 51: ['змея', 'уроборос'], 52: ['зодиак'], 53: ['лев', 'зодиак'], 54: ['дева', 'зодиак'], 55: ['весы', 'зодиак'], 56: ['скорпион', 'зодиак'], 57: ['стрелец', 'зодиак'], 58: ['золотое руно', 'дракон'], 59: ['ибис', 'перо', 'маат'], 60: ['игла'], 61: ['ирис'], 62: ['кадуцей', 'гермес'], 63: ['кабан', 'вепрь'], 64: ['жезл гермеса', 'кадуцей'], 65: ['камень'], 66: ['карлик'], 67: ['квадрат'], 68: ['кедр'], 69: ['ключ', 'ангел'], 70: ['христос', 'пантократор'], 71: ['козел'], 72: ['колесо'], 73: ['колокол'], 74: ['колонна'], 75: ['кольцо'], 76: ['копье'], 77: ['корабль', 'ладья'], 78: ['корона'], 79: ['корова'], 80: ['коса'], 81: ['кот', 'кошка'], 82: ['краб'], 83: ['крест'], 84: ['крокодил'], 85: ['круг'], 86: ['крылья'], 87: ['кувшин'], 88: ['кукушка'], 89: ['лабиринт'], 90: ['лавр'], 91: ['ладья'], 92: ['лампа', 'светильник'], 93: ['ласточка'], 94: ['лебедь'], 95: ['лев'], 96: ['леопард'], 97: ['лестница'], 98: ['лилия'], 99: ['лира'], 100: ['лиса'], 101: ['лист'], 102: ['лодка'], 103: ['лопата'], 104: ['лотос'], 105: ['луг'], 106: ['луна'], 107: ['лук'], 108: ['луч'], 109: ['лягушка'], 110: ['магнолия'], 111: ['мак'], 112: ['мандорла'], 113: ['маска'], 114: ['медведь'], 115: ['медовуха'], 116: ['меч'], 117: ['мировое древо', 'иггдрасиль'], 118: ['молния'], 119: ['молот'], 120: ['море'], 121: ['мост'], 122: ['муравей'], 123: ['муха'], 124: ['мышь'], 125: ['нарцисс'], 126: ['нить'], 127: ['нож'], 128: ['носорог'], 129: ['обезьяна'], 130: ['облако'], 131: ['огонь'], 132: ['олень'], 133: ['олива'], 134: ['омела'], 135: ['орел'], 136: ['осел'], 137: ['осьминог'], 138: ['павлин'], 139: ['пальма'], 140: ['паук'], 141: ['петух'], 142: ['раковина', 'афродита'], 143: ['раковина', 'змея'], 144: ['река', 'рай'], 146: ['роза', 'крест', 'розенкрейцеры'], 148: ['рука'], 149: ['рыба', 'крест'], 150: ['сатир'], 151: ['свастика'], 152: ['свастика', 'будда'], 153: ['свет', 'будда'], 154: ['менора'], 155: ['свинья'], 156: ['свиток'], 157: ['черепаха'], 158: ['сердце'], 159: ['сердце'], 160: ['сикамора', 'древо жизни'], 162: ['синагога'], 163: ['слон'], 164: ['анубис', 'собака'], 165: ['солнце', 'храм'], 167: ['солнце'], 168: ['сосна', 'шишка'], 169: ['спираль', 'свастика'], 170: ['спираль', 'свастика'], 171: ['вечный жид'], 172: ['танец', 'дервиш'], 173: ['таро', 'маг', 'шут'], 174: ['тирс', 'менада'], 175: ['топор', 'лабрис'], 176: ['трезубец', 'вишну'], 177: ['трикветра'], 178: ['тыква', 'ваза'], 179: ['узел'], 180: ['урна'], 181: ['уроборос'], 183: ['феникс'], 184: ['кришна', 'вишну'], 185: ['мандала', 'храм'], 186: ['белый цвет', 'белый'], 187: ['черное и белое', 'анафема'], 188: ['багуа', 'триграммы'], 189: ['роза', 'розенкрейцеры'], 190: ['чакры'], 191: ['череп'], 192: ['ноль', 'круг'], 193: ['два', 'солнце', 'луна'], 194: ['тримурти', 'брахма', 'шива', 'вишну', 'троица'], 196: ['микрокосм', 'человек'], 197: ['семь', 'планеты'], 198: ['девять', 'мандала'], 199: ['шар', 'зевс'], 200: ['шлем', 'афина'], 202: ['четыре', 'элементы', 'христос'], 203: ['юрта'], 204: ['язык', 'медуза'], 205: ['птах'], 206: ['ячмень', 'осирис'], 207: ['ihs', 'монограмма христа'] } with open('/tmp/cooper_fig_mapping.json', 'w', encoding='utf-8') as f: json.dump({str(k): {'page': seen[k][0], 'caption': seen[k][1], 'targets': mapping.get(k, [])} for k in seen}, f, ensure_ascii=False, indent=2) print("Saved /tmp/cooper_fig_mapping.json successfully!")