fix #16, improved formatting

This commit is contained in:
Tangent / Rose / Nebula Rosa 2024-11-05 16:19:37 -07:00
parent 6fe135e278
commit 180e979061
3 changed files with 50 additions and 18 deletions

View File

@ -32,7 +32,7 @@ local dbg = opts.debug and function(f,...) prn("d",f:gsub("#LINE#",str(line(3)))
-- local ElementNode = require"htmlparser.ElementNode" -- local ElementNode = require"htmlparser.ElementNode"
-- local voidelements = require"htmlparser.voidelements" -- local voidelements = require"htmlparser.voidelements"
local success, utility = pcall(function() local success, utility = pcall(function()
return dofile(arg[0]:match("@?(.*/)") or arg[0]:match("@?(.*\\)") .. "utility-functions.lua") return dofile((arg[0]:match("@?(.*/)") or arg[0]:match("@?(.*\\)")) .. "utility-functions.lua")
end) end)
if not success then if not success then
print("\n\n" .. tostring(utility)) print("\n\n" .. tostring(utility))

62
make-epub.lua Normal file → Executable file
View File

@ -19,24 +19,41 @@ Requirements:
- Lua libraries: htmlparser, dkjson (or compatible) - Lua libraries: htmlparser, dkjson (or compatible)
- Binaries: pandoc, curl - Binaries: pandoc, curl
Configuration example: Configuration example(s):
{ {
"author": "Name", "authors": ["Name"], -- "author" with a single string also supported
"title": "Book", "title": "Book",
"keywords": ["fantasy", "dragon", "isekai"], "keywords": ["erotica", "fantasy"],
"base_url": "https://www.literotica.com/s/title-ch-", -- not required if only one section "base_url": "https://www.literotica.com/s/title-ch-", -- not required if only one section
"first_section_url": "https://www.literotica.com/s/title", "first_section_url": "https://www.literotica.com/s/title", -- only if first section is differently-formatted
"sections": { "sections": {
"start": 1, "start": 1,
"finish": 5, "finish": 4,
"naming": "Chapter" -- not required, but will screw up the Table of Contents if absent "naming": "Chapter" -- only required for a Table of Contents (unless using anthology form below)
}, },
"page_counts": [1, 5, 3] "page_counts": [1, 5, 3, 3]
} }
{
"authors": ["Name"], -- first author will be used as the book's primary author
"title": "Anthology",
"keywords": ["erotica", "fantasy"],
"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]
}
For an explanation of these examples, see the .lua-files ReadMe.
]] ]]
local success, utility = pcall(function() local success, utility = pcall(function()
return dofile(arg[0]:match("@?(.*/)") or arg[0]:match("@?(.*\\)") .. "utility-functions.lua") return dofile((arg[0]:match("@?(.*/)") or arg[0]:match("@?(.*\\)")) .. "utility-functions.lua")
end) end)
if not success then if not success then
print("\n\n" .. tostring(utility)) print("\n\n" .. tostring(utility))
@ -45,6 +62,7 @@ end
local json = utility.require("json") local json = utility.require("json")
-- TODO utility.path_separator should be a thing
local path_separator local path_separator
if utility.OS == "Windows" then if utility.OS == "Windows" then
path_separator = "\\" path_separator = "\\"
@ -55,6 +73,7 @@ end
-- also checks for errors -- also checks for errors
-- TODO make it check for required elements and error if any are missing! -- TODO make it check for required elements and error if any are missing!
local function get_config() local function get_config()
-- TODO arg checking REALLY should not be here
if not arg[1] then if not arg[1] then
print(help) print(help)
error("\nA config file name/path must be specified.") error("\nA config file name/path must be specified.")
@ -67,6 +86,14 @@ local function get_config()
config = json.decode(file:read("*a")) config = json.decode(file:read("*a"))
file:close() file:close()
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)
end
-- detecting manually specified sections and flagging it to the rest of the script -- detecting manually specified sections and flagging it to the rest of the script
if config.sections[1] then if config.sections[1] then
config.sections.start = 1 config.sections.start = 1
@ -79,6 +106,10 @@ local function get_config()
error("Number of page_counts does not match number of sections.") error("Number of page_counts does not match number of sections.")
end end
if config.section_titles and #config.section_titles ~= config.sections.finish - config.sections.start + 1 then
error("Number of section_titles does not match number of sections.")
end
return config return config
end end
@ -95,8 +126,7 @@ local function format_metadata(config)
local metadata = { local metadata = {
"---", "---",
"title: \"" .. utility.escape_quotes(config.title) .. "\"", "title: \"" .. utility.escape_quotes(config.title) .. "\"",
"author:", "author: [" .. stringify_list(config.authors) .. "]",
"- \"" .. utility.escape_quotes(config.author) .. "\"",
"keywords: [" .. keywords_string .. "]", "keywords: [" .. keywords_string .. "]",
"tags: [" .. keywords_string .. "]", "tags: [" .. keywords_string .. "]",
"---", "---",
@ -183,8 +213,9 @@ local function get_base_file_name(config)
end end
local base_file_name local base_file_name
if config.title and config.author then if config.title and config.authors[1] then
base_file_name = config.title .. " by " .. config.author -- first author in list gets top billing (this is problematic in anthologies unless an editor is the first entry)
base_file_name = config.title .. " by " .. config.authors[1]
elseif config.title then elseif config.title then
base_file_name = config.title base_file_name = config.title
else else
@ -210,10 +241,11 @@ local function write_markdown_file(config)
for section = config.sections.start, config.sections.finish do for section = config.sections.start, config.sections.finish do
if config.sections.naming then if config.sections.naming then
markdown_file:write("\n\n# " .. config.sections.naming .. " " .. tostring(section) .. "\n\n") markdown_file:write("\n\n# " .. config.sections.naming .. " " .. tostring(section))
else elseif config.section_titles then
markdown_file:write("\n\n\n\n") -- TODO add ability to manually specify names for manually listed sections markdown_file:write("\n\n# " .. config.section_titles[section])
end end
markdown_file:write("\n\n")
local section_file_name = "Sections" .. path_separator .. tostring(section) local section_file_name = "Sections" .. path_separator .. tostring(section)
local section_file, err = io.open(section_file_name .. ".md", "r") local section_file, err = io.open(section_file_name .. ".md", "r")

View File

@ -2,7 +2,7 @@
-- this only works if that file is in the same directory as this one - but works no matter where it was called from -- this only works if that file is in the same directory as this one - but works no matter where it was called from
local function _example_load() local function _example_load()
local success, utility = pcall(function() local success, utility = pcall(function()
return dofile(arg[0]:match("@?(.*/)") or arg[0]:match("@?(.*\\)") .. "utility-functions.lua") return dofile((arg[0]:match("@?(.*/)") or arg[0]:match("@?(.*\\)")) .. "utility-functions.lua")
end) end)
if not success then if not success then
print("\n\n" .. tostring(utility)) print("\n\n" .. tostring(utility))
@ -53,7 +53,7 @@ end
utility.require = function(name) utility.require = function(name)
local success, package_or_err = pcall(function() local success, package_or_err = pcall(function()
return dofile(arg[0]:match("@?(.*/)") or arg[0]:match("@?(.*\\)") .. name .. ".lua") return dofile((arg[0]:match("@?(.*/)") or arg[0]:match("@?(.*\\)")) .. name .. ".lua")
end) end)
if success then if success then
return package_or_err return package_or_err