Marc 'BlackJack' Rintsch hat geschrieben:
Kleines Python-Programm:
Seeeeehr schön! Vielen Dank! 😀 Das gilt natürlich auch für user unknown , aber ein Python-Skript ist mir im Augenblick lieber als Java.
Marc 'BlackJack' Rintsch hat geschrieben:
Könnte man natürlich etwas intelligenter gestalten ─ so wird für jedes Zeichen eine ANSI-Escapesequenz erzeugt. Das ist ja nur wirklich nötig wenn sich die Werte ändern.
Erledigt.
Marc 'BlackJack' Rintsch hat geschrieben:
Und man könnte die Leerzeichen an den Zeilenenden entfernen, wenn die Hintergrundfarbe der des Terminals entspricht.
Hm, nein, das lieber nicht.
Marc 'BlackJack' Rintsch hat geschrieben:
Ausserdem müsste man mit dem höchstwertigen Bit noch etwas anstellen, sollte es gesetzt sein. Ich glaube das war für blinkenden Text!?
Das hängt wohl vom System ab. Eine exakte "Rückübersetzung" ist nicht möglich, da für die 3 ANSI-Attribute "fett", "blinken" und "unterstreichen" nur 2 Bits zur Verfügung stehen.
Bei mir gilt in der ttyX:
ANSI "fett" → helle Schrift (Bit "8" gesetzt)
ANSI "blinken" → heller Hintergrund (Bit "128" gesetzt)
ANSI "unterstrichen" → weißer Text + Fettschrift invertiert (Bits "1","2","4" gesetzt; Bit "8" invertiert)
Wie man sieht, lässt sich das ANSI-Attribut "unterstrichen" in meinem Fall nicht wiederherstellen. Aber das ist nicht weiter schlimm, da mich die Bildschirmausgabe und nicht die Eingangsparameter interessieren.
Also habe ich mir erlaubt, das Skript wie folgt anzupassen:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import struct
from itertools import imap, islice
#
# Mapping from VGA text attribute colors to ANSI colors.
#
VGA_TO_ANSI = (0, 4, 2, 6, 1, 5, 3, 7)
old_result = list()
def character2ansi_sequence((character, attribute)):
"""Converts the (character, attribute) tuple into a string with an
ANSI sequence for the `attribute` followed by the `character`.
`attribute` is a one byte string with a VGA text attribute.
"""
global old_result
result = list()
#
# Extract foreground and background color from attribute.
#
value = ord(attribute)
foreground = value & 7
background = (value >> 4) & 7
#
# reset bold text and emphasis
#
result.append(0)
#
# Check for the "bold" bit.
#
if value & 8:
result.append(1)
#
# Check for the "emphasize" bit.
#
if value & 128:
result.append(5) # might have to be set to 4, according to terminal
#
# Add the colors.
#
result.append(VGA_TO_ANSI[foreground] + 30)
result.append(VGA_TO_ANSI[background] + 40)
if old_result == result:
return character
else:
old_result = result
return '\033[%sm%s' % (';'.join(map(str, result)), character)
def iter_lines(fileobj):
"""Iterates over the lines of the screendump file.
Returns an iterator over a list of (character, attribute) tuples per
line of the screendump. Both elements of the tuples are one byte strings.
"""
line_length = struct.unpack('xB2x', fileobj.read(4))[0]
line_size = line_length * 2
for line in iter(lambda: fileobj.read(line_size), ''):
yield zip(islice(line, 0, None, 2), islice(line, 1, None, 2))
def main():
"""Test code."""
dump_file = open('test.dat', 'rb')
for line in iter_lines(dump_file):
print ''.join(imap(character2ansi_sequence, line))
dump_file.close()
if __name__ == '__main__':
main()
PS: gerade ist mir aufgefallen, dass bei VGA_TO_ANSI lediglich die Bits "1" und "4" vertauscht werden. Mit Bitoperationen lässt sich das nicht machen, oder?