Skip to content

Commit

Permalink
Added plugin export
Browse files Browse the repository at this point in the history
  • Loading branch information
cjmalloy committed Mar 5, 2024
1 parent d2d7af4 commit bd72989
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 10 deletions.
4 changes: 4 additions & 0 deletions src/app/component/plugin/plugin.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
</ng-template>
<a class="fake-link"
(click)="download()" i18n>download</a>
@if (plugin.config?.export) {
<a class="fake-link"
(click)="export()" i18n>export</a>
}
<a *ngIf="!deleting && store.account.admin"
class="fake-link"
(click)="deleting = true" i18n>delete</a>
Expand Down
8 changes: 7 additions & 1 deletion src/app/component/plugin/plugin.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import { Plugin, writePlugin } from '../../model/plugin';
import { tagDeleteNotice } from "../../mods/delete";
import { AdminService } from '../../service/admin.service';
import { PluginService } from '../../service/api/plugin.service';
import { ModService } from '../../service/mod.service';
import { Store } from '../../store/store';
import { downloadTag } from '../../util/download';
import { downloadPluginExport, downloadTag } from '../../util/download';
import { scrollToFirstInvalid } from '../../util/form';
import { printError } from '../../util/http';

Expand Down Expand Up @@ -39,6 +40,7 @@ export class PluginComponent implements OnInit {
schemaErrors: string[] = [];

constructor(
private mod: ModService,
public admin: AdminService,
public store: Store,
private plugins: PluginService,
Expand Down Expand Up @@ -150,4 +152,8 @@ export class PluginComponent implements OnInit {
download() {
downloadTag(writePlugin(this.plugin));
}

export() {
downloadPluginExport(this.plugin, this.mod.exportHtml(this.plugin));
}
}
4 changes: 4 additions & 0 deletions src/app/model/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ export interface Plugin extends Config {
* Disable the editor and use the viewer to edit.
*/
editingViewer?: boolean;
/**
* This plugin can be exported to a self-contained html file.
*/
export?: boolean,
/**
* Show plugin as signature for existing tag.
*/
Expand Down
3 changes: 2 additions & 1 deletion src/app/model/tag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Schema } from 'jtd';
import { defer, isEqual, omitBy, uniqWith } from 'lodash-es';
import { toJS } from 'mobx';
import * as moment from 'moment';
import { MomentInput } from 'moment/moment';
import { v4 as uuid } from 'uuid';
import { hasTag, prefix } from '../util/tag';
import { filterModels } from '../util/zip';
Expand Down Expand Up @@ -352,7 +353,7 @@ Handlebars.registerHelper('defer', (el: Element, fn: () => {}) => {
}
});

Handlebars.registerHelper('fromNow', value => moment(value).fromNow());
Handlebars.registerHelper('fromNow', (value: MomentInput) => moment(value).fromNow());

Handlebars.registerHelper('response', (ref: Ref, value: string) => {
return ref.metadata?.userUrls?.includes(value);
Expand Down
15 changes: 8 additions & 7 deletions src/app/mods/ninga-triangle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ export const ninjaTrianglePlugin: Plugin = {
submitText: true,
add: true,
genId: true,
export: true,
generated: $localize`Generated by jasper-ui ${moment().toISOString()}`,
description: $localize`Create a Japanese Triangle and show the longest Ninja Path.`,
aiInstructions: ` # plugin/ninja.triangle
Let $n$ be a positive integer. A *Japanese triangle* consists of $1 + 2 + \\ldots + n$ circles arranged in an
equilateral triangular shape such that for each $i = 1, 2, \\ldots, n$, the $i$th row contains exactly $i$ circles,
exactly one of which is coloured red. A *ninja path* in a Japanese triangle is a sequence of $n$ circles obtained by
starting in the top row, then repeatedly going from a circle to one of the two circles immediately below it and
finishing in the bottom row. Here is an example of a Japanese triangle with $n = 6$.
Let $n$ be a positive integer. A *Japanese triangle* consists of $1 + 2 + \\ldots + n$ circles arranged in an
equilateral triangular shape such that for each $i = 1, 2, \\ldots, n$, the $i$th row contains exactly $i$ circles,
exactly one of which is coloured red. A *ninja path* in a Japanese triangle is a sequence of $n$ circles obtained by
starting in the top row, then repeatedly going from a circle to one of the two circles immediately below it and
finishing in the bottom row. Here is an example of a Japanese triangle with $n = 6$.
r
r o
Expand All @@ -31,8 +32,8 @@ export const ninjaTrianglePlugin: Plugin = {
o o o r o
r o o o o o
In terms of $n$, find the greatest $k$ such that in each Japanese triangle there is a ninja path containing at
least $k$ red circles.
In terms of $n$, find the greatest $k$ such that in each Japanese triangle there is a ninja path containing at
least $k$ red circles.
`,
icons: [{ label: $localize`🔺️`, order: 2 }],
filters: [
Expand Down
61 changes: 61 additions & 0 deletions src/app/service/mod.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import { DOCUMENT } from '@angular/common';
import { Inject, Injectable } from '@angular/core';
import { Title } from '@angular/platform-browser';
import flatten from 'css-flatten';
import { marked } from 'marked';
import { autorun, runInAction } from 'mobx';
import { of } from 'rxjs';
import { Plugin } from '../model/plugin';
import { Store } from '../store/store';
import { AdminService } from './admin.service';
import { ConfigService } from './config.service';
Expand Down Expand Up @@ -92,6 +94,65 @@ export class ModService {
this.titleService.setTitle(`${this.config.title} ± ${title}`);
}

exportHtml(plugin: Plugin): string {
return `<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>${plugin.name || plugin.tag}</title>
<style>
@media (prefers-color-scheme: dark) {
html, body {
color-scheme: dark;
background-color: #222;
color: #c9c9c9;
}
}
</style>
<script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.8/handlebars.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css">
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js"></script>
${plugin.config?.snippet || ''}
${plugin.config?.css || ''}
<script id="ui" type="text/x-handlebars-template">
${plugin.config?.ui || ''}
</script>
<script>
window.onload = function() {
Handlebars.registerHelper('d3', () => d3);
Handlebars.registerHelper('defer', (el, fn) => {
if (el.defered) {
fn();
} else {
el.deferred = true;
setTimeout(fn, 1);
}
});
var model = {
el: document.body
};
document.getElementById("content").innerHTML = Handlebars.compile(document.getElementById("ui").innerHTML)(model);
renderMathInElement(document.body, {
delimiters: [
{left: '$$', right: '$$', display: true},
{left: '$', right: '$', display: false},
],
throwOnError: false
});
}
</script>
</head>
<body>
<h1>${plugin.name || plugin.tag}</h1>
<p>${marked(plugin.config?.aiInstructions || '')}</p>
<div id="content"></div>
</body>
</html>
`;
}

private getTheme(id: string, sources: Record<string, string>[]) {
if (!id) return [];
return sources.filter(ts => ts[id])
Expand Down
10 changes: 9 additions & 1 deletion src/app/util/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as FileSaver from 'file-saver';
import * as JSZip from 'jszip';
import { Ext, writeExt } from '../model/ext';
import { Page } from '../model/page';
import { writePlugin } from '../model/plugin';
import { Plugin, writePlugin } from '../model/plugin';
import { Ref, writeRef } from '../model/ref';
import { Tag } from '../model/tag';
import { writeTemplate } from '../model/template';
Expand Down Expand Up @@ -46,3 +46,11 @@ export async function downloadSet(ref: Ref[], ext: Ext[], title: string) {
return zip.generateAsync({ type: 'blob' })
.then(content => FileSaver.saveAs(content, title + '.zip'));
}

export function downloadPluginExport(plugin: Plugin, html: string) {
const title = plugin.name || plugin.tag.replace('/', '_');
const zip = new JSZip();
zip.file(title + '.html', html);
return zip.generateAsync({ type: 'blob' })
.then(content => FileSaver.saveAs(content, title + '.zip'));
}

0 comments on commit bd72989

Please sign in to comment.