1"""fontTools.misc.textTools.py -- miscellaneous routines."""
2
3
4from __future__ import print_function, division, absolute_import
5from fontTools.misc.py23 import *
6import ast
7import string
8
9
10safeEval = ast.literal_eval
11
12def readHex(content):
13	"""Convert a list of hex strings to binary data."""
14	return deHexStr(strjoin(chunk for chunk in content if isinstance(chunk, basestring)))
15
16def deHexStr(hexdata):
17	"""Convert a hex string to binary data."""
18	hexdata = strjoin(hexdata.split())
19	if len(hexdata) % 2:
20		hexdata = hexdata + "0"
21	data = []
22	for i in range(0, len(hexdata), 2):
23		data.append(bytechr(int(hexdata[i:i+2], 16)))
24	return bytesjoin(data)
25
26
27def hexStr(data):
28	"""Convert binary data to a hex string."""
29	h = string.hexdigits
30	r = ''
31	for c in data:
32		i = byteord(c)
33		r = r + h[(i >> 4) & 0xF] + h[i & 0xF]
34	return r
35
36
37def num2binary(l, bits=32):
38	items = []
39	binary = ""
40	for i in range(bits):
41		if l & 0x1:
42			binary = "1" + binary
43		else:
44			binary = "0" + binary
45		l = l >> 1
46		if not ((i+1) % 8):
47			items.append(binary)
48			binary = ""
49	if binary:
50		items.append(binary)
51	items.reverse()
52	assert l in (0, -1), "number doesn't fit in number of bits"
53	return ' '.join(items)
54
55
56def binary2num(bin):
57	bin = strjoin(bin.split())
58	l = 0
59	for digit in bin:
60		l = l << 1
61		if digit != "0":
62			l = l | 0x1
63	return l
64
65
66def caselessSort(alist):
67	"""Return a sorted copy of a list. If there are only strings
68	in the list, it will not consider case.
69	"""
70
71	try:
72		return sorted(alist, key=lambda a: (a.lower(), a))
73	except TypeError:
74		return sorted(alist)
75
76