Skip to content

Commit 0eff21b

Browse files
committed
Initial partial implementation of the physics package.
1 parent ad26af6 commit 0eff21b

File tree

7 files changed

+384
-3
lines changed

7 files changed

+384
-3
lines changed

lib/TeX-lab.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import 'mathjax3/input/tex/noundefined/NoUndefinedConfiguration.js';
1313
import 'mathjax3/input/tex/boldsymbol/BoldsymbolConfiguration.js';
1414
import 'mathjax3/input/tex/newcommand/NewcommandConfiguration.js';
1515
import 'mathjax3/input/tex/braket/BraketConfiguration.js';
16+
import 'mathjax3/input/tex/physics/PhysicsConfiguration.js';
1617

1718

1819
let tex = new TeX();

mathjax3-ts/input/tex/base/BaseItems.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,6 @@ export class FnItem extends BaseItem {
658658
}
659659
}
660660
// @test Named Function, Named Function Arg
661-
console.log(Entities);
662661
const node = this.create('token', 'mo', {texClass: TEXCLASS.NONE},
663662
Entities.entities['ApplyFunction']);
664663
return [[top, node, item], true];
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*************************************************************
2+
*
3+
* Copyright (c) 2018 The MathJax Consortium
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
19+
/**
20+
* @fileoverview Configuration file for the Physics package.
21+
*
22+
* @author [email protected] (Volker Sorge)
23+
*/
24+
25+
import {Configuration} from '../Configuration.js';
26+
import './PhysicsMappings.js';
27+
28+
29+
export const PhysicsConfiguration = Configuration.create(
30+
'physics',
31+
{
32+
handler: {
33+
macro: [
34+
'Physics-automatic-bracing-macros',
35+
'Physics-expressions-macros',
36+
'Physics-quick-quad-macros'
37+
]
38+
}
39+
}
40+
);
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*************************************************************
2+
*
3+
* Copyright (c) 2018 The MathJax Consortium
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
19+
/**
20+
* @fileoverview Mappings for TeX parsing of the physics package.
21+
*
22+
* @author [email protected] (Volker Sorge)
23+
*/
24+
25+
import {CommandMap, MacroMap} from '../SymbolMap.js';
26+
import PhysicsMethods from './PhysicsMethods.js';
27+
import {TexConstant} from '../TexConstants.js';
28+
29+
30+
/**
31+
* Macros for physics package.
32+
*/
33+
new CommandMap('Physics-automatic-bracing-macros', {
34+
'quantity': 'Quantity',
35+
'qty': 'Quantity',
36+
'pqty': ['Quantity', '(', ')', true],
37+
'bqty': ['Quantity', '[', ']', true],
38+
'vqty': ['Quantity', '|', '|', true],
39+
'Bqty': ['Quantity', '{', '}', true],
40+
'absolutevalue': ['Quantity', '|', '|', true],
41+
'abs': ['Quantity', '|', '|', true],
42+
'norm': ['Quantity', '\\|', '\\|', true],
43+
'evaluated': 'Eval',
44+
'eval': 'Eval',
45+
'order': ['Quantity', '(', ')', true, 'O',
46+
TexConstant.Variant.CALIGRAPHIC],
47+
'commutator': 'Commutator',
48+
'comm': 'Commutator',
49+
'anticommutator': ['Commutator', '\\{', '\\}'],
50+
'acomm': ['Commutator', '\\{', '\\}'],
51+
'poissonbracket': ['Commutator', '\\{', '\\}'],
52+
'pb': ['Commutator', '\\{', '\\}']
53+
}, PhysicsMethods);
54+
55+
56+
new CommandMap('Physics-expressions-macros', {
57+
'sin': 'Expression',
58+
'sinh': 'Expression',
59+
'arcsin': 'Expression',
60+
'asin': 'Expression',
61+
'cos': 'Expression',
62+
'cosh': 'Expression',
63+
'arccos': 'Expression',
64+
'acos': 'Expression',
65+
'tan': 'Expression',
66+
'tanh': 'Expression',
67+
'arctan': 'Expression',
68+
'atan': 'Expression',
69+
'csc': 'Expression',
70+
'csch': 'Expression',
71+
'arccsc': 'Expression',
72+
'acsc': 'Expression',
73+
'sec': 'Expression',
74+
'sech': 'Expression',
75+
'arcsec': 'Expression',
76+
'asec': 'Expression',
77+
'cot': 'Expression',
78+
'coth': 'Expression',
79+
'arccot': 'Expression',
80+
'acot': 'Expression',
81+
'exp': ['Expression', false],
82+
'log': 'Expression',
83+
'ln': 'Expression',
84+
'det': ['Expression', false],
85+
'Pr': ['Expression', false],
86+
// New expressions.
87+
'tr': ['Expression', false],
88+
'trace': ['Expression', false, 'tr'],
89+
'Tr': ['Expression', false],
90+
'Trace': ['Expression', false, 'Tr'],
91+
'rank': 'NamedFn',
92+
'erf': ['Expression', false],
93+
// Old named functions.
94+
'sine': ['NamedFn', 'sin'],
95+
'hypsine': ['NamedFn', 'sinh'],
96+
'arcsine': ['NamedFn', 'arcsin'],
97+
'asine': ['NamedFn', 'asin'],
98+
'cosine': ['NamedFn', 'cos'],
99+
'hypcosine': ['NamedFn', 'cosh'],
100+
'arccosine': ['NamedFn', 'arccos'],
101+
'acosine': ['NamedFn', 'acos'],
102+
'tangent': ['NamedFn', 'tan'],
103+
'hyptangent': ['NamedFn', 'tanh'],
104+
'arctangent': ['NamedFn', 'arctan'],
105+
'atangent': ['NamedFn', 'atan'],
106+
'cosecant': ['NamedFn', 'csc'],
107+
'hypcosecant': ['NamedFn', 'csch'],
108+
'arccosecant': ['NamedFn', 'arccsc'],
109+
'acosecant': ['NamedFn', 'acsc'],
110+
'secant': ['NamedFn', 'sec'],
111+
'hypsecant': ['NamedFn', 'sech'],
112+
'arcsecant': ['NamedFn', 'arcsec'],
113+
'asecant': ['NamedFn', 'asec'],
114+
'cotangent': ['NamedFn', 'cot'],
115+
'hypcotangent': ['NamedFn', 'coth'],
116+
'arccotangent': ['NamedFn', 'arccot'],
117+
'acotangent': ['NamedFn', 'acot'],
118+
'exponential': ['NamedFn', 'exp'],
119+
'logarithm': ['NamedFn', 'log'],
120+
'naturallogarithm': ['NamedFn', 'ln'],
121+
'determinant': ['NamedFn', 'det'],
122+
'Probability': ['NamedFn', 'Pr'],
123+
}, PhysicsMethods);
124+
125+
126+
new CommandMap('Physics-quick-quad-macros', {
127+
'qqtext': 'Qqtext',
128+
'qq': 'Qqtext',
129+
'qcomma': ['Macro', '\\qqtext*{,}'],
130+
'qc': ['Macro', '\\qqtext*{,}'],
131+
'qcc': ['Qqtext', 'c.c.'],
132+
'qif': ['Qqtext', 'if'],
133+
'qthen': ['Qqtext', 'then'],
134+
'qelse': ['Qqtext', 'else'],
135+
'qotherwise': ['Qqtext', 'otherwise'],
136+
'qunless': ['Qqtext', 'unless'],
137+
'qgiven': ['Qqtext', 'given'],
138+
'qusing': ['Qqtext', 'using'],
139+
'qassume': ['Qqtext', 'assume'],
140+
'qsince,': ['Qqtext', 'since,'],
141+
'qlet': ['Qqtext', 'let'],
142+
'qfor': ['Qqtext', 'for'],
143+
'qall': ['Qqtext', 'all'],
144+
'qeven': ['Qqtext', 'even'],
145+
'qodd': ['Qqtext', 'odd'],
146+
'qinteger': ['Qqtext', 'integer'],
147+
'qand': ['Qqtext', 'and'],
148+
'qor': ['Qqtext', 'or'],
149+
'qas': ['Qqtext', 'as'],
150+
'qin': ['Qqtext', 'in'],
151+
}, PhysicsMethods);
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/*************************************************************
2+
*
3+
* Copyright (c) 2018 The MathJax Consortium
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
19+
/**
20+
* @fileoverview Methods for TeX parsing of the physics package.
21+
*
22+
* @author [email protected] (Volker Sorge)
23+
*/
24+
25+
import {ParseMethod} from '../Types.js';
26+
import BaseMethods from '../base/BaseMethods.js';
27+
import {MapHandler} from '../MapHandler.js';
28+
import TexParser from '../TexParser.js';
29+
import TexError from '../TexError.js';
30+
import {TEXCLASS} from '../../../core/MmlTree/MmlNode.js';
31+
import ParseUtil from '../ParseUtil.js';
32+
import NodeUtil from '../NodeUtil.js';
33+
34+
35+
let PhysicsMethods: Record<string, ParseMethod> = {};
36+
37+
const pairs: {[fence: string]: string} = {
38+
'(': ')',
39+
'[': ']',
40+
'{': '}',
41+
'|': '|',
42+
};
43+
44+
// Maybe regexp?
45+
const biggs = /^(b|B)i(g{1,2})$/;
46+
47+
PhysicsMethods.Quantity = function(parser: TexParser, name: string,
48+
open: string = '(', close: string = ')',
49+
arg: boolean = false, named: string = '',
50+
variant: string = '') {
51+
let star = arg ? parser.GetStar() : false;
52+
let next = parser.GetNext();
53+
let position = parser.i;
54+
let big = null;
55+
if (next === '\\') {
56+
parser.i++;
57+
big = parser.GetCS();
58+
if (!big.match(biggs)) {
59+
// empty
60+
let empty = parser.create('node', 'mrow');
61+
parser.Push(ParseUtil.fenced(parser.configuration, open, empty, close));
62+
parser.i = position;
63+
return;
64+
}
65+
next = parser.GetNext();
66+
}
67+
let right = pairs[next];
68+
if (arg && next !== '{') {
69+
throw new TexError('MissingArgFor', 'Missing argument for %1', parser.currentCS);
70+
}
71+
if (!right) {
72+
let empty = parser.create('node', 'mrow');
73+
parser.Push(ParseUtil.fenced(parser.configuration, open, empty, close));
74+
parser.i = position;
75+
return;
76+
}
77+
// Get the fences
78+
let argument = parser.GetUpTo(name, right).slice(1);
79+
if (arg) {
80+
next = open;
81+
right = close;
82+
} else if (next === '{') {
83+
next = '\\{';
84+
right = '\\}';
85+
}
86+
argument = star ? next + ' ' + argument + ' ' + right :
87+
(big ?
88+
'\\' + big + 'l' + next + ' ' + argument + ' ' + '\\' + big + 'r' + right :
89+
'\\left' + next + ' ' + argument + ' ' + '\\right' + right);
90+
if (named) {
91+
const mml = parser.create('token', 'mi', {texClass: TEXCLASS.OP}, named);
92+
if (variant) {
93+
NodeUtil.setAttribute(mml, 'mathvariant', variant);
94+
}
95+
parser.Push(parser.itemFactory.create('fn', mml));
96+
}
97+
// TODO: Maybe include this in the old parser via replacement?
98+
parser.Push(new TexParser(argument, parser.stack.env,
99+
parser.configuration).mml());
100+
};
101+
102+
103+
PhysicsMethods.Eval = function(parser: TexParser, name: string) {
104+
let star = parser.GetStar();
105+
let next = parser.GetNext();
106+
let arg, left: string;
107+
if (next === '{') {
108+
next = '.';
109+
arg = parser.GetArgument(name);
110+
} else if (next === '(' || next === '[') {
111+
parser.i++;
112+
arg = parser.GetUpTo(name, '|');
113+
} else {
114+
throw new TexError('MissingArgFor', 'Missing argument for %1', parser.currentCS);
115+
}
116+
let replace = '\\left' + next + ' ' +
117+
(star ? '\\smash{' + arg + '}' : arg) +
118+
' ' + '\\vphantom{\\int}\\right|';
119+
parser.string = parser.string.slice(0, parser.i) + replace +
120+
parser.string.slice(parser.i);
121+
};
122+
123+
124+
PhysicsMethods.Commutator = function(parser: TexParser, name: string,
125+
open: string = '[', close: string = ']') {
126+
let star = parser.GetStar();
127+
let next = parser.GetNext();
128+
let big = null;
129+
if (next === '\\') {
130+
parser.i++;
131+
big = parser.GetCS();
132+
if (!big.match(biggs)) {
133+
// Actually a commutator error arg1 error.
134+
throw new TexError('MissingArgFor', 'Missing argument for %1', parser.currentCS);
135+
}
136+
next = parser.GetNext();
137+
}
138+
if (next !== '{') {
139+
throw new TexError('MissingArgFor', 'Missing argument for %1', parser.currentCS);
140+
}
141+
let arg1 = parser.GetArgument(name);
142+
let arg2 = parser.GetArgument(name);
143+
let argument = arg1 + ',' + arg2;
144+
argument = star ? open + ' ' + argument + ' ' + close :
145+
(big ?
146+
'\\' + big + 'l' + open + ' ' + argument + ' ' + '\\' + big + 'r' + close :
147+
'\\left' + open + ' ' + argument + ' ' + '\\right' + close);
148+
// TODO: Maybe include this in the old parser via replacement?
149+
parser.Push(new TexParser(argument, parser.stack.env,
150+
parser.configuration).mml());
151+
};
152+
153+
154+
PhysicsMethods.Expression = function(parser: TexParser, name: string,
155+
opt: boolean = true, id: string = '') {
156+
id = id || name.slice(1);
157+
const exp = opt ? parser.GetBrackets(name) : null;
158+
let mml = parser.create('token', 'mi', {texClass: TEXCLASS.OP}, id);
159+
if (exp) {
160+
const sup = new TexParser(exp, parser.stack.env, parser.configuration).mml();
161+
mml = parser.create('node', 'msup', [mml, sup]);
162+
}
163+
parser.Push(parser.itemFactory.create('fn', mml));
164+
if (parser.GetNext() !== '(') {
165+
return;
166+
}
167+
parser.i++;
168+
let arg = parser.GetUpTo(name, ')');
169+
parser.Push(new TexParser('\\left(' + arg + '\\right)', parser.stack.env,
170+
parser.configuration).mml());
171+
};
172+
173+
174+
PhysicsMethods.Qqtext = function(parser: TexParser, name: string, text: string) {
175+
let star = parser.GetStar();
176+
let arg = text ? text : parser.GetArgument(name);
177+
let replace = (star ? '' : '\\quad') + '\\text{' + arg + '}\\quad ';
178+
parser.string = parser.string.slice(0, parser.i) + replace +
179+
parser.string.slice(parser.i);
180+
};
181+
182+
183+
PhysicsMethods.Macro = BaseMethods.Macro;
184+
185+
PhysicsMethods.NamedFn = BaseMethods.NamedFn;
186+
187+
188+
export default PhysicsMethods;

0 commit comments

Comments
 (0)