Skip to content
This repository was archived by the owner on Mar 23, 2022. It is now read-only.

Commit b8657fa

Browse files
authored
Merge pull request #164 from RaenonX-DL/dev
v2.8.1 Release
2 parents 851a435 + 6bf6a4e commit b8657fa

File tree

13 files changed

+196
-28
lines changed

13 files changed

+196
-28
lines changed

doc/markdown.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,23 @@ Larger (2rem):
5454
==([fx])<Expression>([fx])(Decimal)==
5555
```
5656

57+
> Things in the parentheses are optional.
58+
5759
Show the expression and the result in 2 decimals at the end:
5860

5961
```
6062
==<Expression>[fx][2f]==
6163
```
6264

63-
> Things in the parentheses are optional.
64-
6565
- `[O]` `[fx]` is a constant string representing the placeholder of the calculation expression.
6666
- `[R]` `<Expression>` is the expression used for the calculation.
6767
- `[O]` `<Decimal>` is the number of decimals to display.
6868
- Either have something like `[2f]` for showing 2 decimals, or omit it all.
69+
- Default to 0 decimals i.e., the answer will be an integer if not set.
6970

7071
> Both `*` and `x` mean multiply.
72+
73+
#### References
74+
75+
Check [mathjs documentation](https://mathjs.org/docs/expressions/syntax.html)
76+
for the expression syntax.

src/components/elements/markdown/main.test.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,21 @@ describe('Markdown', () => {
170170

171171
expect(screen.getByText('10 (5 + 5)')).toBeInTheDocument();
172172
});
173+
174+
it('calculates complicating expression', async () => {
175+
const markdown = '==[fx] 13% x 2 + 38% x 1== (3 Hit)';
176+
177+
renderReact(() => <Markdown>{markdown}</Markdown>);
178+
179+
expect(screen.getByText('(13% x 2 + 38% x 1) 64%')).toBeInTheDocument();
180+
expect(screen.getByText(/(3 Hit)/)).toBeInTheDocument();
181+
});
182+
183+
it('skips calculating invalid expression', async () => {
184+
const markdown = '==something==';
185+
186+
renderReact(() => <Markdown>{markdown}</Markdown>);
187+
188+
expect(screen.getByText('something')).toBeInTheDocument();
189+
});
173190
});
Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
1+
import {ExpressionReplacements} from './types';
2+
13
export const expressionPlaceholder = '[fx]';
24

35
export const decimalRegex = /\[(\d+)f]$/;
46

5-
export const charReplacements: Array<[string, string]> = [
6-
['x', '*'],
7+
export const charReplacements: ExpressionReplacements = [
8+
{
9+
name: 'multiplySign',
10+
atCalculate: '*',
11+
atDisplay: 'x',
12+
availableDirections: ['toCalculate', 'toDisplay'],
13+
},
14+
{
15+
name: 'percentSign',
16+
atCalculate: '/100',
17+
atDisplay: '%',
18+
availableDirections: ['toCalculate'],
19+
},
720
];

src/components/elements/markdown/transformers/math/main.test.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,34 @@ describe('Markdown math expression', () => {
6565

6666
expect(screen.getByText('0.63 (5 / 8)')).toBeInTheDocument();
6767
});
68+
69+
it('preserves % if present in the expression using `x` for multiply', async () => {
70+
renderReact(() => <CalcExpression>{'140% x 2 + 2000% [fx]'}</CalcExpression>);
71+
72+
expect(screen.getByText('2280% (140% x 2 + 2000%)')).toBeInTheDocument();
73+
});
74+
75+
it('preserves % if present in the expression', async () => {
76+
renderReact(() => <CalcExpression>{'140% * 2 + 2000% [fx]'}</CalcExpression>);
77+
78+
expect(screen.getByText('2280% (140% x 2 + 2000%)')).toBeInTheDocument();
79+
});
80+
81+
it('calculates complicating expression w/ %', async () => {
82+
renderReact(() => <CalcExpression>{'15% x 1 + 90% x 2 + 105% x 3 [fx]'}</CalcExpression>);
83+
84+
expect(screen.getByText('510% (15% x 1 + 90% x 2 + 105% x 3)')).toBeInTheDocument();
85+
});
86+
87+
it('calculates complicating expression w/o %', async () => {
88+
renderReact(() => <CalcExpression>{'15 x 1 + 90 x 2 + 105 x 3 [fx]'}</CalcExpression>);
89+
90+
expect(screen.getByText('510 (15 x 1 + 90 x 2 + 105 x 3)')).toBeInTheDocument();
91+
});
92+
93+
it('can calculate multiple multiplications', async () => {
94+
renderReact(() => <CalcExpression>{'15 x 5 x 3'}</CalcExpression>);
95+
96+
expect(screen.getByText('225')).toBeInTheDocument();
97+
});
6898
});

src/components/elements/markdown/transformers/math/main.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,28 @@ export const CalcExpression = ({children}: CalcExpressionProps) => {
1717
children = children.trim(); // Trim whitespaces there's any
1818

1919
let evalResult;
20+
const replaceResult = replaceExpression(children, 'toCalculate');
2021
try {
21-
evalResult = evaluate(replaceExpression(children, 'toCalculate'));
22+
evalResult = evaluate(replaceResult.expression, {pct: 0.01});
2223
} catch (e) {
2324
return <>{children}</>;
2425
}
2526

26-
if (decimalInfo.decimalCount) {
27-
evalResult = evalResult.toFixed(decimalInfo.decimalCount);
27+
// Cannot merge this because:
28+
// - *100 and postfix `%` at first: `toFixed()` cannot execute
29+
// - *100 and postfix `%` at last: if `decimalCount` not provided, 510% (5.1) will be 500% (5.0)
30+
if (replaceResult.replacementUsed.percentSign) {
31+
evalResult *= 100;
32+
}
33+
evalResult = evalResult.toFixed(decimalInfo.decimalCount || 0);
34+
if (replaceResult.replacementUsed.percentSign) {
35+
evalResult = `${evalResult}%`;
2836
}
2937

3038
return (
3139
<ExpressionOutput
3240
exprExtractResult={expressionInfo}
33-
expression={replaceExpression(children, 'toDisplay')}
41+
expression={replaceExpression(children, 'toDisplay').expression}
3442
evalResult={evalResult}
3543
/>
3644
);
Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,55 @@
1+
import {escapeRegexChars} from '../../../../../utils/regex';
12
import {charReplacements} from './const';
2-
import {ExpressionReplaceDirection} from './types';
3+
import {ExpressionReplaceDirection, ExpressionReplaceReturn} from './types';
34

45

5-
export const replaceExpression = (expression: string, direction: ExpressionReplaceDirection): string => {
6-
charReplacements.forEach(([display, evaluate]) => {
6+
type ReplaceResult = {
7+
isChanged: boolean,
8+
replacedExpression: string,
9+
}
10+
11+
const replace = (expression: string, src: RegExp, dst: string): ReplaceResult => {
12+
const replacedExpression = expression.replace(src, dst);
13+
14+
return {
15+
isChanged: replacedExpression !== expression,
16+
replacedExpression,
17+
};
18+
};
19+
20+
export const replaceExpression = (
21+
expression: string,
22+
direction: ExpressionReplaceDirection,
23+
): ExpressionReplaceReturn => {
24+
const replacementUsed: ExpressionReplaceReturn['replacementUsed'] = {
25+
multiplySign: false,
26+
percentSign: false,
27+
};
28+
29+
charReplacements.forEach((replacement) => {
30+
if (!replacement.availableDirections.includes(direction)) {
31+
return;
32+
}
33+
734
if (direction === 'toCalculate') {
8-
expression = expression.replace(display, evaluate);
35+
const {replacedExpression, isChanged} = replace(
36+
expression,
37+
new RegExp(escapeRegexChars(replacement.atDisplay), 'g'),
38+
replacement.atCalculate,
39+
);
40+
expression = replacedExpression;
41+
replacementUsed[replacement.name] ||= isChanged;
942
}
1043
if (direction === 'toDisplay') {
11-
expression = expression.replace(evaluate, display);
44+
const {replacedExpression, isChanged} = replace(
45+
expression,
46+
new RegExp(escapeRegexChars(replacement.atCalculate), 'g'),
47+
replacement.atDisplay,
48+
);
49+
expression = replacedExpression;
50+
replacementUsed[replacement.name] ||= isChanged;
1251
}
1352
});
1453

15-
return expression;
54+
return {replacementUsed, expression};
1655
};

src/components/elements/markdown/transformers/math/types.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,22 @@ export type ExtractExpressionReturn = ExtractReturn & {
1414

1515
export type ExpressionReplaceDirection = 'toCalculate' | 'toDisplay';
1616

17+
export type ExpressionReplacementName = 'multiplySign' | 'percentSign';
18+
19+
export type ExpressionReplacement = {
20+
name: ExpressionReplacementName,
21+
atCalculate: string,
22+
atDisplay: string,
23+
availableDirections: Array<ExpressionReplaceDirection>,
24+
}
25+
26+
export type ExpressionReplacements = Array<ExpressionReplacement>
27+
28+
export type ExpressionReplaceReturn = {
29+
expression: string,
30+
replacementUsed: { [name in ExpressionReplacementName]: boolean },
31+
}
32+
1733
export type CalcExpressionProps = {
1834
children: string,
1935
}

src/components/pages/siteAlert.module.css

Lines changed: 9 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/pages/siteAlert.module.css.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/pages/siteAlert.module.scss

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,37 @@
1+
// Height of 2 lines of text
2+
$height: 4.125rem;
3+
14
.container {
25
overflow: hidden;
6+
height: $height;
37
}
48

59
.text {
610
animation: marquee 4s linear infinite;
11+
height: $height;
12+
// Override border radius for alert in bootstrap
713
border-radius: 0 !important;
14+
// Align element vertically at the middle
15+
display: table-cell;
16+
vertical-align: middle;
17+
// Overwritten if `display` is not `table-cell`
18+
margin: 0;
19+
// `display: table-cell` causes the element NOT to stretch
20+
width: 100vw;
21+
// Align with navbar and override bootstrap alert padding
22+
padding: 0.5rem 1rem !important;
823
}
924

1025
@keyframes marquee {
1126
0% {
1227
transform: translate(0, 100%);
1328
}
1429

15-
4% {
30+
5% {
1631
transform: translate(0, 0);
1732
}
1833

19-
96% {
34+
95% {
2035
transform: translate(0, 0);
2136
}
2237

0 commit comments

Comments
 (0)