This module provides a filter for pandoc that can be used to create an interactive HTML page for the Snowflake Method of novel writing.
The input document (e.g. a markdown file) will be used as a database that contains the various items that you need to write according to the Snowflake Method. You can combine this filter with other filters, e.g. pandoc-vimwiki or pandoc-narrative-charts. The input document needs to be structured in a certain way (as explained in the next sections). The output document, when exported as HTML and combined with an appropriate Javascript function and appropriate CSS, will be an interactive, single-page application that will guide you through the steps according to the Snowflake Method.
The app is supposed to show the result of the relevant previous steps (e.g. steps 2 and 3) of the Snowflake in a browser, while you type the text for the current step (e.g. step 4) in a text editor. This ensures even slow computers (e.g. subnotebooks/tablets) can provide a pleasant working environment.
This document assumes that you installed pandoc and this filter such that both executables can be found in the program search path.
This module is compatible with pandoc 2.14 and stack lts-18.28.
- A working Haskell installation, either via cabal or stack
- Get the source code. Either
- clone this repository or
- download and extract the ZIP
- Go to the source code directory
- Run either
cabal install
orstack init
followed bystack install
The installation might take some time due to the size and number of dependencies.
This sections explains how to call pandoc to create the HTML app. We assume
that the input file is named design.markdown
and we generate a file named
design.html
.
Use the following command line arguments for pandoc:
pandoc --from markdown --to html --filter pandoc-snowflake -s -H design_header.html -o design.html design.markdown
The file design_header.html
contains the Javascript code and the CSS
definitions to make the app work.
It is recommended to put the commands above in a Windows Batch or a Shell Script file.
If you generate multiple formats (e.g. design.html
, the EPUB file,
and a PDF) from your novel, you can generate all those with one command.
If you use multiple filters, it is recommended to put pandoc-snowflake
last.
Along with the pandoc
filter itself, a helper program (psf-init
) and some
data files are installed that make the creation of Snowflake writing projects
simpler.
psf-init
is meant to be run in an empty directory. It will ask for the
following items:
- language code
- project name
- character names
From these inputs, it will create a correctly linked VimWiki
document and a
Makefile
that will compile the design document as HTML and the final book as
HTML, EPUB, and possibly .mobi
.
The program will create the following VimWiki
files:
book.mdwiki
The markdown document for the final book.design.mdwiki
The markdown document for the design HTML.title.mdwiki
The markdown document for title and author, used by the two files above.
The inputs will not be checked and will only be sanitized sparingly. As such, make sure to enter them as described in the following sections.
The language code will be used for the Vim
modeline in
every generated file and should be a valid language code understood by
spelllang.
Be advised that the string will not be sanitized. This might constitute a
security issue if the document is not checked properly before opening it in
vim
.
The project name will be used as part of the generated file names. It will be
stripped of any non-alphanumeric characters and converted to lowercase.
Assuming the string my project%5
was entered, the files
output/design_myproject5.html
output/book_myproject5.html
output/myproject5.epub
output/myproject5.mobi
will be created.
The program will ask for character names until an empty string is entered. Each name will be used in lower case, but otherwise unsanitized, for the names of the following files:
character/<name>_overview.mdwiki
character/<name>_details.mdwiki
character/<name>_synopsis.mdwiki
Here, <name>
stands for the entered name in lower case. The name as entered
will be inserted into the files. The character files will be linked to in the
order as entered.
The following commands create the output files:
|Command |Output File|
|make
|Design HTML|
|make design
|Design HTML|
|make html
|Book HTML|
|make epub
|Book EPUB|
|make mobi
|Book MOBI (for Kindle)|
|make all
|All of the above|
The various targets can be combined (e.g. make design epub
).
To use e.g. 3 cores, call make -j 3 all
. This is the maximum parallelism,
this particular setup can exploit.
Be sure to add any other linked files (e.g. chapters) to the variable DEPS
in Makefile
. Refer to the GNU Make
Manual
for the exact syntax.
psf-init
will not overwrite any files when run multiple files. It can be
(ab)used to add characters to an existing project from the template. In this case, the project name
will be ignored (as it is not used in the character templates) and can be
chosen at will. The remaining rules are the same as stated above.
In this case, the newly created character files need to be linked manually to
design.mdwiki
, book.mdwiki
, and Makefile
.
The input document as read by pandoc-snowflake
is to be structured in the
following way. If you use other filters, ensure that they output the structure
as illustrated below.
The document is expected to contain three top-level headings (level 1):
# Design
# Timeline
# Chapters
The header Design will contain the Snowflake database. All other headers at this level (i.e. Timeline and Chapters) are copied to the output in the same order they appear in. Any meta data (i.e. title and author) are preserved. Any matter before the first header will be discarded.
The basic layout is structured according to the steps of the Snowflake Method. However, as long as the nesting of the headers is reproduced as described below, the order of the headers inside their higher-level header is not important.
The Design header is expected to contain the following level-2 headers. The text below the header explains the meaning of this section.
In addition to the Snowflake Method, there are three fields (Internal Conflict, External Conflict, Twist) that I find helpful. See here for an explanation on them.
# Design
## Premise
The one-sentence summary of the novel (step 1).
## Internal Conflict
This is not part of the Snowflake Method as explained in the link above.
However, I find it helpful to sketch the essential (emotional) conflict of the
hero at the start.
If you don't want to use this field, leave it empty.
## External Conflict
Again not part of the Method per se, this section is supposed to show a sketch
of what outer forces oppose the hero. If you don't want to use it, leave it
empty.
## Twist
Since I firmly believe a good (fiction) story requires a twist (or better, a
whole bunch of them), here's the place to list the twist you want to include.
## One Paragraph Summary
The one-paragraph summary of the novel (step 2).
## Characters
This section contains basic information about all your important characters,
respective step 3 of the Snowflake. How to structure this section will be
explained below (Step 3: Characters).
## One Page Summary
Step 4 of the Snowflake. Text here will be displayed as is, incl. formatting.
## Character Synopsis
Step 5 of the Snowflake. Text here will be displayed as is, incl. formatting.
## Four Page Summary
Step 6. See below.
## Character Details
Step 7. See below.
## Scenes
Step 8. The list of scenes. See below.
The filter does not provide a mechanism for step 9 (scene details) and step 10
(first draft). It is recommended to use the linking mechanism of
pandoc-vimwiki
or the soon-to-be-released vimwiki
parser of pandoc
to
link the scenes to individual files. Putting each scene in a separate file
allows you to change the order of the scenes later.
The section ## Characters
is supposed to contain one level-3 header per
character. The title of the header should be the (short) name of the
character and the subordinate headers must be structured like this:
## Characters
### Little Girl
#### Role
Protagonist
#### One-sentence summary
Send on a humanitarian mission by her mother, a little girl becomes an
accomplice in a cold-blooded murder of an sentient canine.
#### Goal
Bring cake and wine to her grandmother.
#### Motivation
Provide help for those in need.
#### Internal Conflict
An evil presence may have taken over her grandmother. Should the girl kill her
apparently senile relative?
#### Epiphany
It pays to be suspicious of strangers.
#### One-paragraph summary
A small girl is sent to bring her sick grandma food. On her voyage, she meets
a mysterious stranger. Once she arrives at her grandma's house, she notices
something strange about the old lady. Together with a hunter, she kills the
murderous stranger and frees her grandmother.
If you name the character Character, the section will be ignored. That allows you to keep prepared copies of the section until they are ready to be filled.
Each level-3 header in this section is matched with the respective paragraph from step 4 and rendered as a table.
Again, provide one level-3 section per character and name them appropriately. Also, naming them Character lets you keep a prepared template as the filter ignores it.
Each non-empty header with a non-empty body text will be converted into a row of a table. The left column will contain the headline text, the right the body text incl. formatting.
The following example show this:
## Character Details
### Little Girl
#### Full Name
Little Red Riding Hood
#### Nickname
Red
#### Place of birth
A small town in the forest.
#### Current address
#### Favorite color
red
No row will be included in the table for Current address as the body is empty.
The template contains the fields listed here.
For each level-3 header of step 6, provide the respective level-3 header here. For each scene in the act represented by the level-3 header, provide a level-4 header. The title of the header should be the character from who's point of view, this scene is shown.
## Scenes
### Act 1
#### Little Girl
Little Girl's mother packs a basket of cake and wine, before she sends Little
Girl to her grandmother.
#### Hunter
The hunter sees a little girl with a basket in the forest. He approaches her
to warn her of the Big Bad Wolf.
If you write a complicated story and need to keep track of where characters
are at which place in which scene, you can use the pandoc-narrative-charts
filter to generate such a chart. Add the chart events to the scene sections
and add the plot in a top-level section.
You might also want to link to the intermediate or final scenes (steps 9 and
10) using pandoc-vimwiki
until the full vimwiki parser becomes part of
pandoc. Another option is to use pandoc-include
and maintain the links
manually.
This section contains information for those brave souls who want to dive into the source of the filter.
The menus are rendered using CSS from the following DOM
<div id="mainmenu">
<span>Item 1</span>
<span>Item 2</span>
<span>Item 3</span>
</div>
<div id="mainmenu.0">
</div>
<div id="mainmenu.1">
</div>
<div id="mainmenu.2">
</div>
The first div
renders the menu bar. The span
elements are the menu items.
The following div
elements contain the content that is associated with each
menu item.
The ids adhere to the pattern above: mainmenu
is the base name of the menu,
mainmenu.<i>
is used to find the content div
of the respective menu item.
Every menu needs to have a unique base name.
Switching the menu items is performed by the function selectMenu
that is
distributed in the file example/design_header.html
. This function sets all
bodies to class bodyhide
and all menu items to empty classes. After that, it
sets the selected body to class bodyshow
and the menu item to class
select
. The invisibility is then acomplished by CSS.
The persistence of a menu selection is done by storing the selected index in
localStorage
. The key is the base name of the menu. A small script after
each menu calls selectMenu
with the stored number.