添加html支持

This commit is contained in:
undefined committed 2020-09-02 13:32:47 +08:00
1 parent 0b0c34b0c6
commit 3f2d98534f
9 files changed
+73 -20

No files matched your search

+5 -5
View File
@@ -5,7 +5,6 @@ import fs from 'fs-extra';
import AdmZip from 'adm-zip';
import xml2js from 'xml2js';
import { LocalProblemConfig } from 'hydrooj';
import { convertHTML } from '@hydrooj/html2md';
import {
Route, Handler, param, Types,
} from 'hydrooj/dist/service/server';
@@ -26,19 +25,19 @@ class FpsProblemImportHandler extends Handler {
if (p.description) {
content.push(
this.translate('problem.import.problem_description'),
p.description.map(convertHTML).join('\n'),
p.description.join('\n'),
);
}
if (p.input) {
content.push(
this.translate('problem.import.input_format'),
p.input.map(convertHTML).join('\n'),
p.input.join('\n'),
);
}
if (p.output) {
content.push(
this.translate('problem.import.output_format'),
p.output.map(convertHTML).join('\n'),
p.output.join('\n'),
);
}
if (p.sample_input) {
@@ -58,7 +57,7 @@ class FpsProblemImportHandler extends Handler {
if (p.hint) {
content.push(
this.translate('problem.import.hint'),
p.hint.map(convertHTML).join('\n'),
p.hint.join('\n'),
);
}
const config: LocalProblemConfig = {
@@ -79,6 +78,7 @@ class FpsProblemImportHandler extends Handler {
});
});
await problem.setTestdata(domainId, pid, file);
await problem.edit(domainId, pid, { html: true });
await fs.unlink(file);
}
this.response.body = { count: result.fps.item.length };
+1 -2
View File
@@ -1,13 +1,12 @@
{
"name": "@hydrooj/fps-importer",
"version": "1.0.2",
"version": "1.0.3",
"description": "Import FPS problems",
"main": "package.json",
"repository": "https://github.com/hydro-dev/Hydro.git",
"author": "undefined <masnn0@outlook.com>",
"license": "AGPL-3.0-only",
"dependencies": {
"@hydrooj/html2md": "^1.0.0",
"adm-zip": "^0.4.16",
"fs-extra": "^9.0.1",
"hydrooj": "^2.12.22",
+9 -3
View File
@@ -2,14 +2,20 @@ import 'hydrooj';
import TurndownService from 'turndown';
import { JSDOM } from 'jsdom';
const turndownService = new TurndownService();
const turndownService = new TurndownService({
headingStyle: 'atx',
codeBlockStyle: 'fenced',
bulletListMarker: '-',
});
export function convertHTML(html: string) {
const DOM = new JSDOM(html);
const eles = DOM.window.document.querySelectorAll('span.katex-mathml');
eles.forEach((ele) => {
const MathML = ele.innerHTML;
ele.parentElement.replaceWith(MathML);
const MathML = ele.innerHTML
.replace(/\\{/gmi, '{')
.replace(/\\}/gmi, '}');
ele.parentElement.replaceWith(`$${MathML}$`);
});
return turndownService.turndown(DOM.serialize());
}
+3 -2
View File
@@ -2,7 +2,8 @@
"name": "@hydrooj/html2md",
"version": "1.0.0",
"description": "turn html into markdown",
"main": "package.json",
"main": "lib.js",
"typings": "lib.d.ts",
"repository": "https://github.com/hydro-dev/Hydro.git",
"author": "undefined <masnn0@outlook.com>",
"license": "AGPL-3.0-only",
@@ -19,4 +20,4 @@
"build": "tsc",
"lint": "eslint . --ext ts --fix"
}
}
}
+44
View File
@@ -0,0 +1,44 @@
import 'hydrooj';
import { convertHTML } from '@hydrooj/html2md/lib';
describe('html2md', () => {
const Katex1 = `\
<span class="katex">
<span class="katex-mathml">nn</span>
<span class="katex-html">
<span class="strut"></span>
<span class="strut bottom" style="vertical-align:0em;"></span>
<span class="base textstyle uncramped">
<span class="mord mathit">n</span>
</span>
</span>
</span>`;
const Katex2 = `\
<span class="katex">
<span class="katex-mathml">E={1,2,..,n}E=\\{1,2,..,n\\}</span>
<span class="katex-html">
<span class="strut"></span>
<span class="strut bottom" style="vertical-align:-0.25em;"></span>
<span class="base textstyle uncramped">
<span class="mord mathit">E</span>
<span class="mrel">=</span>
<span class="mopen">{</span>
<span class="mord mathrm">1</span>
<span class="mpunct">,</span>
<span class="mord mathrm">2</span>
<span class="mpunct">,</span>
<span class="mord mathrm">.</span>
<span class="mord mathrm">.</span>
<span class="mpunct">,</span>
<span class="mord mathit">n</span>
<span class="mclose">}</span>
</span>
</span>
</span>`;
test('convertHTML', () => {
expect(convertHTML('<h1>Test</h1><p>test</p>')).toStrictEqual('# Test\n\ntest');
expect(convertHTML(Katex1)).toStrictEqual('$n$');
expect(convertHTML(Katex2)).toStrictEqual('$E={1,2,..,n}$');
});
});
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "hydrooj",
"version": "2.12.23",
"version": "2.12.24",
"bin": "bin/hydrooj.js",
"main": "dist/loader.js",
"typings": "dist/loader.d.ts",
+2 -2
View File
@@ -1,5 +1,5 @@
import { isSafeInteger, flatten } from 'lodash';
import yaml from 'js-yaml';
import yaml, { safeLoad } from 'js-yaml';
import { ObjectID } from 'mongodb';
import {
NoProblemError, ProblemDataNotFoundError, BadRequestError,
@@ -360,7 +360,7 @@ class ProblemSettingsHandler extends ProblemManageHandler {
async postConfig(domainId: string, pid: string | number, cfg: string) {
const pdoc = await problem.get(domainId, pid);
// TODO validate
const config = yaml.safeLoad(cfg);
const config = yaml.safeLoad(cfg) as any;
await problem.edit(domainId, pdoc.docId, { config });
this.back();
}
+2 -1
View File
@@ -141,11 +141,12 @@ export interface Pdoc {
hidden: boolean,
config: ProblemConfig,
acMsg?: string,
html?: boolean,
difficulty?: number,
difficultyAlgo?: number,
difficultyAdmin?: number,
difficultySetting?: number,
difficultySetting?: any,
}
export type Pdict = NumericDictionary<Pdoc>;
+6 -4
View File
@@ -1,5 +1,6 @@
import { ObjectID } from 'mongodb';
import { ObjectID, FilterQuery } from 'mongodb';
import { Dictionary } from 'lodash';
import { safeLoad } from 'js-yaml';
import { STATUS } from './builtin';
import * as file from './file';
import * as document from './document';
@@ -29,6 +30,7 @@ export const pdocHidden: Pdoc = {
owner: 1,
title: '*',
content: '',
html: false,
nSubmit: 0,
nAccept: 0,
difficulty: 0,
@@ -75,11 +77,11 @@ export function getMulti(domainId: string, query: object) {
return document.getMulti(domainId, document.TYPE_PROBLEM, query);
}
export function getMultiStatus(domainId: string, query: object) {
export function getMultiStatus(domainId: string, query: FilterQuery<Pdoc>) {
return document.getMultiStatus(domainId, document.TYPE_PROBLEM, query);
}
export function edit(domainId: string, _id: number, $set: any): Promise<Pdoc> {
export function edit(domainId: string, _id: number, $set: Partial<Pdoc>): Promise<Pdoc> {
return document.set(domainId, document.TYPE_PROBLEM, _id, $set);
}
@@ -158,7 +160,7 @@ export async function setTestdata(domainId: string, _id: number, filePath: strin
const config = await testdataConfig.readConfig(filePath);
const id = await file.add(filePath, 'data.zip', 1);
if (pdoc.data instanceof ObjectID) file.del(pdoc.data);
return await edit(domainId, _id, { data: id, config });
return await edit(domainId, _id, { data: id, config: safeLoad(config) as any });
}
global.Hydro.model.problem = {