mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 04:50:36 +03:00
Refactor UI labels
This commit is contained in:
parent
b3e866bb00
commit
c322e2e8eb
|
@ -34,6 +34,7 @@ This readme file is used mostly to document project dependencies
|
|||
<pre>
|
||||
- tailwindcss postcss autoprefixer
|
||||
- eslint-plugin-simple-import-sort
|
||||
- eslint-plugin-tsdoc
|
||||
- jest
|
||||
- ts-jest
|
||||
- @types/jest
|
||||
|
|
|
@ -15,13 +15,16 @@
|
|||
"project": ["tsconfig.json", "tsconfig.node.json"]
|
||||
},
|
||||
"plugins": [
|
||||
"react-refresh", "simple-import-sort"
|
||||
"react-refresh",
|
||||
"simple-import-sort",
|
||||
"eslint-plugin-tsdoc"
|
||||
],
|
||||
"rules": {
|
||||
"react-refresh/only-export-components": [
|
||||
"off",
|
||||
{ "allowConstantExport": true }
|
||||
],
|
||||
"simple-import-sort/imports": "warn"
|
||||
"simple-import-sort/imports": "warn",
|
||||
"tsdoc/syntax": "warn"
|
||||
}
|
||||
}
|
||||
|
|
48
rsconcept/frontend/package-lock.json
generated
48
rsconcept/frontend/package-lock.json
generated
|
@ -40,6 +40,7 @@
|
|||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.3",
|
||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||
"eslint-plugin-tsdoc": "^0.2.17",
|
||||
"jest": "^29.6.4",
|
||||
"postcss": "^8.4.29",
|
||||
"tailwindcss": "^3.3.3",
|
||||
|
@ -2228,6 +2229,37 @@
|
|||
"resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.2.tgz",
|
||||
"integrity": "sha512-d8Q9uRK89ZRWmED2JLI9/blpJcfdbh0iEUuMo8TgkMzNfQBY1/GC0FEJWrairTwHkxIf6Oud1vFBP+aHicWqJA=="
|
||||
},
|
||||
"node_modules/@microsoft/tsdoc": {
|
||||
"version": "0.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz",
|
||||
"integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@microsoft/tsdoc-config": {
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz",
|
||||
"integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@microsoft/tsdoc": "0.14.2",
|
||||
"ajv": "~6.12.6",
|
||||
"jju": "~1.4.0",
|
||||
"resolve": "~1.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@microsoft/tsdoc-config/node_modules/resolve": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
|
||||
"integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.1.0",
|
||||
"path-parse": "^1.0.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
|
@ -4252,6 +4284,16 @@
|
|||
"eslint": ">=5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-tsdoc": {
|
||||
"version": "0.2.17",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-tsdoc/-/eslint-plugin-tsdoc-0.2.17.tgz",
|
||||
"integrity": "sha512-xRmVi7Zx44lOBuYqG8vzTXuL6IdGOeF9nHX17bjJ8+VE6fsxpdGem0/SBTmAwgYMKYB1WBkqRJVQ+n8GK041pA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@microsoft/tsdoc": "0.14.2",
|
||||
"@microsoft/tsdoc-config": "0.16.2"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-scope": {
|
||||
"version": "7.2.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
|
||||
|
@ -6837,6 +6879,12 @@
|
|||
"jiti": "bin/jiti.js"
|
||||
}
|
||||
},
|
||||
"node_modules/jju": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
|
||||
"integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/js-file-download": {
|
||||
"version": "0.4.12",
|
||||
"resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz",
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.3",
|
||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||
"eslint-plugin-tsdoc": "^0.2.17",
|
||||
"jest": "^29.6.4",
|
||||
"postcss": "^8.4.29",
|
||||
"tailwindcss": "^3.3.3",
|
||||
|
|
|
@ -19,14 +19,14 @@ function HelpRSLang() {
|
|||
return (
|
||||
<div className='flex flex-col w-full gap-4'>
|
||||
<div>
|
||||
<h1>Язык родов структур</h1>
|
||||
<h1>Родоструктурная экспликация концептуальных схем</h1>
|
||||
<p>Формальная запись (<i>экспликация</i>) концептуальных схем осуществляется с помощью языка родов структур.</p>
|
||||
<p>Данный математический аппарат основан на аксиоматической теории множеств Цермелло-Френкеля и аппарате родов структур Н.Бурбаки.</p>
|
||||
<p>Для ознакомления с основами родов структур можно использовать следующие материалы:</p>
|
||||
<ul>
|
||||
<li>1. <a className='underline' href={urls.intro_video}>Краткое введение в мат. аппарат</a></li>
|
||||
<li>2. <a className='underline' href={urls.full_course}>Видео лекций по мат. аппарату для 4 курса (второй семестр 2022-23 год)</a></li>
|
||||
<li>3. <a className='underline' href={urls.ponomarev}>Учебник И. Н. Пономарева</a></li>
|
||||
<li>1. <a className='underline' href={urls.intro_video}>Видео: Краткое введение в мат. аппарат</a></li>
|
||||
<li>2. <a className='underline' href={urls.ponomarev}>Текст: Учебник И. Н. Пономарева</a></li>
|
||||
<li>3. <a className='underline' href={urls.full_course}>Видео: лекции для 4 курса (второй семестр 2022-23 год)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className='justify-center hidden w-full md:flex fleex-col'>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { IConstituenta } from '../../models/rsform';
|
||||
import { getCstTypificationLabel } from '../../utils/staticUI';
|
||||
import { labelCstTypification } from '../../utils/labels';
|
||||
|
||||
interface InfoConstituentaProps
|
||||
extends React.HTMLAttributes<HTMLDivElement> {
|
||||
|
@ -10,7 +10,7 @@ function InfoConstituenta({ data, ...props }: InfoConstituentaProps) {
|
|||
return (
|
||||
<div {...props}>
|
||||
<h1>Конституента {data.alias}</h1>
|
||||
<p><b>Типизация: </b>{getCstTypificationLabel(data)}</p>
|
||||
<p><b>Типизация: </b>{labelCstTypification(data)}</p>
|
||||
<p><b>Термин: </b>{data.term_resolved || data.term_raw}</p>
|
||||
{data.definition_formal && <p><b>Выражение: </b>{data.definition_formal}</p>}
|
||||
{data.definition_resolved && <p><b>Определение: </b>{data.definition_resolved}</p>}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { useConceptTheme } from '../../context/ThemeContext';
|
||||
import { CstClass } from '../../models/rsform';
|
||||
import { colorbgCstClass } from '../../utils/color';
|
||||
import { prefixes } from '../../utils/constants';
|
||||
import { getCstClassColor, mapCstClassInfo } from '../../utils/staticUI';
|
||||
import { describeCstClass, labelCstClass } from '../../utils/labels';
|
||||
|
||||
interface InfoCstClassProps {
|
||||
title?: string
|
||||
|
@ -12,19 +14,19 @@ function InfoCstClass({ title }: InfoCstClassProps) {
|
|||
return (
|
||||
<div className='flex flex-col gap-1'>
|
||||
{ title && <h1>{title}</h1>}
|
||||
{ [... mapCstClassInfo.entries()].map(
|
||||
([cstClass, info], index) => {
|
||||
{ Object.values(CstClass).map(
|
||||
(cclass, index) => {
|
||||
return (
|
||||
<p key={`${prefixes.cst_status_list}${index}`}>
|
||||
<span
|
||||
className='px-1 inline-block font-semibold min-w-[7rem] text-center border text-sm'
|
||||
style={{backgroundColor: getCstClassColor(cstClass, colors)}}
|
||||
style={{backgroundColor: colorbgCstClass(cclass, colors)}}
|
||||
>
|
||||
{info.text}
|
||||
{labelCstClass(cclass)}
|
||||
</span>
|
||||
<span> - </span>
|
||||
<span>
|
||||
{info.tooltip}
|
||||
{describeCstClass(cclass)}
|
||||
</span>
|
||||
</p>);
|
||||
})}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { useConceptTheme } from '../../context/ThemeContext';
|
||||
import { ExpressionStatus } from '../../models/rsform';
|
||||
import { colorbgCstStatus } from '../../utils/color';
|
||||
import { prefixes } from '../../utils/constants';
|
||||
import { getCstStatusBgColor, mapStatusInfo } from '../../utils/staticUI';
|
||||
import { describeExpressionStatus, labelExpressionStatus } from '../../utils/labels';
|
||||
|
||||
interface InfoCstStatusProps {
|
||||
title?: string
|
||||
|
@ -12,19 +14,19 @@ function InfoCstStatus({ title }: InfoCstStatusProps) {
|
|||
return (
|
||||
<div className='flex flex-col gap-1'>
|
||||
{ title && <h1>{title}</h1>}
|
||||
{ [... mapStatusInfo.entries()].map(
|
||||
([status, info], index) => {
|
||||
{ Object.values(ExpressionStatus).map(
|
||||
(status, index) => {
|
||||
return (
|
||||
<p key={`${prefixes.cst_status_list}${index}`}>
|
||||
<span
|
||||
className='px-1 inline-block font-semibold min-w-[5rem] text-center border text-sm'
|
||||
style={{backgroundColor: getCstStatusBgColor(status, colors)}}
|
||||
style={{backgroundColor: colorbgCstStatus(status, colors)}}
|
||||
>
|
||||
{info.text}
|
||||
{labelExpressionStatus(status)}
|
||||
</span>
|
||||
<span> - </span>
|
||||
<span>
|
||||
{info.tooltip}
|
||||
{describeExpressionStatus(status)}
|
||||
</span>
|
||||
</p>);
|
||||
})}
|
||||
|
|
|
@ -2,13 +2,13 @@ import { Extension } from '@codemirror/state';
|
|||
import { hoverTooltip } from '@codemirror/view';
|
||||
|
||||
import { IConstituenta } from '../../models/rsform';
|
||||
import { getCstTypificationLabel } from '../../utils/staticUI';
|
||||
import { labelCstTypification } from '../../utils/labels';
|
||||
|
||||
function createTooltipFor(cst: IConstituenta) {
|
||||
const dom = document.createElement('div');
|
||||
dom.className = 'overflow-y-auto border shadow-md max-h-[25rem] max-w-[25rem] min-w-[10rem] w-fit z-tooltip text-sm px-2 py-2';
|
||||
const alias = document.createElement('p');
|
||||
alias.innerHTML = `<b>${cst.alias}:</b> ${getCstTypificationLabel(cst)}`;
|
||||
alias.innerHTML = `<b>${cst.alias}:</b> ${labelCstTypification(cst)}`;
|
||||
dom.appendChild(alias);
|
||||
if (cst.term_resolved) {
|
||||
const term = document.createElement('p');
|
||||
|
|
|
@ -5,7 +5,7 @@ import { CstType, IConstituenta, type IRSForm } from '../models/rsform';
|
|||
import { IExpressionParse, IFunctionArg } from '../models/rslang';
|
||||
import { RSErrorType } from '../models/rslang';
|
||||
import { DataCallback, postCheckExpression } from '../utils/backendAPI';
|
||||
import { getCstExpressionPrefix } from '../utils/staticUI';
|
||||
import { getCstExpressionPrefix } from '../utils/misc';
|
||||
|
||||
const LOGIC_TYPIIFCATION = 'LOGIC';
|
||||
|
||||
|
|
20
rsconcept/frontend/src/models/language.test.ts
Normal file
20
rsconcept/frontend/src/models/language.test.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { Grammeme, parseGrammemes } from './language';
|
||||
|
||||
|
||||
describe('Testing grammeme parsing', () => {
|
||||
test('empty input',
|
||||
() => {
|
||||
expect(parseGrammemes('').length).toBe(0);
|
||||
expect(parseGrammemes(' ').length).toBe(0);
|
||||
expect(parseGrammemes(' , ').length).toBe(0);
|
||||
});
|
||||
|
||||
test('regular grammemes',
|
||||
() => {
|
||||
expect(parseGrammemes('NOUN')).toStrictEqual([{type: Grammeme.NOUN, data: 'NOUN'}]);
|
||||
expect(parseGrammemes('sing,nomn')).toStrictEqual([
|
||||
{type: Grammeme.sing, data: 'sing'},
|
||||
{type: Grammeme.nomn, data: 'nomn'}
|
||||
]);
|
||||
});
|
||||
});
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
// ====== Morphology ========
|
||||
export enum Grammeme {
|
||||
// Неизвестная граммема
|
||||
UNKN = 'UNKN',
|
||||
|
||||
// Части речи
|
||||
NOUN = 'NOUN',
|
||||
ADJF = 'ADJF',
|
||||
|
@ -21,7 +24,6 @@ export enum Grammeme {
|
|||
CONJ = 'CONJ',
|
||||
PRCL = 'PRCL',
|
||||
INTJ = 'INTJ',
|
||||
PNCT = 'PNCT',
|
||||
|
||||
// Одушевленность
|
||||
anim = 'anim',
|
||||
|
@ -88,8 +90,7 @@ export const PartOfSpeech = [
|
|||
Grammeme.NOUN, Grammeme.ADJF, Grammeme.ADJS, Grammeme.COMP,
|
||||
Grammeme.VERB, Grammeme.INFN, Grammeme.PRTF, Grammeme.PRTS,
|
||||
Grammeme.GRND, Grammeme.ADVB, Grammeme.NPRO, Grammeme.PRED,
|
||||
Grammeme.PREP, Grammeme.CONJ, Grammeme.PRCL, Grammeme.INTJ,
|
||||
Grammeme.PNCT
|
||||
Grammeme.PREP, Grammeme.CONJ, Grammeme.PRCL, Grammeme.INTJ
|
||||
];
|
||||
|
||||
export const Gender = [
|
||||
|
@ -101,6 +102,94 @@ export const Case = [
|
|||
Grammeme.accs, Grammeme.ablt, Grammeme.loct
|
||||
];
|
||||
|
||||
export const Plurality = [ Grammeme.sing, Grammeme.plur ];
|
||||
|
||||
export const Perfectivity = [ Grammeme.perf, Grammeme.impf ];
|
||||
export const Transitivity = [ Grammeme.tran, Grammeme.intr ];
|
||||
export const Mood = [ Grammeme.indc, Grammeme.impr ];
|
||||
export const Inclusion = [ Grammeme.incl, Grammeme.excl ];
|
||||
export const Voice = [ Grammeme.actv, Grammeme.pssv ];
|
||||
|
||||
export const Tense = [
|
||||
Grammeme.pres,
|
||||
Grammeme.past,
|
||||
Grammeme.futr
|
||||
];
|
||||
|
||||
export const Person = [
|
||||
Grammeme.per1,
|
||||
Grammeme.per2,
|
||||
Grammeme.per3
|
||||
];
|
||||
|
||||
export const GrammemeGroups = [
|
||||
PartOfSpeech, Gender, Case, Plurality, Perfectivity,
|
||||
Transitivity, Mood, Inclusion, Voice, Tense, Person
|
||||
];
|
||||
|
||||
export const NounGrams = [
|
||||
Grammeme.NOUN, Grammeme.ADJF, Grammeme.ADJS,
|
||||
...Gender,
|
||||
...Case,
|
||||
...Plurality
|
||||
];
|
||||
|
||||
export const VerbGrams = [
|
||||
Grammeme.VERB, Grammeme.INFN, Grammeme.PRTF, Grammeme.PRTS,
|
||||
...Perfectivity,
|
||||
...Transitivity,
|
||||
...Mood,
|
||||
...Inclusion,
|
||||
...Voice,
|
||||
...Tense,
|
||||
...Person
|
||||
];
|
||||
|
||||
// Grammeme parse data
|
||||
export interface IGramData {
|
||||
type: Grammeme
|
||||
data: string
|
||||
}
|
||||
|
||||
// Equality comparator for IGramData
|
||||
export function matchGrammeme(value: IGramData, test: IGramData): boolean {
|
||||
if (value.type !== test.type) {
|
||||
return false;
|
||||
}
|
||||
return value.type !== Grammeme.UNKN || value.data === test.data;
|
||||
}
|
||||
|
||||
function parseSingleGrammeme(text: string): IGramData {
|
||||
if (Object.values(Grammeme).includes(text as Grammeme)) {
|
||||
return {
|
||||
data: text,
|
||||
type: text as Grammeme
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
data: text,
|
||||
type: Grammeme.UNKN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function parseGrammemes(termForm: string): IGramData[] {
|
||||
const result: IGramData[] = [];
|
||||
const chunks = termForm.split(',');
|
||||
chunks.forEach(chunk => {
|
||||
chunk = chunk.trim();
|
||||
if (chunk !== '') {
|
||||
result.push(parseSingleGrammeme(chunk));
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
export interface IWordForm {
|
||||
text: string
|
||||
grams: IGramData[]
|
||||
}
|
||||
|
||||
// ====== Reference resolution =====
|
||||
export interface IRefsText {
|
||||
text: string
|
||||
|
@ -110,6 +199,7 @@ export enum ReferenceType {
|
|||
ENTITY = 'entity',
|
||||
SYNTACTIC = 'syntax'
|
||||
}
|
||||
|
||||
export interface IEntityReference {
|
||||
entity: string
|
||||
form: string
|
||||
|
|
|
@ -274,3 +274,30 @@ export function inferClass(type: CstType, isTemplate: boolean): CstClass {
|
|||
}
|
||||
}
|
||||
|
||||
export function createMockConstituenta(schema: number, id: number, alias: string, type: CstType, comment: string): IConstituenta {
|
||||
return {
|
||||
id: id,
|
||||
order: -1,
|
||||
schema: schema,
|
||||
alias: alias,
|
||||
convention: comment,
|
||||
cst_type: type,
|
||||
term_raw: '',
|
||||
term_resolved: '',
|
||||
term_forms: [],
|
||||
definition_formal: '',
|
||||
definition_raw: '',
|
||||
definition_resolved: '',
|
||||
status: ExpressionStatus.INCORRECT,
|
||||
is_template: false,
|
||||
cst_class: CstClass.DERIVED,
|
||||
parse: {
|
||||
status: ParsingStatus.INCORRECT,
|
||||
valueClass: ValueClass.INVALID,
|
||||
typification: 'N/A',
|
||||
syntaxTree: '',
|
||||
args: []
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { HelpTopic } from '../../models/miscelanious';
|
||||
import { prefixes } from '../../utils/constants';
|
||||
import { mapTopicInfo } from '../../utils/staticUI';
|
||||
import { describeHelpTopic, labelHelpTopic } from '../../utils/labels';
|
||||
|
||||
interface TopicsListProps {
|
||||
activeTopic: HelpTopic
|
||||
|
@ -11,15 +11,15 @@ function TopicsList({ activeTopic, onChangeTopic }: TopicsListProps) {
|
|||
return (
|
||||
<div className='sticky top-0 left-0 border-r border-b min-w-[13rem] pt-2 select-none flex flex-col clr-controls'>
|
||||
<div className='mb-2 font-semibold text-center'>Справка</div>
|
||||
{ [... mapTopicInfo.entries()].map(
|
||||
([topic, info], index) => {
|
||||
{ Object.values(HelpTopic).map(
|
||||
(topic, index) => {
|
||||
return (
|
||||
<div key={`${prefixes.topic_list}${index}`}
|
||||
className={`px-3 py-1 border-y cursor-pointer clr-hover ${activeTopic === topic ? 'font-semibold clr-selected ' : ''}`}
|
||||
title={info.tooltip}
|
||||
title={describeHelpTopic(topic)}
|
||||
onClick={() => onChangeTopic(topic)}
|
||||
>
|
||||
{info.text}
|
||||
{labelHelpTopic(topic)}
|
||||
</div>)
|
||||
})}
|
||||
</div>
|
||||
|
|
|
@ -9,7 +9,7 @@ import { useLibrary } from '../../context/LibraryContext';
|
|||
import { useConceptNavigation } from '../../context/NagivationContext';
|
||||
import { useRSForm } from '../../context/RSFormContext';
|
||||
import { IRSFormCreateData } from '../../models/rsform';
|
||||
import { getCloneTitle } from '../../utils/staticUI';
|
||||
import { cloneTitle } from '../../utils/misc';
|
||||
|
||||
interface DlgCloneRSFormProps
|
||||
extends Pick<ModalProps, 'hideWindow'> {}
|
||||
|
@ -27,7 +27,7 @@ function DlgCloneRSForm({ hideWindow }: DlgCloneRSFormProps) {
|
|||
|
||||
useEffect(() => {
|
||||
if (schema) {
|
||||
setTitle(getCloneTitle(schema));
|
||||
setTitle(cloneTitle(schema));
|
||||
setAlias(schema.alias);
|
||||
setComment(schema.comment);
|
||||
setCommon(schema.is_common);
|
||||
|
|
|
@ -6,7 +6,7 @@ import TextArea from '../../components/Common/TextArea';
|
|||
import RSInput from '../../components/RSInput';
|
||||
import { CstType,ICstCreateData } from '../../models/rsform';
|
||||
import { SelectorCstType } from '../../utils/selectors';
|
||||
import { getCstTypeLabel } from '../../utils/staticUI';
|
||||
import { labelCstType } from '../../utils/labels';
|
||||
|
||||
interface DlgCreateCstProps
|
||||
extends Pick<ModalProps, 'hideWindow'> {
|
||||
|
@ -62,7 +62,7 @@ function DlgCreateCst({ hideWindow, initial, onCreate }: DlgCreateCstProps) {
|
|||
className='my-2 min-w-[15rem] self-center'
|
||||
options={SelectorCstType}
|
||||
placeholder='Выберите тип'
|
||||
value={selectedType ? { value: selectedType, label: getCstTypeLabel(selectedType) } : null}
|
||||
value={selectedType ? { value: selectedType, label: labelCstType(selectedType) } : null}
|
||||
onChange={data => setSelectedType(data?.value ?? CstType.BASE)}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useMemo, useState } from 'react';
|
|||
import Checkbox from '../../components/Common/Checkbox';
|
||||
import Modal, { ModalProps } from '../../components/Common/Modal';
|
||||
import { useRSForm } from '../../context/RSFormContext';
|
||||
import { getCstLabel } from '../../utils/staticUI';
|
||||
import { labelConstituenta } from '../../utils/labels';
|
||||
|
||||
interface DlgDeleteCstProps
|
||||
extends Pick<ModalProps, 'hideWindow'> {
|
||||
|
@ -39,14 +39,14 @@ function DlgDeleteCst({ hideWindow, selected, onDelete }: DlgDeleteCstProps) {
|
|||
<div className='px-3 border h-[9rem] mt-1 overflow-y-auto whitespace-nowrap'>
|
||||
{selected.map(id => {
|
||||
const cst = schema!.items.find(cst => cst.id === id);
|
||||
return (cst && <p>{getCstLabel(cst)}</p>);
|
||||
return (cst && <p>{labelConstituenta(cst)}</p>);
|
||||
})}
|
||||
</div>
|
||||
<p className='mt-4'>Зависимые конституенты: <b>{expansion.length}</b></p>
|
||||
<div className='mt-1 mb-3 px-3 border h-[9rem] overflow-y-auto whitespace-nowrap'>
|
||||
{expansion.map(id => {
|
||||
const cst = schema!.items.find(cst => cst.id === id);
|
||||
return (cst && <p>{getCstLabel(cst)}</p>);
|
||||
return (cst && <p>{labelConstituenta(cst)}</p>);
|
||||
})}
|
||||
</div>
|
||||
<Checkbox
|
||||
|
|
|
@ -1,39 +1,100 @@
|
|||
import { useLayoutEffect, useState } from 'react';
|
||||
import { useEffect, useLayoutEffect, useMemo, useState } from 'react';
|
||||
|
||||
import Divider from '../../components/Common/Divider';
|
||||
import MiniButton from '../../components/Common/MiniButton';
|
||||
import Modal from '../../components/Common/Modal';
|
||||
import SelectMulti from '../../components/Common/SelectMulti';
|
||||
import TextArea from '../../components/Common/TextArea';
|
||||
import DataTable, { createColumnHelper } from '../../components/DataTable';
|
||||
import { CheckIcon, ChevronDoubleUpIcon, ChevronUpIcon, CrossIcon } from '../../components/Icons';
|
||||
import { Grammeme } from '../../models/language';
|
||||
import { IConstituenta } from '../../models/rsform';
|
||||
import { SelectorGrammems } from '../../utils/selectors';
|
||||
import { Grammeme, GrammemeGroups, IWordForm, NounGrams, parseGrammemes,VerbGrams } from '../../models/language';
|
||||
import { IConstituenta, TermForm } from '../../models/rsform';
|
||||
import { labelGrammeme } from '../../utils/labels';
|
||||
import { IGrammemeOption, SelectorGrammems } from '../../utils/selectors';
|
||||
|
||||
interface DlgEditTermProps {
|
||||
hideWindow: () => void
|
||||
target: IConstituenta
|
||||
onSave: () => void
|
||||
onSave: (data: TermForm[]) => void
|
||||
}
|
||||
|
||||
const columnHelper = createColumnHelper<IWordForm>();
|
||||
|
||||
function DlgEditTerm({ hideWindow, target, onSave }: DlgEditTermProps) {
|
||||
const [term, setTerm] = useState('');
|
||||
|
||||
const [inputText, setInputText] = useState('');
|
||||
const [inputTags, setInputTags] = useState<{ value: Grammeme, label: string }[]>([]);
|
||||
const [inputGrams, setInputGrams] = useState<IGrammemeOption[]>([]);
|
||||
const [options, setOptions] = useState<IGrammemeOption[]>([]);
|
||||
|
||||
const [forms, setForms] = useState<IWordForm[]>([]);
|
||||
|
||||
function getData(): TermForm[] {
|
||||
const result: TermForm[] = [];
|
||||
forms.forEach(
|
||||
({text, grams}) => result.push({
|
||||
text: text,
|
||||
tags: grams.join(',')
|
||||
}));
|
||||
return result;
|
||||
}
|
||||
|
||||
// function getData() {
|
||||
// return {
|
||||
// Initialization
|
||||
useLayoutEffect(
|
||||
() => {
|
||||
const initForms: IWordForm[] = [];
|
||||
target.term_forms.forEach(
|
||||
term => initForms.push({
|
||||
text: term.text,
|
||||
grams: parseGrammemes(term.tags),
|
||||
}));
|
||||
setForms(initForms);
|
||||
setTerm(target.term_resolved);
|
||||
}, [target]);
|
||||
|
||||
// };
|
||||
// }
|
||||
// Filter grammemes when input changes
|
||||
useEffect(
|
||||
() => {
|
||||
let newFilter: Grammeme[] = [];
|
||||
inputGrams.forEach(({value: gram}) => {
|
||||
if (!newFilter.includes(gram)) {
|
||||
if (NounGrams.includes(gram)) {
|
||||
newFilter.push(...NounGrams);
|
||||
}
|
||||
if (VerbGrams.includes(gram)) {
|
||||
newFilter.push(...NounGrams);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const handleSubmit = () => onSave(); // getData()
|
||||
inputGrams.forEach(({value: gram}) =>
|
||||
GrammemeGroups.forEach(group => {
|
||||
if (group.includes(gram)) {
|
||||
newFilter = newFilter.filter(item => !group.includes(item) || item === gram);
|
||||
}
|
||||
}));
|
||||
|
||||
newFilter.push(...inputGrams.map(({value: gram}) => gram));
|
||||
if (newFilter.length === 0) {
|
||||
newFilter = [...VerbGrams, ...NounGrams];
|
||||
}
|
||||
|
||||
newFilter = [... new Set(newFilter)];
|
||||
setOptions(SelectorGrammems.filter(({value: gram}) => newFilter.includes(gram)));
|
||||
}, [inputGrams]);
|
||||
|
||||
const handleSubmit = () => onSave(getData());
|
||||
|
||||
function handleAddForm() {
|
||||
|
||||
setForms(forms => [
|
||||
...forms,
|
||||
{
|
||||
text: inputText,
|
||||
grams: inputGrams.map(item => ({
|
||||
type: item.value, data: item.value as string
|
||||
}))
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
function handleResetForm() {
|
||||
|
@ -48,10 +109,56 @@ function DlgEditTerm({ hideWindow, target, onSave }: DlgEditTermProps) {
|
|||
|
||||
}
|
||||
|
||||
useLayoutEffect(
|
||||
() => {
|
||||
setTerm(target.term_resolved);
|
||||
}, [target]);
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
columnHelper.accessor('text', {
|
||||
id: 'text',
|
||||
header: 'Текст',
|
||||
size: 350,
|
||||
minSize: 350,
|
||||
maxSize: 350
|
||||
}),
|
||||
columnHelper.accessor('grams', {
|
||||
id: 'grams',
|
||||
header: 'Граммемы',
|
||||
size: 250,
|
||||
minSize: 250,
|
||||
maxSize: 250,
|
||||
cell: props => {
|
||||
return (
|
||||
<div className='flex justify-start gap-1 select-none'>
|
||||
{ props.getValue().map(
|
||||
data => (<>
|
||||
<div
|
||||
className='min-w-[3rem] px-1 text-center rounded-md whitespace-nowrap border clr-border clr-input'
|
||||
title=''
|
||||
// style={{
|
||||
// borderWidth: '1px',
|
||||
// borderColor: getCstStatusFgColor(cst.status, colors),
|
||||
// color: getCstStatusFgColor(cst.status, colors),
|
||||
// fontWeight: 600,
|
||||
// backgroundColor: isMockCst(cst) ? colors.bgWarning : colors.bgInput
|
||||
// }}
|
||||
>
|
||||
{labelGrammeme(data)}
|
||||
</div>
|
||||
{/* <ConstituentaTooltip data={cst} anchor={`#${prefixes.cst_list}${cst.alias}`} /> */}
|
||||
</>))}
|
||||
</div>);
|
||||
}
|
||||
|
||||
// cell: props =>
|
||||
// <div style={{
|
||||
// fontSize: 12,
|
||||
// color: isMockCst(props.row.original) ? colors.fgWarning : undefined
|
||||
// }}>
|
||||
// {props.getValue()}
|
||||
// </div>
|
||||
}),
|
||||
// columnHelper.accessor(, {
|
||||
|
||||
// })
|
||||
], []);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
|
@ -108,15 +215,29 @@ function DlgEditTerm({ hideWindow, target, onSave }: DlgEditTermProps) {
|
|||
</div>
|
||||
<SelectMulti
|
||||
className='z-modal-top min-w-[20rem] max-w-[20rem] h-full flex-grow'
|
||||
options={SelectorGrammems}
|
||||
options={options}
|
||||
placeholder='Выберите граммемы'
|
||||
|
||||
value={inputTags}
|
||||
onChange={data => setInputTags(data.map(value => value))}
|
||||
value={inputGrams}
|
||||
onChange={data => setInputGrams(data.map(value => value))}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
Таблица
|
||||
|
||||
<div className='border overflow-y-auto max-h-[20rem]'>
|
||||
<DataTable
|
||||
data={forms}
|
||||
columns={columns}
|
||||
dense
|
||||
|
||||
noDataComponent={
|
||||
<span className='flex flex-col justify-center p-2 text-center min-h-[2rem]'>
|
||||
<p>Список пуст</p>
|
||||
</span>
|
||||
}
|
||||
|
||||
// onRowDoubleClicked={handleDoubleClick}
|
||||
// onRowClicked={handleRowClicked}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>);
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useLayoutEffect, useState } from 'react';
|
|||
import Checkbox from '../../components/Common/Checkbox';
|
||||
import Modal, { ModalProps } from '../../components/Common/Modal';
|
||||
import { CstType } from '../../models/rsform';
|
||||
import { getCstTypeLabel } from '../../utils/staticUI';
|
||||
import { labelCstType } from '../../utils/labels';
|
||||
import { GraphEditorParams } from './EditorTermGraph';
|
||||
|
||||
interface DlgGraphOptionsProps
|
||||
|
@ -105,42 +105,42 @@ function DlgGraphOptions({ hideWindow, initial, onConfirm }:DlgGraphOptionsProps
|
|||
<div className='flex flex-col gap-1'>
|
||||
<h1>Типы конституент</h1>
|
||||
<Checkbox
|
||||
label={getCstTypeLabel(CstType.BASE)}
|
||||
label={labelCstType(CstType.BASE)}
|
||||
value={allowBase}
|
||||
setValue={ value => setAllowBase(value) }
|
||||
/>
|
||||
<Checkbox
|
||||
label={getCstTypeLabel(CstType.STRUCTURED)}
|
||||
label={labelCstType(CstType.STRUCTURED)}
|
||||
value={allowStruct}
|
||||
setValue={ value => setAllowStruct(value) }
|
||||
/>
|
||||
<Checkbox
|
||||
label={getCstTypeLabel(CstType.TERM)}
|
||||
label={labelCstType(CstType.TERM)}
|
||||
value={allowTerm}
|
||||
setValue={ value => setAllowTerm(value) }
|
||||
/>
|
||||
<Checkbox
|
||||
label={getCstTypeLabel(CstType.AXIOM)}
|
||||
label={labelCstType(CstType.AXIOM)}
|
||||
value={allowAxiom}
|
||||
setValue={ value => setAllowAxiom(value) }
|
||||
/>
|
||||
<Checkbox
|
||||
label={getCstTypeLabel(CstType.FUNCTION)}
|
||||
label={labelCstType(CstType.FUNCTION)}
|
||||
value={allowFunction}
|
||||
setValue={ value => setAllowFunction(value) }
|
||||
/>
|
||||
<Checkbox
|
||||
label={getCstTypeLabel(CstType.PREDICATE)}
|
||||
label={labelCstType(CstType.PREDICATE)}
|
||||
value={allowPredicate}
|
||||
setValue={ value => setAllowPredicate(value) }
|
||||
/>
|
||||
<Checkbox
|
||||
label={getCstTypeLabel(CstType.CONSTANT)}
|
||||
label={labelCstType(CstType.CONSTANT)}
|
||||
value={allowConstant}
|
||||
setValue={ value => setAllowConstant(value) }
|
||||
/>
|
||||
<Checkbox
|
||||
label={getCstTypeLabel(CstType.THEOREM)}
|
||||
label={labelCstType(CstType.THEOREM)}
|
||||
value={allowTheorem}
|
||||
setValue ={ value => setAllowTheorem(value) }
|
||||
/>
|
||||
|
|
|
@ -6,7 +6,8 @@ import TextInput from '../../components/Common/TextInput';
|
|||
import { useRSForm } from '../../context/RSFormContext';
|
||||
import { CstType, ICstRenameData } from '../../models/rsform';
|
||||
import { SelectorCstType } from '../../utils/selectors';
|
||||
import { createAliasFor, getCstTypeLabel, getCstTypePrefix } from '../../utils/staticUI';
|
||||
import { createAliasFor, getCstTypePrefix } from '../../utils/misc';
|
||||
import { labelCstType } from '../../utils/labels';
|
||||
|
||||
interface DlgRenameCstProps
|
||||
extends Pick<ModalProps, 'hideWindow'> {
|
||||
|
@ -72,7 +73,7 @@ function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) {
|
|||
className='min-w-[14rem] self-center z-modal-top'
|
||||
options={SelectorCstType}
|
||||
placeholder='Выберите тип'
|
||||
value={cstType ? { value: cstType, label: getCstTypeLabel(cstType) } : null}
|
||||
value={cstType ? { value: cstType, label: labelCstType(cstType) } : null}
|
||||
onChange={data => setCstType(data?.value ?? CstType.BASE)}
|
||||
/>
|
||||
<div>
|
||||
|
|
|
@ -5,8 +5,9 @@ import Modal, { ModalProps } from '../../components/Common/Modal';
|
|||
import { useConceptTheme } from '../../context/ThemeContext';
|
||||
import { SyntaxTree } from '../../models/rslang';
|
||||
import { graphDarkT, graphLightT } from '../../utils/color';
|
||||
import { colorbgSyntaxTree } from '../../utils/color';
|
||||
import { resources } from '../../utils/constants';
|
||||
import { getASTNodeColor, getASTNodeLabel } from '../../utils/staticUI';
|
||||
import { labelSyntaxTree } from '../../utils/labels';
|
||||
|
||||
interface DlgShowASTProps
|
||||
extends Pick<ModalProps, 'hideWindow'> {
|
||||
|
@ -24,8 +25,8 @@ function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
|
|||
const nodes: GraphNode[] = useMemo(
|
||||
() => syntaxTree.map(node => ({
|
||||
id: String(node.uid),
|
||||
label: getASTNodeLabel(node),
|
||||
fill: getASTNodeColor(node, colors),
|
||||
label: labelSyntaxTree(node),
|
||||
fill: colorbgSyntaxTree(node, colors),
|
||||
})), [syntaxTree, colors]);
|
||||
|
||||
const edges: GraphEdge[] = useMemo(
|
||||
|
|
|
@ -13,7 +13,7 @@ import useWindowSize from '../../hooks/useWindowSize';
|
|||
import { EditMode } from '../../models/miscelanious';
|
||||
import { CstType, IConstituenta, ICstCreateData, ICstRenameData, ICstUpdateData } from '../../models/rsform';
|
||||
import { SyntaxTree } from '../../models/rslang';
|
||||
import { getCstTypificationLabel } from '../../utils/staticUI';
|
||||
import { labelCstTypification } from '../../utils/labels';
|
||||
import EditorRSExpression from './EditorRSExpression';
|
||||
import ViewSideConstituents from './elements/ViewSideConstituents';
|
||||
|
||||
|
@ -78,7 +78,7 @@ function EditorConstituenta({
|
|||
setTerm(activeCst.term_raw || '');
|
||||
setTextDefinition(activeCst.definition_raw || '');
|
||||
setExpression(activeCst.definition_formal || '');
|
||||
setTypification(activeCst ? getCstTypificationLabel(activeCst) : 'N/A');
|
||||
setTypification(activeCst ? labelCstTypification(activeCst) : 'N/A');
|
||||
}
|
||||
}, [activeCst, onOpenEdit, schema]);
|
||||
|
||||
|
|
|
@ -11,8 +11,10 @@ import { useRSForm } from '../../context/RSFormContext';
|
|||
import { useConceptTheme } from '../../context/ThemeContext';
|
||||
import useWindowSize from '../../hooks/useWindowSize';
|
||||
import { CstType, IConstituenta, ICstCreateData, ICstMovetoData } from '../../models/rsform'
|
||||
import { colorfgCstStatus } from '../../utils/color';
|
||||
import { prefixes } from '../../utils/constants';
|
||||
import { getCstStatusFgColor, getCstTypePrefix, getCstTypeShortcut, getCstTypificationLabel, mapStatusInfo } from '../../utils/staticUI';
|
||||
import { describeExpressionStatus, labelCstTypification } from '../../utils/labels';
|
||||
import { getCstTypePrefix, getCstTypeShortcut } from '../../utils/misc';
|
||||
|
||||
// Window width cutoff for columns
|
||||
const COLUMN_DEFINITION_HIDE_THRESHOLD = 1000;
|
||||
|
@ -221,15 +223,14 @@ function EditorItems({ onOpenEdit, onCreateCst, onDeleteCst }: EditorItemsProps)
|
|||
maxSize: 65,
|
||||
cell: props => {
|
||||
const cst = props.row.original;
|
||||
const info = mapStatusInfo.get(cst.status);
|
||||
return (<>
|
||||
<div
|
||||
id={`${prefixes.cst_list}${cst.alias}`}
|
||||
className='w-full min-w-[3.1rem] max-w-[3.1rem] px-1 text-center rounded-md whitespace-nowrap'
|
||||
style={{
|
||||
borderWidth: "1px",
|
||||
borderColor: getCstStatusFgColor(cst.status, colors),
|
||||
color: getCstStatusFgColor(cst.status, colors),
|
||||
borderColor: colorfgCstStatus(cst.status, colors),
|
||||
color: colorfgCstStatus(cst.status, colors),
|
||||
fontWeight: 600,
|
||||
backgroundColor: colors.bgInput
|
||||
}}
|
||||
|
@ -240,12 +241,12 @@ function EditorItems({ onOpenEdit, onCreateCst, onDeleteCst }: EditorItemsProps)
|
|||
anchorSelect={`#${prefixes.cst_list}${cst.alias}`}
|
||||
place='right'
|
||||
>
|
||||
<p><span className='font-semibold'>Статус</span>: {info!.tooltip}</p>
|
||||
<p><span className='font-semibold'>Статус</span>: {describeExpressionStatus(cst.status)}</p>
|
||||
</ConceptTooltip>
|
||||
</>);
|
||||
}
|
||||
}),
|
||||
columnHelper.accessor(cst => getCstTypificationLabel(cst), {
|
||||
columnHelper.accessor(cst => labelCstTypification(cst), {
|
||||
id: 'type',
|
||||
header: 'Типизация',
|
||||
size: 150,
|
||||
|
|
|
@ -10,7 +10,8 @@ import useCheckExpression from '../../hooks/useCheckExpression';
|
|||
import { IConstituenta } from '../../models/rsform';
|
||||
import { IRSErrorDescription, SyntaxTree } from '../../models/rslang';
|
||||
import { TokenID } from '../../models/rslang';
|
||||
import { getCstExpressionPrefix, getTypificationLabel } from '../../utils/staticUI';
|
||||
import { labelTypification } from '../../utils/labels';
|
||||
import { getCstExpressionPrefix } from '../../utils/misc';
|
||||
import ParsingResult from './elements/ParsingResult';
|
||||
import RSLocalButton from './elements/RSLocalButton';
|
||||
import RSTokenButton from './elements/RSTokenButton';
|
||||
|
@ -67,7 +68,7 @@ function EditorRSExpression({
|
|||
rsInput.current?.view?.focus();
|
||||
}
|
||||
setIsModified(false);
|
||||
setTypification(getTypificationLabel({
|
||||
setTypification(labelTypification({
|
||||
isValid: parse.parseResult,
|
||||
resultType: parse.typification,
|
||||
args: parse.args
|
||||
|
@ -111,49 +112,49 @@ function EditorRSExpression({
|
|||
<div className='flex items-center justify-between w-full'>
|
||||
<div className='text-sm w-fit'>
|
||||
<div className='flex justify-start'>
|
||||
<RSTokenButton id={TokenID.NT_DECLARATIVE_EXPR} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.NT_IMPERATIVE_EXPR} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.NT_RECURSIVE_FULL} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.BIGPR} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.SMALLPR} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.FILTER} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.REDUCE} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.CARD} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.BOOL} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.NT_DECLARATIVE_EXPR} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.NT_IMPERATIVE_EXPR} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.NT_RECURSIVE_FULL} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.BIGPR} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.SMALLPR} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.FILTER} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.REDUCE} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.CARD} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.BOOL} onInsert={handleEdit}/>
|
||||
|
||||
</div>
|
||||
<div className='flex justify-start'>
|
||||
<RSTokenButton id={TokenID.BOOLEAN} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.PUNC_PL} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.INTERSECTION} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.LIT_EMPTYSET} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.FORALL} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.NOT} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.IN} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.SUBSET_OR_EQ} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.AND} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.IMPLICATION} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.SET_MINUS} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.PUNC_ITERATE} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.SUBSET} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.DEBOOL} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.BOOLEAN} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.PUNC_PL} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.INTERSECTION} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.LIT_EMPTYSET} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.FORALL} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.NOT} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.IN} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.SUBSET_OR_EQ} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.AND} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.IMPLICATION} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.SET_MINUS} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.PUNC_ITERATE} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.SUBSET} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.DEBOOL} onInsert={handleEdit}/>
|
||||
</div>
|
||||
<div className='flex justify-start'>
|
||||
<RSTokenButton id={TokenID.DECART} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.PUNC_SL} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.UNION} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.LIT_INTSET} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.EXISTS} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.NOTEQUAL} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.NOTIN} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.NOTSUBSET} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.OR} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.EQUIVALENT} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.SYMMINUS} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.PUNC_ASSIGN} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.EQUAL} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.GREATER_OR_EQ} onInsert={handleEdit}/>
|
||||
<RSTokenButton id={TokenID.LESSER_OR_EQ} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.DECART} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.PUNC_SL} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.UNION} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.LIT_INTSET} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.EXISTS} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.NOTEQUAL} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.NOTIN} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.NOTSUBSET} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.OR} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.EQUIVALENT} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.SYMMINUS} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.PUNC_ASSIGN} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.EQUAL} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.GREATER_OR_EQ} onInsert={handleEdit}/>
|
||||
<RSTokenButton token={TokenID.LESSER_OR_EQ} onInsert={handleEdit}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className='text-xs w-fit'>
|
||||
|
|
|
@ -21,9 +21,10 @@ import { prefixes, resources, TIMEOUT_GRAPH_REFRESH } from '../../utils/constant
|
|||
import { Graph } from '../../utils/Graph';
|
||||
import { SelectorGraphLayout } from '../../utils/selectors';
|
||||
import { SelectorGraphColoring } from '../../utils/selectors';
|
||||
import { getCstClassColor, getCstStatusBgColor,
|
||||
mapColoringLabels, mapLayoutLabels
|
||||
} from '../../utils/staticUI';
|
||||
import { colorbgCstClass } from '../../utils/color';
|
||||
import { colorbgCstStatus } from '../../utils/color';
|
||||
import { mapLabelColoring } from '../../utils/labels';
|
||||
import { mapLableLayout } from '../../utils/labels';
|
||||
import DlgGraphOptions from './DlgGraphOptions';
|
||||
import ConstituentaTooltip from './elements/ConstituentaTooltip';
|
||||
|
||||
|
@ -32,10 +33,10 @@ const TREE_SIZE_MILESTONE = 50;
|
|||
|
||||
function getCstNodeColor(cst: IConstituenta, coloringScheme: ColoringScheme, colors: IColorTheme): string {
|
||||
if (coloringScheme === 'type') {
|
||||
return getCstClassColor(cst.cst_class, colors);
|
||||
return colorbgCstClass(cst.cst_class, colors);
|
||||
}
|
||||
if (coloringScheme === 'status') {
|
||||
return getCstStatusBgColor(cst.status, colors);
|
||||
return colorbgCstStatus(cst.status, colors);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
@ -407,7 +408,7 @@ function EditorTermGraph({ onOpenEdit, onCreateCst, onDeleteCst }: EditorTermGra
|
|||
options={SelectorGraphColoring}
|
||||
isSearchable={false}
|
||||
placeholder='Выберите цвет'
|
||||
value={coloringScheme ? { value: coloringScheme, label: mapColoringLabels.get(coloringScheme) } : null}
|
||||
value={coloringScheme ? { value: coloringScheme, label: mapLabelColoring.get(coloringScheme) } : null}
|
||||
onChange={data => setColoringScheme(data?.value ?? SelectorGraphColoring[0].value)}
|
||||
/>
|
||||
|
||||
|
@ -417,7 +418,7 @@ function EditorTermGraph({ onOpenEdit, onCreateCst, onDeleteCst }: EditorTermGra
|
|||
options={SelectorGraphLayout}
|
||||
isSearchable={false}
|
||||
placeholder='Способ расположения'
|
||||
value={layout ? { value: layout, label: mapLayoutLabels.get(layout) } : null}
|
||||
value={layout ? { value: layout, label: mapLableLayout.get(layout) } : null}
|
||||
onChange={data => handleChangeLayout(data?.value ?? SelectorGraphLayout[0].value)}
|
||||
/>
|
||||
<div className='flex flex-col gap-1 mt-2'>
|
||||
|
|
|
@ -17,7 +17,7 @@ import useModificationPrompt from '../../hooks/useModificationPrompt';
|
|||
import { ICstCreateData, ICstRenameData } from '../../models/rsform';
|
||||
import { SyntaxTree } from '../../models/rslang';
|
||||
import { EXTEOR_TRS_FILE, prefixes, TIMEOUT_UI_REFRESH } from '../../utils/constants';
|
||||
import { createAliasFor } from '../../utils/staticUI';
|
||||
import { createAliasFor } from '../../utils/misc';
|
||||
import DlgCloneRSForm from './DlgCloneRSForm';
|
||||
import DlgCreateCst from './DlgCreateCst';
|
||||
import DlgDeleteCst from './DlgDeleteCst';
|
||||
|
|
|
@ -4,7 +4,7 @@ import Dropdown from '../../../components/Common/Dropdown';
|
|||
import DropdownButton from '../../../components/Common/DropdownButton';
|
||||
import useDropdown from '../../../hooks/useDropdown';
|
||||
import { DependencyMode } from '../../../models/miscelanious';
|
||||
import { getDependencyLabel } from '../../../utils/staticUI';
|
||||
import { labelDependencyMode } from '../../../utils/labels';
|
||||
|
||||
interface DependencyModePickerProps {
|
||||
value: DependencyMode
|
||||
|
@ -27,7 +27,7 @@ function DependencyModePicker({ value, onChange }: DependencyModePickerProps) {
|
|||
tabIndex={-1}
|
||||
onClick={pickerMenu.toggle}
|
||||
>
|
||||
{getDependencyLabel(value)}
|
||||
{labelDependencyMode(value)}
|
||||
</span>
|
||||
{ pickerMenu.isActive &&
|
||||
<Dropdown stretchLeft >
|
||||
|
|
|
@ -4,7 +4,7 @@ import Dropdown from '../../../components/Common/Dropdown';
|
|||
import DropdownButton from '../../../components/Common/DropdownButton';
|
||||
import useDropdown from '../../../hooks/useDropdown';
|
||||
import { CstMatchMode } from '../../../models/miscelanious';
|
||||
import { getCstCompareLabel } from '../../../utils/staticUI';
|
||||
import { labelCstMathchMode } from '../../../utils/labels';
|
||||
|
||||
interface MatchModePickerProps {
|
||||
value: CstMatchMode
|
||||
|
@ -27,7 +27,7 @@ function MatchModePicker({ value, onChange }: MatchModePickerProps) {
|
|||
tabIndex={-1}
|
||||
onClick={pickerMenu.toggle}
|
||||
>
|
||||
{getCstCompareLabel(value)}
|
||||
{labelCstMathchMode(value)}
|
||||
</span>
|
||||
{ pickerMenu.isActive &&
|
||||
<Dropdown>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { IExpressionParse, IRSErrorDescription, SyntaxTree } from '../../../models/rslang';
|
||||
import { getRSErrorMessage, getRSErrorPrefix } from '../../../utils/staticUI';
|
||||
import { describeRSError } from '../../../utils/labels';
|
||||
import { getRSErrorPrefix } from '../../../utils/misc';
|
||||
|
||||
interface ParsingResultProps {
|
||||
data: IExpressionParse
|
||||
|
@ -22,7 +23,7 @@ function ParsingResult({ data, onShowAST, onShowError }: ParsingResultProps) {
|
|||
return (
|
||||
<p key={`error-${index}`} className='cursor-pointer text-warning' onClick={() => onShowError(error)}>
|
||||
<span className='mr-1 font-semibold underline'>{error.isCritical ? 'Ошибка' : 'Предупреждение'} {getRSErrorPrefix(error)}:</span>
|
||||
<span> {getRSErrorMessage(error)}</span>
|
||||
<span> {describeRSError(error)}</span>
|
||||
</p>
|
||||
);
|
||||
})}
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
import { TokenID } from '../../../models/rslang';
|
||||
import { getRSButtonData } from '../../../utils/staticUI'
|
||||
import { describeToken, labelToken } from '../../../utils/labels';
|
||||
|
||||
interface RSTokenButtonProps {
|
||||
id: TokenID
|
||||
token: TokenID
|
||||
disabled?: boolean
|
||||
onInsert: (token: TokenID, key?: string) => void
|
||||
}
|
||||
|
||||
function RSTokenButton({ id, disabled, onInsert }: RSTokenButtonProps) {
|
||||
const data = getRSButtonData(id);
|
||||
const width = data.text.length > 3 ? 'w-[4rem]' : 'w-[2rem]';
|
||||
function RSTokenButton({ token, disabled, onInsert }: RSTokenButtonProps) {
|
||||
const label = labelToken(token);
|
||||
const width = label.length > 3 ? 'w-[4rem]' : 'w-[2rem]';
|
||||
return (
|
||||
<button
|
||||
type='button'
|
||||
disabled={disabled}
|
||||
onClick={() => onInsert(id)}
|
||||
title={data.tooltip}
|
||||
onClick={() => onInsert(token)}
|
||||
title={describeToken(token)}
|
||||
tabIndex={-1}
|
||||
className={`px-1 cursor-pointer border rounded-none h-7 ${width} clr-outline clr-hover clr-btn-clear`}
|
||||
>
|
||||
{data.text && <span className='whitespace-nowrap'>{data.text}</span>}
|
||||
{label && <span className='whitespace-nowrap'>{label}</span>}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@ import { useConceptTheme } from '../../../context/ThemeContext';
|
|||
import { ExpressionStatus } from '../../../models/rsform';
|
||||
import { type IConstituenta, inferStatus } from '../../../models/rsform';
|
||||
import { IExpressionParse, ParsingStatus } from '../../../models/rslang';
|
||||
import { getCstStatusBgColor, mapStatusInfo } from '../../../utils/staticUI';
|
||||
import { colorbgCstStatus } from '../../../utils/color';
|
||||
import { describeExpressionStatus, labelExpressionStatus } from '../../../utils/labels';
|
||||
|
||||
interface StatusBarProps {
|
||||
isModified?: boolean
|
||||
|
@ -25,13 +26,12 @@ function StatusBar({ isModified, constituenta, parseData }: StatusBarProps) {
|
|||
return inferStatus(constituenta?.parse?.status, constituenta?.parse?.valueClass);
|
||||
}, [isModified, constituenta, parseData]);
|
||||
|
||||
const data = mapStatusInfo.get(status)!;
|
||||
return (
|
||||
<div title={data.tooltip}
|
||||
<div title={describeExpressionStatus(status)}
|
||||
className='text-sm h-[1.6rem] w-[10rem] font-semibold inline-flex border items-center select-none justify-center align-middle'
|
||||
style={{backgroundColor: getCstStatusBgColor(status, colors)}}
|
||||
style={{backgroundColor: colorbgCstStatus(status, colors)}}
|
||||
>
|
||||
Статус: [ {data.text} ]
|
||||
Статус: [ {labelExpressionStatus(status)} ]
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -9,8 +9,10 @@ import { DependencyMode } from '../../../models/miscelanious';
|
|||
import { CstMatchMode } from '../../../models/miscelanious';
|
||||
import { applyGraphFilter } from '../../../models/miscelanious';
|
||||
import { CstType, extractGlobals, IConstituenta, matchConstituenta } from '../../../models/rsform';
|
||||
import { createMockConstituenta } from '../../../models/rsform';
|
||||
import { colorfgCstStatus } from '../../../utils/color';
|
||||
import { prefixes } from '../../../utils/constants';
|
||||
import { getCstDescription, getCstStatusFgColor, getMockConstituenta } from '../../../utils/staticUI';
|
||||
import { describeConstituenta } from '../../../utils/labels';
|
||||
import ConstituentaTooltip from './ConstituentaTooltip';
|
||||
import DependencyModePicker from './DependencyModePicker';
|
||||
import MatchModePicker from './MatchModePicker';
|
||||
|
@ -74,7 +76,7 @@ function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }:
|
|||
if (diff.length > 0) {
|
||||
diff.forEach(
|
||||
(alias, index) => filtered.push(
|
||||
getMockConstituenta(
|
||||
createMockConstituenta(
|
||||
schema.id,
|
||||
-index,
|
||||
alias,
|
||||
|
@ -124,8 +126,8 @@ function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }:
|
|||
className='min-w-[3.1rem] max-w-[3.1rem] px-1 text-center rounded-md whitespace-nowrap'
|
||||
style={{
|
||||
borderWidth: '1px',
|
||||
borderColor: getCstStatusFgColor(cst.status, colors),
|
||||
color: getCstStatusFgColor(cst.status, colors),
|
||||
borderColor: colorfgCstStatus(cst.status, colors),
|
||||
color: colorfgCstStatus(cst.status, colors),
|
||||
fontWeight: 600,
|
||||
backgroundColor: isMockCst(cst) ? colors.bgWarning : colors.bgInput
|
||||
}}
|
||||
|
@ -136,7 +138,7 @@ function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }:
|
|||
</>);
|
||||
}
|
||||
}),
|
||||
columnHelper.accessor(cst => getCstDescription(cst), {
|
||||
columnHelper.accessor(cst => describeConstituenta(cst), {
|
||||
id: 'description',
|
||||
header: 'Описание',
|
||||
size: 500,
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// ======== ID based fast Graph implementation =============
|
||||
/**
|
||||
* Represents single node of a {@link Graph}, as implemented by storing outgoing and incoming connections.
|
||||
*/
|
||||
export class GraphNode {
|
||||
id: number;
|
||||
outputs: number[];
|
||||
|
@ -36,6 +38,11 @@ export class GraphNode {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a Graph.
|
||||
*
|
||||
* This class is optimized for TermGraph use case and not supposed to be used as generic graph implementation.
|
||||
*/
|
||||
export class Graph {
|
||||
nodes: Map<number, GraphNode> = new Map();
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
// =========== Modules contains all dynamic color definitions ==========
|
||||
|
||||
import { CstClass, ExpressionStatus } from '../models/rsform'
|
||||
import { ISyntaxTreeNode, TokenID } from '../models/rslang'
|
||||
|
||||
|
||||
// ============= MAIN COLOR THEMES ==========
|
||||
export interface IColorTheme {
|
||||
|
@ -269,3 +272,115 @@ export const bracketsDarkT = {
|
|||
color: darkT.fgSelected
|
||||
},
|
||||
};
|
||||
|
||||
// =========== Misc colors ======================
|
||||
export function colorbgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): string {
|
||||
switch (node.typeID) {
|
||||
case TokenID.PUNC_DEFINE:
|
||||
case TokenID.PUNC_STRUCT:
|
||||
case TokenID.ID_LOCAL:
|
||||
return colors.bgGreen;
|
||||
|
||||
case TokenID.ID_GLOBAL:
|
||||
case TokenID.ID_FUNCTION:
|
||||
case TokenID.ID_PREDICATE:
|
||||
case TokenID.ID_RADICAL:
|
||||
case TokenID.LIT_INTEGER:
|
||||
case TokenID.LIT_EMPTYSET:
|
||||
case TokenID.LIT_INTSET:
|
||||
return colors.bgTeal;
|
||||
|
||||
case TokenID.FORALL:
|
||||
case TokenID.EXISTS:
|
||||
case TokenID.NOT:
|
||||
case TokenID.AND:
|
||||
case TokenID.OR:
|
||||
case TokenID.IMPLICATION:
|
||||
case TokenID.EQUIVALENT:
|
||||
case TokenID.GREATER:
|
||||
case TokenID.LESSER:
|
||||
case TokenID.EQUAL:
|
||||
case TokenID.NOTEQUAL:
|
||||
case TokenID.GREATER_OR_EQ:
|
||||
case TokenID.LESSER_OR_EQ:
|
||||
case TokenID.IN:
|
||||
case TokenID.NOTIN:
|
||||
case TokenID.SUBSET_OR_EQ:
|
||||
case TokenID.SUBSET:
|
||||
case TokenID.NOTSUBSET:
|
||||
return colors.bgOrange;
|
||||
|
||||
case TokenID.NT_TUPLE:
|
||||
case TokenID.NT_ENUMERATION:
|
||||
case TokenID.BIGPR:
|
||||
case TokenID.SMALLPR:
|
||||
case TokenID.FILTER:
|
||||
case TokenID.PLUS:
|
||||
case TokenID.MINUS:
|
||||
case TokenID.MULTIPLY:
|
||||
case TokenID.BOOLEAN:
|
||||
case TokenID.DECART:
|
||||
case TokenID.INTERSECTION:
|
||||
case TokenID.UNION:
|
||||
case TokenID.SET_MINUS:
|
||||
case TokenID.SYMMINUS:
|
||||
case TokenID.REDUCE:
|
||||
case TokenID.CARD:
|
||||
case TokenID.BOOL:
|
||||
case TokenID.DEBOOL:
|
||||
return colors.bgBlue;
|
||||
|
||||
case TokenID.NT_FUNC_DEFINITION:
|
||||
case TokenID.NT_DECLARATIVE_EXPR:
|
||||
case TokenID.NT_IMPERATIVE_EXPR:
|
||||
case TokenID.NT_RECURSIVE_FULL:
|
||||
case TokenID.NT_ENUM_DECL:
|
||||
case TokenID.NT_TUPLE_DECL:
|
||||
case TokenID.NT_ARG_DECL:
|
||||
case TokenID.NT_FUNC_CALL:
|
||||
case TokenID.NT_ARGUMENTS:
|
||||
case TokenID.NT_IMP_DECLARE:
|
||||
case TokenID.NT_IMP_ASSIGN:
|
||||
case TokenID.NT_IMP_LOGIC:
|
||||
case TokenID.NT_RECURSIVE_SHORT:
|
||||
return '';
|
||||
|
||||
case TokenID.PUNC_ASSIGN:
|
||||
case TokenID.PUNC_ITERATE:
|
||||
return colors.bgRed;
|
||||
}
|
||||
// node
|
||||
return colors.bgRed;
|
||||
}
|
||||
|
||||
export function colorbgCstStatus(status: ExpressionStatus, colors: IColorTheme): string {
|
||||
switch (status) {
|
||||
case ExpressionStatus.VERIFIED: return colors.bgGreen;
|
||||
case ExpressionStatus.INCORRECT: return colors.bgRed;
|
||||
case ExpressionStatus.INCALCULABLE: return colors.bgOrange;
|
||||
case ExpressionStatus.PROPERTY: return colors.bgTeal;
|
||||
case ExpressionStatus.UNKNOWN: return colors.bgBlue;
|
||||
case ExpressionStatus.UNDEFINED: return colors.bgBlue;
|
||||
}
|
||||
}
|
||||
|
||||
export function colorfgCstStatus(status: ExpressionStatus, colors: IColorTheme): string {
|
||||
switch (status) {
|
||||
case ExpressionStatus.VERIFIED: return colors.fgGreen;
|
||||
case ExpressionStatus.INCORRECT: return colors.fgRed;
|
||||
case ExpressionStatus.INCALCULABLE: return colors.fgOrange;
|
||||
case ExpressionStatus.PROPERTY: return colors.fgTeal;
|
||||
case ExpressionStatus.UNKNOWN: return colors.fgBlue;
|
||||
case ExpressionStatus.UNDEFINED: return colors.fgBlue;
|
||||
}
|
||||
}
|
||||
|
||||
export function colorbgCstClass(cstClass: CstClass, colors: IColorTheme): string {
|
||||
switch (cstClass) {
|
||||
case CstClass.BASIC: return colors.bgGreen;
|
||||
case CstClass.DERIVED: return colors.bgBlue;
|
||||
case CstClass.STATEMENT: return colors.bgRed;
|
||||
case CstClass.TEMPLATE: return colors.bgTeal;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
514
rsconcept/frontend/src/utils/labels.ts
Normal file
514
rsconcept/frontend/src/utils/labels.ts
Normal file
|
@ -0,0 +1,514 @@
|
|||
// =========== Modules contains all text descriptors ==========
|
||||
|
||||
import { Grammeme,IGramData } from '../models/language';
|
||||
import { CstMatchMode, DependencyMode, HelpTopic } from '../models/miscelanious';
|
||||
import { CstClass, CstType, ExpressionStatus, IConstituenta } from '../models/rsform';
|
||||
import { IFunctionArg, IRSErrorDescription, ISyntaxTreeNode, ParsingStatus, RSErrorType, TokenID } from '../models/rslang';
|
||||
|
||||
export function describeConstituenta(cst: IConstituenta): string {
|
||||
if (cst.cst_type === CstType.STRUCTURED) {
|
||||
return (
|
||||
cst.term_resolved || cst.term_raw ||
|
||||
cst.definition_resolved || cst.definition_raw ||
|
||||
cst.convention ||
|
||||
cst.definition_formal
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
cst.term_resolved || cst.term_raw ||
|
||||
cst.definition_resolved || cst.definition_raw ||
|
||||
cst.definition_formal ||
|
||||
cst.convention
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function labelConstituenta(cst: IConstituenta) {
|
||||
return `${cst.alias}: ${describeConstituenta(cst)}`;
|
||||
}
|
||||
|
||||
export function labelToken(id: TokenID): string {
|
||||
switch (id) {
|
||||
case TokenID.BOOLEAN: return 'ℬ()';
|
||||
case TokenID.DECART: return '×';
|
||||
case TokenID.PUNC_PL: return '( )';
|
||||
case TokenID.PUNC_SL: return '[ ]';
|
||||
case TokenID.FORALL: return '∀';
|
||||
case TokenID.EXISTS: return '∃';
|
||||
case TokenID.NOT: return '¬';
|
||||
case TokenID.AND: return '&';
|
||||
case TokenID.OR: return '∨';
|
||||
case TokenID.IMPLICATION: return '⇒';
|
||||
case TokenID.EQUIVALENT: return '⇔';
|
||||
case TokenID.LIT_EMPTYSET: return '∅';
|
||||
case TokenID.LIT_INTSET: return 'Z';
|
||||
case TokenID.EQUAL: return '=';
|
||||
case TokenID.NOTEQUAL: return '≠';
|
||||
case TokenID.GREATER_OR_EQ: return '≥';
|
||||
case TokenID.LESSER_OR_EQ: return '≤';
|
||||
case TokenID.IN: return '∈';
|
||||
case TokenID.NOTIN: return '∉';
|
||||
case TokenID.SUBSET_OR_EQ: return '⊆';
|
||||
case TokenID.SUBSET: return '⊂';
|
||||
case TokenID.NOTSUBSET: return '⊄';
|
||||
case TokenID.INTERSECTION: return '∩';
|
||||
case TokenID.UNION: return '∪';
|
||||
case TokenID.SET_MINUS: return '\\';
|
||||
case TokenID.SYMMINUS: return '∆';
|
||||
case TokenID.NT_DECLARATIVE_EXPR: return 'D{}';
|
||||
case TokenID.NT_IMPERATIVE_EXPR: return 'I{}';
|
||||
case TokenID.NT_RECURSIVE_FULL: return 'R{}';
|
||||
case TokenID.BIGPR: return 'Pr1()';
|
||||
case TokenID.SMALLPR: return 'pr1()';
|
||||
case TokenID.FILTER: return 'Fi1[]()';
|
||||
case TokenID.REDUCE: return 'red()';
|
||||
case TokenID.CARD: return 'card()';
|
||||
case TokenID.BOOL: return 'bool()';
|
||||
case TokenID.DEBOOL: return 'debool()';
|
||||
case TokenID.PUNC_ASSIGN: return ':=';
|
||||
case TokenID.PUNC_ITERATE: return ':∈';
|
||||
}
|
||||
return `no label: ${id}`;
|
||||
}
|
||||
|
||||
export function describeToken(id: TokenID): string {
|
||||
switch (id) {
|
||||
case TokenID.BOOLEAN: return 'Булеан [Alt + E]';
|
||||
case TokenID.DECART: return 'Декартово произведение [Shift + 8 / Alt + Shift + E]';
|
||||
case TokenID.PUNC_PL: return 'Скобки вокруг выражения [Alt + Shift + 9 ]';
|
||||
case TokenID.PUNC_SL: return 'Скобки вокруг выражения [Alt + [ ]';
|
||||
case TokenID.FORALL: return 'Квантор всеобщности [`]';
|
||||
case TokenID.EXISTS: return 'Квантор существования [Shift + `]';
|
||||
case TokenID.NOT: return 'Отрицание [Alt + `]';
|
||||
case TokenID.AND: return 'Конъюнкция [Alt + 3 ~ Shift + 7]';
|
||||
case TokenID.OR: return 'Дизъюнкция [Alt + Shift + 3]';
|
||||
case TokenID.IMPLICATION: return 'Импликация [Alt + 4]';
|
||||
case TokenID.EQUIVALENT: return 'Эквивалентность [Alt + Shift + 4]';
|
||||
case TokenID.LIT_EMPTYSET: return 'Пустое множество [Alt + X]';
|
||||
case TokenID.LIT_INTSET: return 'Целые числа [Alt + Z]';
|
||||
case TokenID.EQUAL: return 'Равенство';
|
||||
case TokenID.NOTEQUAL: return 'Неравенство [Alt + Shift + `]';
|
||||
case TokenID.GREATER_OR_EQ: return 'Больше или равно [Alt + Shift + 7]';
|
||||
case TokenID.LESSER_OR_EQ: return 'Меньше или равно [Alt + Shift + 8]';
|
||||
case TokenID.IN: return 'Быть элементом (принадлежит) [Alt + 1]';
|
||||
case TokenID.NOTIN: return 'Не принадлежит [Alt + Shift + 1]';
|
||||
case TokenID.SUBSET_OR_EQ: return 'Быть частью (нестрогое подмножество) [Alt + 2]';
|
||||
case TokenID.SUBSET: return 'Строгое подмножество [Alt + 7]';
|
||||
case TokenID.NOTSUBSET: return 'Не подмножество [Alt + Shift + 2]';
|
||||
case TokenID.INTERSECTION: return 'Пересечение [Alt + A]';
|
||||
case TokenID.UNION: return 'Объединение [Alt + S]';
|
||||
case TokenID.SET_MINUS: return 'Разность множеств [Alt + 5]';
|
||||
case TokenID.SYMMINUS: return 'Симметрическая разность [Alt + Shift + 5]';
|
||||
case TokenID.NT_DECLARATIVE_EXPR: return 'Декларативная форма определения терма [Alt + D]';
|
||||
case TokenID.NT_IMPERATIVE_EXPR: return 'Императивная форма определения терма [Alt + G]';
|
||||
case TokenID.NT_RECURSIVE_FULL: return 'Рекурсивная (цикличная) форма определения терма [Alt + T]';
|
||||
case TokenID.BIGPR: return 'Большая проекция [Alt + Q]';
|
||||
case TokenID.SMALLPR: return 'Малая проекция [Alt + W]';
|
||||
case TokenID.FILTER: return 'Фильтр [Alt + F]';
|
||||
case TokenID.REDUCE: return 'Множество-сумма [Alt + R]';
|
||||
case TokenID.CARD: return 'Мощность [Alt + C]';
|
||||
case TokenID.BOOL: return 'Синглетон [Alt + B]';
|
||||
case TokenID.DEBOOL: return 'Десинглетон [Alt + V]';
|
||||
case TokenID.PUNC_ASSIGN: return 'Присвоение (императивный синтаксис) [Alt + Shift + 6]';
|
||||
case TokenID.PUNC_ITERATE: return 'Перебор элементов множества (императивный синтаксис) [Alt + 6]';
|
||||
}
|
||||
return `no description: ${id}`;
|
||||
}
|
||||
|
||||
export function labelCstMathchMode(mode: CstMatchMode): string {
|
||||
switch (mode) {
|
||||
case CstMatchMode.ALL: return 'везде';
|
||||
case CstMatchMode.EXPR: return 'выраж';
|
||||
case CstMatchMode.TERM: return 'термин';
|
||||
case CstMatchMode.TEXT: return 'текст';
|
||||
case CstMatchMode.NAME: return 'имя';
|
||||
}
|
||||
}
|
||||
|
||||
export function labelDependencyMode(mode: DependencyMode): string {
|
||||
switch (mode) {
|
||||
case DependencyMode.ALL: return 'вся схема';
|
||||
case DependencyMode.EXPRESSION: return 'выражение';
|
||||
case DependencyMode.OUTPUTS: return 'потребители';
|
||||
case DependencyMode.INPUTS: return 'поставщики';
|
||||
case DependencyMode.EXPAND_INPUTS: return 'влияющие';
|
||||
case DependencyMode.EXPAND_OUTPUTS: return 'зависимые';
|
||||
}
|
||||
}
|
||||
|
||||
export const mapLableLayout: Map<string, string> =
|
||||
new Map([
|
||||
['forceatlas2', 'Граф: Атлас 2D'],
|
||||
['forceDirected2d', 'Граф: Силы 2D'],
|
||||
['forceDirected3d', 'Граф: Силы 3D'],
|
||||
['treeTd2d', 'Граф: ДеревоВерт 2D'],
|
||||
['treeTd3d', 'Граф: ДеревоВерт 3D'],
|
||||
['treeLr2d', 'Граф: ДеревоГор 2D'],
|
||||
['treeLr3d', 'Граф: ДеревоГор 3D'],
|
||||
['radialOut2d', 'Граф: Радиальная 2D'],
|
||||
['radialOut3d', 'Граф: Радиальная 3D'],
|
||||
['circular2d', 'Граф: Круговая'],
|
||||
['hierarchicalTd', 'Граф: ИерархияВерт'],
|
||||
['hierarchicalLr', 'Граф: ИерархияГор'],
|
||||
['nooverlap', 'Граф: Без перекрытия']
|
||||
]);
|
||||
|
||||
export const mapLabelColoring: Map<string, string> =
|
||||
new Map([
|
||||
['none', 'Цвет: моно'],
|
||||
['status', 'Цвет: статус'],
|
||||
['type', 'Цвет: класс'],
|
||||
]);
|
||||
|
||||
export function labelExpressionStatus(status: ExpressionStatus): string {
|
||||
switch (status) {
|
||||
case ExpressionStatus.VERIFIED: return 'ок';
|
||||
case ExpressionStatus.INCORRECT: return 'ошибка';
|
||||
case ExpressionStatus.INCALCULABLE: return 'невыч';
|
||||
case ExpressionStatus.PROPERTY: return 'св-во';
|
||||
case ExpressionStatus.UNKNOWN: return 'неизв';
|
||||
case ExpressionStatus.UNDEFINED: return 'N/A';
|
||||
}
|
||||
}
|
||||
|
||||
export function describeExpressionStatus(status: ExpressionStatus): string {
|
||||
switch (status) {
|
||||
case ExpressionStatus.VERIFIED: return 'выражение корректно и вычислимо';
|
||||
case ExpressionStatus.INCORRECT: return 'ошибка в выражении';
|
||||
case ExpressionStatus.INCALCULABLE: return 'выражение не вычислимо';
|
||||
case ExpressionStatus.PROPERTY: return 'можно проверить принадлежность, но нельзя получить значение';
|
||||
case ExpressionStatus.UNKNOWN: return 'требует проверки выражения';
|
||||
case ExpressionStatus.UNDEFINED: return 'произошла ошибка при проверке выражения';
|
||||
}
|
||||
}
|
||||
|
||||
export function labelHelpTopic(topic: HelpTopic): string {
|
||||
switch (topic) {
|
||||
case HelpTopic.MAIN: return 'Портал';
|
||||
case HelpTopic.RSLANG: return 'Экспликация';
|
||||
case HelpTopic.LIBRARY: return 'Библиотека';
|
||||
case HelpTopic.RSFORM: return '- паспорт схемы';
|
||||
case HelpTopic.CSTLIST: return '- список конституент';
|
||||
case HelpTopic.CONSTITUENTA: return '- конституента';
|
||||
case HelpTopic.GRAPH_TERM: return '- граф термов';
|
||||
case HelpTopic.EXTEOR: return 'Экстеор';
|
||||
case HelpTopic.API: return 'REST API';
|
||||
}
|
||||
}
|
||||
|
||||
export function describeHelpTopic(topic: HelpTopic): string {
|
||||
switch (topic) {
|
||||
case HelpTopic.MAIN: return 'Общая справка по порталу';
|
||||
case HelpTopic.RSLANG: return 'Справка по языку родов структур и экспликации';
|
||||
case HelpTopic.LIBRARY: return 'Описание работы с библиотекой схем';
|
||||
case HelpTopic.RSFORM: return 'Описание работы с описанием схемы';
|
||||
case HelpTopic.CSTLIST: return 'Описание работы со списком конституентт';
|
||||
case HelpTopic.CONSTITUENTA: return 'Описание редактирования конституенты';
|
||||
case HelpTopic.GRAPH_TERM: return 'Описание работы с графом термов схемы';
|
||||
case HelpTopic.EXTEOR: return 'Справка по программе для экспликации "Экстеор" для Windows';
|
||||
case HelpTopic.API: return 'Описание интерфейса для разработчиков';
|
||||
}
|
||||
}
|
||||
|
||||
export function labelCstType(type: CstType) {
|
||||
switch (type) {
|
||||
case CstType.BASE: return 'Базисное множество';
|
||||
case CstType.CONSTANT: return 'Константное множество';
|
||||
case CstType.STRUCTURED: return 'Родовая структура';
|
||||
case CstType.AXIOM: return 'Аксиома';
|
||||
case CstType.TERM: return 'Терм';
|
||||
case CstType.FUNCTION: return 'Терм-функция';
|
||||
case CstType.PREDICATE: return 'Предикат-функция';
|
||||
case CstType.THEOREM: return 'Теорема';
|
||||
}
|
||||
}
|
||||
|
||||
export function labelCstClass(cclass: CstClass): string {
|
||||
switch (cclass) {
|
||||
case CstClass.BASIC: return 'базовый';
|
||||
case CstClass.DERIVED: return 'производный';
|
||||
case CstClass.STATEMENT: return 'утверждение';
|
||||
case CstClass.TEMPLATE: return 'шаблон';
|
||||
}
|
||||
}
|
||||
|
||||
export function describeCstClass(cclass: CstClass): string {
|
||||
switch (cclass) {
|
||||
case CstClass.BASIC: return 'неопределяемое понятие, требует конвенции';
|
||||
case CstClass.DERIVED: return 'выводимое понятие, задаваемое определением';
|
||||
case CstClass.STATEMENT: return 'утверждение формальной логики';
|
||||
case CstClass.TEMPLATE: return 'параметризованный шаблон определения';
|
||||
}
|
||||
}
|
||||
|
||||
export function labelTypification({ isValid, resultType, args }: {
|
||||
isValid: boolean;
|
||||
resultType: string;
|
||||
args: IFunctionArg[];
|
||||
}): string {
|
||||
if (!isValid) {
|
||||
return 'N/A';
|
||||
}
|
||||
if (resultType === '' || resultType === 'LOGIC') {
|
||||
resultType = 'Logical';
|
||||
}
|
||||
if (args.length === 0) {
|
||||
return resultType;
|
||||
}
|
||||
const argsText = args.map(arg => arg.typification).join(', ');
|
||||
return `${resultType} 🠔 [${argsText}]`;
|
||||
}
|
||||
|
||||
export function labelCstTypification(cst: IConstituenta): string {
|
||||
return labelTypification({
|
||||
isValid: cst.parse.status === ParsingStatus.VERIFIED,
|
||||
resultType: cst.parse.typification,
|
||||
args: cst.parse.args
|
||||
});
|
||||
}
|
||||
|
||||
export function labelSyntaxTree(node: ISyntaxTreeNode): string {
|
||||
switch (node.typeID) {
|
||||
case TokenID.ID_LOCAL:
|
||||
case TokenID.ID_GLOBAL:
|
||||
case TokenID.ID_FUNCTION:
|
||||
case TokenID.ID_PREDICATE:
|
||||
case TokenID.ID_RADICAL:
|
||||
return node.data.value as string;
|
||||
|
||||
case TokenID.LIT_INTEGER: return String(node.data.value as number);
|
||||
|
||||
case TokenID.BIGPR: return 'Pr' + (node.data.value as string[]).toString();
|
||||
case TokenID.SMALLPR: return 'pr' + (node.data.value as string[]).toString();
|
||||
case TokenID.FILTER: return 'Fi' + (node.data.value as string[]).toString();
|
||||
|
||||
case TokenID.PLUS: return '+';
|
||||
case TokenID.MINUS: return '-';
|
||||
case TokenID.MULTIPLY: return '*';
|
||||
case TokenID.GREATER: return '>';
|
||||
case TokenID.LESSER: return '<';
|
||||
|
||||
case TokenID.NT_TUPLE: return 'TUPLE';
|
||||
case TokenID.NT_ENUMERATION: return 'ENUM';
|
||||
|
||||
case TokenID.NT_ENUM_DECL: return 'ENUM_DECLARATION';
|
||||
case TokenID.NT_TUPLE_DECL: return 'TUPLE_DECLARATION';
|
||||
case TokenID.PUNC_DEFINE: return 'DEFINITION';
|
||||
case TokenID.PUNC_STRUCT: return 'STRUCTURE_DEFITION';
|
||||
|
||||
case TokenID.NT_ARG_DECL: return 'ARG';
|
||||
case TokenID.NT_FUNC_CALL: return 'CALL';
|
||||
case TokenID.NT_ARGUMENTS: return 'ARGS';
|
||||
|
||||
case TokenID.NT_FUNC_DEFINITION: return 'FUNCTION_DEFINITION';
|
||||
case TokenID.NT_IMP_DECLARE: return 'IDECLARE';
|
||||
case TokenID.NT_IMP_ASSIGN: return 'IASSIGN';
|
||||
case TokenID.NT_IMP_LOGIC: return 'ICHECK';
|
||||
|
||||
case TokenID.NT_RECURSIVE_SHORT: return labelToken(TokenID.NT_RECURSIVE_FULL);
|
||||
|
||||
case TokenID.BOOLEAN:
|
||||
case TokenID.DECART:
|
||||
case TokenID.FORALL:
|
||||
case TokenID.EXISTS:
|
||||
case TokenID.NOT:
|
||||
case TokenID.AND:
|
||||
case TokenID.OR:
|
||||
case TokenID.IMPLICATION:
|
||||
case TokenID.EQUIVALENT:
|
||||
case TokenID.LIT_EMPTYSET:
|
||||
case TokenID.LIT_INTSET:
|
||||
case TokenID.EQUAL:
|
||||
case TokenID.NOTEQUAL:
|
||||
case TokenID.GREATER_OR_EQ:
|
||||
case TokenID.LESSER_OR_EQ:
|
||||
case TokenID.IN:
|
||||
case TokenID.NOTIN:
|
||||
case TokenID.SUBSET_OR_EQ:
|
||||
case TokenID.SUBSET:
|
||||
case TokenID.NOTSUBSET:
|
||||
case TokenID.INTERSECTION:
|
||||
case TokenID.UNION:
|
||||
case TokenID.SET_MINUS:
|
||||
case TokenID.SYMMINUS:
|
||||
case TokenID.NT_DECLARATIVE_EXPR:
|
||||
case TokenID.NT_IMPERATIVE_EXPR:
|
||||
case TokenID.NT_RECURSIVE_FULL:
|
||||
case TokenID.REDUCE:
|
||||
case TokenID.CARD:
|
||||
case TokenID.BOOL:
|
||||
case TokenID.DEBOOL:
|
||||
case TokenID.PUNC_ASSIGN:
|
||||
case TokenID.PUNC_ITERATE:
|
||||
return labelToken(node.typeID);
|
||||
}
|
||||
// node
|
||||
return 'UNKNOWN ' + String(node.typeID);
|
||||
}
|
||||
|
||||
export function labelGrammeme(gram: IGramData): string {
|
||||
switch (gram.type) {
|
||||
case Grammeme.NOUN: return 'ЧР: сущ';
|
||||
case Grammeme.VERB: return 'ЧР: глагол';
|
||||
case Grammeme.INFN: return 'ЧР: глагол инф';
|
||||
case Grammeme.ADJF: return 'ЧР: прил';
|
||||
case Grammeme.PRTF: return 'ЧР: прич';
|
||||
case Grammeme.ADJS: return 'ЧР: кр прил';
|
||||
case Grammeme.PRTS: return 'ЧР: кр прич';
|
||||
case Grammeme.COMP: return 'ЧР: компаратив';
|
||||
case Grammeme.GRND: return 'ЧР: деепричастие';
|
||||
case Grammeme.NUMR: return 'ЧР: число';
|
||||
case Grammeme.ADVB: return 'ЧР: наречие';
|
||||
case Grammeme.NPRO: return 'ЧР: местоимение';
|
||||
case Grammeme.PRED: return 'ЧР: предикатив';
|
||||
case Grammeme.PREP: return 'ЧР: предлог';
|
||||
case Grammeme.CONJ: return 'ЧР: союз';
|
||||
case Grammeme.PRCL: return 'ЧР: частица';
|
||||
case Grammeme.INTJ: return 'ЧР: междометие';
|
||||
case Grammeme.Abbr: return 'ЧР: аббревиатура';
|
||||
|
||||
case Grammeme.sing: return 'Число: един';
|
||||
case Grammeme.plur: return 'Число: множ';
|
||||
|
||||
case Grammeme.nomn: return 'Падеж: имен';
|
||||
case Grammeme.gent: return 'Падеж: род';
|
||||
case Grammeme.datv: return 'Падеж: дат';
|
||||
case Grammeme.accs: return 'Падеж: вин';
|
||||
case Grammeme.ablt: return 'Падеж: твор';
|
||||
case Grammeme.loct: return 'Падеж: пред';
|
||||
|
||||
case Grammeme.masc: return 'Род: муж';
|
||||
case Grammeme.femn: return 'Род: жен';
|
||||
case Grammeme.neut: return 'Род: ср';
|
||||
|
||||
case Grammeme.perf: return 'Совершенный: да';
|
||||
case Grammeme.impf: return 'Совершенный: нет';
|
||||
|
||||
case Grammeme.tran: return 'Переходный: да';
|
||||
case Grammeme.intr: return 'Переходный: нет';
|
||||
|
||||
case Grammeme.pres: return 'Время: наст';
|
||||
case Grammeme.past: return 'Время: прош';
|
||||
case Grammeme.futr: return 'Время: буд';
|
||||
|
||||
case Grammeme.per1: return 'Лицо: 1';
|
||||
case Grammeme.per2: return 'Лицо: 2';
|
||||
case Grammeme.per3: return 'Лицо: 3';
|
||||
|
||||
case Grammeme.impr: return 'Повелительный: да';
|
||||
case Grammeme.indc: return 'Повелительный: нет';
|
||||
|
||||
case Grammeme.incl: return 'Включающий: да';
|
||||
case Grammeme.excl: return 'Включающий: нет';
|
||||
|
||||
case Grammeme.pssv: return 'Страдательный: да';
|
||||
case Grammeme.actv: return 'Страдательный: нет';
|
||||
|
||||
case Grammeme.anim: return 'Одушевленный: да';
|
||||
case Grammeme.inan: return 'Одушевленный: нет';
|
||||
|
||||
case Grammeme.Infr: return 'Стиль: неформальный';
|
||||
case Grammeme.Slng: return 'Стиль: жаргон';
|
||||
case Grammeme.Arch: return 'Стиль: устаревший';
|
||||
case Grammeme.Litr: return 'Стиль: литературный';
|
||||
|
||||
case Grammeme.UNKN: return `Неизв: ${gram.data}`;
|
||||
}
|
||||
}
|
||||
|
||||
export function describeRSError(error: IRSErrorDescription): string {
|
||||
switch (error.errorType) {
|
||||
case RSErrorType.syntax:
|
||||
return 'Неопределенная синтаксическая ошибка';
|
||||
case RSErrorType.missingParanthesis:
|
||||
return 'Некорректная конструкция языка родов структур, проверьте структуру выражения';
|
||||
case RSErrorType.missingCurlyBrace:
|
||||
return "Пропущен символ '}'";
|
||||
case RSErrorType.invalidQuantifier:
|
||||
return 'Некорректная кванторная декларация';
|
||||
case RSErrorType.expectedArgDeclaration:
|
||||
return 'Ожидалось объявление аргументов терм-функции';
|
||||
case RSErrorType.expectedLocal:
|
||||
return 'Ожидалось имя локальной переменной';
|
||||
|
||||
case RSErrorType.localDoubleDeclare:
|
||||
return `Предупреждение! Повторное объявление локальной переменной ${error.params[0]}`;
|
||||
case RSErrorType.localNotUsed:
|
||||
return `Предупреждение! Переменная объявлена, но не использована: ${error.params[0]}`;
|
||||
case RSErrorType.localUndeclared:
|
||||
return `Использование необъявленной переменной: ${error.params[0]}`;
|
||||
case RSErrorType.localShadowing:
|
||||
return `Повторное объявление переменной: ${error.params[0]}`;
|
||||
|
||||
case RSErrorType.typesNotEqual:
|
||||
return `Типизация операндов не совпадает! ${error.params[0]} != ${error.params[1]}`;
|
||||
case RSErrorType.globalNotTyped:
|
||||
return `Типизация конституенты не определена: ${error.params[0]}`;
|
||||
case RSErrorType.invalidDecart:
|
||||
return `τ(α×b) = ℬ(𝔇τ(α)×𝔇τ(b)). Некорректная типизация аргумента: ${error.params[0]}`;
|
||||
case RSErrorType.invalidBoolean:
|
||||
return `τ(ℬ(a)) = ℬℬ𝔇τ(a). Некорректная типизация аргумента: ${error.params[0]}`;
|
||||
case RSErrorType.invalidTypeOperation:
|
||||
return `Типизация операнда теоретико-множественной операции не корректна: ${error.params[0]}`;
|
||||
case RSErrorType.invalidCard:
|
||||
return `Некорректная типизация аргумента операции мощности: ${error.params[0]}`;
|
||||
case RSErrorType.invalidDebool:
|
||||
return `τ(debool(a)) = 𝔇τ(a). Некорректная типизация аргумента: ${error.params[0]}`;
|
||||
case RSErrorType.globalFuncMissing:
|
||||
return `Неизвестное имя функции: ${error.params[0]}`;
|
||||
case RSErrorType.globalFuncWithoutArgs:
|
||||
return `Некорректное использование имени функции без аргументов: ${error.params[0]}`;
|
||||
case RSErrorType.invalidReduce:
|
||||
return `τ(red(a)) = ℬ𝔇𝔇τ(a). Некорректная типизация аргумента: ${error.params[0]}`;
|
||||
case RSErrorType.invalidProjectionTuple:
|
||||
return `Проекция не определена: ${error.params[0]} -> ${error.params[1]}`;
|
||||
case RSErrorType.invalidProjectionSet:
|
||||
return `τ(Pri(a)) = ℬ𝒞i𝔇τ(a). Некорректная типизация аргумента: ${error.params[0]}`;
|
||||
case RSErrorType.invalidEnumeration:
|
||||
return `Типизация аргументов перечисления не совпадает: ${error.params[0]} != ${error.params[1]}`;
|
||||
case RSErrorType.ivalidBinding:
|
||||
return `Количество переменных в кортеже не соответствует размерности декартова произведения`;
|
||||
case RSErrorType.localOutOfScope:
|
||||
return `Использование имени переменной вне области действия: ${error.params[0]}`;
|
||||
case RSErrorType.invalidElementPredicat:
|
||||
return `Несоответствие типизаций операндов для оператора: ${error.params[0]}${error.params[1]}${error.params[2]}`;
|
||||
case RSErrorType.invalidArgsArtity:
|
||||
return `Неверное число аргументов терм-функции: ${error.params[0]} != ${error.params[1]}`;
|
||||
case RSErrorType.invalidArgumentType:
|
||||
return `Типизация аргумента терм-функции не соответствует объявленной: ${error.params[0]} != ${error.params[1]}`;
|
||||
case RSErrorType.invalidEqualsEmpty:
|
||||
return `Только множества можно сравнивать с пустым множеством: ${error.params[0]}`;
|
||||
case RSErrorType.globalStructure:
|
||||
return `Выражение родовой структуры должно быть ступенью`;
|
||||
case RSErrorType.globalExpectedFunction:
|
||||
return `Ожидалось выражение объявления функции`;
|
||||
case RSErrorType.emptySetUsage:
|
||||
return `Запрещено использование пустого множества как типизированного выражения`;
|
||||
case RSErrorType.radicalUsage:
|
||||
return `Радикалы запрещены вне деклараций терм-функции: ${error.params[0]}`;
|
||||
case RSErrorType.invalidFilterArgumentType:
|
||||
return `Типизация аргумента фильтра не корректна: ${error.params[0]}(${error.params[1]})`;
|
||||
case RSErrorType.invalidFilterArity:
|
||||
return `Количество параметров фильтра не соответствует количеству индексов`;
|
||||
case RSErrorType.arithmeticNotSupported:
|
||||
return `Тип не поддерживает арифметические операторы: ${error.params[0]}`;
|
||||
case RSErrorType.typesNotCompatible:
|
||||
return `Типы не совместимы для выбранной операции: ${error.params[0]} и ${error.params[1]}`;
|
||||
case RSErrorType.orderingNotSupported:
|
||||
return `Тип не поддерживает предикаты порядка: ${error.params[0]}`;
|
||||
case RSErrorType.globalNoValue:
|
||||
return `Используется неинтерпретируемый глобальный идентификатор: ${error.params[0]}`;
|
||||
case RSErrorType.invalidPropertyUsage:
|
||||
return `Использование неитерируемого множества в качестве значения`;
|
||||
case RSErrorType.globalMissingAST:
|
||||
return `Не удалось получить дерево разбора для глобального идентификатора: ${error.params[0]}`;
|
||||
case RSErrorType.globalFuncNoInterpretation:
|
||||
return `Функция не интерпретируется для данных аргументов`;
|
||||
case RSErrorType.globalNonemptyBase:
|
||||
return `Непустое выражение базисного/константного множества`;
|
||||
case RSErrorType.globalUnexpectedType:
|
||||
return `Типизация выражения не соответствует типу конституенты`;
|
||||
}
|
||||
return 'UNKNOWN ERROR';
|
||||
}
|
||||
|
72
rsconcept/frontend/src/utils/misc.ts
Normal file
72
rsconcept/frontend/src/utils/misc.ts
Normal file
|
@ -0,0 +1,72 @@
|
|||
|
||||
// Module: miscellaneous static functions to generate UI resources
|
||||
|
||||
import { CstType, IConstituenta, IRSForm } from '../models/rsform';
|
||||
import { IRSErrorDescription } from '../models/rslang';
|
||||
import { resolveErrorClass, RSErrorClass } from '../models/rslang';
|
||||
import { labelCstType } from './labels';
|
||||
|
||||
export function getCstTypePrefix(type: CstType) {
|
||||
switch (type) {
|
||||
case CstType.BASE: return 'X';
|
||||
case CstType.CONSTANT: return 'C';
|
||||
case CstType.STRUCTURED: return 'S';
|
||||
case CstType.AXIOM: return 'A';
|
||||
case CstType.TERM: return 'D';
|
||||
case CstType.FUNCTION: return 'F';
|
||||
case CstType.PREDICATE: return 'P';
|
||||
case CstType.THEOREM: return 'T';
|
||||
}
|
||||
}
|
||||
|
||||
export function getCstExpressionPrefix(cst: IConstituenta): string {
|
||||
return cst.alias + (cst.cst_type === CstType.STRUCTURED ? '::=' : ':==');
|
||||
}
|
||||
|
||||
export function getCstTypeShortcut(type: CstType) {
|
||||
const prefix = labelCstType(type) + ' [Alt + ';
|
||||
switch (type) {
|
||||
case CstType.BASE: return prefix + '1]';
|
||||
case CstType.STRUCTURED: return prefix + '2]';
|
||||
case CstType.TERM: return prefix + '3]';
|
||||
case CstType.AXIOM: return prefix + '4]';
|
||||
case CstType.FUNCTION: return prefix + 'Q]';
|
||||
case CstType.PREDICATE: return prefix + 'W]';
|
||||
case CstType.CONSTANT: return prefix + '5]';
|
||||
case CstType.THEOREM: return prefix + '6]';
|
||||
}
|
||||
}
|
||||
|
||||
export function createAliasFor(type: CstType, schema: IRSForm): string {
|
||||
const prefix = getCstTypePrefix(type);
|
||||
if (!schema.items || schema.items.length <= 0) {
|
||||
return `${prefix}1`;
|
||||
}
|
||||
const index = schema.items.reduce((prev, cst, index) => {
|
||||
if (cst.cst_type !== type) {
|
||||
return prev;
|
||||
}
|
||||
index = Number(cst.alias.slice(1 - cst.alias.length)) + 1;
|
||||
return Math.max(prev, index);
|
||||
}, 1);
|
||||
return `${prefix}${index}`;
|
||||
}
|
||||
|
||||
export function cloneTitle(schema: IRSForm): string {
|
||||
if (!schema.title.includes('[клон]')) {
|
||||
return schema.title + ' [клон]';
|
||||
} else {
|
||||
return (schema.title + '+');
|
||||
}
|
||||
}
|
||||
|
||||
export function getRSErrorPrefix(error: IRSErrorDescription): string {
|
||||
const id = error.errorType.toString(16)
|
||||
switch(resolveErrorClass(error.errorType)) {
|
||||
case RSErrorClass.LEXER: return 'L' + id;
|
||||
case RSErrorClass.PARSER: return 'P' + id;
|
||||
case RSErrorClass.SEMANTIC: return 'S' + id;
|
||||
case RSErrorClass.UNKNOWN: return 'U' + id;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
// Module: Selector maps
|
||||
import { LayoutTypes } from 'reagraph';
|
||||
|
||||
import { Grammeme } from '../models/language';
|
||||
import { Grammeme, IGramData } from '../models/language';
|
||||
import { CstType } from '../models/rsform';
|
||||
import { ColoringScheme } from '../pages/RSFormPage/EditorTermGraph';
|
||||
import { getCstTypeLabel } from './staticUI';
|
||||
import { labelGrammeme } from './labels';
|
||||
import { labelCstType } from './labels';
|
||||
|
||||
|
||||
export const SelectorGraphLayout: { value: LayoutTypes, label: string }[] = [
|
||||
|
@ -33,53 +34,35 @@ export const SelectorCstType = (
|
|||
Object.values(CstType)).map(
|
||||
typeStr => ({
|
||||
value: typeStr as CstType,
|
||||
label: getCstTypeLabel(typeStr as CstType)
|
||||
label: labelCstType(typeStr as CstType)
|
||||
})
|
||||
);
|
||||
|
||||
export const SelectorGrammems: { value: Grammeme, label: string }[] = [
|
||||
{ value: Grammeme.sing, label: 'Число: един' },
|
||||
{ value: Grammeme.plur, label: 'Число: множ' },
|
||||
export interface IGrammemeOption {
|
||||
value: Grammeme
|
||||
label: string
|
||||
}
|
||||
|
||||
{ value: Grammeme.nomn, label: 'Падеж: имен' },
|
||||
{ value: Grammeme.gent, label: 'Падеж: род' },
|
||||
{ value: Grammeme.datv, label: 'Падеж: дат' },
|
||||
{ value: Grammeme.accs, label: 'Падеж: вин' },
|
||||
{ value: Grammeme.ablt, label: 'Падеж: твор' },
|
||||
{ value: Grammeme.loct, label: 'Падеж: пред' },
|
||||
export const SelectorGrammems: IGrammemeOption[] =
|
||||
[
|
||||
Grammeme.NOUN, Grammeme.VERB,
|
||||
|
||||
{ value: Grammeme.NOUN, label: 'ЧР: сущ' },
|
||||
{ value: Grammeme.VERB, label: 'ЧР: глагол' },
|
||||
{ value: Grammeme.INFN, label: 'ЧР: глагол инф' },
|
||||
{ value: Grammeme.ADJF, label: 'ЧР: прил' },
|
||||
{ value: Grammeme.ADJS, label: 'ЧР: кр прил' },
|
||||
{ value: Grammeme.PRTF, label: 'ЧР: прич' },
|
||||
{ value: Grammeme.PRTS, label: 'ЧР: кр прич' },
|
||||
Grammeme.sing, Grammeme.plur,
|
||||
Grammeme.nomn, Grammeme.gent, Grammeme.datv,
|
||||
Grammeme.accs, Grammeme.ablt, Grammeme.loct,
|
||||
|
||||
{ value: Grammeme.perf, label: 'Совершенный: да' },
|
||||
{ value: Grammeme.impf, label: 'Совершенный: нет' },
|
||||
Grammeme.INFN, Grammeme.ADJF, Grammeme.PRTF,
|
||||
Grammeme.ADJS, Grammeme.PRTS,
|
||||
|
||||
{ value: Grammeme.tran, label: 'Переходный: да' },
|
||||
{ value: Grammeme.intr, label: 'Переходный: нет' },
|
||||
|
||||
{ value: Grammeme.pres, label: 'Время: наст' },
|
||||
{ value: Grammeme.past, label: 'Время: прош' },
|
||||
{ value: Grammeme.futr, label: 'Время: буд' },
|
||||
|
||||
{ value: Grammeme.per1, label: 'Лицо: 1' },
|
||||
{ value: Grammeme.per2, label: 'Лицо: 2' },
|
||||
{ value: Grammeme.per3, label: 'Лицо: 3' },
|
||||
|
||||
{ value: Grammeme.impr, label: 'Повелительный: да' },
|
||||
{ value: Grammeme.indc, label: 'Повелительный: нет' },
|
||||
|
||||
{ value: Grammeme.incl, label: 'Включающий: да' },
|
||||
{ value: Grammeme.excl, label: 'Включающий: нет' },
|
||||
|
||||
{ value: Grammeme.pssv, label: 'Страдательный: да' },
|
||||
{ value: Grammeme.actv, label: 'Страдательный: нет' },
|
||||
];
|
||||
|
||||
// { value: Grammeme.masc, label: 'Род: муж' },
|
||||
// { value: Grammeme.femn, label: 'Род: жен' },
|
||||
// { value: Grammeme.neut, label: 'Род: ср' },
|
||||
Grammeme.perf, Grammeme.impf,
|
||||
Grammeme.tran, Grammeme.intr,
|
||||
Grammeme.pres, Grammeme.past, Grammeme.futr,
|
||||
Grammeme.per1, Grammeme.per2, Grammeme.per3,
|
||||
Grammeme.impr, Grammeme.indc,
|
||||
Grammeme.incl, Grammeme.excl,
|
||||
Grammeme.pssv, Grammeme.actv,
|
||||
].map(
|
||||
gram => ({
|
||||
value: gram,
|
||||
label: labelGrammeme({type: gram, data: ''} as IGramData)
|
||||
}));
|
||||
|
|
|
@ -1,740 +0,0 @@
|
|||
|
||||
import { DependencyMode } from '../models/miscelanious';
|
||||
import { HelpTopic } from '../models/miscelanious';
|
||||
import { CstMatchMode } from '../models/miscelanious';
|
||||
import { ExpressionStatus } from '../models/rsform';
|
||||
import { CstClass, CstType, IConstituenta, IRSForm } from '../models/rsform';
|
||||
import { IFunctionArg, IRSErrorDescription, ISyntaxTreeNode, ParsingStatus, ValueClass } from '../models/rslang';
|
||||
import { resolveErrorClass, RSErrorClass, RSErrorType, TokenID } from '../models/rslang';
|
||||
import { IColorTheme } from './color';
|
||||
|
||||
export interface IDescriptor {
|
||||
text: string
|
||||
tooltip: string
|
||||
}
|
||||
|
||||
export function getCstDescription(cst: IConstituenta): string {
|
||||
if (cst.cst_type === CstType.STRUCTURED) {
|
||||
return (
|
||||
cst.term_resolved || cst.term_raw ||
|
||||
cst.definition_resolved || cst.definition_raw ||
|
||||
cst.convention ||
|
||||
cst.definition_formal
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
cst.term_resolved || cst.term_raw ||
|
||||
cst.definition_resolved || cst.definition_raw ||
|
||||
cst.definition_formal ||
|
||||
cst.convention
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function getCstLabel(cst: IConstituenta) {
|
||||
return `${cst.alias}: ${getCstDescription(cst)}`;
|
||||
}
|
||||
|
||||
export function getCstTypePrefix(type: CstType) {
|
||||
switch (type) {
|
||||
case CstType.BASE: return 'X';
|
||||
case CstType.CONSTANT: return 'C';
|
||||
case CstType.STRUCTURED: return 'S';
|
||||
case CstType.AXIOM: return 'A';
|
||||
case CstType.TERM: return 'D';
|
||||
case CstType.FUNCTION: return 'F';
|
||||
case CstType.PREDICATE: return 'P';
|
||||
case CstType.THEOREM: return 'T';
|
||||
}
|
||||
}
|
||||
|
||||
export function getCstExpressionPrefix(cst: IConstituenta): string {
|
||||
return cst.alias + (cst.cst_type === CstType.STRUCTURED ? '::=' : ':==');
|
||||
}
|
||||
|
||||
export function getRSButtonData(id: TokenID): IDescriptor {
|
||||
switch (id) {
|
||||
case TokenID.BOOLEAN: return {
|
||||
text: 'ℬ()',
|
||||
tooltip: 'Булеан [Alt + E]'
|
||||
};
|
||||
case TokenID.DECART: return {
|
||||
text: '×',
|
||||
tooltip: 'Декартово произведение [Shift + 8 / Alt + Shift + E]'
|
||||
};
|
||||
case TokenID.PUNC_PL: return {
|
||||
text: '( )',
|
||||
tooltip: 'Скобки вокруг выражения [Alt + Shift + 9 ]'
|
||||
};
|
||||
case TokenID.PUNC_SL: return {
|
||||
text: '[ ]',
|
||||
tooltip: 'Скобки вокруг выражения [Alt + [ ]'
|
||||
};
|
||||
case TokenID.FORALL: return {
|
||||
text: '∀',
|
||||
tooltip: 'Квантор всеобщности [`]'
|
||||
};
|
||||
case TokenID.EXISTS: return {
|
||||
text: '∃',
|
||||
tooltip: 'Квантор существования [Shift + `]'
|
||||
};
|
||||
case TokenID.NOT: return {
|
||||
text: '¬',
|
||||
tooltip: 'Отрицание [Alt + `]'
|
||||
};
|
||||
case TokenID.AND: return {
|
||||
text: '&',
|
||||
tooltip: 'Конъюнкция [Alt + 3 ~ Shift + 7]'
|
||||
};
|
||||
case TokenID.OR: return {
|
||||
text: '∨',
|
||||
tooltip: 'дизъюнкция [Alt + Shift + 3]'
|
||||
};
|
||||
case TokenID.IMPLICATION: return {
|
||||
text: '⇒',
|
||||
tooltip: 'импликация [Alt + 4]'
|
||||
};
|
||||
case TokenID.EQUIVALENT: return {
|
||||
text: '⇔',
|
||||
tooltip: 'эквивалентность [Alt + Shift + 4]'
|
||||
};
|
||||
case TokenID.LIT_EMPTYSET: return {
|
||||
text: '∅',
|
||||
tooltip: 'пустое множество [Alt + X]'
|
||||
};
|
||||
case TokenID.LIT_INTSET: return {
|
||||
text: 'Z',
|
||||
tooltip: 'целые числа [Alt + Z]'
|
||||
};
|
||||
case TokenID.EQUAL: return {
|
||||
text: '=',
|
||||
tooltip: 'равенство'
|
||||
};
|
||||
case TokenID.NOTEQUAL: return {
|
||||
text: '≠',
|
||||
tooltip: 'неравенство [Alt + Shift + `]'
|
||||
};
|
||||
case TokenID.GREATER_OR_EQ: return {
|
||||
text: '≥',
|
||||
tooltip: 'больше или равно [Alt + Shift + 7]'
|
||||
};
|
||||
case TokenID.LESSER_OR_EQ: return {
|
||||
text: '≤',
|
||||
tooltip: 'меньше или равно [Alt + Shift + 8]'
|
||||
};
|
||||
case TokenID.IN: return {
|
||||
text: '∈',
|
||||
tooltip: 'быть элементом (принадлежит) [Alt + 1]'
|
||||
};
|
||||
case TokenID.NOTIN: return {
|
||||
text: '∉',
|
||||
tooltip: 'не принадлежит [Alt + Shift + 1]'
|
||||
};
|
||||
case TokenID.SUBSET_OR_EQ: return {
|
||||
text: '⊆',
|
||||
tooltip: 'быть частью (нестрогое подмножество) [Alt + 2]'
|
||||
};
|
||||
case TokenID.SUBSET: return {
|
||||
text: '⊂',
|
||||
tooltip: 'строгое подмножество [Alt + 7]'
|
||||
};
|
||||
case TokenID.NOTSUBSET: return {
|
||||
text: '⊄',
|
||||
tooltip: 'не подмножество [Alt + Shift + 2]'
|
||||
};
|
||||
case TokenID.INTERSECTION: return {
|
||||
text: '∩',
|
||||
tooltip: 'пересечение [Alt + A]'
|
||||
};
|
||||
case TokenID.UNION: return {
|
||||
text: '∪',
|
||||
tooltip: 'объединение [Alt + S]'
|
||||
};
|
||||
case TokenID.SET_MINUS: return {
|
||||
text: '\\',
|
||||
tooltip: 'Разность множеств [Alt + 5]'
|
||||
};
|
||||
case TokenID.SYMMINUS: return {
|
||||
text: '∆',
|
||||
tooltip: 'Симметрическая разность [Alt + Shift + 5]'
|
||||
};
|
||||
case TokenID.NT_DECLARATIVE_EXPR: return {
|
||||
text: 'D{}',
|
||||
tooltip: 'Декларативная форма определения терма [Alt + D]'
|
||||
};
|
||||
case TokenID.NT_IMPERATIVE_EXPR: return {
|
||||
text: 'I{}',
|
||||
tooltip: 'императивная форма определения терма [Alt + G]'
|
||||
};
|
||||
case TokenID.NT_RECURSIVE_FULL: return {
|
||||
text: 'R{}',
|
||||
tooltip: 'рекурсивная (цикличная) форма определения терма [Alt + T]'
|
||||
};
|
||||
case TokenID.BIGPR: return {
|
||||
text: 'Pr1()',
|
||||
tooltip: 'большая проекция [Alt + Q]'
|
||||
};
|
||||
case TokenID.SMALLPR: return {
|
||||
text: 'pr1()',
|
||||
tooltip: 'малая проекция [Alt + W]'
|
||||
};
|
||||
case TokenID.FILTER: return {
|
||||
text: 'Fi1[]()',
|
||||
tooltip: 'фильтр [Alt + F]'
|
||||
};
|
||||
case TokenID.REDUCE: return {
|
||||
text: 'red()',
|
||||
tooltip: 'множество-сумма [Alt + R]'
|
||||
};
|
||||
case TokenID.CARD: return {
|
||||
text: 'card()',
|
||||
tooltip: 'мощность [Alt + C]'
|
||||
};
|
||||
case TokenID.BOOL: return {
|
||||
text: 'bool()',
|
||||
tooltip: 'синглетон [Alt + B]'
|
||||
};
|
||||
case TokenID.DEBOOL: return {
|
||||
text: 'debool()',
|
||||
tooltip: 'десинглетон [Alt + V]'
|
||||
};
|
||||
case TokenID.PUNC_ASSIGN: return {
|
||||
text: ':=',
|
||||
tooltip: 'присвоение (императивный синтаксис) [Alt + Shift + 6]'
|
||||
};
|
||||
case TokenID.PUNC_ITERATE: return {
|
||||
text: ':∈',
|
||||
tooltip: 'перебор элементов множества (императивный синтаксис) [Alt + 6]'
|
||||
};
|
||||
}
|
||||
return {
|
||||
text: 'undefined',
|
||||
tooltip: 'undefined'
|
||||
}
|
||||
}
|
||||
|
||||
export function getCstTypeLabel(type: CstType) {
|
||||
switch (type) {
|
||||
case CstType.BASE: return 'Базисное множество';
|
||||
case CstType.CONSTANT: return 'Константное множество';
|
||||
case CstType.STRUCTURED: return 'Родовая структура';
|
||||
case CstType.AXIOM: return 'Аксиома';
|
||||
case CstType.TERM: return 'Терм';
|
||||
case CstType.FUNCTION: return 'Терм-функция';
|
||||
case CstType.PREDICATE: return 'Предикат-функция';
|
||||
case CstType.THEOREM: return 'Теорема';
|
||||
}
|
||||
}
|
||||
|
||||
export function getCstTypeShortcut(type: CstType) {
|
||||
const prefix = getCstTypeLabel(type) + ' [Alt + ';
|
||||
switch (type) {
|
||||
case CstType.BASE: return prefix + '1]';
|
||||
case CstType.STRUCTURED: return prefix + '2]';
|
||||
case CstType.TERM: return prefix + '3]';
|
||||
case CstType.AXIOM: return prefix + '4]';
|
||||
case CstType.FUNCTION: return prefix + 'Q]';
|
||||
case CstType.PREDICATE: return prefix + 'W]';
|
||||
case CstType.CONSTANT: return prefix + '5]';
|
||||
case CstType.THEOREM: return prefix + '6]';
|
||||
}
|
||||
}
|
||||
|
||||
export function getCstCompareLabel(mode: CstMatchMode): string {
|
||||
switch(mode) {
|
||||
case CstMatchMode.ALL: return 'везде';
|
||||
case CstMatchMode.EXPR: return 'выраж';
|
||||
case CstMatchMode.TERM: return 'термин';
|
||||
case CstMatchMode.TEXT: return 'текст';
|
||||
case CstMatchMode.NAME: return 'имя';
|
||||
}
|
||||
}
|
||||
|
||||
export function getDependencyLabel(mode: DependencyMode): string {
|
||||
switch(mode) {
|
||||
case DependencyMode.ALL: return 'вся схема';
|
||||
case DependencyMode.EXPRESSION: return 'выражение';
|
||||
case DependencyMode.OUTPUTS: return 'потребители';
|
||||
case DependencyMode.INPUTS: return 'поставщики';
|
||||
case DependencyMode.EXPAND_INPUTS: return 'влияющие';
|
||||
case DependencyMode.EXPAND_OUTPUTS: return 'зависимые';
|
||||
}
|
||||
}
|
||||
|
||||
export const mapLayoutLabels: Map<string, string> = new Map([
|
||||
['forceatlas2', 'Граф: Атлас 2D'],
|
||||
['forceDirected2d', 'Граф: Силы 2D'],
|
||||
['forceDirected3d', 'Граф: Силы 3D'],
|
||||
['treeTd2d', 'Граф: ДеревоВерт 2D'],
|
||||
['treeTd3d', 'Граф: ДеревоВерт 3D'],
|
||||
['treeLr2d', 'Граф: ДеревоГор 2D'],
|
||||
['treeLr3d', 'Граф: ДеревоГор 3D'],
|
||||
['radialOut2d', 'Граф: Радиальная 2D'],
|
||||
['radialOut3d', 'Граф: Радиальная 3D'],
|
||||
['circular2d', 'Граф: Круговая'],
|
||||
['hierarchicalTd', 'Граф: ИерархияВерт'],
|
||||
['hierarchicalLr', 'Граф: ИерархияГор'],
|
||||
['nooverlap', 'Граф: Без перекрытия']
|
||||
]);
|
||||
|
||||
export const mapColoringLabels: Map<string, string> = new Map([
|
||||
['none', 'Цвет: моно'],
|
||||
['status', 'Цвет: статус'],
|
||||
['type', 'Цвет: класс'],
|
||||
]);
|
||||
|
||||
export function getCstStatusBgColor(status: ExpressionStatus, colors: IColorTheme): string {
|
||||
switch (status) {
|
||||
case ExpressionStatus.VERIFIED: return colors.bgGreen;
|
||||
case ExpressionStatus.INCORRECT: return colors.bgRed;
|
||||
case ExpressionStatus.INCALCULABLE: return colors.bgOrange;
|
||||
case ExpressionStatus.PROPERTY: return colors.bgTeal;
|
||||
case ExpressionStatus.UNKNOWN: return colors.bgBlue;
|
||||
case ExpressionStatus.UNDEFINED: return colors.bgBlue;
|
||||
}
|
||||
}
|
||||
|
||||
export function getCstStatusFgColor(status: ExpressionStatus, colors: IColorTheme): string {
|
||||
switch (status) {
|
||||
case ExpressionStatus.VERIFIED: return colors.fgGreen;
|
||||
case ExpressionStatus.INCORRECT: return colors.fgRed;
|
||||
case ExpressionStatus.INCALCULABLE: return colors.fgOrange;
|
||||
case ExpressionStatus.PROPERTY: return colors.fgTeal;
|
||||
case ExpressionStatus.UNKNOWN: return colors.fgBlue;
|
||||
case ExpressionStatus.UNDEFINED: return colors.fgBlue;
|
||||
}
|
||||
}
|
||||
|
||||
export const mapStatusInfo: Map<ExpressionStatus, IDescriptor> = new Map([
|
||||
[ ExpressionStatus.VERIFIED, {
|
||||
text: 'ок',
|
||||
tooltip: 'выражение корректно и вычислимо'
|
||||
}],
|
||||
[ ExpressionStatus.INCORRECT, {
|
||||
text: 'ошибка',
|
||||
tooltip: 'ошибка в выражении'
|
||||
}],
|
||||
[ ExpressionStatus.INCALCULABLE, {
|
||||
text: 'невыч',
|
||||
tooltip: 'выражение не вычислимо'
|
||||
}],
|
||||
[ ExpressionStatus.PROPERTY, {
|
||||
text: 'св-во',
|
||||
tooltip: 'можно проверить принадлежность, но нельзя получить значение'
|
||||
}],
|
||||
[ ExpressionStatus.UNKNOWN, {
|
||||
text: 'неизв',
|
||||
tooltip: 'требует проверки выражения'
|
||||
}],
|
||||
[ ExpressionStatus.UNDEFINED, {
|
||||
text: 'N/A',
|
||||
tooltip: 'произошла ошибка при проверке выражения'
|
||||
}]
|
||||
]);
|
||||
|
||||
export const mapTopicInfo: Map<HelpTopic, IDescriptor> = new Map([
|
||||
[ HelpTopic.MAIN, {
|
||||
text: 'Портал',
|
||||
tooltip: 'Общая справка по порталу'
|
||||
}],
|
||||
[ HelpTopic.RSLANG, {
|
||||
text: 'Рода структур',
|
||||
tooltip: 'Справка по языку родов структур и экспликации'
|
||||
}],
|
||||
[ HelpTopic.LIBRARY, {
|
||||
text: 'Библиотека',
|
||||
tooltip: 'Интерфейс работы с библиотекой схем'
|
||||
}],
|
||||
[ HelpTopic.RSFORM, {
|
||||
text: '- паспорт схемы',
|
||||
tooltip: 'Интерфейс работы с описанием схемы'
|
||||
}],
|
||||
[ HelpTopic.CSTLIST, {
|
||||
text: '- список конституент',
|
||||
tooltip: 'Интерфейс работы со списком конституент'
|
||||
}],
|
||||
[ HelpTopic.CONSTITUENTA, {
|
||||
text: '- конституента',
|
||||
tooltip: 'Интерфейс редактирования конституенты'
|
||||
}],
|
||||
[ HelpTopic.GRAPH_TERM, {
|
||||
text: '- граф термов',
|
||||
tooltip: 'Интерфейс работ с графом термов схемы'
|
||||
}],
|
||||
[ HelpTopic.EXTEOR, {
|
||||
text: 'Экстеор',
|
||||
tooltip: 'Справка по программе Экстеор'
|
||||
}],
|
||||
[ HelpTopic.API, {
|
||||
text: 'REST API',
|
||||
tooltip: 'Документация интерфейса для разработчиков'
|
||||
}],
|
||||
]);
|
||||
|
||||
export function getCstClassColor(cstClass: CstClass, colors: IColorTheme): string {
|
||||
switch (cstClass) {
|
||||
case CstClass.BASIC: return colors.bgGreen;
|
||||
case CstClass.DERIVED: return colors.bgBlue;
|
||||
case CstClass.STATEMENT: return colors.bgRed;
|
||||
case CstClass.TEMPLATE: return colors.bgTeal;
|
||||
}
|
||||
}
|
||||
|
||||
export const mapCstClassInfo: Map<CstClass, IDescriptor> = new Map([
|
||||
[ CstClass.BASIC, {
|
||||
text: 'базовый',
|
||||
tooltip: 'неопределяемое понятие, требует конвенции'
|
||||
}],
|
||||
[ CstClass.DERIVED, {
|
||||
text: 'производный',
|
||||
tooltip: 'выводимое понятие, задаваемое определением'
|
||||
}],
|
||||
[ CstClass.STATEMENT, {
|
||||
text: 'утверждение',
|
||||
tooltip: 'неопределяемое понятие, требует конвенции'
|
||||
}],
|
||||
[ CstClass.TEMPLATE, {
|
||||
text: 'шаблон',
|
||||
tooltip: 'параметризованный шаблон определения'
|
||||
}],
|
||||
]);
|
||||
|
||||
export function createAliasFor(type: CstType, schema: IRSForm): string {
|
||||
const prefix = getCstTypePrefix(type);
|
||||
if (!schema.items || schema.items.length <= 0) {
|
||||
return `${prefix}1`;
|
||||
}
|
||||
const index = schema.items.reduce((prev, cst, index) => {
|
||||
if (cst.cst_type !== type) {
|
||||
return prev;
|
||||
}
|
||||
index = Number(cst.alias.slice(1 - cst.alias.length)) + 1;
|
||||
return Math.max(prev, index);
|
||||
}, 1);
|
||||
return `${prefix}${index}`;
|
||||
}
|
||||
|
||||
export function getMockConstituenta(schema: number, id: number, alias: string, type: CstType, comment: string): IConstituenta {
|
||||
return {
|
||||
id: id,
|
||||
order: -1,
|
||||
schema: schema,
|
||||
alias: alias,
|
||||
convention: comment,
|
||||
cst_type: type,
|
||||
term_raw: '',
|
||||
term_resolved: '',
|
||||
term_forms: [],
|
||||
definition_formal: '',
|
||||
definition_raw: '',
|
||||
definition_resolved: '',
|
||||
status: ExpressionStatus.INCORRECT,
|
||||
is_template: false,
|
||||
cst_class: CstClass.DERIVED,
|
||||
parse: {
|
||||
status: ParsingStatus.INCORRECT,
|
||||
valueClass: ValueClass.INVALID,
|
||||
typification: 'N/A',
|
||||
syntaxTree: '',
|
||||
args: []
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function getCloneTitle(schema: IRSForm): string {
|
||||
if (!schema.title.includes('[клон]')) {
|
||||
return schema.title + ' [клон]';
|
||||
} else {
|
||||
return (schema.title + '+');
|
||||
}
|
||||
}
|
||||
|
||||
export function getTypificationLabel({isValid, resultType, args}: {
|
||||
isValid: boolean,
|
||||
resultType: string,
|
||||
args: IFunctionArg[]
|
||||
}): string {
|
||||
if (!isValid) {
|
||||
return 'N/A';
|
||||
}
|
||||
if (resultType === '' || resultType === 'LOGIC') {
|
||||
resultType = 'Logical';
|
||||
}
|
||||
if (args.length === 0) {
|
||||
return resultType;
|
||||
}
|
||||
const argsText = args.map(arg => arg.typification).join(', ');
|
||||
return `${resultType} 🠔 [${argsText}]`;
|
||||
}
|
||||
|
||||
export function getCstTypificationLabel(cst: IConstituenta): string {
|
||||
return getTypificationLabel({
|
||||
isValid: cst.parse.status === ParsingStatus.VERIFIED,
|
||||
resultType: cst.parse.typification,
|
||||
args: cst.parse.args
|
||||
});
|
||||
}
|
||||
|
||||
export function getRSErrorPrefix(error: IRSErrorDescription): string {
|
||||
const id = error.errorType.toString(16)
|
||||
switch(resolveErrorClass(error.errorType)) {
|
||||
case RSErrorClass.LEXER: return 'L' + id;
|
||||
case RSErrorClass.PARSER: return 'P' + id;
|
||||
case RSErrorClass.SEMANTIC: return 'S' + id;
|
||||
case RSErrorClass.UNKNOWN: return 'U' + id;
|
||||
}
|
||||
}
|
||||
|
||||
export function getRSErrorMessage(error: IRSErrorDescription): string {
|
||||
switch (error.errorType) {
|
||||
case RSErrorType.syntax:
|
||||
return 'Неопределенная синтаксическая ошибка';
|
||||
case RSErrorType.missingParanthesis:
|
||||
return 'Некорректная конструкция языка родов структур, проверьте структуру выражения';
|
||||
case RSErrorType.missingCurlyBrace:
|
||||
return "Пропущен символ '}'";
|
||||
case RSErrorType.invalidQuantifier:
|
||||
return 'Некорректная кванторная декларация';
|
||||
case RSErrorType.expectedArgDeclaration:
|
||||
return 'Ожидалось объявление аргументов терм-функции';
|
||||
case RSErrorType.expectedLocal:
|
||||
return 'Ожидалось имя локальной переменной';
|
||||
|
||||
case RSErrorType.localDoubleDeclare:
|
||||
return `Предупреждение! Повторное объявление локальной переменной ${error.params[0]}`;
|
||||
case RSErrorType.localNotUsed:
|
||||
return `Предупреждение! Переменная объявлена, но не использована: ${error.params[0]}`;
|
||||
case RSErrorType.localUndeclared:
|
||||
return `Использование необъявленной переменной: ${error.params[0]}`;
|
||||
case RSErrorType.localShadowing:
|
||||
return `Повторное объявление переменной: ${error.params[0]}`;
|
||||
|
||||
case RSErrorType.typesNotEqual:
|
||||
return `Типизация операндов не совпадает! ${error.params[0]} != ${error.params[1]}`;
|
||||
case RSErrorType.globalNotTyped:
|
||||
return `Типизация конституенты не определена: ${error.params[0]}`;
|
||||
case RSErrorType.invalidDecart:
|
||||
return `τ(α×b) = ℬ(𝔇τ(α)×𝔇τ(b)). Некорректная типизация аргумента: ${error.params[0]}`;
|
||||
case RSErrorType.invalidBoolean:
|
||||
return `τ(ℬ(a)) = ℬℬ𝔇τ(a). Некорректная типизация аргумента: ${error.params[0]}`;
|
||||
case RSErrorType.invalidTypeOperation:
|
||||
return `Типизация операнда теоретико-множественной операции не корректна: ${error.params[0]}`;
|
||||
case RSErrorType.invalidCard:
|
||||
return `Некорректная типизация аргумента операции мощности: ${error.params[0]}`;
|
||||
case RSErrorType.invalidDebool:
|
||||
return `τ(debool(a)) = 𝔇τ(a). Некорректная типизация аргумента: ${error.params[0]}`;
|
||||
case RSErrorType.globalFuncMissing:
|
||||
return `Неизвестное имя функции: ${error.params[0]}`;
|
||||
case RSErrorType.globalFuncWithoutArgs:
|
||||
return `Некорректное использование имени функции без аргументов: ${error.params[0]}`;
|
||||
case RSErrorType.invalidReduce:
|
||||
return `τ(red(a)) = ℬ𝔇𝔇τ(a). Некорректная типизация аргумента: ${error.params[0]}`;
|
||||
case RSErrorType.invalidProjectionTuple:
|
||||
return `Проекция не определена: ${error.params[0]} -> ${error.params[1]}`;
|
||||
case RSErrorType.invalidProjectionSet:
|
||||
return `τ(Pri(a)) = ℬ𝒞i𝔇τ(a). Некорректная типизация аргумента: ${error.params[0]}`;
|
||||
case RSErrorType.invalidEnumeration:
|
||||
return `Типизация аргументов перечисления не совпадает: ${error.params[0]} != ${error.params[1]}`;
|
||||
case RSErrorType.ivalidBinding:
|
||||
return `Количество переменных в кортеже не соответствует размерности декартова произведения`;
|
||||
case RSErrorType.localOutOfScope:
|
||||
return `Использование имени переменной вне области действия: ${error.params[0]}`;
|
||||
case RSErrorType.invalidElementPredicat:
|
||||
return `Несоответствие типизаций операндов для оператора: ${error.params[0]}${error.params[1]}${error.params[2]}`;
|
||||
case RSErrorType.invalidArgsArtity:
|
||||
return `Неверное число аргументов терм-функции: ${error.params[0]} != ${error.params[1]}`;
|
||||
case RSErrorType.invalidArgumentType:
|
||||
return `Типизация аргумента терм-функции не соответствует объявленной: ${error.params[0]} != ${error.params[1]}`;
|
||||
case RSErrorType.invalidEqualsEmpty:
|
||||
return `Только множества можно сравнивать с пустым множеством: ${error.params[0]}`;
|
||||
case RSErrorType.globalStructure:
|
||||
return `Выражение родовой структуры должно быть ступенью`;
|
||||
case RSErrorType.globalExpectedFunction:
|
||||
return `Ожидалось выражение объявления функции`;
|
||||
case RSErrorType.emptySetUsage:
|
||||
return `Запрещено использование пустого множества как типизированного выражения`;
|
||||
case RSErrorType.radicalUsage:
|
||||
return `Радикалы запрещены вне деклараций терм-функции: ${error.params[0]}`;
|
||||
case RSErrorType.invalidFilterArgumentType:
|
||||
return `Типизация аргумента фильтра не корректна: ${error.params[0]}(${error.params[1]})`;
|
||||
case RSErrorType.invalidFilterArity:
|
||||
return `Количество параметров фильтра не соответствует количеству индексов`;
|
||||
case RSErrorType.arithmeticNotSupported:
|
||||
return `Тип не поддерживает арифметические операторы: ${error.params[0]}`;
|
||||
case RSErrorType.typesNotCompatible:
|
||||
return `Типы не совместимы для выбранной операции: ${error.params[0]} и ${error.params[1]}`;
|
||||
case RSErrorType.orderingNotSupported:
|
||||
return `Тип не поддерживает предикаты порядка: ${error.params[0]}`;
|
||||
case RSErrorType.globalNoValue:
|
||||
return `Используется неинтерпретируемый глобальный идентификатор: ${error.params[0]}`;
|
||||
case RSErrorType.invalidPropertyUsage:
|
||||
return `Использование неитерируемого множества в качестве значения`;
|
||||
case RSErrorType.globalMissingAST:
|
||||
return `Не удалось получить дерево разбора для глобального идентификатора: ${error.params[0]}`;
|
||||
case RSErrorType.globalFuncNoInterpretation:
|
||||
return `Функция не интерпретируется для данных аргументов`;
|
||||
case RSErrorType.globalNonemptyBase:
|
||||
return `Непустое выражение базисного/константного множества`;
|
||||
case RSErrorType.globalUnexpectedType:
|
||||
return `Типизация выражения не соответствует типу конституенты`;
|
||||
}
|
||||
return 'UNKNOWN ERROR';
|
||||
}
|
||||
|
||||
export function getASTNodeLabel(node: ISyntaxTreeNode): string {
|
||||
switch(node.typeID) {
|
||||
case TokenID.ID_LOCAL:
|
||||
case TokenID.ID_GLOBAL:
|
||||
case TokenID.ID_FUNCTION:
|
||||
case TokenID.ID_PREDICATE:
|
||||
case TokenID.ID_RADICAL:
|
||||
return node.data.value as string;
|
||||
|
||||
case TokenID.LIT_INTEGER: return String(node.data.value as number);
|
||||
|
||||
case TokenID.BIGPR: return 'Pr' + (node.data.value as string[]).toString();
|
||||
case TokenID.SMALLPR: return 'pr' + (node.data.value as string[]).toString();
|
||||
case TokenID.FILTER: return 'Fi' + (node.data.value as string[]).toString();
|
||||
|
||||
case TokenID.PLUS: return '+'
|
||||
case TokenID.MINUS: return '-'
|
||||
case TokenID.MULTIPLY: return '*'
|
||||
case TokenID.GREATER: return '>'
|
||||
case TokenID.LESSER: return '<'
|
||||
|
||||
case TokenID.NT_TUPLE: return 'TUPLE'
|
||||
case TokenID.NT_ENUMERATION: return 'ENUM'
|
||||
|
||||
case TokenID.NT_ENUM_DECL: return 'ENUM_DECLARATION'
|
||||
case TokenID.NT_TUPLE_DECL: return 'TUPLE_DECLARATION'
|
||||
case TokenID.PUNC_DEFINE: return 'DEFINITION'
|
||||
case TokenID.PUNC_STRUCT: return 'STRUCTURE_DEFITION'
|
||||
|
||||
case TokenID.NT_ARG_DECL: return 'ARG'
|
||||
case TokenID.NT_FUNC_CALL: return 'CALL'
|
||||
case TokenID.NT_ARGUMENTS: return 'ARGS'
|
||||
|
||||
case TokenID.NT_FUNC_DEFINITION: return 'FUNCTION_DEFINITION'
|
||||
case TokenID.NT_IMP_DECLARE: return 'IDECLARE'
|
||||
case TokenID.NT_IMP_ASSIGN: return 'IASSIGN'
|
||||
case TokenID.NT_IMP_LOGIC: return 'ICHECK'
|
||||
|
||||
case TokenID.NT_RECURSIVE_SHORT: return getRSButtonData(TokenID.NT_RECURSIVE_FULL).text;
|
||||
|
||||
case TokenID.BOOLEAN:
|
||||
case TokenID.DECART:
|
||||
case TokenID.FORALL:
|
||||
case TokenID.EXISTS:
|
||||
case TokenID.NOT:
|
||||
case TokenID.AND:
|
||||
case TokenID.OR:
|
||||
case TokenID.IMPLICATION:
|
||||
case TokenID.EQUIVALENT:
|
||||
case TokenID.LIT_EMPTYSET:
|
||||
case TokenID.LIT_INTSET:
|
||||
case TokenID.EQUAL:
|
||||
case TokenID.NOTEQUAL:
|
||||
case TokenID.GREATER_OR_EQ:
|
||||
case TokenID.LESSER_OR_EQ:
|
||||
case TokenID.IN:
|
||||
case TokenID.NOTIN:
|
||||
case TokenID.SUBSET_OR_EQ:
|
||||
case TokenID.SUBSET:
|
||||
case TokenID.NOTSUBSET:
|
||||
case TokenID.INTERSECTION:
|
||||
case TokenID.UNION:
|
||||
case TokenID.SET_MINUS:
|
||||
case TokenID.SYMMINUS:
|
||||
case TokenID.NT_DECLARATIVE_EXPR:
|
||||
case TokenID.NT_IMPERATIVE_EXPR:
|
||||
case TokenID.NT_RECURSIVE_FULL:
|
||||
case TokenID.REDUCE:
|
||||
case TokenID.CARD:
|
||||
case TokenID.BOOL:
|
||||
case TokenID.DEBOOL:
|
||||
case TokenID.PUNC_ASSIGN:
|
||||
case TokenID.PUNC_ITERATE:
|
||||
return getRSButtonData(node.typeID).text;
|
||||
}
|
||||
// node
|
||||
return 'UNKNOWN ' + String(node.typeID);
|
||||
}
|
||||
|
||||
export function getASTNodeColor(node: ISyntaxTreeNode, colors: IColorTheme): string {
|
||||
switch(node.typeID) {
|
||||
case TokenID.PUNC_DEFINE:
|
||||
case TokenID.PUNC_STRUCT:
|
||||
case TokenID.ID_LOCAL:
|
||||
return colors.bgGreen;
|
||||
|
||||
case TokenID.ID_GLOBAL:
|
||||
case TokenID.ID_FUNCTION:
|
||||
case TokenID.ID_PREDICATE:
|
||||
case TokenID.ID_RADICAL:
|
||||
case TokenID.LIT_INTEGER:
|
||||
case TokenID.LIT_EMPTYSET:
|
||||
case TokenID.LIT_INTSET:
|
||||
return colors.bgTeal;
|
||||
|
||||
case TokenID.FORALL:
|
||||
case TokenID.EXISTS:
|
||||
case TokenID.NOT:
|
||||
case TokenID.AND:
|
||||
case TokenID.OR:
|
||||
case TokenID.IMPLICATION:
|
||||
case TokenID.EQUIVALENT:
|
||||
case TokenID.GREATER:
|
||||
case TokenID.LESSER:
|
||||
case TokenID.EQUAL:
|
||||
case TokenID.NOTEQUAL:
|
||||
case TokenID.GREATER_OR_EQ:
|
||||
case TokenID.LESSER_OR_EQ:
|
||||
case TokenID.IN:
|
||||
case TokenID.NOTIN:
|
||||
case TokenID.SUBSET_OR_EQ:
|
||||
case TokenID.SUBSET:
|
||||
case TokenID.NOTSUBSET:
|
||||
return colors.bgOrange;
|
||||
|
||||
case TokenID.NT_TUPLE:
|
||||
case TokenID.NT_ENUMERATION:
|
||||
case TokenID.BIGPR:
|
||||
case TokenID.SMALLPR:
|
||||
case TokenID.FILTER:
|
||||
case TokenID.PLUS:
|
||||
case TokenID.MINUS:
|
||||
case TokenID.MULTIPLY:
|
||||
case TokenID.BOOLEAN:
|
||||
case TokenID.DECART:
|
||||
case TokenID.INTERSECTION:
|
||||
case TokenID.UNION:
|
||||
case TokenID.SET_MINUS:
|
||||
case TokenID.SYMMINUS:
|
||||
case TokenID.REDUCE:
|
||||
case TokenID.CARD:
|
||||
case TokenID.BOOL:
|
||||
case TokenID.DEBOOL:
|
||||
return colors.bgBlue;
|
||||
|
||||
case TokenID.NT_FUNC_DEFINITION:
|
||||
case TokenID.NT_DECLARATIVE_EXPR:
|
||||
case TokenID.NT_IMPERATIVE_EXPR:
|
||||
case TokenID.NT_RECURSIVE_FULL:
|
||||
case TokenID.NT_ENUM_DECL:
|
||||
case TokenID.NT_TUPLE_DECL:
|
||||
case TokenID.NT_ARG_DECL:
|
||||
case TokenID.NT_FUNC_CALL:
|
||||
case TokenID.NT_ARGUMENTS:
|
||||
case TokenID.NT_IMP_DECLARE:
|
||||
case TokenID.NT_IMP_ASSIGN:
|
||||
case TokenID.NT_IMP_LOGIC:
|
||||
case TokenID.NT_RECURSIVE_SHORT:
|
||||
return '';
|
||||
|
||||
case TokenID.PUNC_ASSIGN:
|
||||
case TokenID.PUNC_ITERATE:
|
||||
return colors.bgRed;
|
||||
}
|
||||
// node
|
||||
return colors.bgRed;
|
||||
}
|
|
@ -1,5 +1,11 @@
|
|||
COMPOSE_FILE="docker-compose-prod.yml"
|
||||
BACKUP_SCRIPT="./scripts/prod/CreateBackup.sh"
|
||||
|
||||
git reset --hard
|
||||
git pull
|
||||
/bin/bash ./scripts/prod/CreateBackup.sh
|
||||
docker compose --file "docker-compose-prod.yml" up --build --detach
|
||||
|
||||
/bin/bash "${BACKUP_SCRIPT}"
|
||||
|
||||
docker compose --file "${COMPOSE_FILE}" up --build --detach
|
||||
docker image prune --all --force
|
||||
docker compose --file "${COMPOSE_FILE}" restart
|
Loading…
Reference in New Issue
Block a user