117 lines
4.9 KiB
Python
Executable file
117 lines
4.9 KiB
Python
Executable file
#!/usr/bin/env python
|
||
|
||
import re
|
||
import subprocess
|
||
import sys
|
||
|
||
|
||
def get_clipboard_text() -> str:
|
||
"""Читает грязный текст напрямую из буфера обмена ОС через xclip."""
|
||
try:
|
||
process = subprocess.Popen(
|
||
["xclip", "-selection", "clipboard", "-o"],
|
||
stdout=subprocess.PIPE,
|
||
stderr=subprocess.PIPE,
|
||
)
|
||
stdout, _ = process.communicate()
|
||
return stdout.decode("utf-8", errors="ignore")
|
||
except FileNotFoundError:
|
||
print(
|
||
"\n[КРИТИЧЕСКАЯ ОШИБКА] Утилита 'xclip' не найдена в системе!"
|
||
)
|
||
sys.exit(1)
|
||
|
||
|
||
def clean_wolfram_text_to_row(wolfram_text: str) -> str:
|
||
"""Находит все строки таблицы без привязки к переносам строк и собирает значения Y."""
|
||
y_values = []
|
||
|
||
# Регулярное выражение находит структуры вида {"X", Y_блок} сквозь любые переносы строк (\n)
|
||
# Оно сопоставляет начало строки таблицы `{"X"` и забирает весь блок до закрывающей скобки перед запятой или концом списка
|
||
pattern = r'\{"(\d+)"\s*,\s*(.*?)\}(?:,|\s*\n*\s*\})'
|
||
matches = re.findall(pattern, wolfram_text, re.DOTALL)
|
||
|
||
for x_val, y_block in matches:
|
||
# Вытаскиваем все элементы в кавычках внутри блока Y (это решает проблему RowBox)
|
||
quoted_elements = re.findall(r'"([^"]+)"', y_block)
|
||
|
||
if quoted_elements:
|
||
# Склеиваем все части (например, ['-', '2.7105...'])
|
||
y_val = "".join(quoted_elements)
|
||
else:
|
||
# Если кавычек внутри блока нет (чистое число без RowBox и маркеров точности)
|
||
y_val = y_block.strip()
|
||
|
||
# Очищаем маркеры Wolfram
|
||
y_val = y_val.replace("`", "")
|
||
y_val = y_val.replace("*^-", "e-").replace("*^", "e")
|
||
|
||
# Проверяем на экстремально маленькие числа (машинный ноль)
|
||
try:
|
||
num_check = float(y_val)
|
||
if abs(num_check) < 1e-10:
|
||
y_val = "0"
|
||
except ValueError:
|
||
pass
|
||
|
||
y_values.append(y_val)
|
||
|
||
# Объединяем через табуляцию для вставки одной строкой в Google Sheets
|
||
return "\t".join(y_values)
|
||
|
||
|
||
def copy_to_clipboard(text: str):
|
||
"""Помещает очищенный текст обратно в буфер обмена через xclip."""
|
||
process = subprocess.Popen(
|
||
["xclip", "-selection", "clipboard"],
|
||
stdin=subprocess.PIPE,
|
||
close_fds=True,
|
||
)
|
||
process.communicate(input=text.encode("utf-8"))
|
||
|
||
|
||
def main():
|
||
print("=" * 60)
|
||
print(" ИСПРАВЛЕННЫЙ СКРИПТ (ПАРСИНГ ПЕРЕНОСОВ СТРОК И ROWBOX)")
|
||
print("=" * 60)
|
||
print("Инструкция:")
|
||
print("1. Выделите таблицу в Wolfram Mathematica и нажмите Ctrl+C.")
|
||
print("2. Переключитесь сюда и просто нажмите ENTER.")
|
||
print("3. Скрипт сам заберет данные, очистит их и обновит буфер.")
|
||
print("4. Откройте Google Sheets и нажмите Ctrl+V.\n")
|
||
print("Для выхода из скрипта нажмите Ctrl+C.\n")
|
||
|
||
while True:
|
||
try:
|
||
input("Нажмите [ENTER] для обработки буфера обмена...")
|
||
|
||
raw_input = get_clipboard_text()
|
||
|
||
if not raw_input.strip():
|
||
print("[ОШИБКА] Буфер обмена пуст!\n")
|
||
continue
|
||
|
||
cleaned_result = clean_wolfram_text_to_row(raw_input)
|
||
|
||
if cleaned_result:
|
||
copy_to_clipboard(cleaned_result)
|
||
print(
|
||
"[УСПЕХ] Буфер обмена обновлен! Все элементы на месте."
|
||
)
|
||
print("Превью строки для Google Sheets (первые 4 элемента):")
|
||
# Показываем первые 4 элемента для наглядности зануления
|
||
preview_parts = cleaned_result.split("\t")[:4]
|
||
print(" | ".join(preview_parts) + " ...\n")
|
||
else:
|
||
print(
|
||
"[ОШИБКА] В буфере обмена нет таблицы Wolfram. Попробуйте скопировать заново.\n"
|
||
)
|
||
|
||
except KeyboardInterrupt:
|
||
print("\n\nСкрипт успешно остановлен. До свидания!")
|
||
sys.exit(0)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|
||
|