def run(infile, outfile, options):
def main(args): def _get_str(chars):
def _get_word(word):
def _make_tap_block(data, header=False):
def _get_header(title, length, start=None, line=None):
def _get_basic_loader(title, clear, start, scr):
def _get_data_loader(title, org, length, start, stack, scr):
def run(ram, clear, org, start, stack, tapfile, scr):
def main(args): def _parse_font(snapshot, param_str):
def _parse_scr(snapshot, param_str):
def _parse_udg(snapshot, param_str):
def _parse_udgarray(snapshot, param_str):
def _int_pair(arg, sep, desc):
def _coords(arg):
def _dimensions(arg):
def _write_image(frame, img_file, animated):
def run(infile, outfile, options):
def main(args):
MACROS = {
    'FONT': _parse_font,
    'SCR': _parse_scr,
    'UDG': _parse_udg,
    'UDGARRAY': _parse_udgarray
} def clock(quiet, prefix, operation, *args, **kwargs):
def run(skoolfile, options, config):
def main(args): VALID_CTLS = DIRECTIVES + ' *'
class Instruction:
class BinWriter:
    def __init__(self, skool_address, address=None, operation=None, sub=False, keep=None, nowarn=None, data=None, marker=' '):
    def __str__(self):
    def __init__(self, skoolfile, asm_mode=0, fix_mode=0, start=-1, end=65537, data=False, verbose=False, warn=True):
    def _reset(self, data):
    def _parse_skool(self, skoolfile):
    def _parse_instruction(self, address, line, removed):
    def _add_instructions(self, address, skool_address, operations, original_op, removed):
    def _get_size(self, operation, address, marker, overwrite=False, removed=None, offset=0, sub=True, skool_address=None):
    def _parse_asm_directive(self, address, directive, removed):
    def _poke(self, instruction, data):
    def _warn(self, message, instruction):
    def _relocate(self):
    def write(self, binfile):
def run(skoolfile, binfile, options):
def main(args): def run(skoolfile, options):
def main(args): SEARCH_DIRS = (
    '',
    'resources',
    os.path.expanduser('~/.skoolkit'),
    os.path.join(PACKAGE_DIR, 'resources')
)
SEARCH_DIRS_MSG = """
skool2html.py searches the following directories for CSS files, JavaScript
files, font files, and files listed in the [Resources] section of the ref file:

""".lstrip()
def show_search_dirs():
def show_ref_file():
def show_ref_sections(prefix):
def notify(notice):
def clock(operation, prefix, *args, **kwargs):
def _get_search_dirs(extra_search_dirs, first_search_dir=None):
def find(fname, extra_search_dirs, first_search_dir=None):
def add_lines(ref_parser, config_specs, section=None):
def copy_resource(fname, root_dir, dest_dir):
def copy_resources(search_dir, extra_search_dirs, root_dir, fnames, dest_dir, themes=(), suffix=None, single_css=None):
def parse_ref_files(reffiles, ref_parser, fnames, search_dir=''):
def run(infiles, options, config):
def write_disassembly(html_writer, files, search_dir, extra_search_dirs, pages, css_themes, single_css):
def main(args): END = 65536
def run(snafile, options, config):
def main(args): def get_ctl_parser(ctls, infile, start, end, def_start, def_end):
def run(infile, options, config):
def main(args): class Registers:
    def get_lines(self):
    def _reg(self, sep, *registers):
    def _get_value(self, register):
def _analyse_z80(z80file):
def _get_block_id(data, index):
def _print_ramp(block, variables):
def _print_spcr(block, variables):
def _print_z80r(block, variables):
def _analyse_szx(szxfile):
def _print_ram_banks(sna):
def _analyse_sna(snafile):
def _get_address_ranges(specs, step=1):
def _call_graph(snapshot, ctlfiles, prefix, start, end, config):
def _find(snapshot, byte_seq, base_addr=16384):
def _find_tile(snapshot, coords):
def _find_text(snapshot, text):
def _peek(snapshot, specs, fmt):
def _word(snapshot, specs, fmt):
def run(infile, options, config):
def main(args):
BLOCK_ADDRESSES_48K = {
    4: '32768-49151 8000-BFFF',
    5: '49152-65535 C000-FFFF',
    8: '16384-32767 4000-7FFF'
}
BLOCK_ADDRESSES_128K = {
    5: '32768-49151 8000-BFFF',
    8: '16384-32767 4000-7FFF'
}
V2_MACHINES = {
    0: ('48K Spectrum', '16K Spectrum', True),
    1: ('48K Spectrum + IF1', '16K Spectrum + IF1', True),
    2: ('SamRam', 'SamRam', False),
    3: ('128K Spectrum', 'Spectrum +2', False),
    4: ('128K Spectrum + IF1', 'Spectrum +2 + IF1', False)
}
V3_MACHINES = {
    0: ('48K Spectrum', '16K Spectrum', True),
    1: ('48K Spectrum + IF1', '16K Spectrum + IF1', True),
    2: ('SamRam', 'SamRam', False),
    3: ('48K Spectrum + MGT', '16K Spectrum + MGT', True),
    4: ('128K Spectrum', 'Spectrum +2', False),
    5: ('128K Spectrum + IF1', 'Spectrum +2 + IF1', False),
    6: ('128K Spectrum + MGT', 'Spectrum +2 + MGT', False),
}
MACHINES = {
    7: ('Spectrum +3', 'Spectrum +2A', False),
    8: ('Spectrum +3', 'Spectrum +2A', False),
    9: ('Pentagon (128K)', 'Pentagon (128K)', False),
    10: ('Scorpion (256K)', 'Scorpion (256K)', False),
    11: ('Didaktik+Kompakt', 'Didaktik+Kompakt', False),
    12: ('Spectrum +2', 'Spectrum +2', False),
    13: ('Spectrum +2A', 'Spectrum +2A', False),
    14: ('TC2048', 'TC2048', False),
    15: ('TC2068', 'TC2068', False),
    128: ('TS2068', 'TS2068', False),
}
SZX_MACHINES = {
    0: '16K ZX Spectrum',
    1: '48K ZX Spectrum',
    2: 'ZX Spectrum 128',
    3: 'ZX Spectrum +2',
    4: 'ZX Spectrum +2A/+2B',
    5: 'ZX Spectrum +3',
    6: 'ZX Spectrum +3e'
}
SZX_BLOCK_PRINTERS = {
    'RAMP': _print_ramp,
    'SPCR': _print_spcr,
    'Z80R': _print_z80r
} def _read_z80(z80file):
def _write_z80(header, snapshot, fname):
def run(infile, options, outfile):
def main(args): SYSVARS = (
    255, 0, 0, 0,         # 23552 - KSTATE0
    255, 0, 0, 0,         # 23556 - KSTATE4
    0,                    # 23560 - LAST-K
    35,                   # 23561 - REPDEL
    5,                    # 23562 - REPPER
    0, 0,                 # 23563 - DEFADD
    0,                    # 23565 - K-DATA
    0, 0,                 # 23566 - TVDATA
    1, 0,                 # 23568 - STRMS - stream 253 (keyboard)
    6, 0,                 # 23570 - STRMS - stream 254 (screen)
    11, 0,                # 23572 - STRMS - stream 255 (work space)
    1, 0,                 # 23574 - STRMS - stream 0 (keyboard)
    1, 0,                 # 23576 - STRMS - stream 1 (keyboard)
    6, 0,                 # 23578 - STRMS - stream 2 (screen)
    16, 0,                # 23580 - STRMS - stream 3 (printer)
    0, 0,                 # 23582 - STRMS - stream 4
    0, 0,                 # 23584 - STRMS - stream 5
    0, 0,                 # 23586 - STRMS - stream 6
    0, 0,                 # 23588 - STRMS - stream 7
    0, 0,                 # 23590 - STRMS - stream 8
    0, 0,                 # 23592 - STRMS - stream 9
    0, 0,                 # 23594 - STRMS - stream 10
    0, 0,                 # 23596 - STRMS - stream 11
    0, 0,                 # 23598 - STRMS - stream 12
    0, 0,                 # 23600 - STRMS - stream 13
    0, 0,                 # 23602 - STRMS - stream 14
    0, 0,                 # 23604 - STRMS - stream 15
    0, 60,                # 23606 - CHARS
    64,                   # 23608 - RASP
    0,                    # 23609 - PIP
    0,                    # 23610 - ERR-NR
    0,                    # 23611 - FLAGS
    33,                   # 23612 - TV-FLAG
    84, 255,              # 23613 - ERR-SP
    0, 0,                 # 23615 - LIST-SP
    0,                    # 23617 - MODE
    0, 0,                 # 23618 - NEWPPC
    0,                    # 23620 - NSPPC
    0, 0,                 # 23621 - PPC
    0,                    # 23623 - SUBPPC
    56,                   # 23624 - BORDCR
    0, 0,                 # 23625 - E-PPC
    203, 92,              # 23627 - VARS
    0, 0,                 # 23629 - DEST
    182, 92,              # 23631 - CHANS
    182, 92,              # 23633 - CURCHL
    203, 92,              # 23635 - PROG
    0, 0,                 # 23637 - NXTLIN
    202, 92,              # 23639 - DATADD
    204, 92,              # 23641 - E-LINE
    0, 0,                 # 23643 - K-CUR
    0, 0,                 # 23645 - CH-ADD
    0, 0,                 # 23647 - X-PTR
    206, 92,              # 23649 - WORKSP
    206, 92,              # 23651 - STKBOT
    206, 92,              # 23653 - STKEND
    0,                    # 23655 - BREG
    0, 0,                 # 23656 - MEM
    16,                   # 23658 - FLAGS2
    2,                    # 23659 - DF-SZ
    0, 0,                 # 23660 - S-TOP
    0, 0,                 # 23662 - OLDPPC
    0,                    # 23664 - OSPCC
    0,                    # 23665 - FLAGX
    0, 0,                 # 23666 - STRLEN
    0, 0,                 # 23668 - T-ADDR
    0, 0,                 # 23670 - SEED
    0, 0, 0,              # 23672 - FRAMES
    88, 255,              # 23675 - UDG
    0, 0,                 # 23677 - COORDS
    33,                   # 23679 - P-POSN
    0, 91,                # 23680 - PR-CC
    5, 23,                # 23682 - ECHO-E
    0, 64,                # 23684 - DF-CC
    252, 80,              # 23686 - DF-CCL
    33, 24,               # 23688 - S-POSN
    5, 23,                # 23690 - SPOSN-L
    1,                    # 23692 - SCR-CT
    56,                   # 23693 - ATTR-P
    0,                    # 23694 - MASK-P
    56,                   # 23695 - ATTR-T
    0,                    # 23696 - MASK-T
    0,                    # 23697 - P-FLAG
    0, 0, 0, 0, 0,        # 23698 - mem-0
    0, 0, 0, 0, 0,        # 23703 - mem-1
    0, 0, 0, 0, 0,        # 23708 - mem-2
    0, 0, 0, 0, 0,        # 23713 - mem-3
    0, 0, 0, 0, 0,        # 23718 - mem-4
    0, 0, 0, 0, 0,        # 23723 - mem-5
    0, 0,                 # 23728 - NMIADD
    87, 255,              # 23730 - RAMTOP
    255, 255,             # 23732 - P-RAMT
    244, 9, 168, 16, 75,  # 23734 - CHINFO - keyboard
    244, 9, 196, 21, 83,  # 23739 - CHINFO - screen
    129, 15, 196, 21, 82, # 23744 - CHINFO - work space
    244, 9, 196, 21, 80,  # 23749 - CHINFO - printer
    128                   # 23754 - CHINFO - end marker
)
class SkoolKitArgumentParser(argparse.ArgumentParser):
class TapeError(Exception):
    def convert_arg_line_to_args(self, arg_line):
def _write_z80(ram, options, fname):
def _get_load_params(param_str):
def _load_block(snapshot, block, start, length=None, step=None, offset=None, inc=None, index=1):
def _call(snapshot, param_str):
def _load(snapshot, counters, blocks, param_str):
def _get_ram(blocks, options):
def _get_tzx_block(data, i):
def _get_tzx_blocks(data):
def _get_tap_blocks(tap):
def _get_tape_blocks(tape_type, tape):
def _get_tape(urlstring, user_agent, member=None):
def _print_ram_help():
def make_z80(url, options, z80):
def main(args): ARCHIVE_INFO = {
    0: "Full title",
    1: "Software house/publisher",
    2: "Author(s)",
    3: "Year of publication",
    4: "Language",
    5: "Game/utility type",
    6: "Price",
    7: "Protection scheme/loader",
    8: "Origin",
    255: "Comment(s)"
}
HARDWARE_TYPE = {
    0: ('Computer', {
        0x00: 'ZX Spectrum 16K',
        0x01: 'ZX Spectrum 48K Plus',
        0x02: 'ZX Spectrum 48K Issue 1',
        0x03: 'ZX Spectrum 128K + (Sinclair)',
        0x04: 'ZX Spectrum 128K +2 (grey case)',
        0x05: 'ZX Spectrum 128K +2A, +3',
        0x06: 'Timex Sinclair TC-2048',
        0x07: 'Timex Sinclair TS-2068',
        0x08: 'Pentagon 128',
        0x09: 'Sam Coupe',
        0x0A: 'Didaktik M',
        0x0B: 'Didaktik Gama',
        0x0C: 'ZX-80',
        0x0D: 'ZX-81',
        0x0E: 'ZX Spectrum 128K, Spanish version',
        0x0F: 'ZX Spectrum, Arabic version',
        0x10: 'Microdigital TK 90-X',
        0x11: 'Microdigital TK 95',
        0x12: 'Byte',
        0x13: 'Elwro 800-3',
        0x14: 'ZS Scorpion 256',
        0x15: 'Amstrad CPC 464',
        0x16: 'Amstrad CPC 664',
        0x17: 'Amstrad CPC 6128',
        0x18: 'Amstrad CPC 464+',
        0x19: 'Amstrad CPC 6128+',
        0x1A: 'Jupiter ACE',
        0x1B: 'Enterprise',
        0x1C: 'Commodore 64',
        0x1D: 'Commodore 128',
        0x1E: 'Inves Spectrum+',
        0x1F: 'Profi',
        0x20: 'GrandRomMax',
        0x21: 'Kay 1024',
        0x22: 'Ice Felix HC 91',
        0x23: 'Ice Felix HC 2000',
        0x24: 'Amaterske RADIO Mistrum',
        0x25: 'Quorum 128',
        0x26: 'MicroART ATM',
        0x27: 'MicroART ATM Turbo 2',
        0x28: 'Chrome',
        0x29: 'ZX Badaloc',
        0x2A: 'TS-1500',
        0x2B: 'Lambda',
        0x2C: 'TK-65',
        0x2D: 'ZX-97'
    }),
    1: ('External storage', {
        0x00: 'ZX Microdrive',
        0x01: 'Opus Discovery',
        0x02: 'MGT Disciple',
        0x03: 'MGT Plus-D',
        0x04: 'Rotronics Wafadrive',
        0x05: 'TR-DOS (BetaDisk)',
        0x06: 'Byte Drive',
        0x07: 'Watsford',
        0x08: 'FIZ',
        0x09: 'Radofin',
        0x0A: 'Didaktik disk drives',
        0x0B: 'BS-DOS (MB-02)',
        0x0C: 'ZX Spectrum +3 disk drive',
        0x0D: 'JLO (Oliger) disk interface',
        0x0E: 'Timex FDD3000',
        0x0F: 'Zebra disk drive',
        0x10: 'Ramex Millenia',
        0x11: 'Larken',
        0x12: 'Kempston disk interface',
        0x13: 'Sandy',
        0x14: 'ZX Spectrum +3e hard disk',
        0x15: 'ZXATASP',
        0x16: 'DivIDE',
        0x17: 'ZXCF'
    }),
    2: ('ROM/RAM add-on', {
        0x00: 'Sam Ram',
        0x01: 'Multiface ONE',
        0x02: 'Multiface 128k',
        0x03: 'Multiface +3',
        0x04: 'MultiPrint',
        0x05: 'MB-02 ROM/RAM expansion',
        0x06: 'SoftROM',
        0x07: '1k',
        0x08: '16k',
        0x09: '48k',
        0x0A: 'Memory in 8-16k used'
    }),
    3: ('Sound device', {
        0x00: 'Classic AY hardware (compatible with 128k ZXs)',
        0x01: 'Fuller Box AY sound hardware',
        0x02: 'Currah microSpeech',
        0x03: 'SpecDrum',
        0x04: 'AY ACB stereo (A+C=left, B+C=right); Melodik',
        0x05: 'AY ABC stereo (A+B=left, B+C=right)',
        0x06: 'RAM Music Machine',
        0x07: 'Covox',
        0x08: 'General Sound',
        0x09: 'Intec Electronics Digital Interface B8001',
        0x0A: 'Zon-X AY',
        0x0B: 'QuickSilva AY',
        0x0C: 'Jupiter ACE'
    }),
    4: ('Joystick', {
        0x00: 'Kempston',
        0x01: 'Cursor, Protek, AGF',
        0x02: 'Sinclair 2 Left (12345)',
        0x03: 'Sinclair 1 Right (67890)',
        0x04: 'Fuller'
    }),
    5: ('Mouse', {
        0x00: 'AMX mouse',
        0x01: 'Kempston mouse'
    }),
    6: ('Other controller', {
        0x00: 'Trickstick',
        0x01: 'ZX Light Gun',
        0x02: 'Zebra Graphics Tablet',
        0x03: 'Defender Light Gun'
    }),
    7: ('Serial port', {
        0x00: 'ZX Interface 1',
        0x01: 'ZX Spectrum 128k'
    }),
    8: ('Parallel port', {
        0x00: 'Kempston S',
        0x01: 'Kempston E',
        0x02: 'ZX Spectrum +3',
        0x03: 'Tasman',
        0x04: "DK'Tronics",
        0x05: 'Hilderbay',
        0x06: 'INES Printerface',
        0x07: 'ZX LPrint Interface 3',
        0x08: 'MultiPrint',
        0x09: 'Opus Discovery',
        0x0A: 'Standard 8255 chip with ports 31,63,95',
    }),
    9: ('Printer', {
        0x00: 'ZX Printer, Alphacom 32 & compatibles',
        0x01: 'Generic printer',
        0x02: 'EPSON compatible'
    }),
    10: ('Modem', {
        0x00: 'Prism VTX 5000',
        0x01: 'T/S 2050 or Westridge 2050'
    }),
    11: ('Digitizer', {
        0x00: 'RD Digital Tracer',
        0x01: "DK'Tronics Light Pen",
        0x02: 'British MicroGraph Pad',
        0x03: 'Romantic Robot Videoface'
    }),
    12: ('Network adapter', {
        0x00: 'ZX Interface 1'
    }),
    13: ('Keypad', {
        0x00: 'Keypad for ZX Spectrum 128k'
    }),
    14: ('AD/DA converter', {
        0x00: 'Harley Systems ADC 8.2',
        0x01: 'Blackboard Electronics'
    }),
    15: ('EPROM programmer', {
        0x00: 'Orme Electronics'
    }),
    16: ('Graphics', {
        0x00: 'WRX Hi-Res',
        0x01: 'G007',
        0x02: 'Memotech',
        0x03: 'Lambda Colour'
    })
}
HARDWARE_INFO = {
    0: {
        0: 'Runs on this machine, but may not use its special features',
        1: 'Uses special features of this machine',
        2: 'Runs on this machine, but does not use its special features',
        3: 'Does not run on this machine'
    },
    1: {
        0: 'Runs with this hardware, but may not use it',
        1: 'Uses this hardware',
        2: 'Runs but does not use this hardware',
        3: 'Does not run with this hardware'
    }
}
CHARS = {9: '\t', 13: '\n'}
def _bytes_to_str(data):
def _hex_dump(data, as_lines=True, row_size=16):
def _get_str(data, dump=False):
def _format_text(prefix, data, start, length, dump=False):
def _get_block_info(data, i, block_num):
def _print_info(text):
def _print_block(index, data, show_data, info=(), block_id=None, header=None):
def _list_basic(cur_block_num, data, block_num, address):
def _get_basic_block(spec):
def _analyse_tzx(tzx, basic_block, options):
def _analyse_tap(tap, basic_block, show_data):
def main(args):
import sys
import os
import glob
import tempfile
import zlib
from importlib import invalidate_caches
from io import BytesIO, StringIO
from os.path import abspath, dirname
from shutil import rmtree
from textwrap import dedent
from unittest import TestCase
from skoolkit import (bin2sna, bin2tap, sna2img, skool2asm, skool2bin,
                      skool2ctl, skool2html, sna2ctl, sna2skool, snapinfo,
                      snapmod, tap2sna, tapinfo)
            banks = {5: ram[:16384]}
            if (version == 2 and machine_id < 2) or (version == 3 and machine_id in (0, 1, 3)):
                # 16K/48K
                model = 0 if modify else 1
                banks[1] = ram[16384:32768]
                banks[2] = ram[32768:49152]
            else:
                # 128K
                model = 2
                banks[2] = ram[16384:32768]
                banks[out_7ffd & 7] = ram[32768:49152]
                banks.update(pages)
                for bank in set(range(8)) - set(banks.keys()):
                    banks[bank] = [0] * 16384
            z80 = header[:]
            for bank in sorted(banks):
                z80 += self._get_z80_ram_block(banks[bank], compress, bank + 3)
        return model, self.write_bin_file(z80, suffix='.z80')

    def write_z80_file(self, header, ram, version=3, compress=False, machine_id=0, pages={}):
        return self.write_z80(ram, version, compress, machine_id, pages=pages, header=header)[1]

    def _get_szx_header(self, machine_id=1, ch7ffd=0, specregs=True, border=0):
        header = [90, 88, 83, 84] # ZXST
        header.extend((1, 4)) # Version 1.4
        header.append(machine_id) # 0=16K, 1=48K, 2+=128K
        header.append(0) # Flags
        if specregs:
            header.extend((83, 80, 67, 82)) # SPCR
            header.extend((8, 0, 0, 0)) # Size
            header.append(border) # BORDER
            header.append(ch7ffd) # Last OUT to port $7FFD
            header.extend((0, 0, 0, 0, 0, 0))
        return header

    def _get_zxstz80regs(self, registers):
        z80r = [90, 56, 48, 82] # Z80R
        z80r.extend((37, 0, 0, 0)) # Size
        z80r.extend(registers)
        return z80r

    def _get_zxstrampage(self, page, compress, data):
        if compress:
            ram = zlib.compress(bytearray(data), 9)
        else:
            ram = data
        ramp = [82, 65, 77, 80] # RAMP
        size = len(ram) + 3
        ramp.extend((size % 256, size // 256, 0, 0))
        ramp.extend((1 if compress else 0, 0))
        ramp.append(page)
        ramp.extend(ram)
        return ramp

    def write_szx(self, exp_ram, compress=True, machine_id=1, ch7ffd=0, pages={}, registers=None, border=0):
        szx = self._get_szx_header(machine_id, ch7ffd, border=border)
        if registers:
            szx.extend(self._get_zxstz80regs(registers))
        rampages = {5: self._get_zxstrampage(5, compress, exp_ram[:16384])}
        if machine_id >= 1:
            # 48K and 128K
            rampages[2] = self._get_zxstrampage(2, compress, exp_ram[16384:32768])
            if machine_id == 1:
                # 48K
                rampages[0] = self._get_zxstrampage(0, compress, exp_ram[32768:])
            else:
                # 128K
                rampages[ch7ffd & 7] = self._get_zxstrampage(ch7ffd & 7, compress, exp_ram[32768:])
                for bank, data in pages.items():
                    rampages[bank] = self._get_zxstrampage(bank, compress, data)
                for bank in set(range(8)) - set(rampages):
                    rampages[bank] = self._get_zxstrampage(bank, compress, [0] * 16384)
        for bank in sorted(rampages):
            szx.extend(rampages[bank])
        return self.write_bin_file(szx, suffix='.szx')

    def _run_skoolkit_command(self, cmd, args, catch_exit):
        self.clear_streams()
        if catch_exit is None:
            cmd(args.split())
        else:
            with self.assertRaises(SystemExit) as cm:
                cmd(args.split())
            self.assertEqual(cm.exception.args[0], catch_exit)
        return self.out.getvalue(), self.err.getvalue()

    def run_bin2sna(self, args='', catch_exit=None):
        return self._run_skoolkit_command(bin2sna.main, args, catch_exit)

    def run_bin2tap(self, args='', catch_exit=None):
        return self._run_skoolkit_command(bin2tap.main, args, catch_exit)

    def run_sna2img(self, args='', catch_exit=None):
        return self._run_skoolkit_command(sna2img.main, args, catch_exit)

    def run_skool2asm(self, args='', catch_exit=None):
        return self._run_skoolkit_command(skool2asm.main, args, catch_exit)

    def run_skool2bin(self, args='', catch_exit=None):
        return self._run_skoolkit_command(skool2bin.main, args, catch_exit)

    def run_skool2ctl(self, args='', catch_exit=None):
        return self._run_skoolkit_command(skool2ctl.main, args, catch_exit)

    def run_skool2html(self, args='', catch_exit=None):
        return self._run_skoolkit_command(skool2html.main, args, catch_exit)

    def run_sna2ctl(self, args='', catch_exit=None):
        return self._run_skoolkit_command(sna2ctl.main, args, catch_exit)

    def run_sna2skool(self, args='', catch_exit=None):
        return self._run_skoolkit_command(sna2skool.main, args, catch_exit)

    def run_snapinfo(self, args='', catch_exit=None):
        return self._run_skoolkit_command(snapinfo.main, args, catch_exit)

    def run_snapmod(self, args='', catch_exit=None):
        return self._run_skoolkit_command(snapmod.main, args, catch_exit)

    def run_tap2sna(self, args='', catch_exit=None):

        return self._run_skoolkit_command(tap2sna.main, args, catch_exit)