mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-25 15:07:57 +00:00
chore: add moved files added in v14.7.0
This commit is contained in:
parent
1e95a76fde
commit
391a534d3e
57
docs/reference/functions/bigint.md
Normal file
57
docs/reference/functions/bigint.md
Normal file
@ -0,0 +1,57 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
<!-- Note: This file is automatically generated from source code comments. Changes made in this file will be overridden. -->
|
||||
|
||||
<h1 id="function-bigint">Function bigint <a href="#function-bigint" title="Permalink">#</a></h1>
|
||||
|
||||
Create a bigint or convert a string, boolean, or unit to a bigint.
|
||||
When value is a matrix, all elements will be converted to bigint.
|
||||
|
||||
|
||||
<h2 id="syntax">Syntax <a href="#syntax" title="Permalink">#</a></h2>
|
||||
|
||||
```js
|
||||
math.bigint(value)
|
||||
```
|
||||
|
||||
<h3 id="parameters">Parameters <a href="#parameters" title="Permalink">#</a></h3>
|
||||
|
||||
Parameter | Type | Description
|
||||
--------- | ---- | -----------
|
||||
`value` | string | number | BigNumber | bigint | Fraction | boolean | Array | Matrix | null | Value to be converted
|
||||
|
||||
<h3 id="returns">Returns <a href="#returns" title="Permalink">#</a></h3>
|
||||
|
||||
Type | Description
|
||||
---- | -----------
|
||||
bigint | Array | Matrix | The created bigint
|
||||
|
||||
|
||||
<h3 id="throws">Throws <a href="#throws" title="Permalink">#</a></h3>
|
||||
|
||||
Type | Description
|
||||
---- | -----------
|
||||
|
||||
|
||||
<h2 id="examples">Examples <a href="#examples" title="Permalink">#</a></h2>
|
||||
|
||||
```js
|
||||
math.bigint(2) // returns 2n
|
||||
math.bigint('123') // returns 123n
|
||||
math.bigint(true) // returns 1n
|
||||
math.bigint([true, false, true, true]) // returns [1n, 0n, 1n, 1n]
|
||||
```
|
||||
|
||||
|
||||
<h2 id="see-also">See also <a href="#see-also" title="Permalink">#</a></h2>
|
||||
|
||||
[number](number.html),
|
||||
[bignumber](bignumber.html),
|
||||
[boolean](boolean.html),
|
||||
[complex](complex.html),
|
||||
[index](index.html),
|
||||
[matrix](matrix.html),
|
||||
[string](string.html),
|
||||
[unit](unit.html)
|
||||
18
examples/code_editor/README.md
Normal file
18
examples/code_editor/README.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Code Editor Example
|
||||
|
||||
This is an example for using [mathjs](https://mathjs.org) with a code editor.
|
||||
|
||||
To run your own you need to install the dependancies with.
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
You can start development mode with:
|
||||
```
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Or build the project with:
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
59
examples/code_editor/getExpressions.js
Normal file
59
examples/code_editor/getExpressions.js
Normal file
@ -0,0 +1,59 @@
|
||||
import { parse } from 'mathjs'
|
||||
|
||||
/**
|
||||
* Extracts parsable expressions from a multiline string.
|
||||
*
|
||||
* @param {string} str - The multiline string containing expressions.
|
||||
* @returns {Array<{from: number, to: number, source: string}>} An array of objects,
|
||||
* where each object represents a parsable expression and contains:
|
||||
* - from: The starting line number of the expression within the original string.
|
||||
* - to: The ending line number of the expression within the original string.
|
||||
* - source: The actual string content of the expression.
|
||||
*/
|
||||
export default function getExpressions(str) {
|
||||
const lines = str.split('\n');
|
||||
let nextLineToParse = 0;
|
||||
const result = [];
|
||||
|
||||
for (let lineID = 0; lineID < lines.length; lineID++) {
|
||||
const linesToTest = lines.slice(nextLineToParse, lineID + 1).join('\n');
|
||||
if (canBeParsed(linesToTest)) {
|
||||
if (!isEmptyString(linesToTest)) {
|
||||
result.push({ from: nextLineToParse, to: lineID, source: linesToTest });
|
||||
}
|
||||
// Start the next parsing attempt from the line after the successfully parsed expression.
|
||||
nextLineToParse = lineID + 1;
|
||||
}
|
||||
}
|
||||
// Handle any remaining lines that couldn't be parsed as expressions.
|
||||
const linesToTest = lines.slice(nextLineToParse).join('\n');
|
||||
if (!isEmptyString(linesToTest)) {
|
||||
result.push({ from: nextLineToParse, to: lines.length - 1, source: linesToTest });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a given expression can be successfully parsed.
|
||||
*
|
||||
* @param {string} expression - The expression to parse.
|
||||
* @returns {boolean} True if the expression can be parsed, false otherwise.
|
||||
*/
|
||||
function canBeParsed(expression) {
|
||||
try {
|
||||
parse(expression)
|
||||
return true
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given string is empty or only contains whitespace characters.
|
||||
*
|
||||
* @param {string} str - The string to check.
|
||||
* @returns {boolean} True if the string is empty or only contains whitespace, false otherwise.
|
||||
*/
|
||||
function isEmptyString(str) {
|
||||
return str.trim() === ""
|
||||
}
|
||||
18
examples/code_editor/index.html
Normal file
18
examples/code_editor/index.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>math.js | code editor</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<div id="editor"></div>
|
||||
<article id="result" class="markdown-body"></article>
|
||||
</div>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
214
examples/code_editor/main.js
Normal file
214
examples/code_editor/main.js
Normal file
@ -0,0 +1,214 @@
|
||||
import './style.css'
|
||||
import 'github-markdown-css/github-markdown.css'
|
||||
import 'katex/dist/katex.min.css'
|
||||
import { StreamLanguage } from '@codemirror/language'
|
||||
import { EditorState } from '@codemirror/state'
|
||||
import { basicSetup, EditorView } from 'codemirror'
|
||||
import katex from 'katex'
|
||||
import { all, create } from 'mathjs'
|
||||
import getExpressions from './getExpressions'
|
||||
import { mathjsLang } from './mathjs-lang.js'
|
||||
|
||||
const timeout = 250 // milliseconds
|
||||
const digits = 14
|
||||
|
||||
const math = create(all)
|
||||
const parser = math.parser()
|
||||
const editorDOM = document.querySelector('#editor')
|
||||
const resultsDOM = document.querySelector('#result')
|
||||
|
||||
let processedExpressions
|
||||
let previousSelectedExpressionIndex
|
||||
let timer
|
||||
|
||||
const doc = [
|
||||
"round(e, 3)",
|
||||
"atan2(3, -3) / pi",
|
||||
"log(10000, 10)",
|
||||
"sqrt(-4)",
|
||||
"derivative('x^2 + x', 'x')",
|
||||
"pow([[-1, 2], [3, 1]], 2)",
|
||||
"# expressions",
|
||||
"1.2 * (2 + 4.5)",
|
||||
"12.7 cm to inch",
|
||||
"sin(45 deg) ^ 2",
|
||||
"9 / 3 + 2i",
|
||||
"det([-1, 2; 3, 1])"
|
||||
].join('\n')
|
||||
|
||||
let startState = EditorState.create({
|
||||
doc,
|
||||
extensions: [
|
||||
basicSetup,
|
||||
StreamLanguage.define(mathjsLang(math)),
|
||||
EditorView.lineWrapping,
|
||||
EditorView.updateListener.of((update) => {
|
||||
if (update.docChanged) {
|
||||
// if doc changed debounce and update results after a timeout
|
||||
clearTimeout(timer)
|
||||
timer = setTimeout(() => {
|
||||
updateResults()
|
||||
previousSelectedExpressionIndex = null
|
||||
updateSelection()
|
||||
}, timeout)
|
||||
} else if (update.selectionSet) {
|
||||
updateSelection()
|
||||
}
|
||||
})
|
||||
],
|
||||
})
|
||||
|
||||
let editor = new EditorView({
|
||||
state: startState,
|
||||
parent: editorDOM
|
||||
})
|
||||
|
||||
/**
|
||||
* Evaluates a given expression using a parser.
|
||||
*
|
||||
* @param {string} expression - The expression to evaluate.
|
||||
* @returns {any} The result of the evaluation, or the error message if an error occurred.
|
||||
*/
|
||||
function calc(expression) {
|
||||
let result
|
||||
try {
|
||||
result = parser.evaluate(expression)
|
||||
} catch (error) {
|
||||
result = error.toString()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats result depending on the type of result
|
||||
*
|
||||
* @param {number, string, Help, any} result - The result to format
|
||||
* @returns {string} The string in HTML with the formated result
|
||||
*/
|
||||
const formatResult = math.typed({
|
||||
'number': result => math.format(result, { precision: digits }),
|
||||
'string': result => `<code>${result}</code>`,
|
||||
'Help': result => `<pre>${math.format(result)}</pre>`,
|
||||
'any': math.typed.referTo(
|
||||
'number',
|
||||
fnumber => result => katex.renderToString(math.parse(fnumber(result)).toTex())
|
||||
)
|
||||
})
|
||||
|
||||
/**
|
||||
* Processes an array of expressions by evaluating them, formatting the results,
|
||||
* and determining their visibility.
|
||||
*
|
||||
* @param {Array<{from: number, to: number, source: string}>} expressions - An array of objects representing expressions,
|
||||
* where each object has `from`, `to`, and `source` properties.
|
||||
* @returns {Array<{from: number, to: number, source: string, outputs: any, visible: boolean}>} An array of processed expressions,
|
||||
* where each object has additional `outputs` and `visible` properties.
|
||||
*/
|
||||
function processExpressions(expressions) {
|
||||
parser.clear()
|
||||
return expressions.map(expression => {
|
||||
const result = calc(expression.source)
|
||||
const outputs = formatResult(result)
|
||||
// Determine visibility based on the result type:
|
||||
// - Undefined results are hidden.
|
||||
// - Results with an `isResultSet` property are hidden when empty.
|
||||
// - All other results are visible.
|
||||
const visible = result === undefined ? false : (result.isResultSet && result.entries.length === 0) ? false : true
|
||||
return ({
|
||||
...expression,
|
||||
outputs,
|
||||
visible
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the displayed results based on the editor's current content.
|
||||
*
|
||||
* @function updateResults
|
||||
* @requires getExpressions, processExpressions, resultsToHTML
|
||||
*
|
||||
* @description
|
||||
* 1. Extracts expressions from the editor's content.
|
||||
* 2. Evaluates and analyzes the expressions.
|
||||
* 3. Generates HTML to display the processed results.
|
||||
* 4. Renders the generated HTML in the designated results container.
|
||||
*/
|
||||
function updateResults() {
|
||||
// Extract expressions from the editor's content.
|
||||
const expressions = getExpressions(editor.state.doc.toString());
|
||||
|
||||
// Evaluate and analyze the expressions.
|
||||
processedExpressions = processExpressions(expressions);
|
||||
|
||||
// Generate HTML to display the results.
|
||||
const resultsHtml = resultsToHTML(processedExpressions);
|
||||
|
||||
// Render the generated HTML in the results container.
|
||||
resultsDOM.innerHTML = resultsHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the visual highlighting of results based on the current line selection in the editor.
|
||||
*
|
||||
* @function updateSelection
|
||||
* @requires editor, processedExpressions
|
||||
*
|
||||
* @description
|
||||
* 1. Determines the current line number in the editor's selection.
|
||||
* 2. Finds the corresponding result (processed expression) that matches the current line.
|
||||
* 3. If a different result is selected than before:
|
||||
* - Removes highlighting from the previously selected result.
|
||||
* - Highlights the newly selected result.
|
||||
* - Scrolls the newly selected result into view.
|
||||
*/
|
||||
function updateSelection() {
|
||||
const selectedLine = editor.state.doc.lineAt(
|
||||
editor.state.selection.ranges[editor.state.selection.mainIndex].from
|
||||
).number - 1;
|
||||
|
||||
let selectedExpressionIndex;
|
||||
|
||||
processedExpressions.forEach((result, index) => {
|
||||
if ((selectedLine >= result.from) && (selectedLine <= result.to)) {
|
||||
selectedExpressionIndex = index;
|
||||
}
|
||||
});
|
||||
|
||||
if (selectedExpressionIndex !== previousSelectedExpressionIndex) {
|
||||
const previouslyHighlightedResult = document.querySelector('#result').children[previousSelectedExpressionIndex];
|
||||
if (previouslyHighlightedResult !== undefined) {
|
||||
previouslyHighlightedResult.className = null;
|
||||
}
|
||||
|
||||
const currentlySelectedResult = document.querySelector('#result').children[selectedExpressionIndex];
|
||||
if (currentlySelectedResult !== undefined) {
|
||||
currentlySelectedResult.className = 'highlighted';
|
||||
currentlySelectedResult.scrollIntoView({ block: 'nearest', inline: 'start' });
|
||||
}
|
||||
|
||||
previousSelectedExpressionIndex = selectedExpressionIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of processed results into HTML elements for display.
|
||||
*
|
||||
* @function resultsToHTML
|
||||
* @param {Array<{from: number, to: number, source: string, outputs: any, visible: boolean}>} results - An array of processed results, where each object has:
|
||||
* - from: The starting line number of the expression.
|
||||
* - to: The ending line number of the expression.
|
||||
* - source: The original expression string.
|
||||
* - outputs: The formatted result of evaluating the expression.
|
||||
* - visible: A boolean indicating whether the result should be displayed or hidden.
|
||||
* @returns {string} A string of HTML elements representing the results, where each result is enclosed in a <pre> tag with appropriate styling based on its visibility.
|
||||
*/
|
||||
function resultsToHTML(results) {
|
||||
return results.map(el => {
|
||||
const elementStyle = el.visible ? '' : 'style="display:none"'
|
||||
return `<pre ${elementStyle}>${el.outputs}</pre>`
|
||||
}
|
||||
).join('')
|
||||
}
|
||||
|
||||
updateResults()
|
||||
244
examples/code_editor/mathjs-lang.js
Normal file
244
examples/code_editor/mathjs-lang.js
Normal file
@ -0,0 +1,244 @@
|
||||
/**
|
||||
* Create mathjs syntax highlighting for CodeMirror
|
||||
*
|
||||
* TODO: this is using CodeMirror v5 functionality, upgrade this to v6
|
||||
*
|
||||
* @param {Object} math A mathjs instance
|
||||
*/
|
||||
export function mathjsLang(math) {
|
||||
function wordRegexp(words) {
|
||||
return new RegExp('^((' + words.join(')|(') + '))\\b')
|
||||
}
|
||||
|
||||
const singleOperators = new RegExp("^[-+*/&|^~<>!%']")
|
||||
const singleDelimiters = new RegExp('^[([{},:=;.?]')
|
||||
const doubleOperators = new RegExp('^((==)|(!=)|(<=)|(>=)|(<<)|(>>)|(\\.[-+*/^]))')
|
||||
const doubleDelimiters = new RegExp('^((!=)|(^\\|))')
|
||||
const tripleDelimiters = new RegExp('^((>>>)|(<<<))')
|
||||
const expressionEnd = new RegExp('^[\\])]')
|
||||
const identifiers = new RegExp('^[_A-Za-z\xa1-\uffff][_A-Za-z0-9\xa1-\uffff]*')
|
||||
|
||||
const mathFunctions = []
|
||||
const mathPhysicalConstants = []
|
||||
const mathIgnore = ['expr', 'type']
|
||||
const numberLiterals = [
|
||||
'e',
|
||||
'E',
|
||||
'i',
|
||||
'Infinity',
|
||||
'LN2',
|
||||
'LN10',
|
||||
'LOG2E',
|
||||
'LOG10E',
|
||||
'NaN',
|
||||
'null',
|
||||
'phi',
|
||||
'pi',
|
||||
'PI',
|
||||
'SQRT1_2',
|
||||
'SQRT2',
|
||||
'tau',
|
||||
'undefined',
|
||||
'version'
|
||||
]
|
||||
|
||||
// based on https://github.com/josdejong/mathjs/blob/develop/bin/cli.js
|
||||
for (const expr in math.expression.mathWithTransform) {
|
||||
if (!mathIgnore.includes(expr)) {
|
||||
if (typeof math[expr] === 'function') {
|
||||
mathFunctions.push(expr)
|
||||
} else if (!numberLiterals.includes(expr)) {
|
||||
mathPhysicalConstants.push(expr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generates a list of all valid units in mathjs
|
||||
const listOfUnits = []
|
||||
for (const unit in math.Unit.UNITS) {
|
||||
for (const prefix in math.Unit.UNITS[unit].prefixes) {
|
||||
listOfUnits.push(prefix + unit)
|
||||
}
|
||||
}
|
||||
|
||||
const builtins = wordRegexp(mathFunctions)
|
||||
|
||||
const keywords = wordRegexp(['to', 'in', 'and', 'not', 'or', 'xor', 'mod'])
|
||||
|
||||
const units = wordRegexp(Array.from(new Set(listOfUnits)))
|
||||
const physicalConstants = wordRegexp(mathPhysicalConstants)
|
||||
|
||||
// tokenizers
|
||||
function tokenTranspose(stream, state) {
|
||||
if (!stream.sol() && stream.peek() === "'") {
|
||||
stream.next()
|
||||
state.tokenize = tokenBase
|
||||
return 'operator'
|
||||
}
|
||||
state.tokenize = tokenBase
|
||||
return tokenBase(stream, state)
|
||||
}
|
||||
|
||||
function tokenComment(stream, state) {
|
||||
if (stream.match(/^.*#}/)) {
|
||||
state.tokenize = tokenBase
|
||||
return 'comment'
|
||||
}
|
||||
stream.skipToEnd()
|
||||
return 'comment'
|
||||
}
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
// whitespaces
|
||||
if (stream.eatSpace()) return null
|
||||
|
||||
// Handle one line Comments
|
||||
if (stream.match('#{')) {
|
||||
state.tokenize = tokenComment
|
||||
stream.skipToEnd()
|
||||
return 'comment'
|
||||
}
|
||||
|
||||
if (stream.match(/^#/)) {
|
||||
stream.skipToEnd()
|
||||
return 'comment'
|
||||
}
|
||||
|
||||
// Handle Number Literals
|
||||
if (stream.match(/^[0-9.+-]/, false)) {
|
||||
if (stream.match(/^[+-]?0x[0-9a-fA-F]+[ij]?/)) {
|
||||
stream.tokenize = tokenBase
|
||||
return 'number'
|
||||
}
|
||||
if (stream.match(/^[+-]?\d*\.\d+([EeDd][+-]?\d+)?[ij]?/)) {
|
||||
return 'number'
|
||||
}
|
||||
if (stream.match(/^[+-]?\d+([EeDd][+-]?\d+)?[ij]?/)) {
|
||||
return 'number'
|
||||
}
|
||||
}
|
||||
if (stream.match(wordRegexp(numberLiterals))) {
|
||||
return 'number'
|
||||
}
|
||||
|
||||
// Handle Strings
|
||||
let m = stream.match(/^"(?:[^"]|"")*("|$)/) || stream.match(/^'(?:[^']|'')*('|$)/)
|
||||
if (m) {
|
||||
return m[1] ? 'string' : 'string error'
|
||||
}
|
||||
|
||||
// Handle words
|
||||
if (stream.match(keywords)) {
|
||||
return 'keyword'
|
||||
}
|
||||
if (stream.match(builtins)) {
|
||||
return 'builtin'
|
||||
}
|
||||
if (stream.match(physicalConstants)) {
|
||||
return 'tag'
|
||||
}
|
||||
if (stream.match(units)) {
|
||||
return 'attribute'
|
||||
}
|
||||
if (stream.match(identifiers)) {
|
||||
return 'variable'
|
||||
}
|
||||
if (stream.match(singleOperators) || stream.match(doubleOperators)) {
|
||||
return 'operator'
|
||||
}
|
||||
if (
|
||||
stream.match(singleDelimiters) ||
|
||||
stream.match(doubleDelimiters) ||
|
||||
stream.match(tripleDelimiters)
|
||||
) {
|
||||
return null
|
||||
}
|
||||
if (stream.match(expressionEnd)) {
|
||||
state.tokenize = tokenTranspose
|
||||
return null
|
||||
}
|
||||
// Handle non-detected items
|
||||
stream.next()
|
||||
return 'error'
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'mathjs',
|
||||
|
||||
startState: function () {
|
||||
return {
|
||||
tokenize: tokenBase
|
||||
}
|
||||
},
|
||||
|
||||
token: function (stream, state) {
|
||||
const style = state.tokenize(stream, state)
|
||||
if (style === 'number' || style === 'variable') {
|
||||
state.tokenize = tokenTranspose
|
||||
}
|
||||
return style
|
||||
},
|
||||
|
||||
languageData: {
|
||||
commentTokens: { line: '#' },
|
||||
autocomplete: myCompletions
|
||||
}
|
||||
}
|
||||
|
||||
function myCompletions(context) {
|
||||
let word = context.matchBefore(/\w*/)
|
||||
if (word.from == word.to && !context.explicit) return null
|
||||
let options = []
|
||||
mathFunctions.forEach((func) => options.push({ label: func, type: 'function' }))
|
||||
|
||||
mathPhysicalConstants.forEach((constant) => options.push({ label: constant, type: 'constant' }))
|
||||
|
||||
numberLiterals.forEach((number) => options.push({ label: number, type: 'variable' }))
|
||||
|
||||
// units as enum
|
||||
for (const name in math.Unit.UNITS) {
|
||||
if (hasOwnPropertySafe(math.Unit.UNITS, name)) {
|
||||
if (name.startsWith(word.text)) {
|
||||
options.push({ label: name, type: 'enum' })
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const name in math.Unit.PREFIXES) {
|
||||
if (hasOwnPropertySafe(math.Unit.PREFIXES, name)) {
|
||||
const prefixes = math.Unit.PREFIXES[name]
|
||||
for (const prefix in prefixes) {
|
||||
if (hasOwnPropertySafe(prefixes, prefix)) {
|
||||
if (prefix.startsWith(word.text)) {
|
||||
options.push({ label: prefix, type: 'enum' })
|
||||
} else if (word.text.startsWith(prefix)) {
|
||||
const unitKeyword = word.text.substring(prefix.length)
|
||||
for (const n in math.Unit.UNITS) {
|
||||
const fullUnit = prefix + n
|
||||
if (hasOwnPropertySafe(math.Unit.UNITS, n)) {
|
||||
if (
|
||||
!options.includes(fullUnit) &&
|
||||
n.startsWith(unitKeyword) &&
|
||||
math.Unit.isValuelessUnit(fullUnit)
|
||||
) {
|
||||
options.push({ label: fullUnit, type: 'enum' })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
from: word.from,
|
||||
options
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// helper function to safely check whether an object has a property
|
||||
// copy from the function in object.js which is ES6
|
||||
function hasOwnPropertySafe(object, property) {
|
||||
return object && Object.hasOwnProperty.call(object, property)
|
||||
}
|
||||
1303
examples/code_editor/package-lock.json
generated
Normal file
1303
examples/code_editor/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
22
examples/code_editor/package.json
Normal file
22
examples/code_editor/package.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "code-editor",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "7.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/language": "6.11.3",
|
||||
"@codemirror/state": "6.5.2",
|
||||
"codemirror": "6.0.2",
|
||||
"github-markdown-css": "5.8.1",
|
||||
"katex": "0.16.22",
|
||||
"mathjs": "14.6.0"
|
||||
}
|
||||
}
|
||||
60
examples/code_editor/style.css
Normal file
60
examples/code_editor/style.css
Normal file
@ -0,0 +1,60 @@
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#app {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
#editor {
|
||||
flex: 1;
|
||||
height: auto;
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#editor>.cm-editor {
|
||||
flex: 1;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
#app>article {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
article.markdown-body .results {
|
||||
padding: 0.5em;
|
||||
margin: 0.5em;
|
||||
}
|
||||
|
||||
article.markdown-body > .highlighted {
|
||||
background-color: rgba(0, 150, 255, 0.2);
|
||||
}
|
||||
|
||||
article.markdown-body {
|
||||
box-sizing: border-box;
|
||||
min-width: 200px;
|
||||
max-width: 980px;
|
||||
margin: 0 auto;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.markdown-body {
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user