Я хотел бы определить ширину табуляции, используемую в исходных файлах с отступом пробелами. Это несложно для файлов с особенно регулярным отступом, где начальные пробелы используются только для отступа, всегда кратного ширине табуляции, и с отступом, увеличивающимся на один уровень за раз. Но многие файлы будут иметь некоторые отклонения от такого обычного отступа, как правило, для некоторой формы вертикального выравнивания. Таким образом, я ищу хорошую эвристику, чтобы оценить, какая ширина табуляции использовалась, что допускает некоторую возможность нерегулярного отступа.
Мотивация к этому - написание расширения для редактора SubEthaEdit. SubEthaEdit, к сожалению, не делает ширину табуляции доступной для сценариев, поэтому я собираюсь угадать ее на основе текста.
Подходящая эвристика должна:
- Достаточно хорошо для интерактивного использования. Я не думаю, что это будет проблемой, и при необходимости можно использовать только часть текста.
- Будьте независимы от языка.
- Верните самую длинную подходящую ширину табуляции. Например, любой файл с шириной табуляции, равной четырем пробелам, также может быть файлом с двумя пробелами табуляции, если каждый отступ фактически был вдвое больше уровней. Ясно, что четыре пробела были бы правильным выбором.
- Всегда делайте это правильно, если отступы абсолютно правильные.
Некоторые упрощающие факторы:
- Можно предположить, что по крайней мере одна строка имеет отступ.
- Предполагается, что ширина табуляции составляет не менее двух пробелов.
- Можно с уверенностью предположить, что отступ делается только с пробелами. Дело не в том, что я имею что-то против вкладок - наоборот, я сначала проверю, используются ли какие-либо вкладки для отступов, и обработаю их отдельно. Это действительно означает, что табуляции и пробелы, смешанные с отступами, могут не обрабатываться должным образом, но я не считаю это важным.
- Можно предположить, что нет строк, содержащих только пробелы.
- Не со всеми языками нужно обращаться правильно. Например, успех или неудача с такими языками, как lisp и go, будут совершенно неактуальными, поскольку они обычно не имеют отступа вручную.
- Совершенства не требуется. Мир не закончится, если несколько строк нужно будет время от времени корректировать вручную.
Какой подход вы бы выбрали, и в чем вы видите его преимущества и недостатки?
Если вы хотите указать рабочий код в своем ответе, лучшим подходом, вероятно, будет использование сценария оболочки, который считывает исходный файл из 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
Рубин:
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
В этих таблицах «Право» следует рассматривать как определение ширины табуляции по стандарту языка, «Неправильно» - как ненулевую ширину табуляции, не равную ширине стандартной табуляции, а «Нет» как нулевую ширину табуляции или ее отсутствие. отвечать. «Режим» - это стратегия выбора наиболее часто встречающегося изменения отступа; «Первый» - это отступ первой строки с отступом; «No-long» - это стратегия FastAl по исключению строк с большим отступом и переходу в режим с числом, указывающим максимально допустимое изменение отступа; «LR» - это стратегия Patrick87, основанная на линейной регрессии, с вариантами, основанными на изменении отступа между строками и на абсолютном отступе строк; «Doublecheck» (не мог устоять перед каламбуром!) - это модификация Марком стратегии FastAl, ограничивающая возможную ширину табуляции и проверяющую, часто ли встречается половина модального значения, с двумя разными порогами для выбора меньшей ширины.