Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions components/bin/build
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ process.chdir(path.dirname(json));
const mjPath = path.relative(process.cwd(), path.resolve(__dirname, '..', '..', target));
const mjGlobal = path.join('..', mjPath, 'components', 'global.js');

/**
* Determine the module type
*/
function getType() {
const component = config.component || 'part';
if (component.match(/\/(svg|chtml|common)\/fonts\//)) return RegExp.$1 + '-font';
Expand All @@ -69,6 +72,13 @@ function getType() {
return component;
}

/**
* Convert Windows paths to unix paths
*/
const normalize = process.platform === 'win32'
? (file) => file.replace(/\\/g, '/')
: (file) => file;

/**
* Extract the configuration values
*/
Expand Down Expand Up @@ -100,7 +110,7 @@ let PACKAGE = [];
*/
function processList(base, dir, list, top = true) {
for (const item of list) {
const file = path.join(dir, item);
const file = normalize(path.join(dir, item));
if (!EXCLUDE.has(file)) {
const stat = fs.statSync(path.resolve(base, file));
if (stat.isDirectory()) {
Expand Down Expand Up @@ -271,12 +281,12 @@ function getExtraDirectories() {
function processGlobal() {
console.info(' ' + COMPONENT + '.ts');
const lines = (target === 'cjs' ? [
`const {combineWithMathJax} = require('${GLOBAL}')`,
`const {VERSION} = require('${VERSION}');`,
`const {combineWithMathJax} = require('${normalize(GLOBAL)}')`,
`const {VERSION} = require('${normalize(VERSION)}');`,
'',
] : [
`import {combineWithMathJax} from '${GLOBAL}';`,
`import {VERSION} from '${VERSION}';`,
`import {combineWithMathJax} from '${normalize(GLOBAL)}';`,
`import {VERSION} from '${normalize(VERSION)}';`,
'',
]);
const [prefix, indent, postfix] = getExtraDirectories();
Expand Down Expand Up @@ -337,7 +347,7 @@ function processPackage(lines, space, dir) {
if (path.dirname(PACKAGE[0]) === dir) {
const file = PACKAGE.shift();
const name = path.basename(file);
let relativefile = path.join('..', JS, dir, name).replace(/\.ts$/, '.js')
const relativefile = normalize(path.join('..', JS, dir, name).replace(/\.ts$/, '.js'));
const component = 'module' + (++importCount);
lines.push(
target === 'cjs' ?
Expand Down
9 changes: 8 additions & 1 deletion components/bin/makeAll
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ function fileRegExp(name) {
return new RegExp(name.replace(/([\\.{}[\]()?*^$])/g, '\\$1'), 'g');
}

/**
* Options for the execSync() function
*/
const execOptions = process.platform === 'win32'
? { shell: `${process.env.ProgramFiles}\\Git\\bin\\bash.exe` }
: {};

/**
* Get the current working directory
*/
Expand Down Expand Up @@ -196,7 +203,7 @@ function processSubdirs(dir, action, config) {
* Run a command on a given directory
*/
function run(cmd, dir) {
return execSync(cmd + ` '${path.relative('.', dir).replace(/'/g, '\\\'')}'`);
return execSync(cmd + ` '${path.relative('.', dir).replace(/'/g, '\\\'')}'`, execOptions);
}

/**
Expand Down
30 changes: 16 additions & 14 deletions components/bin/pack
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

const fs = require('fs');
const path = require('path');
const {spawn, execSync} = require('child_process');
const {spawn} = require('child_process');

/**
* The module type to use ('cjs' or 'mjs')
Expand Down Expand Up @@ -64,14 +64,7 @@ const rootRE = fileRegExp(path.dirname(jsPath));
const nodeRE = /^.*\/node_modules/;
const fontRE = new RegExp('^.*\\/(mathjax-[^\/-]*)(?:-font)?\/(build|[cm]js)');

/**
* Find the directory where npx runs (so we know where "npx webpack" will run)
* (We use npx rather than pnpm here as it seems that pnpm doesn't
* find the executable from a node_modules directory higher than the
* first package.json, and extensions and fonts can have their own
* package.json.)
*/
const packDir = String(execSync('npx node -e "console.log(process.cwd())"'));
const packDir = process.cwd();

/**
* @param {string} dir The directory to pack
Expand All @@ -80,11 +73,20 @@ const packDir = String(execSync('npx node -e "console.log(process.cwd())"'));
async function readJSON(dir) {
return new Promise((ok, fail) => {
const buffer = [];
const child = spawn('npx', [
'webpack', '--env', `dir=${path.relative(packDir, path.resolve(dir))}`,
'--env', `bundle=${bundle}`, '--json',
'-c', path.relative(packDir, path.join(compPath, 'webpack.config.' + target))
]);
const child = spawn(
'npx',
[
'webpack',
'--env', `dir=${path.relative(packDir, path.resolve(dir))}`,
'--env', `bundle=${bundle}`,
'--json',
'-c', path.relative(packDir, path.join(compPath, 'webpack.config.' + target))
],
{
cwd: packDir,
shell: true,
}
);
child.stdout.on('data', (data) => buffer.push(String(data)));
child.stderr.on('data', (data) => console.error(String(data)));
child.on('close', (code) => {
Expand Down
8 changes: 4 additions & 4 deletions components/mjs/a11y/speech/speech.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ import './lib/speech.js';

import {combineDefaults} from '#js/components/global.js';
import {Package} from '#js/components/package.js';
import {hasWindow} from '#js/util/context.js';
import {context} from '#js/util/context.js';
import {SpeechHandler} from '#js/a11y/speech.js';

if (MathJax.loader) {
let path = Package.resolvePath('[sre]', false);
let maps = Package.resolvePath('[mathmaps]', false);
if (hasWindow) {
if (context.window) {
path = new URL(path, location).href;
maps = new URL(maps, location).href;
} else {
const REQUIRE = typeof require !== 'undefined' ? require : MathJax.config.loader.require;
if (REQUIRE?.resolve) {
path = REQUIRE.resolve(`${path}/require.mjs`).replace(/\/[^\/]*$/, '');
maps = REQUIRE.resolve(`${maps}/base.json`).replace(/\/[^\/]*$/, '');
path = context.path(REQUIRE.resolve(`${path}/require.mjs`)).replace(/\/[^\/]*$/, '');
maps = context.path(REQUIRE.resolve(`${maps}/base.json`)).replace(/\/[^\/]*$/, '');
} else {
path = maps = '';
}
Expand Down
2 changes: 1 addition & 1 deletion components/mjs/node-main/node-main-setup.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ global.require = createRequire(import.meta.url);
const path = require("path");

if (!global.MathJax) global.MathJax = {};
global.MathJax.__dirname = path.dirname(new URL(import.meta.url).pathname);
global.MathJax.__dirname = path.dirname(new URL(import.meta.url).pathname);
3 changes: 2 additions & 1 deletion components/mjs/node-main/node-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ import '../startup/init.js';
import {Loader, CONFIG} from '#js/components/loader.js';
import {Package} from '#js/components/package.js';
import {combineDefaults, combineConfig} from '#js/components/global.js';
import {context} from '#js/util/context.js';
import '../core/core.js';
import '../adaptors/liteDOM/liteDOM.js';
import {source} from '../source.js';

const MathJax = global.MathJax;

const path = eval('require("path")'); // get path from node, not webpack
const dir = MathJax.config.__dirname; // set up by node-main.mjs or node-main.cjs
const dir = context.path(MathJax.config.__dirname); // set up by node-main.mjs or node-main.cjs

/*
* Set up the initial configuration
Expand Down
2 changes: 1 addition & 1 deletion components/mjs/source-lab.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@
* limitations under the License.
*/

export const src = String(new URL('.', import.meta.url)).replace(/\/$/, '');
export const dirname = String(new URL('.', import.meta.url)).replace(/\/$/, '');
2 changes: 1 addition & 1 deletion components/mjs/source.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@
* limitations under the License.
*/

module.exports.src = __dirname;
module.exports.dirname = __dirname;
2 changes: 1 addition & 1 deletion components/mjs/source.d.cts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export declare const src: string;
export declare const dirname: string;
4 changes: 3 additions & 1 deletion components/mjs/source.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
* limitations under the License.
*/

import {src} from '#source/source.cjs';
import {dirname} from '#source/source.cjs';
import {context} from '#js/util/context.js';
const src = context.path(dirname);

export const source = {
'core': `${src}/core/core.js`,
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@
"copy:mml3": "copy() { pnpm -s log:single 'Copying legacy code MathML3'; pnpm copyfiles -u 1 ts/input/mathml/mml3/mml3.sef.json $1; }; copy",
"copy:pkg": "copy() { pnpm -s log:single \"Copying package.json to $1\"; pnpm copyfiles -u 2 components/bin/package.json $1; }; copy",
"=============================================================================== log": "",
"log:comp": "log() { echo \\\\033[32m$1\\\\033[0m; }; log",
"log:header": "log() { echo '============='; echo $1; echo '============='; }; log",
"log:single": "log() { echo \\\\033[34m--$1\\\\033[0m; }; log",
"log:comp": "log() { echo \u001B[32m$1\u001B[0m; }; log",
"log:header": "log() { echo '\u001B[1m============='; echo $1; echo '=============\u001B[0m'; }; log",
"log:single": "log() { echo \u001B[94m--$1\u001B[0m; }; log",
"=============================================================================== cjs": "",
"cjs:build": "pnpm -s log:header 'Building cjs'; pnpm -s cjs:src:build && pnpm -s cjs:components:build",
"cjs:bundle:clean": "pnpm clean:dir bundle-cjs",
Expand Down
2 changes: 2 additions & 0 deletions testsuite/tests/util/Context-android.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ describe('context object', () => {

test('context', async () => {
let {context, hasWindow} = await import("#js/util/context.js");
expect(context.path('C:\\test.js')).toBe('C:\\test.js');
delete context.path;
expect(context).toEqual({window: window, document: window.document, os: 'Unix'});
expect(hasWindow).toBe(true);
});
Expand Down
2 changes: 2 additions & 0 deletions testsuite/tests/util/Context-browser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ describe('context object', () => {

test('context', async () => {
let {context, hasWindow} = await import("#js/util/context.js");
expect(context.path('C:\\test.js')).toBe('C:\\test.js');
delete context.path;
expect(context).toEqual({window: window, document: window.document, os: 'Unix'});
expect(hasWindow).toBe(true);
});
Expand Down
15 changes: 15 additions & 0 deletions testsuite/tests/util/Context-node-unknown.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { describe, test, expect } from '@jest/globals';

global.process = {...process, platform: 'test'} as any;

describe('context object', () => {

test('context', async () => {
let {context, hasWindow} = await import("#js/util/context.js");
expect(context.path('C:\\test.js')).toBe('C:\\test.js');
delete context.path;
expect(context).toEqual({window: null, document: null, os: 'test'});
expect(hasWindow).toBe(false);
});

});
22 changes: 21 additions & 1 deletion testsuite/tests/util/Context-node.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
import { describe, test, expect } from '@jest/globals';
import { context, hasWindow } from '#js/util/context.js';

const OS = {
'linux': 'Unix',
'android': 'Unix',
'aix': 'Unix',
'freebsd': 'Unix',
'netbsd': 'Unix',
'openbsd': 'Unix',
'sunos': 'Unix',
'darwin': 'MacOS',
'win32': 'Windows',
'cygwin': 'Windows',
'haiku': 'unknown',
}[process.platform] || process.platform;

describe('context object', () => {

test('context', () => {
expect(context).toEqual({window: null, document: null, os: 'unknown'});
if (process.platform as string === 'Windows') {
expect(context.path('C:\\test.js')).toBe('C:/test.js');
} else {
expect(context.path('C:\\test.js')).toBe('C:\\test.js');
}
delete context.path;
expect(context).toEqual({window: null, document: null, os: OS});
expect(hasWindow).toBe(false);
});

Expand Down
16 changes: 16 additions & 0 deletions testsuite/tests/util/Context-unknown.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { describe, test, expect } from '@jest/globals';

const window = {document: {}, navigator: {userAgent: '', appVersion: ''}};
(global as any).window = window;

describe('context object', () => {

test('context', async () => {
let {context, hasWindow} = await import("#js/util/context.js");
expect(context.path('C:\\test.js')).toBe('C:\\test.js');
delete context.path;
expect(context).toEqual({window: window, document: window.document, os: 'unknown'});
expect(hasWindow).toBe(true);
});

});
18 changes: 18 additions & 0 deletions testsuite/tests/util/Context-windows.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { describe, test, expect } from '@jest/globals';

const window = {document: {}, navigator: {appVersion: 'Win'}};
(global as any).window = window;

describe('context object', () => {

test('context', async () => {
let {context, hasWindow} = await import("#js/util/context.js");
expect(context.path('C:\\test.js')).toBe('C:/test.js');
expect(context.path('/C:/test.js')).toBe('C:/test.js');
expect(context.path('/test.js')).toBe('/test.js');
delete context.path;
expect(context).toEqual({window: window, document: window.document, os: 'Windows'});
expect(hasWindow).toBe(true);
});

});
5 changes: 4 additions & 1 deletion ts/components/cjs/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@
* The location of this file
*/
declare const __dirname: string;
declare const require: (file: string) => any;

/**
* @return {string} The MathJax component root directory
*/
export function mjxRoot(): string {
return __dirname.replace(/[cm]js\/components\/[cm]js$/, 'bundle');
return require('../../util/context.js')
.context.path(__dirname)
.replace(/[cm]js\/components\/[cm]js$/, 'bundle');
}
7 changes: 5 additions & 2 deletions ts/components/cjs/sre-root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@
* The location of this file
*/
declare const __dirname: string;
declare const require: (file: string) => any;

/**
* @return {string} The MathJax mjs SRE root directory
* @return {string} The MathJax cjs SRE root directory
*/
export function sreRoot(): string {
return __dirname.replace(/components\/[cm]js$/, 'a11y/sre');
return require('../../util/context.js')
.context.path(__dirname)
.replace(/components\/[cm]js$/, 'a11y/sre');
}
2 changes: 1 addition & 1 deletion ts/components/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export const PathFilters: { [name: string]: PathFilterFunction } = {
*/
normalize: (data) => {
const name = data.name;
if (!name.match(/^(?:[a-z]+:\/)?\/|[a-z]:\\|\[/i)) {
if (!name.match(/^(?:[a-z]+:\/)?\/|[a-z]:[/\\]|\[/i)) {
data.name = '[mathjax]/' + name.replace(/^\.\//, '');
}
return true;
Expand Down
9 changes: 5 additions & 4 deletions ts/components/mjs/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@
* @author dpvc@mathjax.org (Davide Cervone)
*/

import { context } from '../../util/context.js';

/**
* @returns {string} The MathJax component root directory
*/
export function mjxRoot(): string {
return new URL(import.meta.url).pathname.replace(
/[cm]js\/components\/[cm]js\/root.js$/,
'bundle'
);
return context
.path(new URL(import.meta.url).pathname)
.replace(/[cm]js\/components\/[cm]js\/root.js$/, 'bundle');
}
9 changes: 5 additions & 4 deletions ts/components/mjs/sre-root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@
* @author dpvc@mathjax.org (Davide Cervone)
*/

import { context } from '../../util/context.js';

/**
* @returns {string} The MathJax mjs SRE root directory
*/
export function sreRoot(): string {
return new URL(import.meta.url).pathname.replace(
/components\/[cm]js\/sre-root.js$/,
'a11y/sre'
);
return context
.path(new URL(import.meta.url).pathname)
.replace(/components\/[cm]js\/sre-root.js$/, 'a11y/sre');
}
Loading