diff --git a/README.md b/README.md index 12b320a..e43b572 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # .lua-files -It's like dotfiles, but no, it's just Lua scripts I find useful. +Personally convenient Lua scripts to add to my path. + +## Installation +1. Put this folder somewhere. +2. Add that somewhere to your path. (On Windows, search for Environment Variables (it's "part of" Control Panel) and use the UI to add them to System variables.) +3. (On Windows) Add `.LUA` to PATHEXT. ## Scripts - `2webm.lua`: Converts everything in the working directory to .webm files. @@ -10,7 +15,61 @@ It's like dotfiles, but no, it's just Lua scripts I find useful. - `utility-functions.lua`: (Library) Required for many of these scripts to run. - `video-dl.lua`: A few premade command lines for using `yt-dlp` to download what I want quicker. -## Installation -1. Put this folder somewhere. -2. Add that somewhere to your path. (On Windows, search for Environment Variables (it's "part of" Control Panel) and use the UI to add them to System variables.) -3. (On Windows) Add `.LUA` to PATHEXT. +### make-epub.lua +The JSON config spec has two major variations ("Book" and "Anthology"). + +The following is shared: +- `authors`: (Optional) Array of Strings: Author names. First in the list is used as a byline in the final output. (Legacy: An `author` string works as well. If this exists, it will be first.) +- `title`: (Optional) String: Title of book. +- `keywords`: Array of Strings: Keywords/Tags. (I'm not sure what the difference is in the final output so it goes in both.) +- `sections`: \! See "Book"/"Anthology" variations. (I call LitErotica's stories sections - because they are often part of a larger whole.) +- `page_counts`: Array of Integers: The number of pages on LitErotica per "story". (I call them sections because this script was made to put together story series originally.) + +#### Variation: Book +- `base_url`: String: A partial URL that is the beginning of the URL used for each section (story) on LitErotica. (This script currently only works for stories that end in a padded two-digit number.) +- `first_section_url`: String: Some stories don't have the same URL structure for their first section. This allows you to specify its full URL. +- `sections`: Object defining which sections to download, and what to call them (ie. Chapters, Parts, ..). + - `start`: (Optional) Number: Where to start. (`1` is the default, since it is the most common.) + - `finish`: Number: Where to end. + - `naming`: (Optional) String: How to name sections in the final output. The result is `[naming] [#]` (using section numbers). If not specified, there will be no Table of Contents. + +Example: +```json +{ + "authors": ["Name"], + "title": "Book", + "keywords": ["erotica", "fantasy"], + "base_url": "https://www.literotica.com/s/title-ch-", + "first_section_url": "https://www.literotica.com/s/title", + "sections": { + "start": 1, + "finish": 4, + "naming": "Chapter" + }, + "page_counts": [1, 5, 3, 3] +} +``` + +#### Variation: Anthology +- `manually_specified_sections`: (Optional) Boolean, must be `true`. Technically not required as the script is capable of figuring out you are using this variation, but *should be* included. +- `sections`: Array of Strings: A complete URL for each story. +- `section_titles`: (Optional) Array of Strings: The titles to be used for Table of Contents / headings. (Must be in the same order as `sections`.) + +Example: +```json +{ + "authors": ["Name"], + "title": "Anthology", + "keywords": ["LitErotica", "erotica"], + "manually_specified_sections": true, + "sections": [ + "https://www.literotica.com/s/unique-title", + "https://www.literotica.com/s/another-title" + ], + "section_titles": [ + "Unique Title", + "Another Title" + ], + "page_counts": [5, 2] +} +``` diff --git a/make-epub.lua b/make-epub.lua index 796d845..7bd80a0 100755 --- a/make-epub.lua +++ b/make-epub.lua @@ -4,7 +4,7 @@ local help = [[Usage: make-epub.lua [action] -[action]: If not specified, all steps will be taken in order (except cleanall). +[action]: If not specified, all steps will be taken in order (except clean*). download: All pages will be downloaded to their own HTML files. concat: A file is created for each section out of its pages. convert: Each section is converted to Markdown. @@ -21,23 +21,24 @@ Requirements: Configuration example(s): { - "authors": ["Name"], -- "author" with a single string also supported + "authors": ["Name"], "title": "Book", "keywords": ["erotica", "fantasy"], - "base_url": "https://www.literotica.com/s/title-ch-", -- not required if only one section - "first_section_url": "https://www.literotica.com/s/title", -- only if first section is differently-formatted + "base_url": "https://www.literotica.com/s/title-ch-", + "first_section_url": "https://www.literotica.com/s/title", "sections": { "start": 1, "finish": 4, - "naming": "Chapter" -- only required for a Table of Contents (unless using anthology form below) + "naming": "Chapter" }, "page_counts": [1, 5, 3, 3] } { - "authors": ["Name"], -- first author will be used as the book's primary author + "authors": ["Name"], "title": "Anthology", - "keywords": ["erotica", "fantasy"], + "keywords": ["LitErotica", "erotica"], + "manually_specified_sections": true, "sections": [ "https://www.literotica.com/s/unique-title", "https://www.literotica.com/s/another-title" @@ -49,7 +50,7 @@ Configuration example(s): "page_counts": [5, 2] } - For an explanation of these examples, see the .lua-files ReadMe. + For an explanation of these examples, see the .lua-files README. ]] local success, utility = pcall(function() @@ -86,12 +87,22 @@ local function get_config() config = json.decode(file:read("*a")) file:close() + -- authors wasn't being loaded correctly and I accidentally fixed it while trying to find what was wrong.. + -- for k,v in pairs(config) do + -- print(k,v) + -- end + -- print("config done") + if not config.authors then config.authors = {} -- at least have an empty table so it doesn't error below end - if type(config.author) then -- old style single author will be added to authors list - table.insert(config.authors, config.author) + if config.author then -- old style single author will be prepended to authors list + table.insert(config.authors, 1, config.author) + end + + if not config.keywords then + config.keywords = {} -- TODO test if it will work empty end -- detecting manually specified sections and flagging it to the rest of the script @@ -102,6 +113,10 @@ local function get_config() config.base_url = "http://example.com/" -- must be defined to prevent errors; it will be manipulated and ignored in this use case end + if not config.sections.start then + config.sections.start = 1 -- the first one can be optional since the common use case is ALL OF THEM + end + if #config.page_counts ~= config.sections.finish - config.sections.start + 1 then error("Number of page_counts does not match number of sections.") end @@ -226,11 +241,10 @@ local function get_base_file_name(config) end local function convert_sections(config) - -- the HTML I'm pulling from is often bugged in a way that breaks ebook readers, but pandoc can understand and fix in Markdown utility.required_program("pandoc") for section = config.sections.start, config.sections.finish do local section_file_name = "Sections" .. path_separator .. tostring(section) - os.execute("pandoc \"" .. section_file_name .. ".html\" -o \"" .. section_file_name .. ".md\"") + os.execute("pandoc --from html --to markdown \"" .. section_file_name .. ".html\" -o \"" .. section_file_name .. ".md\"") end end @@ -260,7 +274,7 @@ end local function make_epub(config) utility.required_program("pandoc") local base_file_name = get_base_file_name(config) - os.execute("pandoc \"" .. base_file_name .. ".md\" -o \"" .. base_file_name .. ".epub\" --toc=true") + os.execute("pandoc --from markdown --to epub \"" .. base_file_name .. ".md\" -o \"" .. base_file_name .. ".epub\" --toc=true") end local function rm_html_files(config) @@ -318,7 +332,7 @@ else write_markdown_file(config) print("\nMaking ePub...\n") make_epub(config) - print("\nRemoving HTML files...\n") - rm_html_files(config) + -- print("\nRemoving HTML files...\n") + -- rm_html_files(config) print("\nDone!\n") end