Author Topic: Epub book creation program  (Read 3591 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • Steve’s QB64 Archive Forum
Epub book creation program
« on: July 28, 2017, 11:59:48 am »
A demo of something a little different from most of the things other people like to post, this one is an illustration of using QB64 to create an EPUB-formatted ebook.

Code: QB64: [Select]
  1. DIM SHARED Id$ 'The unique identifier used for our book, to be created automagically.
  2.  
  3.  
  4. _TITLE "Epub Creation Demo"
  5. 'We'll need some content to use for our book.
  6. 'For this, we're going to store some information in a few diffent arrays.
  7. 'The first array will be for the Chapters (or Pages) for the book.
  8. 'the next array will be for the information in those chapters.
  9. 'I'm making these redimable at this point so that someone could alter them to suit their needs as required.
  10. REDIM SHARED Chapters(0) AS STRING
  11. REDIM SHARED Content(0) AS STRING
  12. 'Now, let's toss some actual information into these Chapters.
  13. REDIM Chapters(2) AS STRING 'a good number for a demo
  14. 'This information just names our chapters and helps set the order by which we'd go to them.
  15. Chapters(0) = "Title Page"
  16. Chapters(1) = "Chapter One"
  17. Chapters(2) = "Chapter Two"
  18.  
  19. 'And since we have a the chapters, let's toss something in them so they're not just blank...
  20. REDIM Content(2) AS STRING
  21. Content(0) = "Steve's Epub Demo Book!"
  22. Content(1) = "This is the Steve Demo for Epub creation!"
  23. Content(2) = "If you study it carefully, you'll see that it's not actually that hard to create or use EPUB files." + CHR$(13) + CHR$(10) + "This page is a quick demo of how we'd write more than a single line onto a page, and this is also quite a long line of text itself so that it will hopefully auto-wrap and auto-format itself to illustrate that we don't usually have to worry about such things manually -- that should be the job of our E-reader!"
  24.  
  25.  
  26. 'Some optional content we can toss into our book if we want.
  27. 'I'm going to include it here, but it can be stripped out if wanted.
  28. DIM SHARED Author$: Author$ = "Steve McNeill"
  29. DIM SHARED Language$: Language$ = "en"
  30. DIM SHARED Rights$: Rights$ = "Public Domain"
  31. DIM SHARED Publisher$: Publisher$ = "Nobody, Nowhere"
  32.  
  33.  
  34. 'So now we can actually make the book
  35.  
  36. MakeEpub "Steve Book" 'notice I didn't actually add the .epub extension here.  We just need the book title
  37.  
  38.  
  39.  
  40. SUB MakeEpub (book$)
  41. 'First we check to make the main folders for our book
  42. 'and the basic files which define our folder structure
  43. result = MakeFolders(book$)
  44. IF result = 0 THEN EXIT SUB
  45. 'then we have to create our  content file
  46. MakeContent book$
  47. MakeToC book$
  48. MakeXPGT book$
  49. MakeCSS book$
  50. MakeChapters book$
  51.  
  52.  
  53. SUB MakeChapters (book$)
  54. 'And here we write our actual content to our files.
  55. FOR i = 0 TO UBOUND(chapters)
  56.     OPEN book$ + "\OEBPS\Text\" + Chapters(i) + ".xhtml" FOR OUTPUT AS #1
  57.     PRINT #1, "<?xml version="; CHR$(34); "1.0"; CHR$(34); " encoding="; CHR$(34); "utf-8"; CHR$(34); "?>"
  58.     PRINT #1, "<!DOCTYPE html PUBLIC "; CHR$(34); "-//W3C//DTD XHTML 1.1//EN"; CHR$(34); ""
  59.     PRINT #1, "  "; CHR$(34); "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"; CHR$(34); ">"
  60.     PRINT #1, ""
  61.     PRINT #1, "<html xmlns="; CHR$(34); "http://www.w3.org/1999/xhtml"; CHR$(34); ">"
  62.     PRINT #1, "<head>"
  63.     PRINT #1, "  <title>Chapter 1</title>"
  64.     PRINT #1, "  <link rel="; CHR$(34); "stylesheet"; CHR$(34); " href="; CHR$(34); "../Styles/stylesheet.css"; CHR$(34); " type="; CHR$(34); "text/css"; CHR$(34); " />"
  65.     PRINT #1, "  <link rel="; CHR$(34); "stylesheet"; CHR$(34); " type="; CHR$(34); "application/vnd.adobe-page-template+xml"; CHR$(34); " href="; CHR$(34); "../Styles/page-template.xpgt"; CHR$(34); " />"
  66.     PRINT #1, "</head>"
  67.     PRINT #1, ""
  68.     PRINT #1, "<body>"
  69.     PRINT #1, ""
  70.     PRINT #1, "  <div>"
  71.     PRINT #1, "    <h3 id="; CHR$(34); "heading_id_2"; CHR$(34); ">"; Chapters(i); "</h3>"
  72.     PRINT #1, ""
  73.     PRINT #1, "    <p>"; Content(i); "</p>"
  74.     PRINT #1, "  </div>"
  75.     PRINT #1, "</body>"
  76.     PRINT #1, "</html>"
  77.     CLOSE #1
  78.  
  79.  
  80.  
  81. SUB MakeCSS (book$)
  82. 'Nothing more than a style sheet to format our pages and such.
  83. 'I'm just going to make this one about as simple as we can and center our stuff on the page.
  84. OPEN book$ + "\OEBPS\Styles\stylesheet.css" FOR OUTPUT AS #1
  85. PRINT #1, "/* Style Sheet */"
  86. PRINT #1, "/* This defines styles and classes used in the book */"
  87. PRINT #1, "body { margin-left: 5%; margin-right: 5%; margin-top: 5%; margin-bottom: 5%; text-align: justify; }"
  88. PRINT #1, "pre { font-size: x-small; }"
  89. PRINT #1, "h1 { text-align: center; }"
  90. PRINT #1, "h2 { text-align: center; }"
  91. PRINT #1, "h3 { text-align: center; }"
  92. PRINT #1, "h4 { text-align: center; }"
  93. PRINT #1, "h5 { text-align: center; }"
  94. PRINT #1, "h6 { text-align: center; }"
  95. PRINT #1, ".CI {"
  96. PRINT #1, "    text-align:center;"
  97. PRINT #1, "    margin-top:0px;"
  98. PRINT #1, "    margin-bottom:0px;"
  99. PRINT #1, "    padding:0px;"
  100. PRINT #1, "    }"
  101. PRINT #1, ".center   {text-align: center;}"
  102. PRINT #1, ".smcap    {font-variant: small-caps;}"
  103. PRINT #1, ".u        {text-decoration: underline;}"
  104. PRINT #1, ".bold     {font-weight: bold;}"
  105.  
  106. SUB MakeXPGT (book$)
  107. 'page-template.xpgt
  108. 'This file isn't part of the IDPF spec, but Adobe Digital Editions uses it for formatting
  109. 'and setting column settings and whatnot.
  110. 'You don't need this file at all, but your book will look nicer in Digital Editions if you include it.
  111. 'Other readers should just ignore it.
  112. OPEN book$ + "\OEBPS\Styles\page-template.xpgt" FOR OUTPUT AS #1
  113. PRINT #1, "<ade:template xmlns="; CHR$(34); "http://www.w3.org/1999/xhtml"; CHR$(34); " xmlns:ade="; CHR$(34); "http://ns.adobe.com/2006/ade"; CHR$(34); ""
  114. PRINT #1, "         xmlns:fo="; CHR$(34); "http://www.w3.org/1999/XSL/Format"; CHR$(34); ">"
  115. PRINT #1, ""
  116. PRINT #1, "  <fo:layout-master-set>"
  117. PRINT #1, "   <fo:simple-page-master master-name="; CHR$(34); "single_column"; CHR$(34); ">"
  118. PRINT #1, "        <fo:region-body margin-bottom="; CHR$(34); "3pt"; CHR$(34); " margin-top="; CHR$(34); "0.5em"; CHR$(34); " margin-left="; CHR$(34); "3pt"; CHR$(34); " margin-right="; CHR$(34); "3pt"; CHR$(34); "/>"
  119. PRINT #1, "    </fo:simple-page-master>"
  120. PRINT #1, ""
  121. PRINT #1, "    <fo:simple-page-master master-name="; CHR$(34); "single_column_head"; CHR$(34); ">"
  122. PRINT #1, "        <fo:region-before extent="; CHR$(34); "8.3em"; CHR$(34); "/>"
  123. PRINT #1, "        <fo:region-body margin-bottom="; CHR$(34); "3pt"; CHR$(34); " margin-top="; CHR$(34); "6em"; CHR$(34); " margin-left="; CHR$(34); "3pt"; CHR$(34); " margin-right="; CHR$(34); "3pt"; CHR$(34); "/>"
  124. PRINT #1, "    </fo:simple-page-master>"
  125. PRINT #1, ""
  126. PRINT #1, "    <fo:simple-page-master master-name="; CHR$(34); "two_column"; CHR$(34); " margin-bottom="; CHR$(34); "0.5em"; CHR$(34); " margin-top="; CHR$(34); "0.5em"; CHR$(34); " margin-left="; CHR$(34); "0.5em"; CHR$(34); " margin-right="; CHR$(34); "0.5em"; CHR$(34); ">"
  127. PRINT #1, "        <fo:region-body column-count="; CHR$(34); "2"; CHR$(34); " column-gap="; CHR$(34); "10pt"; CHR$(34); "/>"
  128. PRINT #1, "    </fo:simple-page-master>"
  129. PRINT #1, ""
  130. PRINT #1, "    <fo:simple-page-master master-name="; CHR$(34); "two_column_head"; CHR$(34); " margin-bottom="; CHR$(34); "0.5em"; CHR$(34); " margin-left="; CHR$(34); "0.5em"; CHR$(34); " margin-right="; CHR$(34); "0.5em"; CHR$(34); ">"
  131. PRINT #1, "        <fo:region-before extent="; CHR$(34); "8.3em"; CHR$(34); "/>"
  132. PRINT #1, "        <fo:region-body column-count="; CHR$(34); "2"; CHR$(34); " margin-top="; CHR$(34); "6em"; CHR$(34); " column-gap="; CHR$(34); "10pt"; CHR$(34); "/>"
  133. PRINT #1, "    </fo:simple-page-master>"
  134. PRINT #1, ""
  135. PRINT #1, "    <fo:simple-page-master master-name="; CHR$(34); "three_column"; CHR$(34); " margin-bottom="; CHR$(34); "0.5em"; CHR$(34); " margin-top="; CHR$(34); "0.5em"; CHR$(34); " margin-left="; CHR$(34); "0.5em"; CHR$(34); " margin-right="; CHR$(34); "0.5em"; CHR$(34); ">"
  136. PRINT #1, "        <fo:region-body column-count="; CHR$(34); "3"; CHR$(34); " column-gap="; CHR$(34); "10pt"; CHR$(34); "/>"
  137. PRINT #1, "    </fo:simple-page-master>"
  138. PRINT #1, ""
  139. PRINT #1, "    <fo:simple-page-master master-name="; CHR$(34); "three_column_head"; CHR$(34); " margin-bottom="; CHR$(34); "0.5em"; CHR$(34); " margin-top="; CHR$(34); "0.5em"; CHR$(34); " margin-left="; CHR$(34); "0.5em"; CHR$(34); " margin-right="; CHR$(34); "0.5em"; CHR$(34); ">"
  140. PRINT #1, "        <fo:region-before extent="; CHR$(34); "8.3em"; CHR$(34); "/>"
  141. PRINT #1, "        <fo:region-body column-count="; CHR$(34); "3"; CHR$(34); " margin-top="; CHR$(34); "6em"; CHR$(34); " column-gap="; CHR$(34); "10pt"; CHR$(34); "/>"
  142. PRINT #1, "    </fo:simple-page-master>"
  143. PRINT #1, ""
  144. PRINT #1, "    <fo:page-sequence-master>"
  145. PRINT #1, "        <fo:repeatable-page-master-alternatives>"
  146. PRINT #1, "            <fo:conditional-page-master-reference master-reference="; CHR$(34); "three_column_head"; CHR$(34); " page-position="; CHR$(34); "first"; CHR$(34); " ade:min-page-width="; CHR$(34); "80em"; CHR$(34); "/>"
  147. PRINT #1, "            <fo:conditional-page-master-reference master-reference="; CHR$(34); "three_column"; CHR$(34); " ade:min-page-width="; CHR$(34); "80em"; CHR$(34); "/>"
  148. PRINT #1, "            <fo:conditional-page-master-reference master-reference="; CHR$(34); "two_column_head"; CHR$(34); " page-position="; CHR$(34); "first"; CHR$(34); " ade:min-page-width="; CHR$(34); "50em"; CHR$(34); "/>"
  149. PRINT #1, "            <fo:conditional-page-master-reference master-reference="; CHR$(34); "two_column"; CHR$(34); " ade:min-page-width="; CHR$(34); "50em"; CHR$(34); "/>"
  150. PRINT #1, "            <fo:conditional-page-master-reference master-reference="; CHR$(34); "single_column_head"; CHR$(34); " page-position="; CHR$(34); "first"; CHR$(34); " />"
  151. PRINT #1, "            <fo:conditional-page-master-reference master-reference="; CHR$(34); "single_column"; CHR$(34); "/>"
  152. PRINT #1, "        </fo:repeatable-page-master-alternatives>"
  153. PRINT #1, "    </fo:page-sequence-master>"
  154. PRINT #1, ""
  155. PRINT #1, "  </fo:layout-master-set>"
  156. PRINT #1, ""
  157. PRINT #1, "  <ade:style>"
  158. PRINT #1, "    <ade:styling-rule selector="; CHR$(34); ".title_box"; CHR$(34); " display="; CHR$(34); "adobe-other-region"; CHR$(34); " adobe-region="; CHR$(34); "xsl-region-before"; CHR$(34); "/>"
  159. PRINT #1, "  </ade:style>"
  160. PRINT #1, ""
  161. PRINT #1, "</ade:template>"
  162.  
  163.  
  164.  
  165. SUB MakeToC (book$)
  166. 'this is the table of Contents for our book.
  167. 'Note that not all e-readers will use (or even look for) this file.
  168. 'For those that do, it makes us a nice little table of contents at the front of our book
  169. 'for ease of navigation and jumping to different chapters.
  170. OPEN book$ + "\OEBPS\toc.ncx" FOR OUTPUT AS #1
  171.  
  172. PRINT #1, "<?xml version="; CHR$(34); "1.0"; CHR$(34); " encoding="; CHR$(34); "UTF-8"; CHR$(34); "?>"
  173. PRINT #1, "<ncx xmlns="; CHR$(34); "http://www.daisy.org/z3986/2005/ncx/"; CHR$(34); " version="; CHR$(34); "2005-1"; CHR$(34); ">"
  174. PRINT #1, ""
  175. PRINT #1, "<head>"
  176. PRINT #1, "    <meta name="; CHR$(34); "dtb:uid"; CHR$(34); " content="; CHR$(34); Id$; CHR$(34); "/>"
  177. PRINT #1, "    <meta name="; CHR$(34); "dtb:depth"; CHR$(34); " content="; CHR$(34); LTRIM$(STR$(UBOUND(chapters) + 1)); CHR$(34); "/>"
  178. PRINT #1, "    <meta name="; CHR$(34); "dtb:totalPageCount"; CHR$(34); " content="; CHR$(34); "0"; CHR$(34); "/>"
  179. PRINT #1, "    <meta name="; CHR$(34); "dtb:maxPageNumber"; CHR$(34); " content="; CHR$(34); "0"; CHR$(34); "/>"
  180. PRINT #1, "</head>"
  181. PRINT #1, ""
  182. PRINT #1, "<docTitle>"
  183. PRINT #1, "    <text>"; book$; "</text>"
  184. PRINT #1, "</docTitle>"
  185. PRINT #1, ""
  186. PRINT #1, "<navMap>"
  187. FOR i = 0 TO UBOUND(chapters)
  188.     PRINT #1, "    <navPoint id="; CHR$(34); "navPoint-"; LTRIM$(STR$(i + 1)); CHR$(34); " playOrder="; CHR$(34); LTRIM$(STR$(i + 1)); CHR$(34); ">"
  189.     PRINT #1, "        <navLabel>"
  190.     PRINT #1, "            <text>"; Chapters(i); "</text>"
  191.     PRINT #1, "        </navLabel>"
  192.     PRINT #1, "        <content src="; CHR$(34); "Text/"; Chapters(i); ".xhtml"; CHR$(34); "/>"
  193.     PRINT #1, "    </navPoint>"
  194. PRINT #1, "</navMap>"
  195. PRINT #1, "</ncx>"
  196.  
  197.  
  198. SUB MakeContent (book$)
  199. 'This file gives a list of all files in the .epub container, defines the order of files,
  200. 'and stores meta data (author, genre, publisher, etc.) information.
  201. OPEN book$ + "\OEBPS\content.opf" FOR OUTPUT AS #1
  202. PRINT #1, "<?xml version="; CHR$(34); "1.0"; CHR$(34); " encoding="; CHR$(34); "UTF-8"; CHR$(34); "?>"
  203. PRINT #1, "<package xmlns="; CHR$(34); "http://www.idpf.org/2007/opf"; CHR$(34); " unique-identifier="; CHR$(34); "BookID"; CHR$(34); " version="; CHR$(34); "2.0"; CHR$(34); " >"
  204. PRINT #1, "    <metadata xmlns:dc="; CHR$(34); "http://purl.org/dc/elements/1.1/"; CHR$(34); " xmlns:opf="; CHR$(34); "http://www.idpf.org/2007/opf"; CHR$(34); ">"
  205. PRINT #1, "        <dc:title>"; book$; "</dc:title>"
  206. PRINT #1, "        <dc:language>"; Language$; "</dc:language>"
  207. 'PRINT #1, "        <dc:rights>"; Rights$; "</dc:rights>"
  208. 'PRINT #1, "        <dc:creator opf:role="; CHR$(34); "aut"; CHR$(34); ">"; Author$; "</dc:creator>"
  209. 'PRINT #1, "        <dc:publisher>"; Publisher$; "</dc:publisher>"
  210. 'Now for the next part here, each book needs to have an unique identifier.
  211. 'To keep this simple, I'm going to name these books after QB64 with a date and time included
  212. Id$ = "QB64Ebook" + DATE$ + LTRIM$(STR$(TIMER))
  213. PRINT #1, "        <dc:identifier id="; CHR$(34); "BookID"; CHR$(34); " opf:scheme="; CHR$(34); "UUID"; CHR$(34); ">"; Id$; "</dc:identifier>"
  214. PRINT #1, "    </metadata>"
  215.  
  216. 'Next comes the manifest. This is just a listing of the files in the .epub container, and their file type.
  217. 'Each item is also assigned an item ID that's used in the spine section of content.opf.
  218. 'This list does not have to be in any particular order.
  219. '(But you'll be happier if it is.)
  220. 'Also, see the section below on the NCX file for more information on the id attribute.
  221. PRINT #1, "    <manifest>"
  222. 'And now we identify the types of files which we're using in the book
  223. PRINT #1, "        <item id="; CHR$(34); "ncx"; CHR$(34); " href="; CHR$(34); "toc.ncx"; CHR$(34); " media-type="; CHR$(34); "application/x-dtbncx+xml"; CHR$(34); " />"
  224. PRINT #1, "        <item id="; CHR$(34); "style"; CHR$(34); " href="; CHR$(34); "Styles/stylesheet.css"; CHR$(34); " media-type="; CHR$(34); "text/css"; CHR$(34); " />"
  225. PRINT #1, "        <item id="; CHR$(34); "pagetemplate"; CHR$(34); " href="; CHR$(34); "Styles/page-template.xpgt"; CHR$(34); " media-type="; CHR$(34); "application/vnd.adobe-page-template+xml"; CHR$(34); " />"
  226. FOR i = 0 TO UBOUND(chapters)
  227.     PRINT #1, "        <item id="; CHR$(34); Chapters(i); CHR$(34); " href="; CHR$(34); "Text/"; Chapters(i); ".xhtml"; CHR$(34); " media-type="; CHR$(34); "application/xhtml+xml"; CHR$(34); " />"
  228. 'If we included any images (which should be PNG format and thus not easily exported in QB64-GL edition yet
  229. 'They would basically be included as the following format
  230. '        <item id="imgl" href="images/sample.png" media-type="image/png" />
  231. PRINT #1, "    </manifest>"
  232.  
  233. 'Since we've now identified the page types, let's tell whatever E-Reader we're using
  234. 'the proper order to read the pages/chapters in.
  235. 'The spine section lists the reading order of the contents.
  236. 'The spine doesn't have to list every file in the manifest, just the reading order.
  237. 'For example, if the manifest lists images, they do not have to be listed in the spine, and in fact, can't be.
  238. 'Only content (i.e. the XHTML files) can be listed here.
  239.  
  240.  
  241. PRINT #1, "    <spine toc="; CHR$(34); "ncx"; CHR$(34); ">"
  242. FOR i = 0 TO UBOUND(chapters)
  243.     PRINT #1, "        <itemref idref="; CHR$(34); Chapters(i); CHR$(34); " />"
  244. PRINT #1, "    </spine>"
  245. PRINT #1, "</package>"
  246. 'And at this point we should now have our table of contents and such written so we now know the proper order
  247. 'to read our book in.  ;)
  248.  
  249.  
  250. FUNCTION MakeFolders (mainfolder$)
  251. 'Returns a 0 if we fail, -1 if we succeed.
  252. 'This should create our main folder structure, and write the basic files needed for EPUB support.
  253. 'This will create the mimetype and container.xml files for us since they shouldn't change
  254. 'and are mainly used to help our OS know where and what type of folders we're using for EPUB format.
  255. IF NOT _DIREXISTS(mainfolder$) THEN
  256.     MKDIR mainfolder$
  257.     CHDIR mainfolder$
  258.     MKDIR "META-INF" + "\"
  259.     MKDIR "OEBPS"
  260.     MKDIR "OEBPS\images"
  261.     MKDIR "OEBPS\Styles"
  262.     MKDIR "OEBPS\Text"
  263.     CHDIR "..\"
  264.     PRINT "Warning: Directory already exists.  Using this name will overwrite or alter existing files inside this folder.  Do you wish to proceed? (Y/N)"
  265.     DO
  266.         i$ = UCASE$(INKEY$)
  267.         IF i$ = "N" THEN MakeFolders = 0: EXIT SUB
  268.     LOOP UNTIL i$ = "Y"
  269. p$ = mainfolder$ + "\"
  270. OPEN p$ + "mimetype" FOR OUTPUT AS #1
  271. PRINT #1, "application/epub+zip"
  272. OPEN p$ + "META-INF\container.xml" FOR OUTPUT AS #1
  273. PRINT #1, "<?xml version="; CHR$(34); "1.0"; CHR$(34); "?>"
  274. PRINT #1, "<container version="; CHR$(34); "1.0"; CHR$(34); " xmlns="; CHR$(34); "urn:oasis:names:tc:opendocument:xmlns:container"; CHR$(34); ">"
  275. PRINT #1, "    <rootfiles>"
  276. PRINT #1, "         <rootfile full-path="; CHR$(34); "OEBPS/content.opf"; CHR$(34); " media-type="; CHR$(34); "application/oebps-package+xml"; CHR$(34); "/>"
  277. PRINT #1, "    </rootfiles>"
  278. PRINT #1, "</container>"
  279. MakeFolders = -1
  280.  

Usage here is easy enough:
1) compile and run to create a folder called "Steve Book"
2) use whatever ZIP program you have on your machine to zip that folder up and give it a EPUB extension instead of a ZIP extension.

Note that I didn't bother to even try to have the program do step two for us, as QB64 doesn't come packaged with any sort of specific ZIP compression toolset.  In the SDL version, I would've used zlib1.dll, which comes packaged with SDL for use with PNG files, to handle the process, but the GL version doesn't come prepacked with any compression tools.  Since there's a ton of utilities to zip up files and folders out there (winrar, 7z, winzip, countless others), I'm not going to try and even guess what an user has installed on their machine.

EPUB files are just glorified ZIP files with a different extension to them (Don't believe it?  Just rename a few sometime and then look at their contents.), so this program simply makes all the necessary files for an EPUB format ebook and leaves it up to the end-user to finish the process by compressing and renaming the ZIP to EPUB for themselves. 

Try it out, have fun, and let me know if you have any questions about any part of the process.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline euklides

  • Forum Regular
  • Posts: 128
Re: Epub book creation program
« Reply #1 on: February 25, 2018, 04:03:34 am »
More easy would be (of course) to open "Sigil", and save what you see (as an empty epub book) !

Yes, -you are right- an epub file is only a zip file...

I've written a text extractor for epub books with VB Excel.
But with QB64, the real problem to extract the text of an epub book is the manipulation of unicodes characters...
More convenient to create a book -for instance- is to use Word, save your document as a htm file, and create the ebook with "Calibre".

But all applications/programs written in QB64 about epub files are interesting for me... Thank's
Why not yes ?

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Epub book creation program
« Reply #2 on: February 25, 2018, 07:28:20 am »
Wow it is not your average post. Very interesting, thanks Steve.

I did not know that of EPUB, useful info.