34.1 Представления текста

Буферы и строки Emacs поддерживают большой набор символов из многих различных алфавитов, что позволяет пользователям вводить и отображать текст на практически любом известном письменном языке.

Для поддержки этого множества символов и алфавитов Emacs тесно следует Стандарту Unicode. Стандарт Unicode присваивает уникальный номер, называемый кодопоинтом, каждому символу. Диапазон кодопоинтов, определенный Unicode, или пространство кодов Unicode, составляет 0..#x10FFFF (в шестнадцатеричной записи), включая. Emacs расширяет этот диапазон кодопоинтами в диапазоне #x110000..#x3FFFFF, которые он использует для представления символов, не унифицированных с Unicode, и сырых 8-битных байтов, которые не могут быть интерпретированы как символы. Таким образом, кодопоинт символа в Emacs — это 22-битное целое число.

Чтобы экономить память, Emacs не хранит фиксированные 22-битные числа, являющиеся кодопоинтами текстовых символов в буферах и строках. Вместо этого Emacs использует внутреннее представление символов переменной длины, которое хранит каждый символ как последовательность от 1 до 5 8-битных байтов, в зависимости от величины его кодопоинта25. Например, любой символ ASCII занимает только 1 байт, символ Latin-1 занимает 2 байта и т. д. Мы называем это представление текста многобайтовым.

Вне Emacs символы могут представляться множеством различных кодировок, таких как ISO-8859-1, GB-2312, Big-5 и т. д. Emacs преобразует между этими внешними кодировками и своим внутренним представлением, в зависимости от необходимости, когда считывает текст в буфер или строку, или когда записывает текст в файл на диске или передает его какому-либо другому процессу.

Иногда Emacs должен хранить и манипулировать закодированным текстом или бинарными нетекстовыми данными в своих буферах или строках. Например, когда Emacs посещает файл, он сначала считывает текст файла дословно в буфер, а затем преобразует его во внутреннее представление. До преобразования буфер содержит закодированный текст.

Закодированный текст не является по сути текстом, насколько это касается Emacs, а скорее последовательностью сырых 8-битных байтов. Мы называем буферы и строки, содержащие закодированный текст, однобайтовыми буферами и строками, потому что Emacs рассматривает их как последовательность отдельных байтов. Обычно Emacs отображает однобайтовые буферы и строки в виде восьмеричных кодов, таких как \237. Мы рекомендуем никогда не использовать однобайтовые буферы и строки, кроме как для манипулирования закодированным текстом или бинарными нетекстовыми данными.

В буфере локальное значение переменной enable-multibyte-characters указывает используемое представление. Представление для строки определяется и записывается в строке при ее создании.

Переменная: enable-multibyte-characters

Эта переменная указывает текстовое представление текущего буфера. Если она не равна nil, буфер содержит многобайтовый текст; в противном случае он содержит однобайтовый закодированный текст или бинарные нетекстовые данные.

Вы не можете установить эту переменную напрямую; вместо этого используйте функцию set-buffer-multibyte для изменения представления буфера.

Функция: position-bytes position

Позиции буфера измеряются в единицах символов. Эта функция возвращает байтовую позицию, соответствующую позиции буфера position в текущем буфере. Это 1 в начале буфера, и счет идет в байтах. Если position выходит за пределы диапазона, возвращается значение nil.

Функция: byte-to-position byte-position

Возвращает позицию буфера в единицах символов, соответствующую заданной byte-position в текущем буфере. Если byte-position выходит за пределы диапазона, возвращается значение nil. В многобайтовом буфере произвольное значение byte-position может не находиться на границе символа, а находиться внутри многобайтовой последовательности, представляющей один символ; в этом случае эта функция возвращает позицию буфера символа, многобайтовая последовательность которого включает byte-position. Другими словами, значение не меняется для всех байтовых позиций, принадлежащих одному и тому же символу.

Следующие две функции полезны, когда программа Lisp должна сопоставить позиции буфера с смещениями байтов в файле, открытом буфером.

Функция: bufferpos-to-filepos position &optional quality coding-system

Эта функция похожа на position-bytes, но вместо байтовой позиции в текущем буфере она возвращает смещение от начала файла текущего буфера до байта, соответствующего заданной позиции символа position в буфере. Преобразование требует знания того, как текст закодирован в файле буфера; для этого аргумент coding-system и предназначен, по умолчанию используется значение buffer-file-coding-system. Необязательный аргумент quality указывает, насколько точным должно быть результат; он должен быть одним из следующих:

exact

Результат должен быть точным. Функция может потребовать кодирования и декодирования большой части буфера, что является ресурсоемким и может быть медленным.

approximate

Значение может быть приближением. Функция может избежать дорогостоящей обработки и вернуть неточный результат.

nil

Если точный результат требует дорогостоящей обработки, функция вернет nil, а не приближение. Это значение по умолчанию, если аргумент опущен.

Функция: filepos-to-bufferpos byte &optional quality coding-system

Эта функция возвращает позицию буфера, соответствующую файловой позиции, указанной byte, нулевым смещением байтов от начала файла. Функция выполняет преобразование в обратном порядке по отношению к тому, что делает bufferpos-to-filepos. Необязательные аргументы quality и coding-system имеют то же значение и смысл, что и для bufferpos-to-filepos.

Функция: multibyte-string-p string

Возвращает t, если string является многобайтовой строкой, иначе nil. Эта функция также возвращает nil, если string является каким-либо объектом, отличным от строки.

Функция: string-bytes string

Эта функция возвращает количество байтов в string. Если string является многобайтовой строкой, это может быть больше, чем (length string).

Функция: unibyte-string &rest bytes

Эта функция конкатенирует все свои аргументы bytes и делает результат однобайтовой строкой.


Примечания

(25)

Это внутреннее представление основано на одной из кодировок, определенных Стандартом Unicode, называемой UTF-8, для представления любого кодопоинта Unicode, но Emacs расширяет UTF-8 для представления дополнительных кодопоинтов, которые он использует для сырых 8-битных байтов и символов, не унифицированных с Unicode.