Я хотел бы определить ширину табуляции, используемую в исходных файлах с отступом пробелами. Это несложно для файлов с особенно регулярным отступом, где начальные пробелы используются только для отступа, всегда кратного ширине табуляции, и с отступом, увеличивающимся на один уровень за раз. Но многие файлы будут иметь некоторые отклонения от такого обычного отступа, как правило, для некоторой формы вертикального выравнивания. Таким образом, я ищу хорошую эвристику, чтобы оценить, какая ширина табуляции использовалась, что допускает некоторую возможность нерегулярного отступа.
Мотивация для этого - написание расширения для редактора SubEthaEdit. SubEthaEdit, к сожалению, не делает ширину табуляции доступной для скриптов, поэтому я собираюсь угадать ее на основе текста.
Подходящая эвристика должна:
Некоторые упрощающие факторы:
Какой подход вы выберете, и в чем вы видите его преимущества и недостатки?
Если вы хотите предоставить рабочий код в своем ответе, лучшим подходом, вероятно, будет использование сценария оболочки, который читает исходный файл из stdin
и записывает ширину табуляции в stdout
. Псевдокод или четкое описание словами тоже подойдут.
Некоторые результаты
Чтобы проверить различные стратегии, мы можем применять разные стратегии к файлам в стандартных библиотеках для языковых дистрибутивов, поскольку они предположительно следуют стандартному отступу для языка. Я рассмотрю библиотеки Python 2.7 и Ruby 1.8 (системный фреймворк устанавливается в Mac OS X 10.7), для которых ожидаемая ширина вкладок составляет 4 и 2 соответственно. Исключаются те файлы, строки которых начинаются с символов табуляции или не имеют строк, начинающихся как минимум с двух пробелов.
Python:
Right None Wrong
Mode: 2523 1 102
First: 2169 1 456
No-long (12): 2529 9 88
No-long (8): 2535 16 75
LR (changes): 2509 1 116
LR (indent): 1533 1 1092
Doublecheck (10): 2480 15 130
Doublecheck (20): 2509 15 101
Ruby:
Right None Wrong
Mode: 594 29 51
First: 578 0 54
No-long (12): 595 29 50
No-long (8): 597 29 48
LR (changes): 585 0 47
LR (indent): 496 0 136
Doublecheck (10): 610 0 22
Doublecheck (20): 609 0 23
В этих таблицах "Right" следует рассматривать как определение стандартной ширины табуляции в языковом стандарте, "Wrong" как ненулевую ширину табуляции, не равную стандарту языка width, а «None» означает нулевую ширину табуляции или отсутствие ответа. «Режим» - это стратегия выбора наиболее часто встречающегося изменения отступа; «Первый» - это отступ первой строки с отступом; «No-long» - это стратегия FastAl по исключению строк с большим отступом и переходу в режим с числом, указывающим максимально допустимое изменение отступа; "LR" - это стратегия Patrick87, основанная на линейной регрессии,с вариантами, основанными на изменении отступа между строками и на абсолютном отступе строк; «Doublecheck» (не мог устоять перед каламбуром!) - это модификация Марком стратегии FastAl, ограничивающая возможную ширину табуляции и проверяющую, часто ли встречается половина модального значения, с двумя разными порогами для выбора меньшей ширины.