Skip to content

Commit

Permalink
Merge pull request #20 from Praxxian/dev_19_v10
Browse files Browse the repository at this point in the history
Dev 19 v10
  • Loading branch information
Praxxian authored Dec 30, 2022
2 parents 752f252 + 6961960 commit 228447e
Show file tree
Hide file tree
Showing 34 changed files with 20,316 additions and 424 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
24 changes: 24 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": ["standard-with-typescript", "prettier", "@typhonjs-fvtt/eslint-config-foundry.js"],
"overrides": [],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module",
"project": ["./tsconfig.json"]
},
"rules": {
"no-var": "warn",
"prefer-const": [
"warn",
{
"destructuring": "any",
"ignoreReadBeforeAssign": false
}
],
"prefer-template": "warn"
}
}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
*.zip
node_modules/
dist/
bundle/
6 changes: 6 additions & 0 deletions .prettierrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
semi: true,
trailingComma: 'all',
singleQuote: true,
printWidth: 120,
};
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Lava Flow

## Release 2.0.0 (2022-09-05)

- Added changelog
- Updated codebase to Typescript
- Foundry v10 compatibility
36 changes: 25 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# Lava Flow
This module allows you to import your notes from Obsidian MD into Foundry journal entries.

## V10
This module is not yet compatible with the Journal changes in v10. It is a [known issue](https://github.com/Praxxian/lava-flow/issues/19). I hope to fix this very soon!
This module allows you to import your notes from Obsidian MD into Foundry journal entries.

## Features

- Select your whole vault or even just one folder within it. Or even just any folder with .md files.
- Uses [showdown](https://github.com/showdownjs/showdown) to convert markdown to HTML.
- Replaces Obsidian links with journal entry links in Foundry.
- Overwrite or ignore existing journal entries.
- Give your players permission to observe all notes or not during import.
Expand All @@ -16,29 +14,45 @@ This module is not yet compatible with the Journal changes in v10. It is a [know
- All created folders have the flag "lavaFlowFolder" and likewise journal entries will have the flag "lavaFlowJournalEntry".

## How to Use

1. Under the Journal tab, there is an "Import Obsidian Vault" button.\
![image](https://user-images.githubusercontent.com/54974037/146979663-d754caeb-df13-454c-8b2a-00ecce5ff8a4.png)
![image](https://user-images.githubusercontent.com/54974037/146979663-d754caeb-df13-454c-8b2a-00ecce5ff8a4.png)
1. Click this to open the import menu.\
![image](https://user-images.githubusercontent.com/54974037/153740928-d2f8f780-1496-4bd9-808a-97d94b982eb3.png)
![image](https://user-images.githubusercontent.com/54974037/153740928-d2f8f780-1496-4bd9-808a-97d94b982eb3.png)
1. Name the top journal folder you wish to place your notes in. If this folder does not already exist, it will be created. Leaving this blank will place your notes directly into your journal entries.
1. Select the folder you wish to import. This can be any folder within your vault, including the root, or any folder with markdown files.
1. Select if you wish to overwrite journal entries that already exist with the same name in the same folder.
- (Optional) If you do not wish to overwrite existing journal entries, you can choose to skip duplicates.
- (Optional) If you do not wish to overwrite existing journal entries, you can choose to skip duplicates.
1. Select if all players should have the [Observer](https://foundryvtt.com/article/users/) permission on the notes that get imported.
1. Select if you wish to create an Index journal entry. This lists links to every imported entry, organized by their top-level folder.\
![image](https://user-images.githubusercontent.com/54974037/146980929-400ce499-c352-47a1-890a-5f3ae574b8d3.png)
![image](https://user-images.githubusercontent.com/54974037/146980929-400ce499-c352-47a1-890a-5f3ae574b8d3.png)
1. Select if you wish to create backlinks in each imported journal entry. This creates a "Reference" section to the end of each journal entry, linking to all the journal entries that reference it.\
![image](https://user-images.githubusercontent.com/54974037/146981259-6755cb58-a4d6-4df6-9473-8ad8c5914182.png)
![image](https://user-images.githubusercontent.com/54974037/146981259-6755cb58-a4d6-4df6-9473-8ad8c5914182.png)
1. If you want to import images, select "Import non-markdown files". By default, this uses local storage, you can also select S3 storage.

## Known Issues

- Folder depth is limited to Foundry's folder depth limit.
- Desktop app only: the version of Electron used in v9 has a [bug](https://github.com/electron/electron/issues/31663) with webkitdirectory, meaning the import function does not work in the desktop app. Easy workaround: access your instance through your web browser instead by going to http://localhost:30000/ while the desktop app is running.
- Obsidian Canvas files are not supported. These will be ignored.
- Not all Obsidian markdown is supported in Foundry.
- Callouts are formatted as block quotes.
- Code blocks work, but do not have syntax highlighting.
- Comments
- Diagrams
- Embeds
- Footnotes
- Highlighting
- Resizing images
- Obsidian URI links: you should not need these anyway since you would not want to link from the Foundry server's file system. Us normal `[[Links]]`.
- Math using Mathjax.
- Tasks are formatted as lists with `[x]` instead of checkboxes. Still readable, but not as clean.

## License

Lava Flow is released under the MIT License.

## Contact

The best place to track bugs is to create a [new issue](https://github.com/Praxxian/lava-flow/issues/new).

For other questions, I am on Discord as @praxis#2944.
For other questions, I am on both the Obsidian and FoundryVTT Discord as @praxis#2944.
File renamed without changes.
229 changes: 229 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
const gulp = require('gulp');
const path = require('path');
var fs = require('fs');
const del = require('del');
const ts = require('gulp-typescript');
const sm = require('gulp-sourcemaps');
const zip = require('gulp-zip');
const rename = require('gulp-rename');
const minify = require('gulp-minify');
const tabify = require('gulp-tabify');
const stringify = require('json-stringify-pretty-compact');

const GLOB = '**/*';
const DIST = 'dist/';
const BUNDLE = 'bundle/';
const SOURCE = 'src/';
const LANG = 'lang/';
const TEMPLATES = 'templates/';
const CSS = 'css/';

var PACKAGE = JSON.parse(fs.readFileSync('package.json'));
function reloadPackage(cb) {
PACKAGE = JSON.parse(fs.readFileSync('package.json'));
cb();
}
function DEV_DIST() {
return path.join(PACKAGE.devDir, PACKAGE.name) + '/';
}

String.prototype.replaceAll = function (pattern, replace) {
return this.split(pattern).join(replace);
};
function pdel(patterns, options) {
return () => {
return del(patterns, options);
};
}
function plog(message) {
return (cb) => {
console.log(message);
cb();
};
}

/**
* Compile the source code into the distribution directory
* @param {Boolean} keepSources Include the TypeScript SourceMaps
*/
function buildSource(keepSources, minifySources = false, output = null) {
return () => {
var stream = gulp.src(SOURCE + GLOB);
if (keepSources) stream = stream.pipe(sm.init());
stream = stream.pipe(ts.createProject('tsconfig.json')());
if (keepSources) stream = stream.pipe(sm.write());
if (minifySources)
stream = stream.pipe(
minify({
ext: { min: '.js' },
mangle: false,
noSource: true,
}),
);
else stream = stream.pipe(tabify(4, false));
return stream.pipe(gulp.dest((output || DIST) + SOURCE));
};
}
exports.step_buildSourceDev = buildSource(true);
exports.step_buildSource = buildSource(false);
exports.step_buildSourceMin = buildSource(false, true);

/**
* Builds the module manifest based on the package, sources, and css.
*/
function buildManifest(output = null) {
const files = []; // Collector for all the file paths
return (cb) =>
gulp
.src(PACKAGE.main) // collect the source files
.pipe(rename({ extname: '.js' })) // rename their extensions to `.js`
.pipe(gulp.src(CSS + GLOB)) // grab all the CSS files
.on('data', (file) => files.push(path.relative(file.cwd, file.path))) // Collect all the file paths
.on('end', () => {
// output the filepaths to the module.json
if (files.length == 0) throw Error('No files found in ' + SOURCE + GLOB + ' or ' + CSS + GLOB);
const js = files.filter((e) => e.endsWith('js')); // split the CSS and JS files
const css = files.filter((e) => e.endsWith('css'));
fs.readFile('module.json', (err, data) => {
const module = data
.toString() // Inject the data into the module.json
.replaceAll('{{name}}', PACKAGE.name)
.replaceAll('{{title}}', PACKAGE.title)
.replaceAll('{{version}}', PACKAGE.version)
.replaceAll('{{description}}', PACKAGE.description)
.replace('"{{sources}}"', stringify(js, null, '\t').replaceAll('\n', '\n\t'))
.replace('"{{css}}"', stringify(css, null, '\t').replaceAll('\n', '\n\t'));
fs.writeFile((output || DIST) + 'module.json', module, cb); // save the module to the distribution directory
});
});
}
exports.step_buildManifest = buildManifest();

function outputLanguages(output = null) {
return () => gulp.src(LANG + GLOB).pipe(gulp.dest((output || DIST) + LANG));
}
function outputTemplates(output = null) {
return () => gulp.src(TEMPLATES + GLOB).pipe(gulp.dest((output || DIST) + TEMPLATES));
}
function outputStylesCSS(output = null) {
return () => gulp.src(CSS + GLOB).pipe(gulp.dest((output || DIST) + CSS));
}
function outputMetaFiles(output = null) {
return () => gulp.src(['LICENSE', 'README.md', 'CHANGELOG.md']).pipe(gulp.dest(output || DIST));
}

/**
* Copy files to module named directory and then compress that folder into a zip
*/
function compressDistribution() {
return gulp.series(
// Copy files to folder with module's name
() => gulp.src(DIST + GLOB).pipe(gulp.dest(DIST + `${PACKAGE.name}/${PACKAGE.name}`)),
// Compress the new folder into a ZIP and save it to the `bundle` folder
() =>
gulp
.src(DIST + PACKAGE.name + '/' + GLOB)
.pipe(zip(PACKAGE.name + '.zip'))
.pipe(gulp.dest(BUNDLE)),
// Copy the module.json to the bundle directory
() => gulp.src(DIST + '/module.json').pipe(gulp.dest(BUNDLE)),
// Cleanup by deleting the intermediate module named folder
pdel(DIST + PACKAGE.name),
);
}
exports.step_compressDistribution = compressDistribution();

/**
* Simple clean command
*/
exports.clean = pdel([DIST, BUNDLE]);
exports.devClean = pdel([DEV_DIST()]);
/**
* Default Build operation
*/
exports.default = gulp.series(
pdel([DIST]),
gulp.parallel(
buildSource(true, false),
buildManifest(),
outputLanguages(),
outputTemplates(),
outputStylesCSS(),
outputMetaFiles(),
),
);
/**
* Extends the default build task by copying the result to the Development Environment
*/
exports.dev = gulp.series(
pdel([DEV_DIST() + GLOB], { force: true }),
gulp.parallel(
buildSource(true, false, DEV_DIST()),
buildManifest(DEV_DIST()),
outputLanguages(DEV_DIST()),
outputTemplates(DEV_DIST()),
outputStylesCSS(DEV_DIST()),
outputMetaFiles(DEV_DIST()),
),
);
/**
* Performs a default build and then zips the result into a bundle
*/
exports.zip = gulp.series(
pdel([DIST]),
gulp.parallel(
buildSource(false, false),
buildManifest(),
outputLanguages(),
outputTemplates(),
outputStylesCSS(),
outputMetaFiles(),
),
compressDistribution(),
pdel([DIST]),
);
/**
* Sets up a file watch on the project to detect any file changes and automatically rebuild those components.
*/
exports.watch = function () {
exports.default();
gulp.watch(SOURCE + GLOB, gulp.series(pdel(DIST + SOURCE), buildSource(true, false)));
gulp.watch([CSS + GLOB, 'module.json', 'package.json'], buildManifest());
gulp.watch(LANG + GLOB, gulp.series(pdel(DIST + LANG), outputLanguages()));
gulp.watch(TEMPLATES + GLOB, gulp.series(pdel(DIST + TEMPLATES), outputTemplates()));
gulp.watch(CSS + GLOB, gulp.series(pdel(DIST + CSS), outputStylesCSS()));
gulp.watch(['LICENSE', 'README.md', 'CHANGELOG.md'], outputMetaFiles());
};
/**
* Sets up a file watch on the project to detect any file changes and automatically rebuild those components, and then copy them to the Development Environment.
*/
exports.devWatch = function () {
const devDist = DEV_DIST();
exports.dev();
gulp.watch(
SOURCE + GLOB,
gulp.series(
plog('deleting: ' + devDist + SOURCE + GLOB),
pdel(devDist + SOURCE + GLOB, { force: true }),
buildSource(true, false, devDist),
plog('sources done.'),
),
);
gulp.watch(
[CSS + GLOB, 'module.json', 'package.json'],
gulp.series(reloadPackage, buildManifest(devDist), plog('manifest done.')),
);
gulp.watch(
LANG + GLOB,
gulp.series(pdel(devDist + LANG + GLOB, { force: true }), outputLanguages(devDist), plog('langs done.')),
);
gulp.watch(
TEMPLATES + GLOB,
gulp.series(pdel(devDist + TEMPLATES + GLOB, { force: true }), outputTemplates(devDist), plog('templates done.')),
);
gulp.watch(
CSS + GLOB,
gulp.series(pdel(devDist + CSS + GLOB, { force: true }), outputStylesCSS(devDist), plog('css done.')),
);
gulp.watch(['LICENSE', 'README.md', 'CHANGELOG.md'], gulp.series(outputMetaFiles(devDist), plog('metas done.')));
};
8 changes: 4 additions & 4 deletions lang/en.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"LAVA-FLOW":{
"button-label": "Import Obsidian Vault"
}
}
"LAVA-FLOW": {
"button-label": "Import Obsidian Vault"
}
}
35 changes: 18 additions & 17 deletions module.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
{
"name": "lava-flow",
"title": "Lava Flow",
"description": "A module for importing Obsidian MD vaults into Foundry VTT as journal entries.",
"author": "Chase Burke",
"version": "1.1.2",
"minimumCoreVersion": "0.8.8",
"compatibleCoreVersion": "9",
"scripts": ["scripts/js/showdown.min.js", "scripts/js/lava-flow.js"],
"languages": [
"name": "{{name}}",
"title": "{{title}}",
"description": "{{description}}",
"version": "{{version}}",
"authors": [
{
"lang": "en",
"name": "English",
"path": "lang/en.json"
"name": "Chase Burke"
}
],
"styles": ["styles/lava-flow.css"],
"readme": "README.md",
"license": "https://opensource.org/licenses/MIT",
"compatibility": {
"minimum": "10",
"verified": "10"
},
"esmodules": "{{sources}}",
"styles": "{{css}}",
"languages": [{ "lang": "en", "name": "English", "path": "lang/en.json" }],
"url": "https://github.com/Praxxian/lava-flow",
"manifest": "https://github.com/Praxxian/lava-flow/releases/download/1.1.2/module.json",
"download": "https://github.com/Praxxian/lava-flow/releases/download/1.1.2/lava-flow.zip"
"license": "https://github.com/Praxxian/lava-flow/LICENSE",
"manifest": "https://github.com/Praxxian/lava-flow/bundle/module.json",
"download": "https://github.com/Praxxian/lava-flow/bundle/{{name}}.zip",
"readme": "https://github.com/Praxxian/lava-flow/README.md",
"changelog": "https://github.com/Praxxian/lava-flow/CHANGELOG.md"
}
Loading

0 comments on commit 228447e

Please sign in to comment.