Giter VIP home page Giter VIP logo

spiner's Introduction

Hello! I am Mike Rombout, and I'm a Software Engineer at Elastisys helping customers succeed with Kubernetes!

  • โ›… I'm interested in cloud native and cloud agnostic software solutions.
  • ๐Ÿน And building beautiful software in Go, but I don't mind a bit of โ™จ๏ธ either.
  • ๐Ÿ“š For fun I like to read and write novels, games and interactive fiction.
  • ๐Ÿฅพ To relax, I like to be outside enjoying nature ๐Ÿ‡ณ๐Ÿ‡ด๐Ÿ‡ธ๐Ÿ‡ช๐Ÿ‡ซ๐Ÿ‡ฎ.

spiner's People

Contributors

codacy-badger avatar mrombout avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

spiner's Issues

Add support for latest Twiner

Spiner is no longer able to transform stories from the latest Twine version. It looks like tw-storydata changed and now has a zoom, which Spiner doesn't like. There is also size on tw-passagedata.

22:14:16.126 [JavaFX Application Thread] ERROR nl.mikero.spiner.frontend.main.ApplicationView - Could not transform document.
nl.mikero.spiner.core.exception.TwineTransformationFailedException: Could not transform input.
        at nl.mikero.spiner.core.transformer.TransformService.transform(TransformService.java:70)
        at nl.mikero.spiner.frontend.TransformTask.call(TransformTask.java:44)
        at nl.mikero.spiner.frontend.TransformTask.call(TransformTask.java:14)
        at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
        at java.util.concurrent.FutureTask.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
Caused by: nl.mikero.spiner.core.exception.TwineParseFailedException: javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 212; cvc-complex-type.3.2.2: Attribute 'zoom' is not allowed to appear in element 'tw-storydata'.]
        at nl.mikero.spiner.core.twine.TwineArchiveParser.parse(TwineArchiveParser.java:43)
        at nl.mikero.spiner.core.transformer.TransformService.parse(TransformService.java:112)
        at nl.mikero.spiner.core.transformer.TransformService.transform(TransformService.java:65)
        ... 5 common frames omitted
Caused by: javax.xml.bind.UnmarshalException: null
        at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(Unknown Source)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(Unknown Source)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(Unknown Source)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(Unknown Source)
        at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source)
        at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source)
        at nl.mikero.spiner.core.twine.TwineArchiveParser.parse(TwineArchiveParser.java:40)
        ... 7 common frames omitted
Caused by: org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'zoom' is not allowed to appear in element 'tw-storydata'.
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processAttributes(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(Unknown Source)
        at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.startElement(Unknown Source)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.ValidatingUnmarshaller.startElement(Unknown Source)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
        ... 12 common frames omitted
no warnings or errors were found
22:17:57.356 [JavaFX Application Thread] ERROR nl.mikero.spiner.frontend.main.ApplicationView - Could not transform document.
nl.mikero.spiner.core.exception.TwineTransformationFailedException: Could not transform input.
        at nl.mikero.spiner.core.transformer.TransformService.transform(TransformService.java:70)
        at nl.mikero.spiner.frontend.TransformTask.call(TransformTask.java:44)
        at nl.mikero.spiner.frontend.TransformTask.call(TransformTask.java:14)
        at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
        at java.util.concurrent.FutureTask.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
Caused by: nl.mikero.spiner.core.exception.TwineParseFailedException: javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 212; cvc-complex-type.3.2.2: Attribute 'zoom' is not allowed to appear in element 'tw-storydata'.]
        at nl.mikero.spiner.core.twine.TwineArchiveParser.parse(TwineArchiveParser.java:43)
        at nl.mikero.spiner.core.transformer.TransformService.parse(TransformService.java:112)
        at nl.mikero.spiner.core.transformer.TransformService.transform(TransformService.java:65)
        ... 5 common frames omitted
Caused by: javax.xml.bind.UnmarshalException: null
        at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(Unknown Source)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(Unknown Source)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(Unknown Source)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(Unknown Source)
        at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source)
        at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source)
        at nl.mikero.spiner.core.twine.TwineArchiveParser.parse(TwineArchiveParser.java:40)
        ... 7 common frames omitted
Caused by: org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'zoom' is not allowed to appear in element 'tw-storydata'.
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processAttributes(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(Unknown Source)
        at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.startElement(Unknown Source)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.ValidatingUnmarshaller.startElement(Unknown Source)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
        ... 12 common frames omitted

Spiner Story Format

Ideally I would like Spiner to support all story formats, but realistically EPUB2 is a much more limited format than modern browsers. While EPUB3 might allow a bit more magic through scripting, this would again split the available feature Spiner.

So in essence, users of Spiners must be very careful to only use features that work with Spiner in order to be able to export a good storybook.

Perhaps an idea would be to create a custom story format that limits the amount of available features to what is supported by Spiner. Additionally it could provide some options to simulate how things would look like on an e-reader.


As a result, it is probably better to update Spiners description from "A tool to convert a Twine 2 story into a book." to "A tool-suite to use use Twine 2 as a physical (EPUB/PDF) gamebook authoring tool" (or something along those lines, keyboard being that it now longer converts any Twine 2 story, but rather is a gamebook authoring toolkit).

Support for Java > 8

Running Spiner with any version higher than Java 8 will cause the following error:

Error: Could not find or load main class nl.mikero.spiner.frontend.SpinerApplication
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application

The default version of Java (package default-jre) on Ubuntu 18 is 11, will causes the error.


  • Include JavaFX as a module(https://openjfx.io/). Low impact, since the UI is quite small.
  • Use alternative for JAXB. It's possible to use the legacy modules (low impact). Or switch to an opensource implementation of the jaxb-api (higher impact, but preferable IMO). Potential hard-to-find differences between the implementations.
  • Fix Parboiled. Looks like there is no intent to fix this any time soon: sirthias/parboiled#128. Might want to look into it myself. Alternative would be to find a different library, or manually write a parser.
  • Get unit tests to run (current no tests found under java 11), and fix failing ones if any. Gradle can't find them because of gradle/gradle#5731, when changing source compat they don't run because of troubles with Jacoco.
  • Potentially update Gradle to improve compatibility with Java 11???
    • Update/replace Cucumber plugin, it's not compatible with Gradle 6.0.1
  • Update Mockito
  • Update Jacoco
  • Update Checkstyle

Fix/upgrade SonarQube GitHub Action

Update build.gradle with:

plugins {
  id "org.sonarqube" version "4.2.1.3168"
}

sonar {
  properties {
    property "sonar.projectKey", "mrombout_Spiner"
    property "sonar.organization", "mrombout"
    property "sonar.host.url", "https://sonarcloud.io"
  }
}

Update GitHub actions workflow with something like:

name: SonarCloud
on:
  push:
    branches:
      - develop
  pull_request:
    types: [opened, synchronize, reopened]
jobs:
  build:
    name: Build and analyze
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0  # Shallow clones should be disabled for a better relevancy of analysis
      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          java-version: 11
          distribution: 'zulu' # Alternative distribution options are available
      - name: Cache SonarCloud packages
        uses: actions/cache@v3
        with:
          path: ~/.sonar/cache
          key: ${{ runner.os }}-sonar
          restore-keys: ${{ runner.os }}-sonar
      - name: Cache Gradle packages
        uses: actions/cache@v3
        with:
          path: ~/.gradle/caches
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
          restore-keys: ${{ runner.os }}-gradle
      - name: Build and analyze
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}  # Needed to get PR information, if any
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        run: ./gradlew build sonar --info

Update Spiner to be more flexible when parsing

Right now Spiner fails if the format of the Twine story isn't exactly like Spiner expects (see #42). I think the parser should be a little more lenient and at least ignore attributes that are not mapped. This should make it easier to maintain when Twine makes changes to its output.

Twine links should adhere to linebreaks

Summary

Spiner places all twine links on a the same line even when separated by linebreaks. Instead it should place them in a new line.

[[Enter the cold cave|Page17]]
[[Enter the windy cave|Page8]]
[[Walk up the trail|Page12]]

Expected behaviour

The following markdown syntax in Twine:

[[Enter the cold cave|Page17]]
[[Enter the windy cave|Page8]]
[[Walk up the trail|Page12]]

Should translate to something along the lines of:

<a href="">Enter the cold cave</a><br />
<a href="">Enter the windy cave</a><br />
<a href="">Walk up the trail</a><br />

Actual behaviour:

The example above translates to the following:

<p>
  <a href="">Enter the cold cave</a>
  <a href="">Enter the windy cave</a>
  <a href="">Walk up the trail</a>
</p>

Issue with releasing executables

psiegman/epublib#58

09:13:55.331 [Thread-4] ERROR nl.siegmann.epublib.epub.EpubProcessorSupport - When creating XmlSerializer: org.xmlpull.v1.XmlPullParserException: No valid serializer classes found in resource /META-INF/services/org.xmlpull.v1.XmlPullParserFactory that contained 'org.xmlpull.mxp1.MXParser,org.xmlpull.mxp1_serializer.MXSerializer'
09:13:55.337 [Thread-4] ERROR nl.siegmann.epublib.epub.EpubWriter - Error writing table of contents: java.lang.NullPointerException: null
09:13:55.345 [Thread-4] ERROR nl.siegmann.epublib.epub.EpubProcessorSupport - When creating XmlSerializer: org.xmlpull.v1.XmlPullParserException: No valid serializer classes found in resource /META-INF/services/org.xmlpull.v1.XmlPullParserFactory that contained 'org.xmlpull.mxp1.MXParser,org.xmlpull.mxp1_serializer.MXSerializer'
09:13:55.370 [JavaFX Application Thread] ERROR nl.mikero.spiner.frontend.main.ApplicationView - Could not transform document.
nl.mikero.spiner.core.exception.TwineTransformationFailedException: Could not transform input.
        at nl.mikero.spiner.core.transformer.TransformService.transform(TransformService.java:70)
        at nl.mikero.spiner.frontend.TransformTask.call(TransformTask.java:44)
        at nl.mikero.spiner.frontend.TransformTask.call(TransformTask.java:14)
        at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException: null
        at nl.siegmann.epublib.epub.PackageDocumentWriter.write(PackageDocumentWriter.java:38)
        at nl.siegmann.epublib.epub.EpubWriter.writePackageDocument(EpubWriter.java:112)
        at nl.siegmann.epublib.epub.EpubWriter.write(EpubWriter.java:53)
        at nl.mikero.spiner.core.transformer.epub.TwineStoryEpubTransformer.transform(TwineStoryEpubTransformer.java:157)
        at nl.mikero.spiner.core.transformer.epub.TwineStoryEpubTransformer.transform(TwineStoryEpubTransformer.java:93)
        at nl.mikero.spiner.core.transformer.TransformService.transform(TransformService.java:67)
        ... 5 common frames omitted

Invalid XML character (Unicode: 0x0) (NULL)

Hi,

This might be related to Issue #43 , but when I try to convert a twine file I get the following error message:

[Fatal Error] :14399:69: An invalid XML character (Unicode: 0x0) was found in the element content of the document.
19:53:39.379 [JavaFX Application Thread] ERROR nl.mikero.spiner.frontend.main.ApplicationView - Could not transform document.
nl.mikero.spiner.core.exception.TwineTransformationFailedException: Could not transform input.
at nl.mikero.spiner.core.transformer.TransformService.transform(TransformService.java:70)
at nl.mikero.spiner.frontend.TransformTask.call(TransformTask.java:44)
at nl.mikero.spiner.frontend.TransformTask.call(TransformTask.java:14)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:748)
Caused by: nl.mikero.spiner.core.exception.ExtendTwineXmlTransformFailedException: org.xml.sax.SAXParseException; lineNumber: 14399; columnNumber: 69; An invalid XML character (Unicode: 0x0) was found in the element content of the document.
at nl.mikero.spiner.core.twine.extended.ExtendTwineXmlTransformer.transform(ExtendTwineXmlTransformer.java:51)
at nl.mikero.spiner.core.transformer.TransformService.extend(TransformService.java:99)
at nl.mikero.spiner.core.transformer.TransformService.transform(TransformService.java:63)
... 5 common frames omitted
Caused by: org.xml.sax.SAXParseException: An invalid XML character (Unicode: 0x0) was found in the element content of the document.
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:257)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:121)
at nl.mikero.spiner.core.twine.extended.ExtendTwineXmlTransformer.transform(ExtendTwineXmlTransformer.java:40)

Any idea what might be causing it? The twine .html opens fine but it's possible there are errors in it?

Thanks.

Implement GUI in HTML

Design the GUI of Spiner in HTML. The layout and style do not have to be a complete match as long as it somewhat matches the original design of the Desktop applications.

  • It must work with JavaScript disabled.
  • It must work with JavaScript enabled.
  • Drag-and-drop is optional.
  • Transformation flow must match that of the Desktop application.

Write Dockerfile for Web Spiner

Write a Dockerfile that runs both the API and the GUI and that exposes in on some port. It should be easy to get it up and running with a simpe docker run.

  • Runs both API and GUI
  • Easy to start
  • Easy to use

Automatically prepend/assume file:/// protocol for local images

Currently, due to the way resource are embedded the user is always required to specify a protocol(e.g. http://, file:///). This is quite inconvenient for local images since this has to be prepended by the user manually.

Instead the transformer should automatically prepend the file:/// protocol when no protocol is found.

Embed images declare using HTML `<img />` tag

Images declared using the <img /> from a Twine passage should also be embedded into the EPUB and rewritten to point to that embedded resources.

Currently the embedding is done by a visitor over the flexmark AST, which doesn't get triggered for <img /> tags. Instead perhaps it's better to scan the resulting HTML for <img /> tags instead because at that point everything should be <img /> regardless of how it was included (this may also help when introducing custom inserts like Chapbook.

Add LINEBREAK options to switch between linebreak behaviours

Twine storyformats do not consistently follow the same behaviour to handle newlines. This causes an issue with multiple passage links seperated by a single linebreak (so no white line in between).

See #40 for the original bug report regarding this issue.
See #46 for more information on why Spiner needs this option.

Depends on #49 to provide the options mechanism.

Decide fate on LaTeX transformer

Generally the interest in using LaTeX is much more niche because it's just plain complicated to use. It also requires considerably more post-work to turn it into a nice gamebook. Perhaps it's better to focus on the EPUB transformation only and drop LaTeX.

Nevertheless, with a bit of effort LaTeX is probably capable of creating really nice gamebooks.

Transform to DocBook

At the moment Spiner directly converts to an EPUB by internally converting Twine passages to XHTML and adding them to an EPUB archive in memory before writing in to EPUB. It used to also support LaTeX by building a object model of a LaTeX document writing that to a file.

The problem here is that is requires a lot of very specific code for each format and it takes a bit of effort to find the right abstraction and avoid duplication. The problem with that is that it works off of a Twine XML file and then tries to a new format while at the same time trying to convert formatting.


DocBook is a way to represent the contents of a book in a generic fashion using XML. Then from this XML definition it allows exporting to final formats such as HTML, EPUB and PDF. Apparently it was used by O'Reilly for their publishing work (they are working on HTMLBook now).


Perhaps it's a good idea to update Spiner to generate a DocBook first and generate the the final format as the second step.

Pros

  • One way to represent a book, no need for building a custom object model like I had to for LaTeX to make generation manageable.
  • Only one transformer doing the heavy lifting of converting Twine to DocBook. This will make the transformation for rendering much easier.

Cons

  • DocBook is archaic, using archaic tools (XSL, XST).
  • It will be more difficult to match Twine markup
    • Now we basically go from Markdown to HTML using standard libraries. When using DocBook we go from Markdown to DocBook to HTML and something might get lost in translation.

Display errors during transformation in GUI

Right now when transformation fails the error is only visible in the terminal, no indication is given in the GUI. If an error happens the icon should turn into a cross of warning sign. A snackbar/notification or dialog should tell the user what has failed.

does it work?

I created a quick Twine story and published the file to my desktop. Before doing so, I ran it online and the twine game was fine. I converted it into an ePub with Spiner and it seemed to be fine and downloaded it also to my desktop. But when I tried to open the ePub, it could not open. I tried uploading it to KDP to use the viewer and it could not read it either because it said the file had no content. Please, help.

Add support for "->" style links

Add support for arrow-based links in Twine:

[[Go to the cellar->Cellar]] is a link that goes to a passage named "Cellar".
[[Parachuting<-Jump]] is a link that goes to a passage named "Parachuting".
[[Down the hatch]] is a link that goes to a passage named "Down the hatch".

See https://twine2.neocities.org/#markup_link for more information. This format is supported by at least Harlowe, Snowman and Chapbook story formats.

๐Ÿšจ Look here for better alternatives ๐Ÿ“™

Spiner has not been updated in a while, and in the meantime (or perhaps they were there all along) better solutions have appeared.

  • WritingFantasy is a story format designed for old-school adventure books like Fighting Fantasy series. Use this if you want to play your game in the browser, but still have that old-school feel.
  • Gordian Book converts a Twine story into gamebook as PDF. Use this if you want to create a gamebook for print.
  • PrePub is a Twine proofing format for converting simple stories to a flat (pandoc extended) Markdown file. You can then convert this Markdown file to EPUB, PDF or other formats using Pandoc. Use this if you want to support multiple formats (and have some technical skills).

Support custom options

Using a hidden passage users should be able to pass options to the Spiner transformer. This hidden passage should contain an XML configuration, for example:

<options>
  <linebreaks>true</linebreaks>
  <title>My book</title>
  <cover>mybook.png</cover>
</options>

The main goal for these options is to be able to produce an end result that is as close to the final production as possible. E.g. set a proper cover image for EPUB, etc.

Rewrite

Spiner is outdated and hadn't been maintained for a while. It isn't very user friendly and difficult to run because of it being written in Java. This project should either be rewritten, or archived. If I go for the latter option, I've documented some alternatives in #75.

If I'm going to rewrite this tool I will either use Go because I like it and builds self-contained executables, or JavaScript because it's easy for users to use because it simply runs in the browser. My preference goes to Go because I like that language better, if it can be made to work in the browser with WebAssembly that would be great.

It needs to be a self-contained one-stop shop otherwise the pandoc-based solutions are better to use. That means the parsing needs to happen in the application itself. It needs to create an EPUB3 without the need of external tools. And finally, it order to be user-friendly it needs a story-format that supports everything that the converter does, and no more.

Alternatively, it might be an idea implement a custom story format using paged.js which should be able to create nicely formatted PDFs for print. Turning them into EPUB is not supported by default, though.

Go

A native binary will take in the story and use tweego to parse (will have to fork because most is private/internal). It will then render an EPUB internally and write it to a file.

JavaScript

If I can get this to work client-side (with epub-gen-memory for example and put it in a story format it would be very accessible for people using the Twine UI.

It follow a similar process as prepub. Users must use the custom story format, then when they "play" a web-page is generated with a download button to download the EPUB.

For people using Twee it would probably be a two-step process, use tweego to export, then open browser to generate EPUB. Not ideal, but not too complicated either. For automation, I suppose something like Puppeteer could be used with a node.js based CLI to control it.

Relative resource paths

It should be possible to configure a base_path somewhere. This base_path is used to point to the directory where the resources for a certain story are found. It is then used to resolve relative path for embedding images.

Implement transform Web API

Implement an API with one or two end-points that accept a Twine html file and returns a transformed EPUB or LaTeX file.

  • Directly return converted file
  • Allows transforming to either EPUB
  • Swagger file is defined and exposed.

Automated releases

JavaFX requires target host machine to build native executables.

  • Windows
    • Visual Studio Online?
  • macOS (also needs feature testing since I don't have regular access to a mac)
    • Travis
  • Linux
    • Travis

Replace local JavaFX GUI with web-based version

In order to cut down on the amount of clients to maintain I am considered replacing the JavaFX GUI with the web-based version.

  • It must run locally for people to do not want to upload their story to the cloud.
  • It automatically starts a server in the background on an available port.
  • It automatically starts in the browser (preferred) or a JavaFX WebView.

Replace pegdown with flexmark-java

Pegdown has been deprecated and bugs/tickets aren't being fixed anymore (see their readme). They suggest flexmark-java which apparently is an excellent replacement.

Porting over to pegdown would mean re-implementing any customization (such as the Twine links) and the LaTeX renderer. This can turn out to be quite an endeavor, but it must be done at some point.


Example story with all available Spiner features

  • Create an example story with all available Spiner features
  • Include both the exported story HTML, and the generated EPUB in the repository
  • Include these examples as downloads on the README.md and website
  • Write an oracle test to detect any breaking changes in the future

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.