Skip to content

Commit

Permalink
Deploying to gh-pages from @ 658b5b9 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
lucafabbian committed Jan 25, 2024
0 parents commit dd0ce30
Show file tree
Hide file tree
Showing 100 changed files with 184,413 additions and 0 deletions.
Empty file added .nojekyll
Empty file.
13 changes: 13 additions & 0 deletions .vscode/easycode.ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
node_modules/
dist/
vendor/
cache/
.*/
*.min.*
*.test.*
*.spec.*
*.bundle.*
*.bundle-min.*
*.*.js
*.*.ts
*.log
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"svelte.plugin.svelte.compilerWarnings": {
"unused-export-let": "ignore",
"a11y-click-events-have-key-events": "ignore"
},
}
8 changes: 8 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Copyright 2022 Luca Fabbian

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Magebook web editor
A web editor for gamebook writing. Try last version here: [https://magebook.github.io](https://magebook.github.io)


<img src="https://librogamesland.github.io/magebook/docs/screenshots/1.jpg" alt="magebook screenshot" style="max-width:100%;">



## Usage guide

This file is intended for developer who wants to contribute to Magebook. If you are an user or a write, check the [official guide instead](https://librogamesland.github.io/magebook).

If you are looking for the API or the command line converter, check the [API documentation](https://www.npmjs.com/package/magebook).

## Getting started

Make sure to have git and Node.js installed on your system.

First of all, clone the project from github:
```bash
git clone https://github.com/librogamesland/magebook.git
cd magebook # move inside the directory
```


Setup dependencies.

Optional: keep in mind that we use google chrome to test components. You may skip chrome download and use your local chrome by exporting the following env vars:
```bash
export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
export PUPPETEER_EXECUTABLE_PATH=/usr/bin/google-chrome
```
(replace `/usr/bin/google-chrome` with your local path, on linux you may find it with `whereis google-chrome`)

Finally, install dependencies with:

```
npm i
```


Now you may run:
```bash
npm run dev # start magebook locally with live reload on save
npm run build # prepare for deployment
npm run preview # check if the built version works as expected


npm run docs # start docs server
npm run test # run tests (you need to export PUPPETEER_EXECUTABLE_PATH again)
```

### Deploy on firebase

As explained here: <https://medium.com/@prathampoddar01/deploying-a-vite-app-with-firebase-a-beginners-overview-c4064959353a>

```bash
npm install -g firebase-tools

firebase login
firebase init hosting

# And after npm run build
cd editor
firebase deploy

```

163 changes: 163 additions & 0 deletions dist/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Magebook API
API of the [Magebook editor](https://magebook.github.com/).
<img src="https://librogamesland.github.io/magebook/docs/screenshots/1.jpg" alt="magebook screenshot" style="max-width:100%;">


Magebook provides a command line tool and a javascript ([Node.js](https://nodejs.org/)) api to work with Magebook md format. You can use it to convert book formats, analyze books, or bundle your book inside a web app with [Rollup](https://rollupjs.org/) or [Vite](https://vitejs.dev/).


## Usage

To use the cli tool, install [bun](https://bun.sh/) and run:
```bash
bunx magebook --help
```

Otherwise, install the api as a Node module using `npm install magebook`



## Book indexes
The core feature of this api is an indexing function that generates a js object from a text, with every info about chapters, links and so on.

Book indexes have the following structure:
```javascript
const book = {
text: ... , // Here the full book text will be displayed
index: {
title: 'Book title',
properties: {
author: 'Luca Fabbian',
revision: '1',
},
chapters: [
{
key: '1',
title: '',
group: 'groupname',
flags: ['death'],
lines: {
start: 4,
textStart: 5,
textEnd: 8,
end: 10,
}
links: ['1'], // keys of chapter a user could go from this one
linkedFrom: [0], // index of chapters who are referring the key of this one
}
],

lineStarts: [ 0, 10, ...], // position of starting character of each line

lines: {
titlePageEnd: 3, // last line of the title page
end: 10, // last line of the book
}

// default mapping for links
keys: {
'1': 0, // means that the chapter with index 0 is the default chapter with key 1
},


chaptersWith: {
key: {
'1': [0],
}
groups: {
'groupname': [0],
}
flag: {
'death': [0],
}
}
},

content: {
titlePage,
chapters: [
{
text: ... // full text of the chapter
content: .... // just the content, purified by everything else
}
]
}
}

```

Thanks to book indexes, everything may be obtained in constant time without iterating the entire chapter array.

Some examples:
```javascript
// get all the link of chapter with key 1

book.index.chapters[book.index.keys['1']].links

```

#### Encode/decode formats
Magebook is able to create a markdown text from other formats and then convert this text into html, docx, fodt, etc.
```javascript
import {md, xlgc, fodt, docx, html, json } from 'magebook'


const test = `
# My Book
author: Luca Fabbian
### 1
Welcome`



// Or get the md file from another format
// const lgcBook = xlgc.decode(text)

// Write to fodt file
fs.writeFileSync('example.fodt', fodt.encode(data).encodedBook)


```


#### Rollup plugin

THIS FEATURE IS CURRENTLY UNDER REVISION
To import a `.md` file inside a javascript code, you need a bundler. Magebook includes a rollup plugin already configured for that. It will read the book and transpile it to a standard format book (like above).

You can set the `trasform` option to encode markdown to html on the fly.

Example:
```javascript
import { rollupMagebook, encodeChapter, textToHtml, htmlToText } from 'magebook';


// Set custom magebook parser
const magebookPlugin = rollupMagebook({
transform: (key, chapter, book) => ({
title: chapter.title,
text: encodeChapter(chapter.text, {
html: text => textToHtml(text),
paragraph: text => `${text}<br>`,
strong: text => `<b>${text}</b>`,
em: text => `<i>${text}</i>`,
codespan: text => htmlToText(text),
code: (code) => code,
link: (href,i, text) => `<mage-link to="${href.replace('#', '')}">` +
(text || book.chapters[href.replace('#', '')].title || href.replace('#', '')) +
`</mage-link>`
}),
})
})


export default {
// Put here your rollup config
plugins: [
magebookPlugin
]
}

```
118 changes: 118 additions & 0 deletions dist/bin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#!/usr/bin/env bun
'use strict';
import fs from 'fs'
import packageJson from './package.json' assert { type: "json" };
import { getTextOfRemoteBook,
md, xlgc, docx, json, fodt, html } from './index.js'

const helpMsg = `=== Magebook converter v.${packageJson.version}===
Usage:
magebook-converter <input> <output>
Options:
-h, --help output usage information
-V, --version output the version number
Supported inputs/outputs:
urls: any url including a #fsession= parameter
files: any file name
--: stdin/stdout. Specify an extension after to force format.
Examples:
magebook book.md book.docx # Convert book.md to book.docx
magebook book.md --.json # Convert book.md to json and print to stdout
`

for (let j = 2; j < process.argv.length; j++) {
if(process.argv[j] === '-h' || process.argv[j] === '--help'){
console.log(helpMsg);
process.exit(0);
}
if(process.argv[j] === '-V' || process.argv[j] === '--version'){
console.log(packageJson.version);
process.exit(0);
}
}

const fatal = (message) => {
console.error(message);
process.exit(1);
};

if(process.argv.length < 4) fatal('Error: specify at least 2 arguments');



const inputExtensions = {
'magebook': md,
'md': md,
'xlgc': xlgc,
}

const outputExtensions = {
'magebook': md,
'md': md,
'xlgc': xlgc,
'html': html,
'docx': docx,
'json': json,
'fodt': fodt,
}

const readStdin = () => new Promise((resolve, reject) => {
process.stdin.setEncoding('utf8');
let input = '';
process.stdin.on('data', (chunk) => {input += chunk; });
process.stdin.on('end', () => { resolve(input); });
process.stdin.on('error', (err) => { reject(err); });
})

const magebookOrExtension = (input) => {
const lastIndex = input.lastIndexOf('.');
if(lastIndex === -1) return 'magebook';
return input.substring(lastIndex + 1);
}

const getInput = () => {
const input = process.argv[2];
if(input.startsWith('--')) return [magebookOrExtension(input), () => readStdin()]
if(input.includes('#fsession=')) return ['magebook', () => getTextOfRemoteBook(input)]

const lastIndex = input.lastIndexOf('.');
if(lastIndex === -1) fatal(`Error: input file "${input}" has no extension`);
return [input.substring(lastIndex + 1), () => fs.readFileSync(input, 'utf8')]
}

const getOutput = () => {
const output = process.argv[3]
if(output.startsWith('--')) return [magebookOrExtension(output), (text) => process.stdout.write(text)]
if(output.includes('#fsession=')) fatal(`Error: urls are unsupported as output format`);

const lastIndex = output.lastIndexOf('.');
if(lastIndex === -1) fatal(`Error: output file "${output}" has no extension`);
return [output.substring(lastIndex + 1), (text) => fs.writeFileSync(output, text)]


}


(async () => {
const [inputExtension, readInput] = getInput();
const [outputExtension, writeOutput] = getOutput();

if(!(inputExtension in inputExtensions )) fatal(`Error: unsupported input format: ${inputExtension}`);
if(!(outputExtension in outputExtensions)) fatal(`Error: unsupported output format: ${outputExtension}`);

const text = await Promise.resolve(readInput())
if(inputExtension === outputExtension){
writeOutput(text);
return
}

const {encodedBook} = outputExtensions[outputExtension].encode(inputExtensions[inputExtension].decode(text))
writeOutput(encodedBook)

})()
Loading

0 comments on commit dd0ce30

Please sign in to comment.