cyclops-infobook-html 4.0.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/generate-infobook-html.js +1 -1
- package/lib/infobook/FileWriter.d.ts +1 -1
- package/lib/infobook/FileWriter.js +13 -6
- package/lib/infobook/IFileWriter.d.ts +1 -1
- package/lib/infobook/IInfoAppendix.d.ts +1 -1
- package/lib/infobook/appendix/InfoBookAppendixAd.d.ts +1 -1
- package/lib/infobook/appendix/InfoBookAppendixAd.js +4 -1
- package/lib/infobook/appendix/InfoBookAppendixHandlerAbstractRecipe.d.ts +1 -1
- package/lib/infobook/appendix/InfoBookAppendixHandlerAbstractRecipe.js +4 -3
- package/lib/infobook/appendix/InfoBookAppendixHandlerAdvancementRewards.js +5 -4
- package/lib/infobook/appendix/InfoBookAppendixHandlerCraftingRecipe.d.ts +1 -1
- package/lib/infobook/appendix/InfoBookAppendixHandlerCraftingRecipe.js +30 -27
- package/lib/infobook/appendix/InfoBookAppendixHandlerImage.js +4 -3
- package/lib/infobook/appendix/InfoBookAppendixHandlerKeybinding.js +3 -2
- package/lib/infobook/appendix/InfoBookAppendixHandlerSmeltingRecipe.d.ts +1 -1
- package/lib/infobook/appendix/InfoBookAppendixHandlerSmeltingRecipe.js +7 -4
- package/lib/infobook/appendix/InfoBookAppendixHandlerTextfield.js +3 -2
- package/lib/infobook/appendix/InfoBookAppendixTagIndex.d.ts +1 -1
- package/lib/infobook/appendix/InfoBookAppendixTagIndex.js +22 -19
- package/lib/parse/XmlInfoBookParser.js +1 -1
- package/lib/resource/ResourceHandler.d.ts +2 -1
- package/lib/resource/ResourceHandler.js +6 -2
- package/lib/resource/ResourceLoader.d.ts +5 -5
- package/lib/resource/ResourceLoader.js +11 -10
- package/lib/serialize/HtmlInfoBookSerializer.d.ts +2 -2
- package/lib/serialize/HtmlInfoBookSerializer.js +46 -38
- package/package.json +1 -1
- package/CHANGELOG.md +0 -83
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@ If you want to re-download the mods without re-installing Forge, you can run `ge
|
|
|
64
64
|
|
|
65
65
|
### 2. Icon Generation
|
|
66
66
|
|
|
67
|
-
This phase should be done using the [
|
|
67
|
+
This phase should be done using the [Icon Exporter mod](https://github.com/CyclopsMC/IconExporter).
|
|
68
68
|
|
|
69
69
|
Simply create a modpack with all the mods that were downloaded in the previous step (including the Item Exporter mod),
|
|
70
70
|
start a world, and run the `/iconexporter export 64` command.
|
|
@@ -54,7 +54,7 @@ function create() {
|
|
|
54
54
|
yield resourceLoader.loadItemTranslationKeys('registries');
|
|
55
55
|
yield resourceLoader.loadFluidTranslationKeys('registries');
|
|
56
56
|
yield resourceLoader.loadKeybindings(config.keybindings);
|
|
57
|
-
yield resourceLoader.loadAll(process.cwd(), 'mod_assets');
|
|
57
|
+
yield resourceLoader.loadAll(process.cwd(), 'mod_assets', config.excludedModLanguages || []);
|
|
58
58
|
// Setup infobook loader
|
|
59
59
|
const infoBookInitializer = new InfoBookInitializer_1.InfoBookInitializer(config);
|
|
60
60
|
infoBookInitializer.registerAppendixHandler('advancement_rewards', new InfoBookAppendixHandlerAdvancementRewards_1.InfoBookAppendixHandlerAdvancementRewards(resourceLoader.getResourceHandler()));
|
|
@@ -9,5 +9,5 @@ export declare class FileWriter implements IFileWriter {
|
|
|
9
9
|
private readonly context;
|
|
10
10
|
private readonly writtenFiles;
|
|
11
11
|
constructor(context: ISerializeContext);
|
|
12
|
-
write(baseName: string, contents: Readable): string
|
|
12
|
+
write(baseName: string, contents: () => Readable): Promise<string>;
|
|
13
13
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FileWriter = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const fs_1 = require("fs");
|
|
5
6
|
const path_1 = require("path");
|
|
6
7
|
/**
|
|
@@ -12,12 +13,18 @@ class FileWriter {
|
|
|
12
13
|
this.writtenFiles = {};
|
|
13
14
|
}
|
|
14
15
|
write(baseName, contents) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
// Don't write the file if it has been written before
|
|
18
|
+
if (!this.writtenFiles[baseName]) {
|
|
19
|
+
const eventEmitter = contents().pipe(fs_1.createWriteStream(path_1.join(this.context.basePath, 'assets', baseName)));
|
|
20
|
+
this.writtenFiles[baseName] = true;
|
|
21
|
+
yield new Promise((resolve, reject) => {
|
|
22
|
+
eventEmitter.on('finish', resolve);
|
|
23
|
+
eventEmitter.on('error', reject);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return this.context.baseUrl + 'assets/' + baseName;
|
|
27
|
+
});
|
|
21
28
|
}
|
|
22
29
|
}
|
|
23
30
|
exports.FileWriter = FileWriter;
|
|
@@ -10,5 +10,5 @@ export interface IFileWriter {
|
|
|
10
10
|
* @param {"stream".internal.Readable} contents A stream of contents to write.
|
|
11
11
|
* @returns {string} The file path in the output, relative to the output root.
|
|
12
12
|
*/
|
|
13
|
-
write(baseName: string, contents: Readable): string
|
|
13
|
+
write(baseName: string, contents: () => Readable): Promise<string>;
|
|
14
14
|
}
|
|
@@ -19,5 +19,5 @@ export interface IInfoAppendix {
|
|
|
19
19
|
* @param serializer The HTML serializer.
|
|
20
20
|
* @returns {string} The HTML representation of this appendix.
|
|
21
21
|
*/
|
|
22
|
-
toHtml(context: ISerializeContext, fileWriter: IFileWriter, serializer: HtmlInfoBookSerializer): string
|
|
22
|
+
toHtml(context: ISerializeContext, fileWriter: IFileWriter, serializer: HtmlInfoBookSerializer): Promise<string>;
|
|
23
23
|
}
|
|
@@ -8,5 +8,5 @@ export declare class InfoBookAppendixAd implements IInfoAppendix {
|
|
|
8
8
|
readonly skipWrapper: boolean;
|
|
9
9
|
private readonly templateTagIndex;
|
|
10
10
|
constructor();
|
|
11
|
-
toHtml(context: ISerializeContext, fileWriter: IFileWriter, serializer: HtmlInfoBookSerializer): string
|
|
11
|
+
toHtml(context: ISerializeContext, fileWriter: IFileWriter, serializer: HtmlInfoBookSerializer): Promise<string>;
|
|
12
12
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InfoBookAppendixAd = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const pug_1 = require("pug");
|
|
5
6
|
/**
|
|
6
7
|
* An appendix with an add
|
|
@@ -11,7 +12,9 @@ class InfoBookAppendixAd {
|
|
|
11
12
|
this.templateTagIndex = pug_1.compileFile(__dirname + '/../../../template/appendix/ad.pug');
|
|
12
13
|
}
|
|
13
14
|
toHtml(context, fileWriter, serializer) {
|
|
14
|
-
return
|
|
15
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
return this.templateTagIndex(context.googleAdsense);
|
|
17
|
+
});
|
|
15
18
|
}
|
|
16
19
|
}
|
|
17
20
|
exports.InfoBookAppendixAd = InfoBookAppendixAd;
|
|
@@ -14,7 +14,7 @@ export declare abstract class InfoBookAppendixHandlerAbstractRecipe<R extends IR
|
|
|
14
14
|
static indexRegistry<R extends IRecipe>(registryRead: IRecipeRegistryRead<R>): IRecipeRegistryIndexed<R>;
|
|
15
15
|
createAppendix(data: any): IInfoAppendix;
|
|
16
16
|
protected abstract getRecipeNameUnlocalized(): string;
|
|
17
|
-
protected abstract serializeRecipe(recipe: R, context: ISerializeContext, fileWriter: IFileWriter, serializer: HtmlInfoBookSerializer): string
|
|
17
|
+
protected abstract serializeRecipe(recipe: R, context: ISerializeContext, fileWriter: IFileWriter, serializer: HtmlInfoBookSerializer): Promise<string>;
|
|
18
18
|
}
|
|
19
19
|
export interface IRecipeRegistryRead<R extends IRecipe> {
|
|
20
20
|
recipes: [R];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InfoBookAppendixHandlerAbstractRecipe = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const fs = require("fs");
|
|
5
6
|
const path_1 = require("path");
|
|
6
7
|
/**
|
|
@@ -41,9 +42,9 @@ class InfoBookAppendixHandlerAbstractRecipe {
|
|
|
41
42
|
}
|
|
42
43
|
return {
|
|
43
44
|
getName: (context) => this.resourceHandler.getTranslation(this.getRecipeNameUnlocalized(), context.language),
|
|
44
|
-
toHtml: (context, fileWriter, serializer) => {
|
|
45
|
-
return recipes.map((recipe) => this.serializeRecipe(recipe, context, fileWriter, serializer)).join('<hr />');
|
|
46
|
-
},
|
|
45
|
+
toHtml: (context, fileWriter, serializer) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
46
|
+
return (yield Promise.all(recipes.map((recipe) => this.serializeRecipe(recipe, context, fileWriter, serializer)))).join('<hr />');
|
|
47
|
+
}),
|
|
47
48
|
};
|
|
48
49
|
}
|
|
49
50
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InfoBookAppendixHandlerAdvancementRewards = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const pug_1 = require("pug");
|
|
5
6
|
/**
|
|
6
7
|
* Handles advancement rewards appendices.
|
|
@@ -26,17 +27,17 @@ class InfoBookAppendixHandlerAdvancementRewards {
|
|
|
26
27
|
}
|
|
27
28
|
return {
|
|
28
29
|
getName: (context) => this.resourceHandler.getTranslation('gui.advancements', context.language),
|
|
29
|
-
toHtml: (context, fileWriter, serializer) => {
|
|
30
|
+
toHtml: (context, fileWriter, serializer) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
30
31
|
const advancements = advancementsData
|
|
31
32
|
.map((advancement) => ({
|
|
32
33
|
description: this.resourceHandler.getTranslation(advancement.description, context.language),
|
|
33
34
|
title: this.resourceHandler.getTranslation(advancement.title, context.language),
|
|
34
35
|
}));
|
|
35
|
-
const rewards = rewardsData
|
|
36
|
-
.map((reward) => serializer.createItemDisplay(this.resourceHandler, context, fileWriter, reward, true));
|
|
36
|
+
const rewards = yield Promise.all(rewardsData
|
|
37
|
+
.map((reward) => serializer.createItemDisplay(this.resourceHandler, context, fileWriter, reward, true)));
|
|
37
38
|
const rewardsString = this.resourceHandler.getTranslation(`gui.cyclopscore.rewards`, context.language);
|
|
38
39
|
return this.templateAdvancementRewards({ advancements, rewards, rewardsString });
|
|
39
|
-
},
|
|
40
|
+
}),
|
|
40
41
|
};
|
|
41
42
|
}
|
|
42
43
|
}
|
|
@@ -10,7 +10,7 @@ export declare class InfoBookAppendixHandlerCraftingRecipe extends InfoBookAppen
|
|
|
10
10
|
private readonly templateCraftingRecipe;
|
|
11
11
|
constructor(resourceHandler: ResourceHandler, registriesPath: string, recipeOverrides: any);
|
|
12
12
|
protected getRecipeNameUnlocalized(): string;
|
|
13
|
-
protected serializeRecipe(recipe: IRecipeCrafting, context: ISerializeContext, fileWriter: IFileWriter, serializer: HtmlInfoBookSerializer): string
|
|
13
|
+
protected serializeRecipe(recipe: IRecipeCrafting, context: ISerializeContext, fileWriter: IFileWriter, serializer: HtmlInfoBookSerializer): Promise<string>;
|
|
14
14
|
}
|
|
15
15
|
export interface IRecipeCrafting extends IRecipe {
|
|
16
16
|
id: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InfoBookAppendixHandlerCraftingRecipe = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const pug_1 = require("pug");
|
|
5
6
|
const InfoBookAppendixHandlerAbstractRecipe_1 = require("./InfoBookAppendixHandlerAbstractRecipe");
|
|
6
7
|
/**
|
|
@@ -15,35 +16,37 @@ class InfoBookAppendixHandlerCraftingRecipe extends InfoBookAppendixHandlerAbstr
|
|
|
15
16
|
return 'block.minecraft.crafting_table';
|
|
16
17
|
}
|
|
17
18
|
serializeRecipe(recipe, context, fileWriter, serializer) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
recipe.width
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
for (let
|
|
27
|
-
let
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
items.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
19
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
// Prepare input array
|
|
21
|
+
const inputs = "|".repeat(9).split("|").map(() => []);
|
|
22
|
+
// Define custom dimensions for shapeless recipes
|
|
23
|
+
if (!recipe.width || !recipe.height) {
|
|
24
|
+
recipe.width = recipe.height = Math.sqrt(recipe.input.length);
|
|
25
|
+
}
|
|
26
|
+
// Format items in grid
|
|
27
|
+
for (let x = 0; x < 3; x++) {
|
|
28
|
+
for (let y = 0; y < 3; y++) {
|
|
29
|
+
let items;
|
|
30
|
+
if (x < recipe.width && y < recipe.height) {
|
|
31
|
+
const inputIndex = y * recipe.width + x;
|
|
32
|
+
items = recipe.input[inputIndex] || [];
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
items = [];
|
|
36
|
+
}
|
|
37
|
+
if (!items.length) {
|
|
38
|
+
items.push({ item: 'minecraft:air' });
|
|
39
|
+
}
|
|
40
|
+
const outputIndex = y * 3 + x;
|
|
41
|
+
for (const item of items) {
|
|
42
|
+
inputs[outputIndex].push(yield serializer.createItemDisplay(this.resourceHandler, context, fileWriter, item, true));
|
|
43
|
+
}
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
const output = yield serializer.createItemDisplay(this.resourceHandler, context, fileWriter, recipe.output, true);
|
|
47
|
+
const appendixIcon = yield serializer.createItemDisplay(this.resourceHandler, context, fileWriter, { item: 'minecraft:crafting_table' }, false);
|
|
48
|
+
return this.templateCraftingRecipe({ inputs, output, appendixIcon });
|
|
49
|
+
});
|
|
47
50
|
}
|
|
48
51
|
}
|
|
49
52
|
exports.InfoBookAppendixHandlerCraftingRecipe = InfoBookAppendixHandlerCraftingRecipe;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InfoBookAppendixHandlerImage = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const fs_1 = require("fs");
|
|
5
6
|
const path_1 = require("path");
|
|
6
7
|
/**
|
|
@@ -15,10 +16,10 @@ class InfoBookAppendixHandlerImage {
|
|
|
15
16
|
const fileName = path_1.basename(data._);
|
|
16
17
|
const { width, height } = data.$;
|
|
17
18
|
return {
|
|
18
|
-
toHtml: (context, fileWriter) => {
|
|
19
|
-
const writtenPath = fileWriter.write(fileName, fs_1.createReadStream(fullPath));
|
|
19
|
+
toHtml: (context, fileWriter) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
const writtenPath = yield fileWriter.write(fileName, () => fs_1.createReadStream(fullPath));
|
|
20
21
|
return `<canvas class="appendix-image" style="background: url(${writtenPath}); width: ${width * 2}px; height: ${height * 2}px; background-size: 512px 512px;"></canvas>`;
|
|
21
|
-
},
|
|
22
|
+
}),
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
25
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InfoBookAppendixHandlerKeybinding = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const pug_1 = require("pug");
|
|
5
6
|
/**
|
|
6
7
|
* Handles keybindings appendices.
|
|
@@ -15,10 +16,10 @@ class InfoBookAppendixHandlerKeybinding {
|
|
|
15
16
|
const key = this.resourceHandler.getKeybinding(id);
|
|
16
17
|
return {
|
|
17
18
|
getName: (context) => this.resourceHandler.getTranslation(`infobook.cyclopscore.keybinding`, context.language),
|
|
18
|
-
toHtml: (context) => {
|
|
19
|
+
toHtml: (context) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
19
20
|
const name = this.resourceHandler.getTranslation(id, context.language);
|
|
20
21
|
return this.templateKeybinding({ name, key });
|
|
21
|
-
},
|
|
22
|
+
}),
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
25
|
}
|
|
@@ -10,7 +10,7 @@ export declare class InfoBookAppendixHandlerSmeltingRecipe extends InfoBookAppen
|
|
|
10
10
|
private readonly templateFurnaceRecipe;
|
|
11
11
|
constructor(resourceHandler: ResourceHandler, registriesPath: string, recipeOverrides: any);
|
|
12
12
|
protected getRecipeNameUnlocalized(): string;
|
|
13
|
-
protected serializeRecipe(recipe: IRecipeSmelting, context: ISerializeContext, fileWriter: IFileWriter, serializer: HtmlInfoBookSerializer): string
|
|
13
|
+
protected serializeRecipe(recipe: IRecipeSmelting, context: ISerializeContext, fileWriter: IFileWriter, serializer: HtmlInfoBookSerializer): Promise<string>;
|
|
14
14
|
}
|
|
15
15
|
export interface IRecipeSmelting extends IRecipe {
|
|
16
16
|
input: IItem[];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InfoBookAppendixHandlerSmeltingRecipe = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const pug_1 = require("pug");
|
|
5
6
|
const InfoBookAppendixHandlerAbstractRecipe_1 = require("./InfoBookAppendixHandlerAbstractRecipe");
|
|
6
7
|
/**
|
|
@@ -15,10 +16,12 @@ class InfoBookAppendixHandlerSmeltingRecipe extends InfoBookAppendixHandlerAbstr
|
|
|
15
16
|
return 'block.minecraft.furnace';
|
|
16
17
|
}
|
|
17
18
|
serializeRecipe(recipe, context, fileWriter, serializer) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
const input = yield Promise.all(recipe.input.map((item) => serializer.createItemDisplay(this.resourceHandler, context, fileWriter, item, true)));
|
|
21
|
+
const output = yield serializer.createItemDisplay(this.resourceHandler, context, fileWriter, recipe.output, true);
|
|
22
|
+
const appendixIcon = yield serializer.createItemDisplay(this.resourceHandler, context, fileWriter, { item: 'minecraft:furnace' }, false);
|
|
23
|
+
return this.templateFurnaceRecipe({ input, output, appendixIcon });
|
|
24
|
+
});
|
|
22
25
|
}
|
|
23
26
|
}
|
|
24
27
|
exports.InfoBookAppendixHandlerSmeltingRecipe = InfoBookAppendixHandlerSmeltingRecipe;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InfoBookAppendixHandlerTextfield = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
/**
|
|
5
6
|
* Handles text field appendices.
|
|
6
7
|
*/
|
|
@@ -14,9 +15,9 @@ class InfoBookAppendixHandlerTextfield {
|
|
|
14
15
|
.replace(/\n/g, '<br \>');
|
|
15
16
|
const scale = data.$.scale || 1;
|
|
16
17
|
return {
|
|
17
|
-
toHtml: (context, fileWriter) => {
|
|
18
|
+
toHtml: (context, fileWriter) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
18
19
|
return `<div class="appendix-textfield" style="font-size: ${scale}em">${contents}</div>`;
|
|
19
|
-
},
|
|
20
|
+
}),
|
|
20
21
|
};
|
|
21
22
|
}
|
|
22
23
|
}
|
|
@@ -9,5 +9,5 @@ export declare class InfoBookAppendixTagIndex implements IInfoAppendix {
|
|
|
9
9
|
private readonly resourceHandler;
|
|
10
10
|
private readonly templateTagIndex;
|
|
11
11
|
constructor(resourceHandler: ResourceHandler);
|
|
12
|
-
toHtml(context: ISerializeContext, fileWriter: IFileWriter, serializer: HtmlInfoBookSerializer): string
|
|
12
|
+
toHtml(context: ISerializeContext, fileWriter: IFileWriter, serializer: HtmlInfoBookSerializer): Promise<string>;
|
|
13
13
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InfoBookAppendixTagIndex = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const pug_1 = require("pug");
|
|
5
6
|
/**
|
|
6
7
|
* An appendix that lists all tags with links to them
|
|
@@ -11,26 +12,28 @@ class InfoBookAppendixTagIndex {
|
|
|
11
12
|
this.templateTagIndex = pug_1.compileFile(__dirname + '/../../../template/appendix/tag_index.pug');
|
|
12
13
|
}
|
|
13
14
|
toHtml(context, fileWriter, serializer) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
const links = [];
|
|
17
|
+
for (const tag in context.sectionIndex.tags) {
|
|
18
|
+
const url = context.sectionIndex.tags[tag];
|
|
19
|
+
// First try localizing as item, and if that fails, as fluid
|
|
20
|
+
let icon;
|
|
21
|
+
const item = { item: tag };
|
|
22
|
+
let translationKey = this.resourceHandler.getItemTranslationKey(item);
|
|
23
|
+
if (translationKey) {
|
|
24
|
+
icon = yield serializer.createItemDisplay(this.resourceHandler, context, fileWriter, item, false);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const fluid = { fluid: tag };
|
|
28
|
+
translationKey = this.resourceHandler.getFluidTranslationKey(fluid);
|
|
29
|
+
icon = yield serializer.createFluidDisplay(this.resourceHandler, context, fileWriter, fluid, false);
|
|
30
|
+
}
|
|
31
|
+
const name = this.resourceHandler.getTranslation(translationKey, context.language);
|
|
32
|
+
links.push({ url, name, icon });
|
|
23
33
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
icon = serializer.createFluidDisplay(this.resourceHandler, context, fileWriter, fluid, false);
|
|
28
|
-
}
|
|
29
|
-
const name = this.resourceHandler.getTranslation(translationKey, context.language);
|
|
30
|
-
links.push({ url, name, icon });
|
|
31
|
-
}
|
|
32
|
-
links.sort((link1, link2) => link1.name.localeCompare(link2.name));
|
|
33
|
-
return this.templateTagIndex({ links });
|
|
34
|
+
links.sort((link1, link2) => link1.name.localeCompare(link2.name));
|
|
35
|
+
return this.templateTagIndex({ links });
|
|
36
|
+
});
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
exports.InfoBookAppendixTagIndex = InfoBookAppendixTagIndex;
|
|
@@ -65,7 +65,7 @@ class XmlInfoBookParser {
|
|
|
65
65
|
paragraphTranslationKeys: (data.paragraph || []).map((subData) => this.jsonToParagraph(subData)),
|
|
66
66
|
appendix: ((data.appendix || []).concat(data.appendix_list || []))
|
|
67
67
|
.map((subData) => this.jsonToAppendix(subData, modId)),
|
|
68
|
-
tags: data.tag || [],
|
|
68
|
+
tags: (data.tag ? data.tag.filter((entry) => typeof entry === 'string') : undefined) || [],
|
|
69
69
|
modId,
|
|
70
70
|
};
|
|
71
71
|
sections[section.nameTranslationKey] = section;
|
|
@@ -6,6 +6,7 @@ import { IItem } from "../infobook/IItem";
|
|
|
6
6
|
export declare class ResourceHandler {
|
|
7
7
|
private static readonly TRANSLATION_DEFAULTS;
|
|
8
8
|
private readonly translations;
|
|
9
|
+
private readonly languages;
|
|
9
10
|
private readonly resourcePackBasePaths;
|
|
10
11
|
private readonly iconsItem;
|
|
11
12
|
private readonly itemTranslationKeys;
|
|
@@ -49,7 +50,7 @@ export declare class ResourceHandler {
|
|
|
49
50
|
*/
|
|
50
51
|
addTranslations(language: string, translations: {
|
|
51
52
|
[key: string]: string;
|
|
52
|
-
}): void;
|
|
53
|
+
}, excludedModLanguage: boolean): void;
|
|
53
54
|
/**
|
|
54
55
|
* Get the translation for the given key.
|
|
55
56
|
* @param {string} translationKey A translation key.
|
|
@@ -8,6 +8,7 @@ const path_1 = require("path");
|
|
|
8
8
|
class ResourceHandler {
|
|
9
9
|
constructor() {
|
|
10
10
|
this.translations = {};
|
|
11
|
+
this.languages = {};
|
|
11
12
|
this.resourcePackBasePaths = {};
|
|
12
13
|
this.iconsItem = {};
|
|
13
14
|
this.itemTranslationKeys = {};
|
|
@@ -71,14 +72,14 @@ class ResourceHandler {
|
|
|
71
72
|
* @returns {string[]} All available language keys.
|
|
72
73
|
*/
|
|
73
74
|
getLanguages() {
|
|
74
|
-
return Object.keys(this.
|
|
75
|
+
return Object.keys(this.languages);
|
|
75
76
|
}
|
|
76
77
|
/**
|
|
77
78
|
* Add translations for the given language.
|
|
78
79
|
* @param {string} language A language key.
|
|
79
80
|
* @param {{[p: string]: string}} translations A mapping from translation key to translated value.
|
|
80
81
|
*/
|
|
81
|
-
addTranslations(language, translations) {
|
|
82
|
+
addTranslations(language, translations, excludedModLanguage) {
|
|
82
83
|
language = language.toLowerCase();
|
|
83
84
|
const existingTranslations = this.translations[language];
|
|
84
85
|
if (!existingTranslations) {
|
|
@@ -89,6 +90,9 @@ class ResourceHandler {
|
|
|
89
90
|
existingTranslations[key] = translations[key];
|
|
90
91
|
}
|
|
91
92
|
}
|
|
93
|
+
if (!excludedModLanguage && Object.keys(translations).length > 0) {
|
|
94
|
+
this.languages[language] = true;
|
|
95
|
+
}
|
|
92
96
|
}
|
|
93
97
|
/**
|
|
94
98
|
* Get the translation for the given key.
|
|
@@ -33,7 +33,7 @@ export declare class ResourceLoader {
|
|
|
33
33
|
* @param {string[]} paths An array of paths to traverse to look for resources.
|
|
34
34
|
* @returns {Promise<void>} A promise resolving when loading is done.
|
|
35
35
|
*/
|
|
36
|
-
loadAll(baseDir: string, path: string): Promise<void>;
|
|
36
|
+
loadAll(baseDir: string, path: string, excludedModLanguages: string[]): Promise<void>;
|
|
37
37
|
/**
|
|
38
38
|
* Load a resource somewhere within the given path.
|
|
39
39
|
*
|
|
@@ -42,21 +42,21 @@ export declare class ResourceLoader {
|
|
|
42
42
|
* @param {string} fullPath A full path to look in.
|
|
43
43
|
* @returns {Promise<void>} A promise resolving when loading is done.
|
|
44
44
|
*/
|
|
45
|
-
load(fullPath: string): Promise<void>;
|
|
45
|
+
load(fullPath: string, excludedModLanguages: string[]): Promise<void>;
|
|
46
46
|
/**
|
|
47
47
|
* Load the assets of the given pack.
|
|
48
48
|
* @param {string} modid A mod id.
|
|
49
49
|
* @param {string} fullPath The full path of the pack.
|
|
50
50
|
* @returns {Promise<void>} A promise resolving when loading is done.
|
|
51
51
|
*/
|
|
52
|
-
loadAssets(modid: string, fullPath: string): Promise<void>;
|
|
52
|
+
loadAssets(modid: string, fullPath: string, excludedModLanguage: boolean): Promise<void>;
|
|
53
53
|
/**
|
|
54
54
|
* Load the language file within the given language folder.
|
|
55
55
|
* @param {string} modid A mod id.
|
|
56
56
|
* @param {string} langDir The full language directory path.
|
|
57
57
|
* @returns {Promise<void>} A promise resolving when loading is done.
|
|
58
58
|
*/
|
|
59
|
-
loadAssetsLang(modid: string, langDir: string): Promise<void>;
|
|
59
|
+
loadAssetsLang(modid: string, langDir: string, excludedModLanguage: boolean): Promise<void>;
|
|
60
60
|
/**
|
|
61
61
|
* Load a single language file.
|
|
62
62
|
* @param {string} modid A mod id.
|
|
@@ -64,7 +64,7 @@ export declare class ResourceLoader {
|
|
|
64
64
|
* @param {string} fullFilePath The full language file path.
|
|
65
65
|
* @returns {Promise<void>} A promise resolving when loading is done.
|
|
66
66
|
*/
|
|
67
|
-
loadAssetsLangFile(modid: string, language: string, fullFilePath: string): Promise<void>;
|
|
67
|
+
loadAssetsLangFile(modid: string, language: string, fullFilePath: string, excludedModLanguage: boolean): Promise<void>;
|
|
68
68
|
/**
|
|
69
69
|
* Load the advancements within the given folder, recursively.
|
|
70
70
|
* @param {string} modid A mod id.
|
|
@@ -80,9 +80,9 @@ class ResourceLoader {
|
|
|
80
80
|
* @param {string[]} paths An array of paths to traverse to look for resources.
|
|
81
81
|
* @returns {Promise<void>} A promise resolving when loading is done.
|
|
82
82
|
*/
|
|
83
|
-
loadAll(baseDir, path) {
|
|
83
|
+
loadAll(baseDir, path, excludedModLanguages) {
|
|
84
84
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
85
|
-
yield this.load(path_1.join(baseDir, path));
|
|
85
|
+
yield this.load(path_1.join(baseDir, path), excludedModLanguages);
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
@@ -93,14 +93,15 @@ class ResourceLoader {
|
|
|
93
93
|
* @param {string} fullPath A full path to look in.
|
|
94
94
|
* @returns {Promise<void>} A promise resolving when loading is done.
|
|
95
95
|
*/
|
|
96
|
-
load(fullPath) {
|
|
96
|
+
load(fullPath, excludedModLanguages) {
|
|
97
97
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
98
98
|
const entries = yield fs_1.promises.readdir(fullPath);
|
|
99
99
|
// Look for a valid pack
|
|
100
100
|
for (const modid of entries) {
|
|
101
|
+
const excludedModLanguage = excludedModLanguages.includes(modid);
|
|
101
102
|
const modPath = path_1.join(fullPath, modid);
|
|
102
103
|
if ((yield fs_1.promises.stat(modPath)).isDirectory()) {
|
|
103
|
-
yield this.loadAssets(modid, modPath);
|
|
104
|
+
yield this.loadAssets(modid, modPath, excludedModLanguage);
|
|
104
105
|
}
|
|
105
106
|
}
|
|
106
107
|
});
|
|
@@ -111,7 +112,7 @@ class ResourceLoader {
|
|
|
111
112
|
* @param {string} fullPath The full path of the pack.
|
|
112
113
|
* @returns {Promise<void>} A promise resolving when loading is done.
|
|
113
114
|
*/
|
|
114
|
-
loadAssets(modid, fullPath) {
|
|
115
|
+
loadAssets(modid, fullPath, excludedModLanguage) {
|
|
115
116
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
116
117
|
// Set base path
|
|
117
118
|
this.resourceHandler.setResourcePackBasePath(modid, fullPath);
|
|
@@ -119,7 +120,7 @@ class ResourceLoader {
|
|
|
119
120
|
const langDir = path_1.join(fullPath, 'lang');
|
|
120
121
|
try {
|
|
121
122
|
if ((yield fs_1.promises.stat(langDir)).isDirectory()) {
|
|
122
|
-
yield this.loadAssetsLang(modid, langDir);
|
|
123
|
+
yield this.loadAssetsLang(modid, langDir, excludedModLanguage);
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
catch (e) {
|
|
@@ -143,12 +144,12 @@ class ResourceLoader {
|
|
|
143
144
|
* @param {string} langDir The full language directory path.
|
|
144
145
|
* @returns {Promise<void>} A promise resolving when loading is done.
|
|
145
146
|
*/
|
|
146
|
-
loadAssetsLang(modid, langDir) {
|
|
147
|
+
loadAssetsLang(modid, langDir, excludedModLanguage) {
|
|
147
148
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
148
149
|
const entries = yield fs_1.promises.readdir(langDir);
|
|
149
150
|
for (const entry of entries) {
|
|
150
151
|
const language = entry.substring(0, entry.indexOf('.'));
|
|
151
|
-
yield this.loadAssetsLangFile(modid, language, path_1.join(langDir, entry));
|
|
152
|
+
yield this.loadAssetsLangFile(modid, language, path_1.join(langDir, entry), excludedModLanguage);
|
|
152
153
|
}
|
|
153
154
|
});
|
|
154
155
|
}
|
|
@@ -159,10 +160,10 @@ class ResourceLoader {
|
|
|
159
160
|
* @param {string} fullFilePath The full language file path.
|
|
160
161
|
* @returns {Promise<void>} A promise resolving when loading is done.
|
|
161
162
|
*/
|
|
162
|
-
loadAssetsLangFile(modid, language, fullFilePath) {
|
|
163
|
+
loadAssetsLangFile(modid, language, fullFilePath, excludedModLanguage) {
|
|
163
164
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
164
165
|
const translations = JSON.parse((yield fs_1.promises.readFile(fullFilePath)).toString('utf8'));
|
|
165
|
-
this.resourceHandler.addTranslations(language, translations);
|
|
166
|
+
this.resourceHandler.addTranslations(language, translations, excludedModLanguage);
|
|
166
167
|
});
|
|
167
168
|
}
|
|
168
169
|
/**
|
|
@@ -26,8 +26,8 @@ export declare class HtmlInfoBookSerializer {
|
|
|
26
26
|
link: string;
|
|
27
27
|
linkTarget: string;
|
|
28
28
|
};
|
|
29
|
-
createItemDisplay(resourceHandler: ResourceHandler, context: ISerializeContext, fileWriter: IFileWriter, item: IItem, slot: boolean, annotation?: string): string
|
|
30
|
-
createFluidDisplay(resourceHandler: ResourceHandler, context: ISerializeContext, fileWriter: IFileWriter, fluid: IFluid, slot: boolean): string
|
|
29
|
+
createItemDisplay(resourceHandler: ResourceHandler, context: ISerializeContext, fileWriter: IFileWriter, item: IItem, slot: boolean, annotation?: string): Promise<string>;
|
|
30
|
+
createFluidDisplay(resourceHandler: ResourceHandler, context: ISerializeContext, fileWriter: IFileWriter, fluid: IFluid, slot: boolean): Promise<string>;
|
|
31
31
|
tagFluid(context: ISerializeContext, fluidName: string): string;
|
|
32
32
|
getLanguagePath(language: string, path?: string): string;
|
|
33
33
|
/**
|
|
@@ -97,23 +97,26 @@ class HtmlInfoBookSerializer {
|
|
|
97
97
|
if (context.googleAdsense && language === 'en_us') {
|
|
98
98
|
appendices.unshift(new InfoBookAppendixAd_1.InfoBookAppendixAd());
|
|
99
99
|
}
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
.filter((appendix) => appendix) // TODO: rm
|
|
105
|
-
.map((appendix) => {
|
|
106
|
-
const appendixContents = appendix.toHtml(context, this.fileWriter, this);
|
|
100
|
+
const sectionAppendices = [];
|
|
101
|
+
for (const appendix of appendices) {
|
|
102
|
+
if (appendix) {
|
|
103
|
+
const appendixContents = yield appendix.toHtml(context, this.fileWriter, this);
|
|
107
104
|
if (appendix.skipWrapper) {
|
|
108
|
-
|
|
105
|
+
sectionAppendices.push(appendixContents);
|
|
109
106
|
}
|
|
110
107
|
else {
|
|
111
|
-
|
|
108
|
+
sectionAppendices.push(this.appendixWrapper({
|
|
112
109
|
appendixContents,
|
|
113
110
|
appendixName: appendix.getName ? appendix.getName(context) : null,
|
|
114
|
-
});
|
|
111
|
+
}));
|
|
115
112
|
}
|
|
116
|
-
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Create leaf file
|
|
116
|
+
const fileContents = this.templateSection(Object.assign(Object.assign({}, context), { breadcrumbs, headSuffix: context.headSuffixGetters.map((g) => g(context)).join(''), languages,
|
|
117
|
+
nextPage,
|
|
118
|
+
previousPage,
|
|
119
|
+
sectionAppendices, sectionParagraphs: section.paragraphTranslationKeys
|
|
117
120
|
.map((key) => context.resourceHandler.getTranslation(key, context.language))
|
|
118
121
|
.map((value) => this.formatString(value)), sectionTitle }));
|
|
119
122
|
yield fs_1.promises.writeFile(filePath, fileContents);
|
|
@@ -174,35 +177,39 @@ class HtmlInfoBookSerializer {
|
|
|
174
177
|
return { link, linkTarget };
|
|
175
178
|
}
|
|
176
179
|
createItemDisplay(resourceHandler, context, fileWriter, item, slot, annotation = '') {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
180
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
181
|
+
if (item.item === 'minecraft:air') {
|
|
182
|
+
return slot ? '<div class="item item-slot"> </div>' : '<div class="item"> </div>';
|
|
183
|
+
}
|
|
184
|
+
const icon = resourceHandler.getItemIconFile(item.item, item.components);
|
|
185
|
+
if (!icon) {
|
|
186
|
+
throw new Error(`Could not find an icon for item ${JSON.stringify(item)}`);
|
|
187
|
+
}
|
|
188
|
+
const iconUrl = yield fileWriter.write('icons/' + path_1.basename(icon), () => fs_1.createReadStream(icon));
|
|
189
|
+
const key = resourceHandler.getItemTranslationKey(item);
|
|
190
|
+
if (!key) {
|
|
191
|
+
throw new Error(`Could not find translation key for item ${JSON.stringify(item)}`);
|
|
192
|
+
}
|
|
193
|
+
const { link, linkTarget } = this.createResourceLink(resourceHandler, context, item.item, key);
|
|
194
|
+
return this.templateItem(Object.assign(Object.assign({}, context), { annotation, count: item.count || 1, icon: iconUrl, link,
|
|
195
|
+
linkTarget, name: resourceHandler.getTranslation(resourceHandler.getItemTranslationKey(item), context.language), slot }));
|
|
196
|
+
});
|
|
192
197
|
}
|
|
193
198
|
createFluidDisplay(resourceHandler, context, fileWriter, fluid, slot) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
199
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
200
|
+
const icon = resourceHandler.getFluidIconFile(fluid.fluid);
|
|
201
|
+
if (!icon) {
|
|
202
|
+
throw new Error(`Could not find an icon for fluid ${JSON.stringify(fluid)}`);
|
|
203
|
+
}
|
|
204
|
+
const iconUrl = yield fileWriter.write('icons/' + path_1.basename(icon), () => fs_1.createReadStream(icon));
|
|
205
|
+
const key = resourceHandler.getFluidTranslationKey(fluid);
|
|
206
|
+
if (!key) {
|
|
207
|
+
throw new Error(`Could not find translation key for fluid ${JSON.stringify(fluid)}`);
|
|
208
|
+
}
|
|
209
|
+
const { link, linkTarget } = this.createResourceLink(resourceHandler, context, this.tagFluid(context, fluid.fluid), key);
|
|
210
|
+
return this.templateItem(Object.assign(Object.assign({}, context), { count: (fluid.amount || 1), icon: iconUrl, link,
|
|
211
|
+
linkTarget, name: resourceHandler.getTranslation(resourceHandler.getFluidTranslationKey(fluid), context.language), slot }));
|
|
212
|
+
});
|
|
206
213
|
}
|
|
207
214
|
tagFluid(context, fluidName) {
|
|
208
215
|
return fluidName;
|
|
@@ -229,6 +236,7 @@ class HtmlInfoBookSerializer {
|
|
|
229
236
|
value = value.replace(/§o([^§]*)§r/g, '<em>$1</em>');
|
|
230
237
|
value = value.replace(/§N/g, '<br />');
|
|
231
238
|
// Colors to HTML
|
|
239
|
+
value = value.replace(/§r([^§]*)§0/g, '<span style="color: #000000">$1</span>');
|
|
232
240
|
value = value.replace(/§1([^§]*)§0/g, '<span style="color: #0000AA">$1</span>');
|
|
233
241
|
value = value.replace(/§2([^§]*)§0/g, '<span style="color: #00AA00">$1</span>');
|
|
234
242
|
value = value.replace(/§3([^§]*)§0/g, '<span style="color: #00AAAA">$1</span>');
|
package/package.json
CHANGED
package/CHANGELOG.md
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
All notable changes to this project will be documented in this file.
|
|
3
|
-
|
|
4
|
-
<a name="v4.0.0"></a>
|
|
5
|
-
## [v4.0.0](https://github.com/CyclopsMC/infobook-html/compare/v3.0.0...v4.0.0) - 2024-07-23
|
|
6
|
-
|
|
7
|
-
### BREAKING CHANGE
|
|
8
|
-
* [Update to NeoForge 1.21](https://github.com/CyclopsMC/infobook-html/commit/bec55a8a0d2049a07cc3dafee2276c94ed738e73)
|
|
9
|
-
The most notable change here is that "nbt" on items and fluids is replaced by "components".
|
|
10
|
-
|
|
11
|
-
<a name="v3.1.0"></a>
|
|
12
|
-
## [v3.1.0](https://github.com/CyclopsMC/infobook-html/compare/v3.0.0...v3.1.0) - 2024-01-31
|
|
13
|
-
|
|
14
|
-
### Added
|
|
15
|
-
* [Support text field appendix](https://github.com/CyclopsMC/infobook-html/commit/6f24bbbd606b6cfd1237e3bf740e73ffc23008be)
|
|
16
|
-
* [Allowing raw mod URLs in modpack](https://github.com/CyclopsMC/infobook-html/commit/11c9ed5adc554ae7dafa66a202ac83fcacd240fb)
|
|
17
|
-
|
|
18
|
-
<a name="v3.0.0"></a>
|
|
19
|
-
## [v3.0.0](https://github.com/CyclopsMC/infobook-html/compare/v2.0.0...v3.0.0) - 2022-03-10
|
|
20
|
-
|
|
21
|
-
### Changed
|
|
22
|
-
* [Update to MC 1.18](https://github.com/CyclopsMC/infobook-html/commit/1fb77959593a2b84cb14e56406f0df20ad450e16)
|
|
23
|
-
|
|
24
|
-
<a name="v2.0.0"></a>
|
|
25
|
-
## [v2.0.0](https://github.com/CyclopsMC/infobook-html/compare/v1.1.2...v2.0.0) - 2021-02-03
|
|
26
|
-
|
|
27
|
-
### Changed
|
|
28
|
-
* [Update to MC 1.16](https://github.com/CyclopsMC/infobook-html/commit/249b211cb524414db95e3600dcdf14d9304926db)
|
|
29
|
-
* [Also extract mod data](https://github.com/CyclopsMC/infobook-html/commit/c11023465f93c2018deaa10e14270102398dfb2a)
|
|
30
|
-
* [Update footer year](https://github.com/CyclopsMC/infobook-html/commit/c946bab5c16c293b8a6a01a1c7ee1eb9c28b0ad6)
|
|
31
|
-
|
|
32
|
-
### Fixed
|
|
33
|
-
* [Fix incorrect dumpregistries command](https://github.com/CyclopsMC/infobook-html/commit/90bf5675f8a71170e36e91d41c01d5ec94fab430)
|
|
34
|
-
* [Fix server start failing after install in a hacky way](https://github.com/CyclopsMC/infobook-html/commit/03319253969e45b76d98b7b918bbf493c5985693)
|
|
35
|
-
|
|
36
|
-
<a name="v1.1.2"></a>
|
|
37
|
-
## [v1.1.2](https://github.com/CyclopsMC/infobook-html/compare/v1.1.1...v1.1.2) - 2019-07-31
|
|
38
|
-
|
|
39
|
-
### Fixed
|
|
40
|
-
* [Fix some URLs ending with two slashes](https://github.com/CyclopsMC/infobook-html/commit/8bb6b5f2efaa5babdbb0365258a911e82121ec74)
|
|
41
|
-
|
|
42
|
-
<a name="v1.1.1"></a>
|
|
43
|
-
## [v1.1.1](https://github.com/CyclopsMC/infobook-html/compare/v1.1.0...v1.1.1) - 2019-07-31
|
|
44
|
-
|
|
45
|
-
### Added
|
|
46
|
-
* [Allow baseUrl to be overridden via CLI](https://github.com/CyclopsMC/infobook-html/commit/c0090fd3fedc664cb33049bef5bc7e27225cb2b8)
|
|
47
|
-
|
|
48
|
-
### Fixed
|
|
49
|
-
* [Fix _lang dirs not being served on GitHub pages](https://github.com/CyclopsMC/infobook-html/commit/bb0c7bda1a8081322d1192ff293bbee1bdb411b0)
|
|
50
|
-
* [Fix language links not resolving to baseIRI](https://github.com/CyclopsMC/infobook-html/commit/e87eb5a8cf5e5a1651350dfc49923503e3badb7e)
|
|
51
|
-
* [Always end directory URLs with a slash](https://github.com/CyclopsMC/infobook-html/commit/9185cefa713e2d07783ff1f9b800926e24af8a8e)
|
|
52
|
-
|
|
53
|
-
<a name="v1.1.0"></a>
|
|
54
|
-
## [v1.1.0](https://github.com/CyclopsMC/infobook-html/compare/v1.0.1...v1.1.0) - 2019-07-29
|
|
55
|
-
|
|
56
|
-
### Added
|
|
57
|
-
* [Add furnace recipe handler](https://github.com/CyclopsMC/infobook-html/commit/7b6f2728c47283ed4c2e7a29da17a59af91be8bd)
|
|
58
|
-
* [Add support for combined formatting codes and newlines](https://github.com/CyclopsMC/infobook-html/commit/47a857e5a42465fa27c08ad0473065118cfa6fac)
|
|
59
|
-
* [Add support for predefined crafting recipes](https://github.com/CyclopsMC/infobook-html/commit/ecc794b36be7cdb2e7835723d62e729e9d89a629)
|
|
60
|
-
|
|
61
|
-
### Fixed
|
|
62
|
-
* [Fix item icons not being selected based on nbt](https://github.com/CyclopsMC/infobook-html/commit/1fe8f2938af881cc1a8911ccce4dafeaf6a9e25f)
|
|
63
|
-
* [Fix too many ad blocks being added](https://github.com/CyclopsMC/infobook-html/commit/5db0b9321116c710ced4cb9a6bcbfb2de0224324)
|
|
64
|
-
|
|
65
|
-
### Changed
|
|
66
|
-
* [Make page controls slightly smaller](https://github.com/CyclopsMC/infobook-html/commit/c2bd0167b93eeab8e8feb343e5e3f8a0634c8379)
|
|
67
|
-
* [Add support for multiple crafting recipes](https://github.com/CyclopsMC/infobook-html/commit/232f4c293564c818ce73b278b665282f12a7e4d7)
|
|
68
|
-
* [Make templateItem field public](https://github.com/CyclopsMC/infobook-html/commit/dd22d9bbfa3ac6d2b7e9aa6c3eb2e98d91e45556)
|
|
69
|
-
* [Throw error when translation keys are not found](https://github.com/CyclopsMC/infobook-html/commit/904c82275a84a3027b25660c0d87581d16decd43)
|
|
70
|
-
* [Throw error if predefined is not found](https://github.com/CyclopsMC/infobook-html/commit/43cac0f927e5f8c5dbc05312e6008fe7ea96b345)
|
|
71
|
-
* [Handle tagged crafting recipes](https://github.com/CyclopsMC/infobook-html/commit/d6d2dc821a868e790bc229da035c546a5b3e8ade)
|
|
72
|
-
* [Exit with non-zero exit code on error](https://github.com/CyclopsMC/infobook-html/commit/33e3ef8fee72fc72d5608ddb865c53c91b24f59c)
|
|
73
|
-
|
|
74
|
-
<a name="v1.0.1"></a>
|
|
75
|
-
## [v1.0.1](https://github.com/CyclopsMC/infobook-html/compare/v1.0.0...v1.0.1) - 2019-07-25
|
|
76
|
-
|
|
77
|
-
### Fixed
|
|
78
|
-
* [Package assets](https://github.com/CyclopsMC/infobook-html/commit/1d6eda2f7618a7fb312427481f90528dd07185c9)
|
|
79
|
-
|
|
80
|
-
<a name="v1.0.0"></a>
|
|
81
|
-
## [v1.0.0] - 2019-06-25
|
|
82
|
-
|
|
83
|
-
Initial release
|