Это сайт — моя персональная записная книжка. Интересна мне, по большей части, история, своя жизнь и немного программирование.

Стань стальной крысой!

Стань стальной крысой!

Решил показать жене игру-книгу «Стань стальной крысой». Но оказалось, что читать и переходить по ссылкам в таком варианте неудобно.

Сделал конвертор на «Пайтоне», преобразующий книгу с «Либрусека» в HTML (может так же использовать любое «зеркало», например копию на «Флибусте».). Получается гиперигра (работает только в современных браузерах), плюс я запрограммировал простенький ДОСП (см. книгу) на JavaScript.

# coding: utf-8
import re, urllib

n, articles, skip = 0, {}, True

content = urllib.urlopen('http://lib.rus.ec/b/115854/read')

for line in content.readlines():
    line = re.sub(u'<[^>]+>', '', line.decode('utf-8'))
    
    if line.find(u'Добро пожаловать!') != -1:
        skip = False
    elif line.find(u'Оглавление') != -1:
        break
    
    if skip: continue
    
    try:
        n = int(line)
    except ValueError:
        
        line = re.sub(r'\[\s*(\d+)\s*\]', r'[<a href="#a\1">\1</a>]', line)
        
        try:
            articles[n] += line
        except KeyError:
            articles[n] = line

articles[0] = re.sub(r'\[([^\]]+)\]', r'[<a href="#a30">\1</a>]', articles[0])

t = u"""
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8" />
<title>Стань стальной крысой</title>
<style type="text/css">
html {
    background: white;
}

body {
    background: #eee; color: black;
    font: 14px/1.4em Helvetica, 'Trebuchet MS', Arial, sans-serif;
    padding: 20px;
    margin: 100px;
}

header {
    font-size: 25px;
    margin: 0 0 20px;
    padding: 0 0 5px;
    border-bottom: 2px solid #ccc;
    color: #ccc;
}

article {
    display: none;
    white-space: pre-wrap;
}

article:last-of-type {
    display: block;
}

article:target ~ article:last-of-type {
    display: none;
}

article:target {
    display: block;
}

footer {
    margin-top: 10px;
    color: #ccc;
    text-align: right;
    font-size: x-small;
}

i {
    cursor: pointer;
    background: url('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAEBAQEBAQEBAQECAQECAgMCAgICAgQDAwIDBQQFBQUEB-
    QUFBggHBQYHBgUFBwkHBwgICQkJBQcKCgoICggJCQj/wgALCAAtACwBAREA/8QAGwAAAgMBAQEAAAAAAAAAAAAABgcEBQgCAwn/2gAIAQEAAAAB+zdD-
    Wxyy5FAAc4AtfBIfe0adbXjDJ+UuXGa9nRF1ti8ReInBsko//8QAHhAAAgMBAQADAQAAAAAAAAAABAUBAgMABhESExT/2gAIAQEAAQUC23rhXT9LxNx46Cv-
    ykUyhMdGn2s2IYV6qi9uJ0MBHqwNDJGIzLHpMQOyy23J5nWJFMr9aeTcUoBiw/lC1YyTAZND7mD5cbNddfEAVaLfTLZwpnlr8w0/DPW55FSxt22y1eMqA5340I-
    mWXp26ojyqc/wBNZSmXJBu//8QANRAAAgECAwQFCgcAAAAAAAAAAQIDAAQRITEFEhNBEBRRYaEiJDJSU3GBkbHhBkJDcsHC0f/aAAgBAQAGPwLFgWY5Ko1Y-
    1vXU5iX2cRw8dayt9/vbWsUZ4+4tvCsNJBqOiW7bPMpEOwff/KgjsVXiyEgyyejF8OdFrnat3PMeYmKD5LSx8TrGeAkbWo7tZmYqccCcjUNzFnG67wq0jGixL9K2-
    YqjzdZDLIfcMAPHw6Ix+YvRq4tZv0Z9we4qrf2q2jnUvcRebS9zrl4jA0E4W7HiDrnkcanS3Q70Z3W54HCg7XflgeguYrhKcF1Y9g5mr7ahUxxz3bsgPYFVfqpq/2r-
    aw8VpFTirjpun0vkT8qZYCt2VALKh8oD3ULYR8FPUAwxP81iIuqwevJ5K/eoPw/sKUvdSk9bm9ggOp9XuGpyq02bZpuW0KCNR0SX1lOdnXAXQDeTly5acjTWnX-
    7iXBeHiLhlGOWeHw8a6xcbae1XcCtw48ZGH7mJw05Cuq7Ot+ChO87E4tI3ax5no//8QAIxABAAEDBAICAwAAAAAAAAAAAREAITFBUWGBEHGRobHh8P/aAAgB-
    AQABPyEqxIGdgVfUsJ+Ru6gr73E/JlqZ5yH4hx1FNLcYbJueByIk0WF7E+qLSPukAzuOhxQ2XA7eIgpxNKh4mzFl5qU2VaGpHNMPBcE6UzklnNtQPJc6r2mfg/LyD0-
    H78Qb26cP5Kq0e745LoKYNx4vQZaYpG8I4IGJ9NXxDiMb26dNGYrOxr/B4cCmRDpTYK7Qdh4c0owRRcCOuIS+KSNRXOjKpqXev7Yaz9CWrIs9hBjaZWuCSLV6n-
    FkGfbmvunXUnUitIcWA4oVjEQY3zu1o9mPoOicwXIG9RPIIHstu274//2gAIAQEAAAAQ2dRilY//xAAhEAEBAAICAgMAAwAAAAAAAAABEQAhMUFRYRBxgZGhwf/-
    aAAgBAQABPxCWwNoyhKHSqoAKoFyNtZF/Ggp5TeHJYaOLr3/oYqGcsVdn0/b3llDWp5X2cUdi76XCLvgQuH7VnJHWMFrCpmiO1uCq5PGT7rUN6R+3ASpkpRBA-
    DZpsNi1wp72Lwl4AKM6c5+K8UCqnY0fY5YWk9kv6TGNaoB9kOE+G/lT8LF/k4NnJgUQ3s0thUGxBwMpLQDQaLlWnddQSJsOnKgTTCGICgXiXGrMihvNBj7PI4Kk-
    PKg1HoC/1zjTHn2P0ezQTkwAlegiHQE2iKtFDBaAq17SIHaW6x4rugOBoqKtKub+vSsjRplWzSnRjAnKRqMeUdR0AB+C0A61Tsq9riCIgEiJRMMifRjYvlnAnk5eelvIr-
    ZUqRz3rYO3LAmNdBkFRMXKK4ZalhVTlfj//Z');
    display: block;
    width: 44px; height: 45px;
    margin-top: 10px;
}

</style>
<script type="text/javascript">
function Coin(n) {
    location.hash = '#a' + n[Math.floor(Math.random() * n.length)];
}
</script>
</head>
<body>
<header>Стань стальной крысой. Гарри Гаррисон</header>
    
%(articles)s

<article id="a0">%(welcome)s</article>

<footer>Адаптировано Евгением Степанищевым. <a href="//bolknote.ru">bolknote.ru</a></footer>

</body>
</html>
"""

def dosp(v):
    v = v.strip()
    
    if re.search(u'ДОСП|(?i)случайных процессов', v, re.U):
        n = ','.join(re.findall(u'href="#a(\d+)"', v, re.U))
        
        return v + u'\n<i onclick="Coin([' + n + u'])" title="ДОСП"></i>'
    else:
        n = re.findall(u'\[[^]]+\]', v, re.U)
        
        return v + (u'\n\nИдём дальше? ' if len(n) == 1 else u'\n\nКуда дальше? ') + ', '.join(n) + '.'

welcome = articles[0]

articles = ''.join(
    '<article id="a' + unicode(k) + '">' + dosp(v) + '</article>'
        for k, v in articles.iteritems() if k
)

t = t.replace('-\n', '') % vars()
open('index.html', 'w').write(t.encode('utf-8'))

Конвертор создаёт на диске файл «index.html», который надо открыть браузером.

10 комментариев
Ruslan Petrenko (starcat13.livejournal.com) 2011

«Конвертор создаёт на диске файл „index.html“, который надо открыть браузером. $ Конвертор создаёт на диске файл „index.html“, который надо открыть браузером.» — а это опечатка или хитрый замысел?

Евгений Степанищев (bolknote.ru) 2011

Комментарий для starcat13.livejournal.com:

Спасибо! Это случайно вышло. Копипастил.

Ruslan Petrenko (starcat13.livejournal.com) 2011

спасибо за конвертер — ностальгия :)
хотя имхо цель автора была как раз увеличить время прохождения за счет постоянного перелистывания книги из одного конца в другой и поиска нужной части :)

Евгений Степанищев (bolknote.ru) 2011

Комментарий для starcat13.livejournal.com:

Я думаю, перелистывать нужно, чтобы вперёд нельзя было заглянуть :)

Евгений Степанищев (bolknote.ru) 2011

Комментарий для starcat13.livejournal.com:

Ну, в смысле, чтобы нельзя было узнать к чему приведёт выбор. И ещё создать какую-то иллюзию движения.

eyeless 2011

А можно куда-нибудь результат выложить?

spiridonov@gmail.com 2011

Да, примерно об этом мечталось, когда приходилось листать бумажную книгу в детстве :)

Лекс 2011

Комментарий для eyeless:

Во, но с баннером: http://rrat.chat.ru/

Лекс 2011

Комментарий для spiridonov@gmail.com:

А вот без баннера!!! http://steel-rrat.narod.ru/

Евгений Степанищев (bolknote.ru) 2011

Комментарий для Лекс:

Спасибо! Но, кажется, вы нарушаете авторские права. Я сомневаюсь, что эта книга в открытом доступе.