mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-03 09:49:19 +02:00
intro ePub auto generation
This commit is contained in:
parent
3d5ab599f4
commit
7fa54dfd9b
20 changed files with 196 additions and 47 deletions
|
@ -1,16 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink"><description><title-info><author><last-name>FBReader</last-name></author> <book-title>О программе FBReader</book-title> <lang>ru</lang></title-info></description>
|
|
||||||
<body>
|
|
||||||
<title><p>О программе FBReader &FBReaderVersion;</p></title>
|
|
||||||
<p>Эта программа предназначена для чтения электронных книг в форматах ePub и fb2. Если у вас уже есть подходящие книги, положите их на карту памяти в каталог Books. После этого вы найдете свои книги в <a l:href="fbreader-action:library">библиотеке</a>. В FBReader встроена <a l:href="fbreader-action:networkLibrary">сетевaя библиотека</a>, из которой можно бесплатно скачивать и покупать книги.</p>
|
|
||||||
<p>Для перелистывания страницы коснитесь правой части экрана (или левой, если хотите вернуться на предыдущую страницу). Другие варианты перелистывания – провести по экрану пальцем справа налево, или воспользоваться кнопками регулировки громкости.</p>
|
|
||||||
<p>Вы можете настроить FBReader, чтобы читать так, как удобно именно вам. Цвета, шрифты, каталоги, способы листания, и многое другое можно поменять в <a l:href="fbreader-action:preferences">диалоге настроек</a>.</p>
|
|
||||||
<p>Обычно управление программой происходит с помощью меню. Если на вашем устройстве нет кнопки Menu, просто нажмите на экран в середине его нижней части.</p>
|
|
||||||
<p>Приятного чтения!</p>
|
|
||||||
<empty-line/>
|
|
||||||
<subtitle><p>Ссылки</p></subtitle>
|
|
||||||
<p>Узнать подробнее о программе FBReader, скачать версии для разных устройств и исходные тексты можно на <a l:href="http://www.fbreader.org/FBReaderJ">нашем сайте</a>.</p>
|
|
||||||
<p>Сообщения о вышедших версиях и другие новости публикуются в <a l:href="http://twitter.com/fbreader_ru">twitter'е</a>.</p>
|
|
||||||
<p>Если вы хотите связаться с авторами, <a l:href="mailto:contact@fbreader.org">напишите</a> нам электронное письмо.</p>
|
|
||||||
</body>
|
|
||||||
</FictionBook>
|
|
Binary file not shown.
11
build.xml
11
build.xml
|
@ -55,7 +55,15 @@
|
||||||
<echo message="DONE (Checking if native libraries are up-to-date)"/>
|
<echo message="DONE (Checking if native libraries are up-to-date)"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="-pre-build" depends="init, native">
|
<target name="genhelp">
|
||||||
|
<exec executable="./help/generate.py">
|
||||||
|
<arg value="help/proto"/>
|
||||||
|
<arg value="help/html"/>
|
||||||
|
<arg value="assets/data/intro"/>
|
||||||
|
</exec>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="-pre-build" depends="init, native, genhelp">
|
||||||
</target>
|
</target>
|
||||||
<!--
|
<!--
|
||||||
<target name="-pre-compile">
|
<target name="-pre-compile">
|
||||||
|
@ -69,6 +77,7 @@
|
||||||
<delete dir="gen" />
|
<delete dir="gen" />
|
||||||
<delete dir="bin" />
|
<delete dir="bin" />
|
||||||
<delete dir="out" />
|
<delete dir="out" />
|
||||||
|
<delete dir="assets/data/intro" />
|
||||||
<echo message="DONE (Deleting temporary files)" />
|
<echo message="DONE (Deleting temporary files)" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
|
63
help/generate.py
Executable file
63
help/generate.py
Executable file
|
@ -0,0 +1,63 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import os, re, shutil, sys, time, zipfile
|
||||||
|
|
||||||
|
def collect_languages(proto_dir):
|
||||||
|
return [os.path.splitext(name)[0] for name in os.listdir(proto_dir) if name.endswith('.html')]
|
||||||
|
|
||||||
|
def find_title(path):
|
||||||
|
pattern = re.compile(r'<h2>(.*)<\/h2>')
|
||||||
|
with open(path, 'r') as stream:
|
||||||
|
for line in stream:
|
||||||
|
match = pattern.match(line)
|
||||||
|
if match:
|
||||||
|
return match.group(1)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def string_from_template(template_path, data):
|
||||||
|
result = ''
|
||||||
|
pattern = re.compile(r'(.*)\$([^$]*)\$(.*\n)')
|
||||||
|
with open(template_path, 'r') as istream:
|
||||||
|
for line in istream:
|
||||||
|
match = pattern.match(line)
|
||||||
|
if match:
|
||||||
|
result += match.group(1) + data[match.group(2)] + match.group(3)
|
||||||
|
else:
|
||||||
|
result += line
|
||||||
|
return result
|
||||||
|
|
||||||
|
def generate_epub(proto_dir, html_dir, epub, lang):
|
||||||
|
html_file = os.path.join(html_dir, lang + '.html')
|
||||||
|
title = find_title(html_file)
|
||||||
|
if not title:
|
||||||
|
raise Exception('Title not found in %s' % htmlfile)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'TITLE': title,
|
||||||
|
'LANG': lang,
|
||||||
|
'ID': 'fbreader:intro:%s:%d' % (lang, time.time())
|
||||||
|
}
|
||||||
|
|
||||||
|
with zipfile.ZipFile(epub, 'w', zipfile.ZIP_DEFLATED) as zip_file:
|
||||||
|
zip_file.writestr('mimetype', 'application/epub+zip', zipfile.ZIP_STORED)
|
||||||
|
zip_file.write(os.path.join(proto_dir, 'container.xml'), arcname='META-INF/container.xml')
|
||||||
|
zip_file.write(os.path.join(proto_dir, 'style.css'), arcname='style.css')
|
||||||
|
zip_file.writestr('main.html', string_from_template(html_file, data))
|
||||||
|
zip_file.writestr('content.opf', string_from_template(os.path.join(proto_dir, 'content.opf'), data))
|
||||||
|
zip_file.write(os.path.join(proto_dir, 'fbreader.png'), arcname='fbreader.png')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
if len(sys.argv) != 4:
|
||||||
|
exit('Usage: %s <proto_dir> <html_dir> <output_dir>' % sys.argv[0])
|
||||||
|
|
||||||
|
proto_dir = sys.argv[1]
|
||||||
|
html_dir = sys.argv[2]
|
||||||
|
output_dir = sys.argv[3]
|
||||||
|
|
||||||
|
os.mkdirs(output_dir)
|
||||||
|
for lang in collect_languages(html_dir):
|
||||||
|
epub = os.path.join(output_dir, 'intro_' + lang + '.epub')
|
||||||
|
if os.path.exists(epub):
|
||||||
|
os.remove(epub)
|
||||||
|
print 'Generating intro for language %s...' % lang
|
||||||
|
generate_epub(proto_dir, html_dir, epub, lang)
|
32
help/html/ru.html
Normal file
32
help/html/ru.html
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<html xmlns:fbreader='http://data.fbreader.org/xhtml-extension/'>
|
||||||
|
<head>
|
||||||
|
<link type='text/css' rel='stylesheet' href='style.css'/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>FBReader: краткое руководство</h2>
|
||||||
|
<h3>Оглавление</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href='#introduction'>Что такое FBReader</a></li>
|
||||||
|
<li><a href='#first'>Популярные книги</a></li>
|
||||||
|
<li><a href='#network'>Где взять ещё книг</a></li>
|
||||||
|
<li><a href='#sync'>Как копировать книги с компьютера</a></li>
|
||||||
|
<li><a href='#more'>И это всё?</a></li>
|
||||||
|
<li><a href='#help'>У меня проблема, кто мне поможет?</a></li>
|
||||||
|
</ul>
|
||||||
|
<h3 id='introduction'>Что такое FBReader</h3>
|
||||||
|
<p>FBReader – свободная программа для чтения электронных книг. Если у вас есть книги в виде файлов <code>ePub</code>, <code>fb2</code>, <code>mobi</code> или во многих других форматах, вы можете скопировать их на это устройство, открыть в FBReader, и читать прямо здесь. «Не совсем текстовые» форматы книг, <code>PDF</code> и <code>DjVu</code>, FBReader тоже понимает. Но чтобы программа не слишком разрасталась, мы вынесли их поддержку в отдельные плагины <a href='https://play.google.com/store/apps/details?id=org.geometerplus.fbreader.plugin.pdf'>для PDF</a> и <a href='https://play.google.com/store/apps/details?id=org.geometerplus.fbreader.plugin.djvu'>для DjVu</a>.</p>
|
||||||
|
<h3 id='first'>Популярные книги</h3>
|
||||||
|
<p>Хотите начать читать прямо сейчас? Мы предлагаем на выбор несколько книг, может быть, одна из них вас заинтересует? Нажмите на обложку, книга скачается из сети и сразу же откроется в FBReader. Чтобы вернуться потом к этому тексту, выберите в меню пункт «Стартовый экран».</p>
|
||||||
|
<p class='opds'><fbreader:opds size='5' src='https://books.fbreader.org/recommended/lang/$LANG$.xml'/></p>
|
||||||
|
<h3 id='network'>Где взять ещё книг</h3>
|
||||||
|
<p>В FBReader есть раздел <a href='fbreader-action:networkLibrary'>«Сетевая библиотека»</a>. В нескольких каталогах собраны книги на разных языках, некоторые можно полностью скачать бесплатно, в некоторых доступны только первые несколько глав, а продолжение можно купить за деньги. Если вы знаете адреса других каталогов, вы можете добавить их в свой список, и скачивать книги из них прямо в свой FBReader.</p>
|
||||||
|
<h3 id='sync'>Как копировать книги с компьютера</h3>
|
||||||
|
<p>У вас есть книги на компьютере, и вы хотите перенести их на это устройство? Или наоборот, книги, которые вы скачали на это устройство, хотите сохранить понадёжнее? Это можно сделать, не соединяя компьютер и телефон (планшет) между собой. В FBReader есть возможность синхронизации. <a href='fbreader-action:preferences#sync'>Включите её</a>, и все ваши книги автоматически попадут в облако (на ваш собственный Google Drive). С компьютера доступ к коллекции книг происходит через сайт <a href='https://books.fbreader.org/'>Книжной сети FBReader</a>.</p>
|
||||||
|
<p>Хотите читать одну и ту же книгу днём на телефоне, а вечером на планшете? И не искать место, где остановились? Синхронизация FBReader решит и эту проблему. Включите её на обоих устройствах, и вы никогда не потеряете место, на котором остановились.</p>
|
||||||
|
<h3 id='more'>И это всё?</h3>
|
||||||
|
<p>Разумеется, нет. В таком кратком тексте мы не рассказали про возможности настройки FBReader, про интеграцию с программой Calibre, про другие плагины, например, для автоматического чтения вслух. Новые возможности появляются регулярно, ведь обновления FBReader выходят не реже раза в месяц. Если вы хотите узнать больше – заходите <a href='http://ru.fbreader.org/'>на наш сайт</a>, или <a href='http://ru.fbreader.org/content/about-us#social'>ищите нас в социальных сетях</a>.</p>
|
||||||
|
<h3 id='help'>У меня проблема, кто мне поможет?</h3>
|
||||||
|
<p>Лучший способ – написать о проблеме в одной из социальных сетей. Ссылки вы найдёте выше, а в сетях много активных пользователей, которые увидят ваш вопрос. Мы тоже читаем сети, и регулярно в них отвечаем. Если вы уверены, что ваш вопрос обязательно задать напрямую разработчикам, <a href="mailto:contact@fbreader.org">напишите нам электронное письмо</a>.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
6
help/proto/container.xml
Normal file
6
help/proto/container.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
|
||||||
|
<rootfiles>
|
||||||
|
<rootfile full-path="content.opf" media-type="application/oebps-package+xml"/>
|
||||||
|
</rootfiles>
|
||||||
|
</container>
|
18
help/proto/content.opf
Normal file
18
help/proto/content.opf
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<package xmlns='http://www.idpf.org/2007/opf' unique-identifier='dcidid' version='2.0'>
|
||||||
|
<metadata xmlns:dc='http://purl.org/dc/elements/1.1/'>
|
||||||
|
<dc:title>$TITLE$</dc:title>
|
||||||
|
<dc:language>$LANG$</dc:language>
|
||||||
|
<dc:identifier>$ID$</dc:identifier>
|
||||||
|
<dc:creator>FBReader</dc:creator>
|
||||||
|
<meta content='cover_image' name='cover'/>
|
||||||
|
</metadata>
|
||||||
|
<manifest>
|
||||||
|
<item id='stylesheet' href='styles.css' media-type='text/css'/>
|
||||||
|
<item id='main' href='main.html' media-type='application/xhtml+xml'/>
|
||||||
|
<item href='fbreader.png' id='cover_image' media-type='image/png'/>
|
||||||
|
</manifest>
|
||||||
|
<spine toc='ncx'>
|
||||||
|
<itemref idref='main'/>
|
||||||
|
</spine>
|
||||||
|
</package>
|
BIN
help/proto/fbreader.png
Normal file
BIN
help/proto/fbreader.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
2
help/proto/style.css
Normal file
2
help/proto/style.css
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
p { margin: 10px 0 0 0; }
|
||||||
|
p.opds { text-align: center; text-indent: 0; }
|
|
@ -247,7 +247,7 @@ void BookReader::addVideoEntry(const ZLVideoEntry &entry) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BookReader::addFBReaderSpecialEntry(const std::string &action, const std::string &data) {
|
void BookReader::addFBReaderSpecialEntry(const std::string &action, const std::map<std::string,std::string> &data) {
|
||||||
if (myCurrentTextModel != 0) {
|
if (myCurrentTextModel != 0) {
|
||||||
myCurrentTextModel->addFBReaderSpecialEntry(action, data);
|
myCurrentTextModel->addFBReaderSpecialEntry(action, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <map>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -73,7 +74,7 @@ public:
|
||||||
void addImage(const std::string &id, shared_ptr<const ZLImage> image);
|
void addImage(const std::string &id, shared_ptr<const ZLImage> image);
|
||||||
|
|
||||||
void addVideoEntry(const ZLVideoEntry &entry);
|
void addVideoEntry(const ZLVideoEntry &entry);
|
||||||
void addFBReaderSpecialEntry(const std::string &action, const std::string &data);
|
void addFBReaderSpecialEntry(const std::string &action, const std::map<std::string,std::string> &data);
|
||||||
|
|
||||||
void beginContentsParagraph(int referenceNumber = -1);
|
void beginContentsParagraph(int referenceNumber = -1);
|
||||||
void endContentsParagraph();
|
void endContentsParagraph();
|
||||||
|
|
|
@ -543,10 +543,7 @@ void XHTMLTagPreAction::doAtEnd(XHTMLReader &reader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XHTMLTagOpdsAction::doAtStart(XHTMLReader &reader, const char **xmlattributes) {
|
void XHTMLTagOpdsAction::doAtStart(XHTMLReader &reader, const char **xmlattributes) {
|
||||||
const char *src = reader.attributeValue(xmlattributes, "src");
|
bookReader(reader).addFBReaderSpecialEntry("opds", reader.attributeMap(xmlattributes));
|
||||||
if (src != 0) {
|
|
||||||
bookReader(reader).addFBReaderSpecialEntry("opds", src);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XHTMLTagOpdsAction::doAtEnd(XHTMLReader &reader) {
|
void XHTMLTagOpdsAction::doAtEnd(XHTMLReader &reader) {
|
||||||
|
|
|
@ -168,6 +168,20 @@ const char *ZLXMLReader::attributeValue(const char **xmlattributes, const char *
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<std::string,std::string> ZLXMLReader::attributeMap(const char **xmlattributes) const {
|
||||||
|
std::map<std::string,std::string> map;
|
||||||
|
while (*xmlattributes != 0) {
|
||||||
|
std::string key = *xmlattributes;
|
||||||
|
++xmlattributes;
|
||||||
|
if (*xmlattributes == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
map[key] = *xmlattributes;
|
||||||
|
++xmlattributes;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
ZLXMLReader::NamePredicate::~NamePredicate() {
|
ZLXMLReader::NamePredicate::~NamePredicate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,7 @@ public:
|
||||||
|
|
||||||
const char *attributeValue(const char **xmlattributes, const char *name) const;
|
const char *attributeValue(const char **xmlattributes, const char *name) const;
|
||||||
const char *attributeValue(const char **xmlattributes, const NamePredicate &predicate) const;
|
const char *attributeValue(const char **xmlattributes, const NamePredicate &predicate) const;
|
||||||
|
std::map<std::string,std::string> attributeMap(const char **xmlattributes) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize(const char *encoding = 0);
|
void initialize(const char *encoding = 0);
|
||||||
|
|
|
@ -385,22 +385,32 @@ void ZLTextModel::addVideoEntry(const ZLVideoEntry &entry) {
|
||||||
++myParagraphLengths.back();
|
++myParagraphLengths.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZLTextModel::addFBReaderSpecialEntry(const std::string &action, const std::string &data) {
|
void ZLTextModel::addFBReaderSpecialEntry(const std::string &action, const std::map<std::string,std::string> &data) {
|
||||||
|
std::size_t fullLength = 2; // entry type + map size
|
||||||
|
fullLength += 2 + ZLUnicodeUtil::utf8Length(action) * 2; // action name
|
||||||
|
for (std::map<std::string,std::string>::const_iterator it = data.begin(); it != data.end(); ++it) {
|
||||||
|
fullLength += 2 + ZLUnicodeUtil::utf8Length(it->first) * 2; // data key
|
||||||
|
fullLength += 2 + ZLUnicodeUtil::utf8Length(it->second) * 2; // data value
|
||||||
|
}
|
||||||
|
|
||||||
|
myLastEntryStart = myAllocator->allocate(fullLength);
|
||||||
|
*myLastEntryStart = ZLTextParagraphEntry::FBREADER_SPECIAL;
|
||||||
|
*(myLastEntryStart + 1) = data.size();
|
||||||
|
|
||||||
|
char *p = myLastEntryStart + 2;
|
||||||
ZLUnicodeUtil::Ucs2String ucs2action;
|
ZLUnicodeUtil::Ucs2String ucs2action;
|
||||||
ZLUnicodeUtil::utf8ToUcs2(ucs2action, action);
|
ZLUnicodeUtil::utf8ToUcs2(ucs2action, action);
|
||||||
ZLUnicodeUtil::Ucs2String ucs2data;
|
|
||||||
ZLUnicodeUtil::utf8ToUcs2(ucs2data, data);
|
|
||||||
|
|
||||||
const std::size_t actionLength = ucs2action.size() * 2;
|
|
||||||
const std::size_t dataLength = ucs2data.size() * 2;
|
|
||||||
|
|
||||||
myLastEntryStart = myAllocator->allocate(6 + actionLength + dataLength);
|
|
||||||
*myLastEntryStart = ZLTextParagraphEntry::FBREADER_SPECIAL;
|
|
||||||
*(myLastEntryStart + 1) = 0;
|
|
||||||
|
|
||||||
char *p = myLastEntryStart + 2;
|
|
||||||
p = ZLCachedMemoryAllocator::writeString(p, ucs2action);
|
p = ZLCachedMemoryAllocator::writeString(p, ucs2action);
|
||||||
p = ZLCachedMemoryAllocator::writeString(p, ucs2data);
|
|
||||||
|
for (std::map<std::string,std::string>::const_iterator it = data.begin(); it != data.end(); ++it) {
|
||||||
|
ZLUnicodeUtil::Ucs2String key;
|
||||||
|
ZLUnicodeUtil::utf8ToUcs2(key, it->first);
|
||||||
|
p = ZLCachedMemoryAllocator::writeString(p, key);
|
||||||
|
ZLUnicodeUtil::Ucs2String value;
|
||||||
|
ZLUnicodeUtil::utf8ToUcs2(value, it->second);
|
||||||
|
p = ZLCachedMemoryAllocator::writeString(p, value);
|
||||||
|
}
|
||||||
|
|
||||||
myParagraphs.back()->addEntry(myLastEntryStart);
|
myParagraphs.back()->addEntry(myLastEntryStart);
|
||||||
++myParagraphLengths.back();
|
++myParagraphLengths.back();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,10 @@
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <ZLHyperlinkType.h>
|
#include <ZLHyperlinkType.h>
|
||||||
#include <ZLTextParagraph.h>
|
#include <ZLTextParagraph.h>
|
||||||
|
@ -77,7 +78,7 @@ public:
|
||||||
void addFixedHSpace(unsigned char length);
|
void addFixedHSpace(unsigned char length);
|
||||||
void addBidiReset();
|
void addBidiReset();
|
||||||
void addVideoEntry(const ZLVideoEntry &entry);
|
void addVideoEntry(const ZLVideoEntry &entry);
|
||||||
void addFBReaderSpecialEntry(const std::string &action, const std::string &data);
|
void addFBReaderSpecialEntry(const std::string &action, const std::map<std::string,std::string> &data);
|
||||||
|
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
|
|
|
@ -73,14 +73,14 @@ public abstract class BookUtil {
|
||||||
final Locale locale = Locale.getDefault();
|
final Locale locale = Locale.getDefault();
|
||||||
|
|
||||||
ZLResourceFile file = ZLResourceFile.createResourceFile(
|
ZLResourceFile file = ZLResourceFile.createResourceFile(
|
||||||
"data/help/fb-intro-" + locale.getLanguage() + ".epub"
|
"data/intro/intro-" + locale.getLanguage() + ".epub"
|
||||||
);
|
);
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = ZLResourceFile.createResourceFile(
|
file = ZLResourceFile.createResourceFile(
|
||||||
"data/help/fb-intro-ru.epub"
|
"data/intro/intro-ru.epub"
|
||||||
);
|
);
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
return file;
|
return file;
|
||||||
|
|
|
@ -19,11 +19,13 @@
|
||||||
|
|
||||||
package org.geometerplus.zlibrary.text.model;
|
package org.geometerplus.zlibrary.text.model;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class FBReaderSpecialEntry {
|
public class FBReaderSpecialEntry {
|
||||||
public final String Type;
|
public final String Type;
|
||||||
public final String Data;
|
public final Map<String,String> Data;
|
||||||
|
|
||||||
FBReaderSpecialEntry(String type, String data) {
|
FBReaderSpecialEntry(String type, Map<String,String> data) {
|
||||||
Type = type;
|
Type = type;
|
||||||
Data = data;
|
Data = data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,10 +277,18 @@ public class ZLTextPlainModel implements ZLTextModel, ZLTextStyleEntry.Feature {
|
||||||
final short kindLength = (short)data[dataOffset++];
|
final short kindLength = (short)data[dataOffset++];
|
||||||
final String kind = new String(data, dataOffset, kindLength);
|
final String kind = new String(data, dataOffset, kindLength);
|
||||||
dataOffset += kindLength;
|
dataOffset += kindLength;
|
||||||
final short paramLength = (short)data[dataOffset++];
|
|
||||||
final String param = new String(data, dataOffset, paramLength);
|
final Map<String,String> map = new HashMap<String,String>();
|
||||||
dataOffset += paramLength;
|
final short dataSize = (short)((first >> 8) & 0xFF);
|
||||||
myFBReaderSpecialEntry = new FBReaderSpecialEntry(kind, param);
|
for (short i = 0; i < dataSize; ++i) {
|
||||||
|
final short keyLength = (short)data[dataOffset++];
|
||||||
|
final String key = new String(data, dataOffset, keyLength);
|
||||||
|
dataOffset += keyLength;
|
||||||
|
final short valueLength = (short)data[dataOffset++];
|
||||||
|
map.put(key, new String(data, dataOffset, valueLength));
|
||||||
|
dataOffset += valueLength;
|
||||||
|
}
|
||||||
|
myFBReaderSpecialEntry = new FBReaderSpecialEntry(kind, map);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,7 @@ public final class ZLTextParagraphCursor {
|
||||||
{
|
{
|
||||||
final FBReaderSpecialEntry entry = it.getFBReaderSpecialEntry();
|
final FBReaderSpecialEntry entry = it.getFBReaderSpecialEntry();
|
||||||
if ("opds".equals(entry.Type)) {
|
if ("opds".equals(entry.Type)) {
|
||||||
|
System.err.println("OPDS DATA = " + entry.Data);
|
||||||
elements.add(new BookElement(null, null));
|
elements.add(new BookElement(null, null));
|
||||||
elements.add(new BookElement(null, null));
|
elements.add(new BookElement(null, null));
|
||||||
elements.add(new BookElement(null, null));
|
elements.add(new BookElement(null, null));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue