diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..051d09d --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +eval "$(lorri direnv)" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0b62354 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +result +*.epub +*.mobi +*.pdf +.redo diff --git a/all.do b/all.do new file mode 100644 index 0000000..ec382f4 --- /dev/null +++ b/all.do @@ -0,0 +1,2 @@ +redo-ifchange Spellblade.mobi +redo wordcount diff --git a/clean.do b/clean.do new file mode 100644 index 0000000..afb2d18 --- /dev/null +++ b/clean.do @@ -0,0 +1 @@ +rm out/Spellblade.* \ No newline at end of file diff --git a/default.epub.do b/default.epub.do new file mode 100644 index 0000000..425a60c --- /dev/null +++ b/default.epub.do @@ -0,0 +1,11 @@ +DEPS="$(ls ./src/**/*.md | grep -v plans)" + +redo-ifchange $DEPS ./src/style.css ./src/pagebreak.lua ./src/title.txt + +pandoc \ + -o $3 \ + --resource-path=./src \ + --css ./src/style.css \ + --lua-filter ./src/pagebreak.lua \ + --to epub \ + ./src/title.txt $DEPS \ No newline at end of file diff --git a/default.mobi.do b/default.mobi.do new file mode 100644 index 0000000..3c44ddb --- /dev/null +++ b/default.mobi.do @@ -0,0 +1,5 @@ +exec >&2 + +redo-ifchange ./out/$2.epub + +ebook-convert ./out/$2.epub ./out/$2.mobi >/dev/null \ No newline at end of file diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..37b1826 --- /dev/null +++ b/default.nix @@ -0,0 +1,31 @@ +{ pkgs ? import { } }: + +let + nur = import (builtins.fetchTarball + "https://github.com/nix-community/NUR/archive/master.tar.gz") { + inherit pkgs; + }; + version = "devel"; +in pkgs.stdenv.mkDerivation { + pname = "Spellblade"; + inherit version; + src = ./.; + phases = "buildPhase installPhase"; + buildInputs = with pkgs; [ + calibre + nur.repos.mic92.pandoc-bin + redo-apenwarr + ]; + + buildPhase = '' + cp -rf $src/src . + cp -rf $src/*.do . + mkdir -p out + redo + ''; + + installPhase = '' + mkdir -p $out + cp -vrf out/* $out + ''; +} diff --git a/out/.gitignore b/out/.gitignore new file mode 100644 index 0000000..3050176 --- /dev/null +++ b/out/.gitignore @@ -0,0 +1,6 @@ +!.gitkeep +!.gitignore + +*.epub +*.mobi +*.pdf diff --git a/out/.gitkeep b/out/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/plans.md b/plans.md index cd4a167..75ba64c 100644 --- a/plans.md +++ b/plans.md @@ -36,18 +36,18 @@ she wants to see where it will end up. The teachers have never seen this happen and deliberate before accepting Alicia and encouraging them to continue down that path. -- Cover the setting - - Introduce the bladecraft school - - Introduce spellcraft and frame it as an "other" - - Introduce Alicia undergoing a magical awakening - First battle + - Cover the setting + - Introduce the bladecraft school + - Introduce spellcraft and frame it as an "other" + - Introduce Alicia undergoing a magical awakening - Accidentally uses powers on the field - - Leads to victory - - Get sus by Zekas + - Leads to victory + - Puts herself in the line of fire - Tongue-lashing for the absurdly crazy strategy - Meal hall - Bed, idle thoughts about her magic -- Spiritualist +- Spiritualist discussions - Various battles? - Flashbacks to her father noticing signs of this happening and teaching her how to suppress her gift diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..8c0c4f0 --- /dev/null +++ b/shell.nix @@ -0,0 +1,17 @@ +{ pkgs ? import { } }: + +let + nur = import (builtins.fetchTarball + "https://github.com/nix-community/NUR/archive/master.tar.gz") { + inherit pkgs; + }; +in pkgs.mkShell { + buildInputs = with pkgs; [ + calibre + nur.repos.mic92.pandoc-bin + redo-apenwarr + + # keep this line if you use bash + bashInteractive + ]; +} diff --git a/src/00_overhead/overhead.md b/src/00_overhead/overhead.md new file mode 100644 index 0000000..031055a --- /dev/null +++ b/src/00_overhead/overhead.md @@ -0,0 +1,17 @@ +\pagebreak + +
+ +

This book is dedicated to all of those that need a ray of hope in these +trying times.

+ +This book is a Within Studios publication. Find out more at +https://withinstudios.itch.io + +This book is a work of fiction, Names, characters, business, events and +incidents are the products of the author’s imagination. Any resemblance to +actual persons, living or dead, or actual events is purely coincidental. +However, the topics that the author alludes to are entirely real and serious +problems that require deep thought and consideration. + +
diff --git a/src/chapter-1/index.md b/src/chapter-1/index.md new file mode 100644 index 0000000..b743fda --- /dev/null +++ b/src/chapter-1/index.md @@ -0,0 +1 @@ +# Chapter 1 diff --git a/src/chapter-1/plans.md b/src/chapter-1/plans.md index 6c307a2..e2fb924 100644 --- a/src/chapter-1/plans.md +++ b/src/chapter-1/plans.md @@ -3,7 +3,7 @@ Introduction to the school of bladecraft. Alicia is shown to suppress their magic and tensions between spellcraft and bladecraft are hinted at. -- [x] The first battle between team red and team blue, team red barely wins, +- [ ] The first battle between team red and team blue, team red barely wins, Alicia has to hide their magic from Zekas - [ ] A dressing-down from the instructors, Alicia starts to feel fiery rage and has to suppress their magic again lest they fireball the instructors diff --git a/src/chapter-1/scene-1.md b/src/chapter-1/scene-1.md new file mode 100644 index 0000000..5d91b9b --- /dev/null +++ b/src/chapter-1/scene-1.md @@ -0,0 +1,70 @@ +Alicia scanned across the clearing. Her cat eyes darted across the field, her +ears focused forward and ready for victory. The battlefield was a wide open +grassy field without any good spots to take cover. Her team was losing. Badly. +Her team's flag was solidly in the hands of the enemy and every attempt to +wrestle it free had failed. Alicia looked over the field and got a very terrible +idea. She turned towards her friend Tistus and whispered "We're going to try a +pincer attack, when you get the flag, run like your life depends on it" into his +ear. Tistus nodded back and stretched his legs a little. Alicia told the other +group the plan via hand signals. Alicia sent the "go" signal and they all took +off sprinting. + +The two groups managed to pinch the blue team together, their backs against +eachother and tails interlocking for stability. Zekas, the blue team leader with +the red team's flag loomed over red team and readied his wooden sword. His plan +almost worked, if only he wasn't struck in the back on his right side by +Alicia's matching wooden sword. Zekas dropped his sword and growled at Alicia, +baring his shark teeth to her. Tistus managed to squeeze between the other blue +team members and yanked the flag free. He held it for dear life in his claws and +gave Alicia a signal with his tail. + +Alicia took a hit to the side from one of the guards she was struggling against +and a small trickle of blood started to run down her left leg. Zekas noticed +that his flag was missing and saw Alicia's cut, sending him into a rage. "You +witch, I'll kill you!". Zekas knocked Alicia to the ground with an uppercut and +Tistus sprinted off for home base while blue team surrounded Alicia. Zekas tried +to grab what he thought was the flag and got Alicia's blood on his hand. Zekas +growled again and looked around, seeing Tistus fleeing like his life depended on +it. + +"AFTER THEM!" + +Blue team took off and tried to catch up with Tistus, but the distraction was +long enough that his victory was all but guaranteed. The rest of red team didn't +bother to chase down blue team, they knew Tistus was the fastest sprinter at the +bladecraft school. + +The horn sound resonated throughout the area. Tistus had made it to the base and +the exercise was over. + +Red team had won. + +Puri helped Alicia up and gave her a bandage. Alicia dressed her wound and felt +a surge of lightning race up her hand. The exact kind of surge she didn't want +to have around other people. + +_No no no no no no. Focus, calm, let it drain to the lightning rod in my heart._ +Alicia ran through the exercises her father told her to do and the feeling +settled. The surge had stopped, but so had the bleeding. Alicia and the rest of +her team started walking back to camp, catching up with Zekas' slow gait. + +Zekas growled at Alicia in frustration, "Nice trick with that fake flag. You got +me." + +"Trick? Oh, the guard to my left cut my leg with his sword. I think you got +got." + +Zekas facepalmed and looked at Alicia. No real emotion, he just looked at her. +Alicia's roughly six foot snep frame. There was a trickle of blood down her left +side, but other than that her white fur and gray spots were well-kept, with her +chocolate brown hair tied into a battle bun. "Lemme see that wound." + +"I'm gonna let the apothecary take a look at it, it's still hurting but I can +walk on it." + +Alicia and Zekas started walking back to camp with the remnants of their teams. + +Zekas laughed, "At least you didn't let that witch beat you." and he lead the +way towards the teacher's garrison. + +Alicia nervously laughed back and followed suit. diff --git a/src/chapter-1/scene-2.md b/src/chapter-1/scene-2.md index e69de29..8520232 100644 --- a/src/chapter-1/scene-2.md +++ b/src/chapter-1/scene-2.md @@ -0,0 +1,69 @@ +\pagebreak + +Belsa facepalmed at the news of what had happened on the battlefield. She knew +that today's debrief was going to be a frustrating one. She heard a knock on +her door and knew it was Alicia and Zekas ready to debrief. She let them in and +stated "Sit." like she was telling animals what to do. + +"So, let's talk about the...unorthodox strategy I saw on the field today." + +_Oh no, this is how I die, isn't it?_, thought Alicia. + +Belsa continued, "I have to admit, that is one of the best ways to get +yourselves KILLED that I have ever seen. Well done." + +Belsa clapped a very sarcastic slow clap. + +"Excuse me, I think I can exp-" + +Belsa raised a hand and cut Alicia off. + +"Now, what's done is done and all we can really do is learn from these mistakes +so that future events won't end up repeating this, right?" + +Alicia cautiously nodded and looked to Zekas. Zekas had a very dumb grin on his +face. He was loving every minute of this. + +Belsa looked over at Zekas and glared with the force of a thousand suns. Zekas' +grin quickly turned into a grimace. Belsa smiled and redirected her scolding. +"Now, for you. What the hell were YOU thinking letting yourself get pincered +like that? That was even dumber than what that cat did." + +Zekas stuttered back "But I didn't see them! Those sneps came out of nowhere and +they got us!" + +"So you're _really_ telling me you didn't notice a bunch of gray streaks coming +at you contrasted against a green field? I'm not an expert in shark eyesight but +what I know about cetacean eyesight tells me the difference is as clear as night +and day. Did _anyone_ in your cadre of oafs see them?" + +"Well we did see them when they attacked us." + +Belsa facepalmed. One of these days she was going to actually hurt herself doing +this job. + +Alicia cut in "By the way, we accidentally tore the flag in the process of +wrestling it free. Is there anything we need to do about that?" + +Belsa laughed. "Not unless you make a habit of it. Say speak of which, how did +you manage to get the flag away anyways?" + +Alicia pointed at Zekas and answered "Apparently our resident genius over there +thought a cut on my leg was the flag. It's fine now, but it seems my blood is +the exact same red as the flag, which made him think I stole the flag or +something. Tistus actually stole the flag and got away with it as soon as he +could." + +"You know, I was wrong. That strategy wasn't just an amazing way to get yourself +killed, I'm amazed you didn't get infected. You took that to the aopthecary +right?" + +"Yes ma'am. I've always been a fast healer so the field bandage did most of the +trick." + +"Alright. I've heard everything I need to know. You two are dismissed. Try to +not get yourself killed next time, or I'll be there when you get judged." + +Zekas stood up and proudly trod off towards his team's barracks. Alicia +stretched a moment and then continued towards the mess hall. Being scolded at +always made Alicia hungry. diff --git a/src/pagebreak.lua b/src/pagebreak.lua new file mode 100644 index 0000000..b931051 --- /dev/null +++ b/src/pagebreak.lua @@ -0,0 +1,109 @@ +--[[ +pagebreak – convert raw LaTeX page breaks to other formats + +Copyright © 2017-2021 Benct Philip Jonsson, Albert Krewinkel + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +]] +local stringify_orig = (require 'pandoc.utils').stringify + +local function stringify(x) + return type(x) == 'string' and x or stringify_orig(x) +end + +--- configs – these are populated in the Meta filter. +local pagebreak = { + asciidoc = '<<<\n\n', + context = '\\page', + epub = '

', + html = '
', + latex = '\\newpage{}', + ms = '.bp', + ooxml = '', + odt = '' +} + +local function pagebreaks_from_config (meta) + local html_class = + (meta.newpage_html_class and stringify(meta.newpage_html_class)) + or os.getenv 'PANDOC_NEWPAGE_HTML_CLASS' + if html_class and html_class ~= '' then + pagebreak.html = string.format('
', html_class) + end + + local odt_style = + (meta.newpage_odt_style and stringify(meta.newpage_odt_style)) + or os.getenv 'PANDOC_NEWPAGE_ODT_STYLE' + if odt_style and odt_style ~= '' then + pagebreak.odt = string.format('', odt_style) + end +end + +--- Return a block element causing a page break in the given format. +local function newpage(format) + if format:match 'asciidoc' then + return pandoc.RawBlock('asciidoc', pagebreak.asciidoc) + elseif format == 'context' then + return pandoc.RawBlock('context', pagebreak.context) + elseif format == 'docx' then + return pandoc.RawBlock('openxml', pagebreak.ooxml) + elseif format:match 'epub' then + return pandoc.RawBlock('html', pagebreak.epub) + elseif format:match 'html.*' then + return pandoc.RawBlock('html', pagebreak.html) + elseif format:match 'latex' then + return pandoc.RawBlock('tex', pagebreak.latex) + elseif format:match 'ms' then + return pandoc.RawBlock('ms', pagebreak.ms) + elseif format:match 'odt' then + return pandoc.RawBlock('opendocument', pagebreak.odt) + else + -- fall back to insert a form feed character + return pandoc.Para{pandoc.Str '\f'} + end +end + +local function is_newpage_command(command) + return command:match '^\\newpage%{?%}?$' + or command:match '^\\pagebreak%{?%}?$' +end + +-- Filter function called on each RawBlock element. +function RawBlock (el) + -- Don't do anything if the output is TeX + if FORMAT:match 'tex$' then + return nil + end + -- check that the block is TeX or LaTeX and contains only + -- \newpage or \pagebreak. + if el.format:match 'tex' and is_newpage_command(el.text) then + -- use format-specific pagebreak marker. FORMAT is set by pandoc to + -- the targeted output format. + return newpage(FORMAT) + end + -- otherwise, leave the block unchanged + return nil +end + +-- Turning paragraphs which contain nothing but a form feed +-- characters into line breaks. +function Para (el) + if #el.content == 1 and el.content[1].text == '\f' then + return newpage(FORMAT) + end +end + +return { + {Meta = pagebreaks_from_config}, + {RawBlock = RawBlock, Para = Para} +} diff --git a/src/style.css b/src/style.css new file mode 100644 index 0000000..e5a6d6a --- /dev/null +++ b/src/style.css @@ -0,0 +1,56 @@ +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +body { + font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", serif; + margin: auto; + text-align: justify; + font-size: 16px; + line-height: 1.7; +} + +h1 { text-align: left; } +h2 { text-align: left; } +h3 { text-align: left; } +h4 { text-align: left; } +h5 { text-align: left; } +h6 { text-align: left; } + +h1.title { + margin-top: 0; + text-align: center; +} + +p.author { + text-align: center; +} + +ol.toc { + padding: 0; + margin: 1em 0; + padding: 0 0 0 2em; +} + +ul.toc ul, ol.toc ol { + margin: .3em 0; +} + +li { margin: 0; padding: 0 5px; } + +code { + font-family: monospace; + background-color: rgb(247, 247, 247); +} + +pre { + font-family: monospace;; + padding: 16px; + overflow: auto; + font-size: 80%; + line-height: 1.45; + border-radius: 3px; + background-color: rgb(247, 247, 247); +} diff --git a/src/style.tex b/src/style.tex new file mode 100644 index 0000000..7afe9ce --- /dev/null +++ b/src/style.tex @@ -0,0 +1,6 @@ +\usepackage{titlesec} + +\titleclass{\section}{top} +\newcommand\sectionbreak{\clearpage} + +\usepackage[width=4.25in, height=7.5in, top=1.0in, papersize={6in,9in}]{geometry} diff --git a/src/title.txt b/src/title.txt new file mode 100644 index 0000000..26de837 --- /dev/null +++ b/src/title.txt @@ -0,0 +1,13 @@ +--- +title: Spellblade +author: Xe +rights: All Rights Reserved +language: en-US +# cover-image: ./Spellblade.png + +# pandoc LaTeX crud +documentclass: book +links-as-notes: true +toc-depth: 2 +fontfamily: bitter +--- diff --git a/src/wordcount.lua b/src/wordcount.lua new file mode 100644 index 0000000..517e4ac --- /dev/null +++ b/src/wordcount.lua @@ -0,0 +1,30 @@ +-- counts words in a document +-- from https://pandoc.org/lua-filters.html#examples + +words = 0 + +wordcount = { + Str = function(el) + -- we don't count a word if it's entirely punctuation: + if el.text:match("%P") then + words = words + 1 + end + end, + + Code = function(el) + _,n = el.text:gsub("%S+","") + words = words + n + end, + + CodeBlock = function(el) + _,n = el.text:gsub("%S+","") + words = words + n + end +} + +function Pandoc(el) + -- skip metadata, just count body: + pandoc.walk_block(pandoc.Div(el.blocks), wordcount) + print(words .. " words in body") + os.exit(0) +end diff --git a/src/zz_end/dictionary.md b/src/zz_end/dictionary.md new file mode 100644 index 0000000..39d285c --- /dev/null +++ b/src/zz_end/dictionary.md @@ -0,0 +1,7 @@ +## Dictionary + +This list of words will help you + +#### Snep + +Snow Leopard. diff --git a/wordcount.do b/wordcount.do new file mode 100644 index 0000000..152192e --- /dev/null +++ b/wordcount.do @@ -0,0 +1,5 @@ +DEPS="$(ls ./src/**/*.md | grep -v plans)" + +redo-ifchange $DEPS ./src/wordcount.lua + +pandoc --lua-filter ./src/wordcount.lua $DEPS >&2 \ No newline at end of file