From 23cd86a2e3e0b93779df1b0615c67f486ecf1c96 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 5 Mar 2022 18:19:20 +0100 Subject: [PATCH 01/26] Starting latex rendering --- LogarithmPlotter/logarithmplotter.py | 2 + .../LogarithmPlotter/Setting/ListSetting.qml | 18 ++++++ LogarithmPlotter/util/latex.py | 58 +++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 LogarithmPlotter/util/latex.py diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 53b29e0..6a3cc9d 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -46,6 +46,7 @@ from LogarithmPlotter import __VERSION__ from LogarithmPlotter.util import config, native from LogarithmPlotter.util.update import check_for_updates from LogarithmPlotter.util.helper import Helper +from LogarithmPlotter.util.latex import Latex config.init() @@ -107,6 +108,7 @@ def run(): engine = QQmlApplicationEngine() global tmpfile helper = Helper(pwd, tmpfile) + latex = Latex(tempdir, app.palette()) engine.rootContext().setContextProperty("Helper", helper) engine.rootContext().setContextProperty("TestBuild", "--test-build" in argv) engine.rootContext().setContextProperty("StartTime", dep_time) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml index 718181f..c71fddd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml @@ -1,3 +1,21 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2022 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQml.Models 2.12 diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py new file mode 100644 index 0000000..943edfc --- /dev/null +++ b/LogarithmPlotter/util/latex.py @@ -0,0 +1,58 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2022 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" + +from PySide2.QtCore import QObject, Slot +from PySide2.QtGui import QImage, QColor +from PySide2.QtWidgets import QApplication + +from os import path +from sympy import preview +from tempfile import TemporaryDirectory + +class Latex(QObject): + def __init__(self, tempdir: str, palette): + QObject.__init__(self) + self.tempdir = tempdir + self.palette = palette + fg = self.palette.windowText().color().convertTo(QColor.Rgb) + + @Slot(str, float, bool, result=str) + def render(self, latexstring, font_size, themeFg = True): + exprpath = path.join(self.tempdir.name, str(hash(latexstring)) + '.png') + print(latexstring, exprpath) + if not path.exists(exprpath): + if themeFg: + fg = self.palette.windowText().color().convertTo(QColor.Rgb) + fg = f'rgb {fg.redF()} {fg.greenF()} {fg.blueF()}' + else: + fg = 'rgb 1.0 1.0 1.0' + preview('$$' + latexstring + '$$', viewer='file', filename=exprpath, dvioptions=[ + "-T", "tight", + "-z", "0", + "--truecolor", + f"-D {font_size * 72.27 / 10}", # See https://linux.die.net/man/1/dvipng#-D for convertion + "-bg", "Transparent", + "-fg", fg], + euler=False) + return exprpath + + @Slot(str) + def copyLatexImageToClipboard(self, latexstring): + global tempfile + clipboard = QApplication.clipboard() + clipboard.setImage(QImage(self.render(latexstring))) From 1142ca1c00ddb58d26b3c5b023524aaed33b9ade Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 5 Mar 2022 20:57:21 +0100 Subject: [PATCH 02/26] Starting latex rendering (canvas side). --- LogarithmPlotter/logarithmplotter.py | 1 + .../LogarithmPlotter/LogGraphCanvas.qml | 76 +++++++++++++--- .../ad5001/LogarithmPlotter/js/math/latex.js | 91 +++++++++++++++---- .../ad5001/LogarithmPlotter/js/objs/common.js | 6 +- .../ad5001/LogarithmPlotter/js/objs/point.js | 76 +++++++++------- LogarithmPlotter/util/latex.py | 23 +++-- 6 files changed, 191 insertions(+), 82 deletions(-) diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 6a3cc9d..2ce7b94 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -110,6 +110,7 @@ def run(): helper = Helper(pwd, tmpfile) latex = Latex(tempdir, app.palette()) engine.rootContext().setContextProperty("Helper", helper) + engine.rootContext().setContextProperty("Latex", latex) engine.rootContext().setContextProperty("TestBuild", "--test-build" in argv) engine.rootContext().setContextProperty("StartTime", dep_time) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index f140007..3009868 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -157,26 +157,40 @@ Canvas { */ property int drawMaxX: Math.ceil(Math.max(Math.abs(xmin), Math.abs(px2x(canvasSize.width)))/xaxisstep1) + property var imageLoaders: {} + property var ctx - onPaint: { + Component.onCompleted: imageLoaders = {} + + onPaint: function(rect) { //console.log('Redrawing') - var ctx = getContext("2d"); - reset(ctx) - drawGrille(ctx) - drawAxises(ctx) - ctx.lineWidth = linewidth - for(var objType in Objects.currentObjects) { - for(var obj of Objects.currentObjects[objType]){ - ctx.strokeStyle = obj.color - ctx.fillStyle = obj.color - if(obj.visible) obj.draw(canvas, ctx) + if(rect.width == canvas.width) { // Redraw full canvas + ctx = getContext("2d"); + reset(ctx) + drawGrille(ctx) + drawAxises(ctx) + drawLabels(ctx) + ctx.lineWidth = linewidth + for(var objType in Objects.currentObjects) { + for(var obj of Objects.currentObjects[objType]){ + ctx.strokeStyle = obj.color + ctx.fillStyle = obj.color + if(obj.visible) obj.draw(canvas, ctx) + } } + ctx.lineWidth = 1 } - ctx.lineWidth = 1 - drawLabels(ctx) - } + onImageLoaded: { + Object.keys(imageLoaders).forEach((key) => { + if(isImageLoaded(key)) { + // Calling callback + imageLoaders[key][0](canvas, ctx, imageLoaders[key][1]) + delete imageLoaders[key] + } + }) + } /*! \qmlmethod void LogGraphCanvas::reset(var ctx) @@ -314,6 +328,19 @@ Canvas { } } + /*! + \qmlmethod void LogGraphCanvas::drawVisibleImage(var ctx, var image, double x, double y) + Draws an \c image onto the canvas using 2D \c ctx. + \note The \c x, \c y \c width and \c height properties here are relative to the canvas, not the plot. + */ + function drawVisibleImage(ctx, image, x, y, width, height) { + console.log("Drawing image", isImageLoaded(image), isImageError(image)) + markDirty(Qt.rect(x, y, width, height)); + ctx.drawImage(image, x, y, width, height) + /*if(true || (x > 0 && x < canvasSize.width && y > 0 && y < canvasSize.height)) { + }*/ + } + /*! \qmlmethod var LogGraphCanvas::measureText(var ctx, string text) Measures the wicth and height of a multiline \c text that would be drawn onto the canvas using 2D \c ctx. @@ -415,4 +442,25 @@ Canvas { } ctx.stroke(); } + + /*! + \qmlmethod var LogGraphCanvas::renderLatexImage(string ltxText, color) + Renders latex markup \c ltxText to an image and loads it. Returns a dictionary with three values: source, width and height. + */ + function renderLatexImage(ltxText, color, callback) { + let [ltxSrc, ltxWidth, ltxHeight] = Latex.render(ltxText, textsize, color).split(",") + let imgData = { + "source": ltxSrc, + "width": parseFloat(ltxWidth), + "height": parseFloat(ltxHeight) + }; + if(!isImageLoaded(ltxSrc) && !isImageLoading(ltxSrc)){ + // Wait until the image is loaded to callback. + loadImage(ltxSrc) + imageLoaders[ltxSrc] = [callback, imgData] + } else { + // Callback directly + callback(canvas, ctx, imgData) + } + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index d7620fc..efb4cba 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -42,8 +42,75 @@ function parif(elem, contents) { return contents.some(x => elem.toString().includes(x)) ? par(elem) : elem } + /** - * This function converts expr-eval tokens to a latex string. + * Creates a latex expression for a function. + * + * @param {string} f - Function to convert + * @param {Array} args - Arguments of the function + * @returns {string} + */ +function functionToLatex(f, args) { + switch(f) { + case "derivative": + return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(by, 'g'), 'x') + '}{dx}'; + break; + case "integral": + return '\\int\\limits^{' + args[0] + '}_{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3]; + break; + case "sqrt": + return '\\sqrt\\left(' + args.join(', ') + '\\right)'; + break; + case "abs": + return '\\left|' + args.join(', ') + '\\right|'; + break; + case "floor": + return '\\left\\lfloor' + args.join(', ') + '\\right\\rfloor'; + break; + case "ceil": + return '\\left\\lceil' + args.join(', ') + '\\right\\rceil'; + break; + default: + return '\\mathrm{' + f + '}\\left(' + args.join(', ') + '\\right)'; + break; + } +} + + +/** + * Creates a latex variable from a variable. + * + * @param {string} vari - variable to convert + * @returns {string} + */ +function variableToLatex(vari) { + unicodechars = ["α","β","γ","δ","ε","ζ","η", + "π","θ","κ","λ","μ","ξ","ρ", + "ς","σ","τ","φ","χ","ψ","ω", + "Γ","Δ","Θ","Λ","Ξ","Π","Σ", + "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", + "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", + "ₜ","¹","²","³","⁴","⁵","⁶", + "⁷","⁸","⁹","⁰","₁","₂","₃", + "₄","₅","₆","₇","₈","₉","₀"] + equivalchars = ["alpha","beta","gamma","delta","epsilon","zeta","eta", + "pi","theta","kappa","lambda","mu","xi","rho", + "sigma","sigma","tau","phi","chi","psi","omega", + "Gamma","Delta","Theta","Lambda","Xi","Pi","Sigma", + "Phy","Psi","Omega","{}_{a}","{}_{e}","{}_{o}","{}_{x}", + "{}_{h}","{}_{k}","{}_{l}","{}_{m}","{}_{n}","{}_{p}","{}_{s}", + "{}_{t}","{}^{1}","{}^{2}","{}^{3}","{}^{4}","{}^{5}","{}^{6}", + "{}^{7}","{}^{8}","{}^{9}","{}^{0}","{}_{1}","{}_{2}","{}_{3}", + "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}"] + for(int i = 0; i < unicodechars.length; i++) { + if(vari.includes(unicodechars[i])) + vari = vari.replaceAll(unicodechars[i], equivalchars[i]) + } + return vari; +} + +/** + * Converts expr-eval tokens to a latex string. * * @param {Array} tokens - expr-eval tokens list * @returns {string} @@ -115,10 +182,7 @@ function expressionToLatex(tokens) { break; case ExprEval.IVAR: case ExprEval.IVARNAME: - if(item.value == "pi") - nstack.push("π") - else - nstack.push(item.value); + nstack.push(variableToLatex(item.value)); break; case ExprEval.IOP1: // Unary operator n1 = nstack.pop(); @@ -144,21 +208,7 @@ function expressionToLatex(tokens) { } f = nstack.pop(); // Handling various functions - if(f == "derivative") - nstack.push('\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(by, 'g'), 'x') + '}{dx}'); - else if(f == "integral") - nstack.push('\\int\\limits^{' + args[0] + '}_{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3]); - else if(f == "sqrt") - nstack.push('\\sqrt\\left(' + args.join(', ') + '\\right)'); - else if(f == "abs") - nstack.push('\\left|' + args.join(', ') + '\\right|'); - else if(f == "floor") - nstack.push('\\left\\lfloor' + args.join(', ') + '\\right\\rfloor'); - else if(f == "ceil") - nstack.push('\\left\\lceil' + args.join(', ') + '\\right\\rceil'); - else - nstack.push('\\mathrm{' + f + '}\\left(' + args.join(', ') + '\\right)'); - break; + nstack.push(functionToLatex(f, args)) case ExprEval.IFUNDEF: nstack.push(par(n1 + '(' + args.join(', ') + ') = ' + n2)); break; @@ -191,5 +241,6 @@ function expressionToLatex(tokens) { nstack = [ nstack.join(';') ]; } } + console.log(nstack[0]); return String(nstack[0]); } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index 8eb3036..d9dc33f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -84,12 +84,16 @@ class DrawableObject { return `${this.name} = Unknown` } + toLatexString() { + return this.getReadableString() + } + getLabel() { switch(this.labelContent) { case 'name': return this.name case 'name + value': - return this.getReadableString() + return this.toLatexString() case 'null': return '' diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js index e0b9c58..feb965f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js @@ -58,6 +58,10 @@ class Point extends Common.DrawableObject { return `${this.name} = (${this.x}, ${this.y})` } + toLatexString() { + return `${this.name} = \\left(${this.x.latexMarkup}, ${this.y.latexMarkup}\\right)` + } + export() { return [this.name, this.visible, this.color.toString(), this.labelContent, this.x.toEditableString(), this.y.toEditableString(), this.labelPosition, this.pointStyle] } @@ -80,41 +84,43 @@ class Point extends Common.DrawableObject { ctx.fillRect(canvasX-1, canvasY-pointSize/2, 2, pointSize) break; } - var text = this.getLabel() - ctx.font = `${canvas.textsize}px sans-serif` - var textSize = ctx.measureText(text).width - switch(this.labelPosition) { - case 'top': - case 'above': - canvas.drawVisibleText(ctx, text, canvasX-textSize/2, canvasY-16) - break; - case 'bottom': - case 'below': - canvas.drawVisibleText(ctx, text, canvasX-textSize/2, canvasY+16) - break; - case 'left': - canvas.drawVisibleText(ctx, text, canvasX-textSize-10, canvasY+4) - break; - case 'right': - canvas.drawVisibleText(ctx, text, canvasX+10, canvasY+4) - break; - case 'top-left': - case 'above-left': - canvas.drawVisibleText(ctx, text, canvasX-textSize-10, canvasY-16) - break; - case 'top-right': - case 'above-right': - canvas.drawVisibleText(ctx, text, canvasX+10, canvasY-16) - break; - case 'bottom-left': - case 'below-left': - canvas.drawVisibleText(ctx, text, canvasX-textSize-10, canvasY+16) - break; - case 'bottom-right': - case 'below-right': - canvas.drawVisibleText(ctx, text, canvasX+10, canvasY+16) - break; - + + let drawLabel = function(canvas, ctx, ltxImg) { + //console.log(JSON.stringify(ltxImg), canvas.isImageLoaded(ltxImg.source), this, this.labelPosition) + switch(this.labelPosition) { + case 'top': + case 'above': + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-ltxImg.width/2, canvasY-(ltxImg.height+4), ltxImg.width, ltxImg.height) + break; + case 'bottom': + case 'below': + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-ltxImg.width/2, canvasY+4, ltxImg.width, ltxImg.height) + break; + case 'left': + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+4), canvasY+4, ltxImg.width, ltxImg.height) + break; + case 'right': + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+4, canvasY+4, ltxImg.width, ltxImg.height) + break; + case 'top-left': + case 'above-left': + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+4), canvasY-(ltxImg.height+4), ltxImg.width, ltxImg.height) + break; + case 'top-right': + case 'above-right': + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+4, canvasY-(ltxImg.height+4), ltxImg.width, ltxImg.height) + break; + case 'bottom-left': + case 'below-left': + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+4), canvasY+4, ltxImg.width, ltxImg.height) + break; + case 'bottom-right': + case 'below-right': + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+4, canvasY+4, ltxImg.width, ltxImg.height) + break; + } } + canvas.renderLatexImage(this.getLabel(), this.color, drawLabel.bind(this)) + //canvas.drawVisibleImage(ctx, ltxImg.source, canvasX, canvasY) } } diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index 943edfc..680613a 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -31,16 +31,13 @@ class Latex(QObject): self.palette = palette fg = self.palette.windowText().color().convertTo(QColor.Rgb) - @Slot(str, float, bool, result=str) - def render(self, latexstring, font_size, themeFg = True): - exprpath = path.join(self.tempdir.name, str(hash(latexstring)) + '.png') - print(latexstring, exprpath) + @Slot(str, float, QColor, result=str) + def render(self, latexstring, font_size, color = True): + exprpath = path.join(self.tempdir.name, f'{hash(latexstring)}_{font_size}_{color.rgb()}.png') + print("Rendering", latexstring, exprpath) if not path.exists(exprpath): - if themeFg: - fg = self.palette.windowText().color().convertTo(QColor.Rgb) - fg = f'rgb {fg.redF()} {fg.greenF()} {fg.blueF()}' - else: - fg = 'rgb 1.0 1.0 1.0' + fg = color.convertTo(QColor.Rgb) + fg = f'rgb {fg.redF()} {fg.greenF()} {fg.blueF()}' preview('$$' + latexstring + '$$', viewer='file', filename=exprpath, dvioptions=[ "-T", "tight", "-z", "0", @@ -48,11 +45,13 @@ class Latex(QObject): f"-D {font_size * 72.27 / 10}", # See https://linux.die.net/man/1/dvipng#-D for convertion "-bg", "Transparent", "-fg", fg], - euler=False) - return exprpath + euler=True) + img = QImage(exprpath); + # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded + return f'{exprpath},{img.width()},{img.height()}' @Slot(str) def copyLatexImageToClipboard(self, latexstring): global tempfile clipboard = QApplication.clipboard() - clipboard.setImage(QImage(self.render(latexstring))) + clipboard.setImage(self.render(latexstring)) From b5600046e9fee583fc2b2aa5855413838c162b10 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 5 Mar 2022 20:58:38 +0100 Subject: [PATCH 03/26] Fixing build to add sympy. --- ci/drone.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/drone.yml b/ci/drone.yml index 0eb4b7a..82dbc36 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -14,6 +14,7 @@ steps: - name: Linux test image: ad5001/ubuntu-pyside2-xvfb:hirsute-5.15.2 commands: + - pip3 install sympy - xvfb-run python3 run.py --test-build --no-check-for-updates - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test2.lpf @@ -24,6 +25,7 @@ steps: image: ad5001/ubuntu-pyside2-xvfb-wine:win7-5.15.2 commands: - # For some reason, launching GUI apps with wine, even with xvfb-run, fails. + - pip install sympy - xvfb-run python run.py --test-build --no-check-for-updates - xvfb-run python run.py --test-build --no-check-for-updates ./ci/test1.lpf - xvfb-run python run.py --test-build --no-check-for-updates ./ci/test2.lpf From ccf3de57835e6aa8e95e06d4cd7cb6f50ecb5f3c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 5 Mar 2022 21:00:29 +0100 Subject: [PATCH 04/26] Fixing typos --- .../ad5001/LogarithmPlotter/js/math/latex.js | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index efb4cba..099994f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -84,25 +84,25 @@ function functionToLatex(f, args) { * @returns {string} */ function variableToLatex(vari) { - unicodechars = ["α","β","γ","δ","ε","ζ","η", - "π","θ","κ","λ","μ","ξ","ρ", - "ς","σ","τ","φ","χ","ψ","ω", - "Γ","Δ","Θ","Λ","Ξ","Π","Σ", - "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", - "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", - "ₜ","¹","²","³","⁴","⁵","⁶", - "⁷","⁸","⁹","⁰","₁","₂","₃", - "₄","₅","₆","₇","₈","₉","₀"] - equivalchars = ["alpha","beta","gamma","delta","epsilon","zeta","eta", - "pi","theta","kappa","lambda","mu","xi","rho", - "sigma","sigma","tau","phi","chi","psi","omega", - "Gamma","Delta","Theta","Lambda","Xi","Pi","Sigma", - "Phy","Psi","Omega","{}_{a}","{}_{e}","{}_{o}","{}_{x}", - "{}_{h}","{}_{k}","{}_{l}","{}_{m}","{}_{n}","{}_{p}","{}_{s}", - "{}_{t}","{}^{1}","{}^{2}","{}^{3}","{}^{4}","{}^{5}","{}^{6}", - "{}^{7}","{}^{8}","{}^{9}","{}^{0}","{}_{1}","{}_{2}","{}_{3}", - "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}"] - for(int i = 0; i < unicodechars.length; i++) { + let unicodechars = ["α","β","γ","δ","ε","ζ","η", + "π","θ","κ","λ","μ","ξ","ρ", + "ς","σ","τ","φ","χ","ψ","ω", + "Γ","Δ","Θ","Λ","Ξ","Π","Σ", + "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", + "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", + "ₜ","¹","²","³","⁴","⁵","⁶", + "⁷","⁸","⁹","⁰","₁","₂","₃", + "₄","₅","₆","₇","₈","₉","₀"] + let equivalchars = ["alpha","beta","gamma","delta","epsilon","zeta","eta", + "pi","theta","kappa","lambda","mu","xi","rho", + "sigma","sigma","tau","phi","chi","psi","omega", + "Gamma","Delta","Theta","Lambda","Xi","Pi","Sigma", + "Phy","Psi","Omega","{}_{a}","{}_{e}","{}_{o}","{}_{x}", + "{}_{h}","{}_{k}","{}_{l}","{}_{m}","{}_{n}","{}_{p}","{}_{s}", + "{}_{t}","{}^{1}","{}^{2}","{}^{3}","{}^{4}","{}^{5}","{}^{6}", + "{}^{7}","{}^{8}","{}^{9}","{}^{0}","{}_{1}","{}_{2}","{}_{3}", + "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}"] + for(let i = 0; i < unicodechars.length; i++) { if(vari.includes(unicodechars[i])) vari = vari.replaceAll(unicodechars[i], equivalchars[i]) } From 0975189615dbfb8e27cf232fe7dec8996027699d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 6 Mar 2022 00:55:32 +0100 Subject: [PATCH 05/26] A lot of changes related to latex: - Implemented latex for functions - Fixed Points with greek variable names - Small changes to test1 to fit latex better - History re/undos only redraw the graph every 4 change in order to speed up the process when re/undoing a lot of changes. - Removing some debug related to latex - Added latexMarkup property for domains, allowing them to be integrated into objects latex. - Fixed issues related to derivatives and integrals on latex - Fully fixed variable substitution for latex - Fixed sequence crashing - Adding getLatexLabel method for objects that have a latex label. --- .../LogarithmPlotter/History/History.qml | 20 +++++--- .../LogarithmPlotter/LogGraphCanvas.qml | 2 +- .../LogarithmPlotter/Setting/TextSetting.qml | 2 +- .../ad5001/LogarithmPlotter/js/math/domain.js | 37 ++++++++++++-- .../ad5001/LogarithmPlotter/js/math/latex.js | 37 +++++++------- .../LogarithmPlotter/js/math/sequence.js | 8 +-- .../ad5001/LogarithmPlotter/js/objs/common.js | 12 +++++ .../LogarithmPlotter/js/objs/function.js | 51 +++++++++++++++++-- .../ad5001/LogarithmPlotter/js/objs/point.js | 24 +++++---- LogarithmPlotter/util/latex.py | 6 +-- ci/test1.lpf | 2 +- 11 files changed, 144 insertions(+), 57 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml index 99fc4cb..e6caf9d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml @@ -124,14 +124,16 @@ Item { } /*! - \qmlmethod void History::undo() + \qmlmethod void History::undo(bool updateObjectList = true) Undoes the historylib.Action at the top of the undo stack and pushes it to the top of the redo stack. + By default, will update the graph and the object list. This behavior can be disabled by setting the \c updateObjectList to false. */ - function undo() { + function undo(updateObjectList = true) { if(undoStack.length > 0) { var action = undoStack.pop() action.undo() - objectLists.update() + if(updateObjectList) + objectLists.update() redoStack.push(action) undoCount--; redoCount++; @@ -140,14 +142,16 @@ Item { } /*! - \qmlmethod void History::redo() + \qmlmethod void History::redo(bool updateObjectList = true) Redoes the historylib.Action at the top of the redo stack and pushes it to the top of the undo stack. + By default, will update the graph and the object list. This behavior can be disabled by setting the \c updateObjectList to false. */ - function redo() { + function redo(updateObjectList = true) { if(redoStack.length > 0) { var action = redoStack.pop() action.redo() - objectLists.update() + if(updateObjectList) + objectLists.update() undoStack.push(action) undoCount++; redoCount--; @@ -186,7 +190,7 @@ Item { property int toUndoCount: 0 onTriggered: { if(toUndoCount > 0) { - historyObj.undo() + historyObj.undo(toUndoCount % 4 == 1) // Only redraw once every 4 changes. toUndoCount--; } else { running = false; @@ -200,7 +204,7 @@ Item { property int toRedoCount: 0 onTriggered: { if(toRedoCount > 0) { - historyObj.redo() + historyObj.redo(toRedoCount % 4 == 1) // Only redraw once every 4 changes. toRedoCount--; } else { running = false; diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 3009868..a819da1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -334,7 +334,7 @@ Canvas { \note The \c x, \c y \c width and \c height properties here are relative to the canvas, not the plot. */ function drawVisibleImage(ctx, image, x, y, width, height) { - console.log("Drawing image", isImageLoaded(image), isImageError(image)) + //console.log("Drawing image", isImageLoaded(image), isImageError(image)) markDirty(Qt.rect(x, y, width, height)); ctx.drawImage(image, x, y, width, height) /*if(true || (x > 0 && x < canvasSize.width && y > 0 && y < canvasSize.height)) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index 739f7d8..d9239c8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -83,7 +83,7 @@ Item { id: iconLabel anchors.top: parent.top anchors.topMargin: icon == "" ? 0 : 3 - source: control.visible ? "../icons/" + control.icon : "" + source: control.visible && icon != "" ? "../icons/" + control.icon : "" width: height height: icon == "" || !visible ? 0 : 24 color: sysPalette.windowText diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js index cdf9902..48c23cf 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js @@ -152,10 +152,15 @@ class Domain { * Represents an empty set. */ class EmptySet extends Domain { + constructor() { + super() + this.displayName = "∅" + this.latexMarkup = "\\emptyset" + } includes(x) { return false } - toString() { return "∅" } + toString() { return this.displayName } union(domain) { return domain } @@ -177,6 +182,7 @@ class Range extends Domain { this.openBegin = openBegin this.openEnd = openEnd this.displayName = (openBegin ? "]" : "[") + begin.toString() + ";" + end.toString() + (openEnd ? "[" : "]") + this.latexMarkup = `\\mathopen${openBegin ? "]" : "["}${this.begin.latexMarkup};${this.end.latexMarkup}\\mathclose${openEnd ? "[" : "]"}` } includes(x) { @@ -292,6 +298,8 @@ class DomainSet extends SpecialDomain { } this.executedValues.sort((a,b) => a-b) this.values = this.executedValues.map(val => newVals[val]) + this.displayName = "{" + this.values.join(";") + "}" + this.latexMarkup = `\\{${this.values.join(";")}\\}` } includes(x) { @@ -325,7 +333,7 @@ class DomainSet extends SpecialDomain { } toString() { - return "{" + this.values.join(";") + "}" + return this.displayName } union(domain) { @@ -397,6 +405,8 @@ class UnionDomain extends Domain { super() this.dom1 = dom1 this.dom2 = dom2 + this.displayName = this.dom1.toString() + " ∪ " + this.dom2.toString() + this.latexMarkup = `${dom1.latexMarkup}\\cup${dom2.latexMarkup}` } includes(x) { @@ -404,7 +414,7 @@ class UnionDomain extends Domain { } toString() { - return this.dom1.toString() + " ∪ " + this.dom2.toString() + return this.displayName } union(domain) { @@ -441,6 +451,8 @@ class IntersectionDomain extends Domain { super() this.dom1 = dom1 this.dom2 = dom2 + this.displayName = dom1.toString() + " ∩ " + dom2.toString() + this.latexMarkup = `${dom1.latexMarkup}\\cap${dom2.latexMarkup}` } includes(x) { @@ -448,7 +460,7 @@ class IntersectionDomain extends Domain { } toString() { - return this.dom1.toString() + " ∩ " + this.dom2.toString() + return this.displayName } union(domain) { @@ -484,6 +496,8 @@ class MinusDomain extends Domain { super() this.dom1 = dom1 this.dom2 = dom2 + this.displayName = dom1.toString() + "∖" + dom2.toString() + this.latexMarkup = `${dom1.latexMarkup}\\setminus${dom2.latexMarkup}` } includes(x) { @@ -491,7 +505,7 @@ class MinusDomain extends Domain { } toString() { - return this.dom1.toString() + "∖" + this.dom2.toString() + return this.displayName } static import(frm) { @@ -505,33 +519,45 @@ class MinusDomain extends Domain { Domain.RE = new MinusDomain("R", "{0}") Domain.RE.displayName = "ℝ*" +Domain.RE.latexMarkup = "\\mathbb{R}^{*}" Domain.R = new Range(-Infinity,Infinity,true,true) Domain.R.displayName = "ℝ" +Domain.R.latexMarkup = "\\mathbb{R}" Domain.RP = new Range(0,Infinity,true,false) Domain.RP.displayName = "ℝ⁺" +Domain.RP.latexMarkup = "\\mathbb{R}^{+}" Domain.RM = new Range(-Infinity,0,true,false) Domain.RM.displayName = "ℝ⁻" +Domain.RM.latexMarkup = "\\mathbb{R}^{-}" Domain.RPE = new Range(0,Infinity,true,true) Domain.RPE.displayName = "ℝ⁺*" +Domain.RPE.latexMarkup = "\\mathbb{R}^{+*}" Domain.RME = new Range(-Infinity,0,true,true) Domain.RME.displayName = "ℝ⁻*" +Domain.RME.latexMarkup = "\\mathbb{R}^{+*}" Domain.N = new SpecialDomain('ℕ', x => x%1==0 && x >= 0, x => Math.max(Math.floor(x)+1, 0), x => Math.max(Math.ceil(x)-1, 0)) +Domain.N.latexMarkup = "\\mathbb{N}" Domain.NE = new SpecialDomain('ℕ*', x => x%1==0 && x > 0, x => Math.max(Math.floor(x)+1, 1), x => Math.max(Math.ceil(x)-1, 1)) +Domain.NE.latexMarkup = "\\mathbb{N}^{*}" Domain.Z = new SpecialDomain('ℤ', x => x%1==0, x => Math.floor(x)+1, x => Math.ceil(x)-1) +Domain.Z.latexMarkup = "\\mathbb{Z}" Domain.ZE = new SpecialDomain('ℤ*', x => x%1==0 && x != 0, x => Math.floor(x)+1 == 0 ? Math.floor(x)+2 : Math.floor(x)+1, x => Math.ceil(x)-1 == 0 ? Math.ceil(x)-2 : Math.ceil(x)-1) +Domain.ZE.latexMarkup = "\\mathbb{Z}^{*}" Domain.ZM = new SpecialDomain('ℤ⁻', x => x%1==0 && x <= 0, x => Math.min(Math.floor(x)+1, 0), x => Math.min(Math.ceil(x)-1, 0)) +Domain.ZM.latexMarkup = "\\mathbb{Z}^{-}" Domain.ZME = new SpecialDomain('ℤ⁻*', x => x%1==0 && x < 0, x => Math.min(Math.floor(x)+1, -1), x => Math.min(Math.ceil(x)-1, -1)) +Domain.ZME.latexMarkup = "\\mathbb{Z}^{-*}" Domain.NLog = new SpecialDomain('ℕˡᵒᵍ', x => x/Math.pow(10, x.toString().length-1) % 1 == 0 && x > 0, function(x) { @@ -542,6 +568,7 @@ Domain.NLog = new SpecialDomain('ℕˡᵒᵍ', var x10pow = Math.pow(10, x.toString().length-1) return Math.max(1, (Math.ceil(x/x10pow)-1)*x10pow) }) +Domain.NLog.latexMarkup = "\\mathbb{N}^{log}" var refedDomains = [] diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index 099994f..35bc2dc 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -53,10 +53,10 @@ function parif(elem, contents) { function functionToLatex(f, args) { switch(f) { case "derivative": - return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(by, 'g'), 'x') + '}{dx}'; + return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(args[1].substr(1, args[1].length-2), 'g'), 'x') + '}{dx}'; break; case "integral": - return '\\int\\limits^{' + args[0] + '}_{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3]; + return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3].substr(1, args[3].length-2); break; case "sqrt": return '\\sqrt\\left(' + args.join(', ') + '\\right)'; @@ -92,19 +92,22 @@ function variableToLatex(vari) { "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", "ₜ","¹","²","³","⁴","⁵","⁶", "⁷","⁸","⁹","⁰","₁","₂","₃", - "₄","₅","₆","₇","₈","₉","₀"] - let equivalchars = ["alpha","beta","gamma","delta","epsilon","zeta","eta", - "pi","theta","kappa","lambda","mu","xi","rho", - "sigma","sigma","tau","phi","chi","psi","omega", - "Gamma","Delta","Theta","Lambda","Xi","Pi","Sigma", - "Phy","Psi","Omega","{}_{a}","{}_{e}","{}_{o}","{}_{x}", + "₄","₅","₆","₇","₈","₉","₀", + "pi"] + let equivalchars = ["\\alpha","\\beta","\\gamma","\\delta","\\epsilon","\\zeta","\\eta", + "\\pi","\\theta","\\kappa","\\lambda","\\mu","\\xi","\\rho", + "\\sigma","\\sigma","\\tau","\\phi","\\chi","\\psi","\\omega", + "\\Gamma","\\Delta","\\Theta","\\Lambda","\\Xi","\\Pi","\\Sigma", + "\\Phy","\\Psi","\\Omega","{}_{a}","{}_{e}","{}_{o}","{}_{x}", "{}_{h}","{}_{k}","{}_{l}","{}_{m}","{}_{n}","{}_{p}","{}_{s}", "{}_{t}","{}^{1}","{}^{2}","{}^{3}","{}^{4}","{}^{5}","{}^{6}", "{}^{7}","{}^{8}","{}^{9}","{}^{0}","{}_{1}","{}_{2}","{}_{3}", - "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}"] + "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}", + "\\pi"] for(let i = 0; i < unicodechars.length; i++) { + //console.log(vari, unicodechars[i], equivalchars[i]); if(vari.includes(unicodechars[i])) - vari = vari.replaceAll(unicodechars[i], equivalchars[i]) + vari = vari.replace(new RegExp(unicodechars[i], 'g'), equivalchars[i]) } return vari; } @@ -140,7 +143,7 @@ function expressionToLatex(tokens) { switch(f) { case '-': case '+': - nstack.push(n1 + this.ope + n2); + nstack.push(n1 + f + n2); break; case '||': case 'or': @@ -148,7 +151,7 @@ function expressionToLatex(tokens) { case 'and': case '==': case '!=': - nstack.push(par(n1) + this.ope + par(n2)); + nstack.push(par(n1) + f + par(n2)); break; case '*': nstack.push(parif(n1,['+','-']) + " \\times " + parif(n2,['+','-'])); @@ -182,7 +185,7 @@ function expressionToLatex(tokens) { break; case ExprEval.IVAR: case ExprEval.IVARNAME: - nstack.push(variableToLatex(item.value)); + nstack.push(variableToLatex(item.value.toString())); break; case ExprEval.IOP1: // Unary operator n1 = nstack.pop(); @@ -209,6 +212,7 @@ function expressionToLatex(tokens) { f = nstack.pop(); // Handling various functions nstack.push(functionToLatex(f, args)) + break; case ExprEval.IFUNDEF: nstack.push(par(n1 + '(' + args.join(', ') + ') = ' + n2)); break; @@ -235,12 +239,7 @@ function expressionToLatex(tokens) { } } if (nstack.length > 1) { - if (toJS) { - nstack = [ nstack.join(',') ]; - } else { - nstack = [ nstack.join(';') ]; - } + nstack = [ nstack.join(';') ] } - console.log(nstack[0]); return String(nstack[0]); } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js index 7988949..ced0cfa 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js @@ -34,7 +34,7 @@ class Sequence extends Expr.Expression { this.calcValues = Object.assign({}, baseValues) for(var n in this.calcValues) if(['string', 'number'].includes(typeof this.calcValues[n])) - this.calcValues[n] = parser.parse(this.calcValues[n].toString()).simplify().evaluate(C.evalVariables) + this.calcValues[n] = C.parser.parse(this.calcValues[n].toString()).simplify().evaluate(C.evalVariables) this.valuePlus = parseInt(valuePlus) } @@ -58,11 +58,11 @@ class Sequence extends Expr.Expression { cache(n = 1) { var str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString()) - var expr = parser.parse(str).simplify() + var expr = C.parser.parse(str).simplify() var l = {'n': n-this.valuePlus} // Just in case, add n (for custom functions) l[this.name] = this.calcValues - currentVars = Object.assign(l, C.evalVariables) - this.calcValues[n] = expr.evaluate(currentVars) + C.currentVars = Object.assign(l, C.evalVariables) + this.calcValues[n] = expr.evaluate(C.currentVars) } toString(forceSign=false) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index d9dc33f..c602224 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -89,6 +89,18 @@ class DrawableObject { } getLabel() { + switch(this.labelContent) { + case 'name': + return this.name + case 'name + value': + return this.getReadableString() + case 'null': + return '' + + } + } + + getLatexLabel() { switch(this.labelContent) { case 'name': return this.name diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js index 9b474a2..c640a8d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js @@ -22,6 +22,7 @@ .import "../utils.js" as Utils .import "../mathlib.js" as MathLib .import "../parameters.js" as P +.import "../math/latex.js" as Latex class Function extends Common.ExecutableObject { @@ -87,6 +88,14 @@ class Function extends Common.ExecutableObject { } } + toLatexString() { + if(this.displayMode == 'application') { + return `${Latex.variableToLatex(this.name)}:\\begin{array}{llll}${this.definitionDomain.latexMarkup} & \\rightarrow & ${this.destinationDomain.latexMarkup}\\\\x & \\mapsto & ${this.expression.latexMarkup}\\end{array}` + } else { + return `\\begin{array}{l}${Latex.variableToLatex(this.name)}(x) = ${this.expression.latexMarkup}\\\\ D_{${this.name}} = ${this.definitionDomain.latexMarkup}\\end{array}` + } + } + export() { return [this.name, this.visible, this.color.toString(), this.labelContent, this.expression.toEditableString(), this.definitionDomain.toString(), this.destinationDomain.toString(), @@ -117,7 +126,41 @@ class Function extends Common.ExecutableObject { var textSize = canvas.measureText(ctx, text) var posX = canvas.x2px(this.labelX) var posY = canvas.y2px(this.execute(this.labelX)) - switch(this.labelPosition) { + + let drawLabel = function(canvas, ctx, ltxImg) { + switch(this.labelPosition) { + case 'above': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY-(ltxImg.height+10), ltxImg.width, ltxImg.height) + break; + case 'below': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY+10, ltxImg.width, ltxImg.height) + break; + case 'left': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY-ltxImg.height/2, ltxImg.width, ltxImg.height) + break; + case 'right': + canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY-ltxImg.height/2, ltxImg.width, ltxImg.height) + break; + case 'above-left': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY-(ltxImg.height+10), ltxImg.width, ltxImg.height) + break; + case 'above-right': + canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY-(ltxImg.height+10), ltxImg.width, ltxImg.height) + break; + case 'below-left': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY+10, ltxImg.width, ltxImg.height) + break; + case 'below-right': + canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY+10, ltxImg.width, ltxImg.height) + break; + } + } + let ltxLabel = this.getLatexLabel(); + if(ltxLabel != "") + canvas.renderLatexImage(ltxLabel, this.color, drawLabel.bind(this)) + //canvas.drawVisibleImage(ctx, ltxImg.source, posX, posY) + + /*switch(this.labelPosition) { case 'above': canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height) break; @@ -142,13 +185,13 @@ class Function extends Common.ExecutableObject { case 'below-right': canvas.drawVisibleText(ctx, text, posX, posY+textSize.height) break; - } + }*/ } static drawFunction(canvas, ctx, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) { // Reusable in other objects. - // Drawing small traits every 2px - var pxprecision = 0.2 + // Drawing small traits every 0.2px + var pxprecision = 1 var previousX = canvas.px2x(0) var previousY; if(definitionDomain instanceof MathLib.SpecialDomain && definitionDomain.moveSupported) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js index feb965f..dd1fc1e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js @@ -21,6 +21,7 @@ .import "common.js" as Common .import "../mathlib.js" as MathLib .import "../parameters.js" as P +.import "../math/latex.js" as Latex class Point extends Common.DrawableObject { @@ -59,7 +60,7 @@ class Point extends Common.DrawableObject { } toLatexString() { - return `${this.name} = \\left(${this.x.latexMarkup}, ${this.y.latexMarkup}\\right)` + return `${Latex.variableToLatex(this.name)} = \\left(${this.x.latexMarkup}, ${this.y.latexMarkup}\\right)` } export() { @@ -86,41 +87,42 @@ class Point extends Common.DrawableObject { } let drawLabel = function(canvas, ctx, ltxImg) { - //console.log(JSON.stringify(ltxImg), canvas.isImageLoaded(ltxImg.source), this, this.labelPosition) switch(this.labelPosition) { case 'top': case 'above': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-ltxImg.width/2, canvasY-(ltxImg.height+4), ltxImg.width, ltxImg.height) + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-ltxImg.width/2, canvasY-(ltxImg.height+10), ltxImg.width, ltxImg.height) break; case 'bottom': case 'below': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-ltxImg.width/2, canvasY+4, ltxImg.width, ltxImg.height) + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-ltxImg.width/2, canvasY+10, ltxImg.width, ltxImg.height) break; case 'left': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+4), canvasY+4, ltxImg.width, ltxImg.height) + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+10), canvasY-ltxImg.height/2, ltxImg.width, ltxImg.height) break; case 'right': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+4, canvasY+4, ltxImg.width, ltxImg.height) + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+10, canvasY-ltxImg.height/2, ltxImg.width, ltxImg.height) break; case 'top-left': case 'above-left': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+4), canvasY-(ltxImg.height+4), ltxImg.width, ltxImg.height) + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+10), canvasY-(ltxImg.height+10), ltxImg.width, ltxImg.height) break; case 'top-right': case 'above-right': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+4, canvasY-(ltxImg.height+4), ltxImg.width, ltxImg.height) + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+10, canvasY-(ltxImg.height+10), ltxImg.width, ltxImg.height) break; case 'bottom-left': case 'below-left': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+4), canvasY+4, ltxImg.width, ltxImg.height) + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+10), canvasY+10, ltxImg.width, ltxImg.height) break; case 'bottom-right': case 'below-right': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+4, canvasY+4, ltxImg.width, ltxImg.height) + canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+10, canvasY+10, ltxImg.width, ltxImg.height) break; } } - canvas.renderLatexImage(this.getLabel(), this.color, drawLabel.bind(this)) + let ltxLabel = this.getLatexLabel(); + if(ltxLabel != "") + canvas.renderLatexImage(ltxLabel, this.color, drawLabel.bind(this)) //canvas.drawVisibleImage(ctx, ltxImg.source, canvasX, canvasY) } } diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index 680613a..07b4b9d 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -38,14 +38,14 @@ class Latex(QObject): if not path.exists(exprpath): fg = color.convertTo(QColor.Rgb) fg = f'rgb {fg.redF()} {fg.greenF()} {fg.blueF()}' - preview('$$' + latexstring + '$$', viewer='file', filename=exprpath, dvioptions=[ + preview('$${' + latexstring + '}$$', viewer='file', filename=exprpath, dvioptions=[ "-T", "tight", "-z", "0", "--truecolor", - f"-D {font_size * 72.27 / 10}", # See https://linux.die.net/man/1/dvipng#-D for convertion + f"-D {int(font_size * 72.27 / 100) * 10}", # See https://linux.die.net/man/1/dvipng#-D for convertion "-bg", "Transparent", "-fg", fg], - euler=True) + euler=False) img = QImage(exprpath); # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded return f'{exprpath},{img.width()},{img.height()}' diff --git a/ci/test1.lpf b/ci/test1.lpf index 7785158..b21f304 100644 --- a/ci/test1.lpf +++ b/ci/test1.lpf @@ -1 +1 @@ -LPFv1{"xzoom":100,"yzoom":485,"xmin":-1,"ymax":1,"xaxisstep":"1","yaxisstep":"0.1","xaxislabel":"ω (rad/s)","yaxislabel":"G (dB)","logscalex":false,"linewidth":2,"showxgrad":true,"showygrad":true,"textsize":22,"history":[[["EditedProperty",["h","Function","labelX",3,2.5,false]],["EditedProperty",["h","Function","labelPosition","above-left","above",false]],["EditedProperty",["h","Function","labelPosition","above","left",false]],["EditedProperty",["h","Function","labelX",2.5,2,false]],["EditedProperty",["h","Function","labelX",2,2.2,false]],["EditedProperty",["h","Function","labelX",2.2,9,false]]],[]],"width":1908,"height":1005,"objects":{"Sequence":[["u",true,"#ff5500","name + value",true,true,{"1":"cos(u[n])"},{"0":"-1"},"above-left",8]],"Function":[["f",true,"#2b156d","name + value","integral((x + 1), x, \"cos (t)\", \"t\")","ℝ⁺*","ℝ","application","left",7,true,true],["g",true,"#ac539c","name + value","0.739083","ℝ","ℝ","application","below",-1,true,false],["h",true,"#00aa00","name + value","derivative(\"cos t\", \"t\", x)","ℤ","ℝ","application","left",9,true,true]],"Repartition":[["X",true,"#1E1EAF","name",true,true,{"0":"0.2","1":"0.1","2":"0.2"},"above",2.5]],"Point":[["A",true,"#060759","name + value","4","(-0.5)","top","●"]]},"type":"logplotv1"} \ No newline at end of file +LPFv1{"xzoom":100,"yzoom":485,"xmin":-1,"ymax":1,"xaxisstep":"1","yaxisstep":"0.1","xaxislabel":"ω (rad/s)","yaxislabel":"G (dB)","logscalex":false,"linewidth":2,"showxgrad":true,"showygrad":true,"textsize":22,"history":[[["EditedProperty",["h","Function","labelX",3,2.5,false]],["EditedProperty",["h","Function","labelPosition","above-left","above",false]],["EditedProperty",["h","Function","labelPosition","above","left",false]],["EditedProperty",["h","Function","labelX",2.5,2,false]],["EditedProperty",["h","Function","labelX",2,2.2,false]],["EditedProperty",["h","Function","labelX",2.2,9,false]],["EditedProperty",["f","Function","labelPosition","left","above-left",false]],["EditedProperty",["f","Function","labelX",7,7.4,false]],["EditedProperty",["A","Point","y","(-0.5)","(-0.6)",true]]],[["EditedProperty",["A","Point","labelPosition","top","above",false]]]],"width":1908,"height":1005,"objects":{"Sequence":[["u",true,"#ff5500","name + value",true,true,{"1":"cos(u[n])"},{"0":"-1"},"above-left",8]],"Function":[["f",true,"#2b156d","name + value","integral((x + 1), x, \"cos (t)\", \"t\")","ℝ⁺*","ℝ","application","above-left",7.4,true,true],["g",true,"#ac539c","null","0.739083","ℝ","ℝ","application","below",-1,true,false],["h",true,"#00aa00","name + value","derivative(\"cos t\", \"t\", x)","ℤ","ℝ","application","left",9,true,true]],"Repartition":[["X",true,"#1E1EAF","name",true,true,{"0":"0.2","1":"0.1","2":"0.2"},"above",2.5]],"Point":[["A",true,"#060759","name + value","4","(-0.6)","top","●"]]},"type":"logplotv1"} From c4ffcdaa3503e31b47c85ecdc2a9ddeb93fe7315 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 6 Mar 2022 01:01:12 +0100 Subject: [PATCH 06/26] Removing custom copyrights from license in order to have better referencing. --- LICENSE.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index a9530c3..2fb2e74 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -630,8 +630,8 @@ attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - LogarithmPlotter - Create graphs with logarithm scales. - Copyright (C) 2021 Ad5001 + + Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -652,7 +652,7 @@ mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: - LogarithmPlotter Copyright (C) 2021 Ad5001 + Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. @@ -673,4 +673,3 @@ library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . - From de0220fecf98237aba9c9cc65aeb785e668672ab Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 6 Mar 2022 01:13:20 +0100 Subject: [PATCH 07/26] Implemented latex for distributions --- .../LogarithmPlotter/js/objs/repartition.js | 44 ++++++++++++++++++- ci/test1.lpf | 2 +- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js index 341a2a8..ff6b12a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js @@ -20,6 +20,8 @@ .import "common.js" as Common .import "../parameters.js" as P +.import "../math/latex.js" as Latex + class RepartitionFunction extends Common.ExecutableObject { static type(){return 'Repartition'} @@ -66,6 +68,12 @@ class RepartitionFunction extends Common.ExecutableObject { return `F_${this.name}(x) = P(${this.name} ≤ x)\n` + keys.map(idx => `P(${this.name}=${idx})=${this.probabilities[idx]}`).join("; ") } + toLatexString() { + let keys = Object.keys(this.probabilities).sort((a,b) => a-b); + let varName = Latex.variableToLatex(this.name) + return `\\begin{array}{l}F_{${varName}}(x) = P(${varName} \\le x)\\\\` + keys.map(idx => `P(${varName}=${idx})=${this.probabilities[idx]}`).join("; ") + '\\end{array}' + } + execute(x = 1) { var ret = 0; Object.keys(this.probabilities).sort((a,b) => a-b).forEach(idx => { @@ -150,6 +158,40 @@ class RepartitionFunction extends Common.ExecutableObject { var textSize = canvas.measureText(ctx, text) var posX = canvas.x2px(this.labelX) var posY = canvas.y2px(this.execute(this.labelX)) + + let drawLabel = function(canvas, ctx, ltxImg) { + switch(this.labelPosition) { + case 'above': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY-(ltxImg.height+10), ltxImg.width, ltxImg.height) + break; + case 'below': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY+10, ltxImg.width, ltxImg.height) + break; + case 'left': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY-ltxImg.height/2, ltxImg.width, ltxImg.height) + break; + case 'right': + canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY-ltxImg.height/2, ltxImg.width, ltxImg.height) + break; + case 'above-left': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY-(ltxImg.height+10), ltxImg.width, ltxImg.height) + break; + case 'above-right': + canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY-(ltxImg.height+10), ltxImg.width, ltxImg.height) + break; + case 'below-left': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY+10, ltxImg.width, ltxImg.height) + break; + case 'below-right': + canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY+10, ltxImg.width, ltxImg.height) + break; + } + } + let ltxLabel = this.getLatexLabel(); + console.log(ltxLabel) + if(ltxLabel != "") + canvas.renderLatexImage(ltxLabel, this.color, drawLabel.bind(this)) + /* switch(this.labelPosition) { case 'above': canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height) @@ -175,7 +217,7 @@ class RepartitionFunction extends Common.ExecutableObject { case 'below-right': canvas.drawVisibleText(ctx, text, posX, posY+textSize.height) break; - } + }*/ } } diff --git a/ci/test1.lpf b/ci/test1.lpf index b21f304..eb766f5 100644 --- a/ci/test1.lpf +++ b/ci/test1.lpf @@ -1 +1 @@ -LPFv1{"xzoom":100,"yzoom":485,"xmin":-1,"ymax":1,"xaxisstep":"1","yaxisstep":"0.1","xaxislabel":"ω (rad/s)","yaxislabel":"G (dB)","logscalex":false,"linewidth":2,"showxgrad":true,"showygrad":true,"textsize":22,"history":[[["EditedProperty",["h","Function","labelX",3,2.5,false]],["EditedProperty",["h","Function","labelPosition","above-left","above",false]],["EditedProperty",["h","Function","labelPosition","above","left",false]],["EditedProperty",["h","Function","labelX",2.5,2,false]],["EditedProperty",["h","Function","labelX",2,2.2,false]],["EditedProperty",["h","Function","labelX",2.2,9,false]],["EditedProperty",["f","Function","labelPosition","left","above-left",false]],["EditedProperty",["f","Function","labelX",7,7.4,false]],["EditedProperty",["A","Point","y","(-0.5)","(-0.6)",true]]],[["EditedProperty",["A","Point","labelPosition","top","above",false]]]],"width":1908,"height":1005,"objects":{"Sequence":[["u",true,"#ff5500","name + value",true,true,{"1":"cos(u[n])"},{"0":"-1"},"above-left",8]],"Function":[["f",true,"#2b156d","name + value","integral((x + 1), x, \"cos (t)\", \"t\")","ℝ⁺*","ℝ","application","above-left",7.4,true,true],["g",true,"#ac539c","null","0.739083","ℝ","ℝ","application","below",-1,true,false],["h",true,"#00aa00","name + value","derivative(\"cos t\", \"t\", x)","ℤ","ℝ","application","left",9,true,true]],"Repartition":[["X",true,"#1E1EAF","name",true,true,{"0":"0.2","1":"0.1","2":"0.2"},"above",2.5]],"Point":[["A",true,"#060759","name + value","4","(-0.6)","top","●"]]},"type":"logplotv1"} +LPFv1{"xzoom":100,"yzoom":485,"xmin":-1,"ymax":1,"xaxisstep":"1","yaxisstep":"0.1","xaxislabel":"ω (rad/s)","yaxislabel":"G (dB)","logscalex":false,"linewidth":2,"showxgrad":true,"showygrad":true,"textsize":22,"history":[[["EditedProperty",["h","Function","labelX",3,2.5,false]],["EditedProperty",["h","Function","labelPosition","above-left","above",false]],["EditedProperty",["h","Function","labelPosition","above","left",false]],["EditedProperty",["h","Function","labelX",2.5,2,false]],["EditedProperty",["h","Function","labelX",2,2.2,false]],["EditedProperty",["h","Function","labelX",2.2,9,false]],["EditedProperty",["f","Function","labelPosition","left","above-left",false]],["EditedProperty",["f","Function","labelX",7,7.4,false]],["EditedProperty",["A","Point","y","(-0.5)","(-0.6)",true]],["EditedProperty",["X","Repartition","labelX",2.5,5,false]],["EditedProperty",["u","Sequence","labelPosition","above-left","below-right",false]],["EditedProperty",["u","Sequence","labelPosition","below-right","below-left",false]],["EditedProperty",["u","Sequence","labelX",8,6,false]],["EditedProperty",["u","Sequence","baseValues",{"0":"-1"},{"0":"-1"},false]],["EditedProperty",["u","Sequence","labelX",6,7,false]],["EditedProperty",["u","Sequence","labelPosition","below-left","above-right",false]]],[]],"width":1908,"height":1005,"objects":{"Sequence":[["u",true,"#ff5500","name + value",true,true,{"1":"cos(u[n])"},{"0":"-1"},"above-right",7]],"Function":[["f",true,"#2b156d","name + value","integral((x + 1), x, \"cos (t)\", \"t\")","ℝ⁺*","ℝ","application","above-left",7.4,true,true],["g",true,"#ac539c","null","0.739083","ℝ","ℝ","application","below",-1,true,false],["h",true,"#00aa00","name + value","derivative(\"cos t\", \"t\", x)","ℤ","ℝ","application","left",9,true,true]],"Repartition":[["X",true,"#1E1EAF","name + value",true,true,{"0":"0.2","1":"0.1","2":"0.2"},"above",5]],"Point":[["A",true,"#060759","name + value","4","(-0.6)","top","●"]]},"type":"logplotv1"} \ No newline at end of file From 650e43894cccba6ccd5edb16c46034cd0442e43b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 6 Mar 2022 17:44:31 +0100 Subject: [PATCH 08/26] Merging label drawing functions, adding comments to common objects, adding bode magnitude. --- LogarithmPlotter/i18n/lp_de.ts | 66 ++--- LogarithmPlotter/i18n/lp_en.ts | 66 ++--- LogarithmPlotter/i18n/lp_es.ts | 66 ++--- LogarithmPlotter/i18n/lp_fr.ts | 66 ++--- LogarithmPlotter/i18n/lp_hu.ts | 66 ++--- LogarithmPlotter/i18n/lp_nb_NO.ts | 66 ++--- LogarithmPlotter/i18n/lp_template.ts | 66 ++--- LogarithmPlotter/logarithmplotter.py | 3 +- .../ad5001/LogarithmPlotter/js/math/latex.js | 4 +- .../ad5001/LogarithmPlotter/js/objs/common.js | 265 ++++++++++++++++-- .../LogarithmPlotter/js/objs/function.js | 84 +----- .../LogarithmPlotter/js/objs/gainbode.js | 51 +--- .../ad5001/LogarithmPlotter/js/objs/point.js | 50 +--- .../LogarithmPlotter/js/objs/repartition.js | 70 +---- 14 files changed, 496 insertions(+), 493 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index d6d6ee9..5fc986d 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Über LogarithmPlotter @@ -279,7 +279,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" ListSetting - + + Add Entry + Neuer Eintrag @@ -507,12 +507,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" changelog - + Could not fetch changelog: Server error {}. Changelog konnte nicht geholt werden: Server-Fehler {}. - + Could not fetch update: {}. Changelog konnte nicht geholt werden: {}. @@ -529,17 +529,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Beispiel: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) - + Note: Specify the probability for each value. Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. @@ -554,7 +554,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" - + %1: %1: @@ -594,12 +594,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" function - + Function Funktion - + Functions Funktionen @@ -794,12 +794,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" point - + Point Punkt - + Points Punkte @@ -807,26 +807,26 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" prop - + expression Ausdruck - + definitionDomain Definitionsbereich - + destinationDomain Reichweite - + - - + + @@ -836,15 +836,15 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Position des Etiketts - + displayMode Anzeigemodus - + - + @@ -852,13 +852,13 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" X-Position des Etiketts - + drawPoints Unentschiedene Punkte - + drawDashedLines Gestrichelte Linien anzeigen @@ -895,25 +895,25 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Einheit - + x X - + y Y - + pointStyle Punkt-Stil - + probabilities Wahrscheinlichkeiten @@ -965,12 +965,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" repartition - + Repartition Verteilungsfunktion - + Repartition functions Verteilungsfunktionen @@ -1022,22 +1022,22 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" update - + An update for LogarithPlotter (v{}) is available. Ein Aktualisierung für LogarithmPlotter (v{}) ist verfügbar. - + No update available. Keine Aktualisierung verfügbar. - + Could not fetch update information: Server error {}. Es konnten keine Aktualisierungsinformationen abgerufen werden: Server-Fehler {}. - + Could not fetch update information: {}. Es konnten keine Aktualisierungsinformationen abgerufen werden:{}. diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index c721ac3..fd9567a 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter About LogarithmPlotter @@ -279,7 +279,7 @@ These settings can be changed at any time from the "Settings" menu. ListSetting - + + Add Entry + Add Entry @@ -507,12 +507,12 @@ These settings can be changed at any time from the "Settings" menu. changelog - + Could not fetch changelog: Server error {}. Could not fetch changelog: Server error {}. - + Could not fetch update: {}. Could not fetch changelog: {}. @@ -529,17 +529,17 @@ These settings can be changed at any time from the "Settings" menu. comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) - + Note: Specify the probability for each value. Note: Specify the probability for each value. @@ -554,7 +554,7 @@ These settings can be changed at any time from the "Settings" menu. - + %1: %1: @@ -594,12 +594,12 @@ These settings can be changed at any time from the "Settings" menu. function - + Function Function - + Functions Functions @@ -794,12 +794,12 @@ These settings can be changed at any time from the "Settings" menu. point - + Point Point - + Points Points @@ -807,26 +807,26 @@ These settings can be changed at any time from the "Settings" menu. prop - + expression Expression - + definitionDomain Domain - + destinationDomain Range - + - - + + @@ -836,15 +836,15 @@ These settings can be changed at any time from the "Settings" menu.Label position - + displayMode Display mode - + - + @@ -852,13 +852,13 @@ These settings can be changed at any time from the "Settings" menu.Label's X position - + drawPoints Show points - + drawDashedLines Show dashed lines @@ -895,25 +895,25 @@ These settings can be changed at any time from the "Settings" menu.Unit to use - + x X - + y Y - + pointStyle Point style - + probabilities Probabilities list @@ -965,12 +965,12 @@ These settings can be changed at any time from the "Settings" menu. repartition - + Repartition Distribution - + Repartition functions Distribution functions @@ -1022,22 +1022,22 @@ These settings can be changed at any time from the "Settings" menu. update - + An update for LogarithPlotter (v{}) is available. An update for LogarithmPlotter (v{}) is available. - + No update available. No update available. - + Could not fetch update information: Server error {}. Could not fetch update information: Server error {}. - + Could not fetch update information: {}. Could not fetch update information: {}. diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 16c53ff..fe30649 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Sobre LogarithmPlotter @@ -278,7 +278,7 @@ These settings can be changed at any time from the "Settings" menu. ListSetting - + + Add Entry @@ -506,12 +506,12 @@ These settings can be changed at any time from the "Settings" menu. changelog - + Could not fetch changelog: Server error {}. - + Could not fetch update: {}. @@ -528,17 +528,17 @@ These settings can be changed at any time from the "Settings" menu. comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - + Note: Specify the probability for each value. @@ -553,7 +553,7 @@ These settings can be changed at any time from the "Settings" menu. - + %1: @@ -593,12 +593,12 @@ These settings can be changed at any time from the "Settings" menu. function - + Function - + Functions @@ -766,12 +766,12 @@ These settings can be changed at any time from the "Settings" menu. point - + Point - + Points @@ -779,26 +779,26 @@ These settings can be changed at any time from the "Settings" menu. prop - + expression - + definitionDomain - + destinationDomain - + - - + + @@ -808,15 +808,15 @@ These settings can be changed at any time from the "Settings" menu. - + displayMode - + - + @@ -824,13 +824,13 @@ These settings can be changed at any time from the "Settings" menu. - + drawPoints - + drawDashedLines @@ -867,25 +867,25 @@ These settings can be changed at any time from the "Settings" menu. - + x - + y - + pointStyle - + probabilities @@ -933,12 +933,12 @@ These settings can be changed at any time from the "Settings" menu. repartition - + Repartition - + Repartition functions @@ -990,22 +990,22 @@ These settings can be changed at any time from the "Settings" menu. update - + An update for LogarithPlotter (v{}) is available. - + No update available. - + Could not fetch update information: Server error {}. - + Could not fetch update information: {}. diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 2fb1234..42ef942 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter À propos de LogarithmPlotter @@ -287,7 +287,7 @@ These settings can always be changed at any time from the "Settings" m ListSetting - + + Add Entry + Nouvelle entrée @@ -515,12 +515,12 @@ These settings can always be changed at any time from the "Settings" m changelog - + Could not fetch changelog: Server error {}. Impossible de récupérer l'historique des modifications : Erreur de serveur {}. - + Could not fetch update: {}. Impossible de récupérer l'historique des modifications : {}. @@ -537,17 +537,17 @@ These settings can always be changed at any time from the "Settings" m comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Par exemple : R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) - + Note: Specify the probability for each value. Note : Spécifiez la probabilité pour chaque valeur. @@ -563,7 +563,7 @@ These settings can always be changed at any time from the "Settings" m - + %1: %1 : @@ -603,12 +603,12 @@ These settings can always be changed at any time from the "Settings" m function - + Function Fonction - + Functions Fonctions @@ -803,12 +803,12 @@ These settings can always be changed at any time from the "Settings" m point - + Point Point - + Points Points @@ -816,26 +816,26 @@ These settings can always be changed at any time from the "Settings" m prop - + expression Expression - + definitionDomain Domaine de définition - + destinationDomain Portée - + - - + + @@ -845,15 +845,15 @@ These settings can always be changed at any time from the "Settings" m Position de l'étiquette - + displayMode Mode d'affichage - + - + @@ -861,13 +861,13 @@ These settings can always be changed at any time from the "Settings" m Position en X de l'étiquette - + drawPoints Afficher les points - + drawDashedLines Afficher les pointillés @@ -904,25 +904,25 @@ These settings can always be changed at any time from the "Settings" m Unité de la phase - + x X - + y Y - + pointStyle Style du point - + probabilities Liste de probabilités @@ -974,12 +974,12 @@ These settings can always be changed at any time from the "Settings" m repartition - + Repartition Répartition - + Repartition functions Fonctions de répartition @@ -1031,22 +1031,22 @@ These settings can always be changed at any time from the "Settings" m update - + An update for LogarithPlotter (v{}) is available. Une mise à jour de LogarithmPlotter (v{}) est disponible. - + No update available. À jour. - + Could not fetch update information: Server error {}. Impossible de récupérer les informations de mise à jour. Erreur du serveur {}. - + Could not fetch update information: {}. Impossible de récupérer les informations de mise à jour. {}. diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 43a5bad..0ee9d08 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter LogarithmPlotter névjegye @@ -279,7 +279,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. ListSetting - + + Add Entry + Bejegyzés hozzáadása @@ -507,12 +507,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. changelog - + Could not fetch changelog: Server error {}. Nem sikerült lekérni a változásnaplót: Kiszolgálóhiba: {}. - + Could not fetch update: {}. Nem sikerült lekérni a változásnaplót: {}. @@ -529,17 +529,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Példák: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) - + Note: Specify the probability for each value. Megjegyzés: Adja meg az egyes értékek valószínűségét. @@ -554,7 +554,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - + %1: %1: @@ -594,12 +594,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. function - + Function Függvény - + Functions Függvények @@ -790,12 +790,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. point - + Point Pont - + Points Pontok @@ -803,26 +803,26 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. prop - + expression Kifejezés - + definitionDomain Abszcissza tartomány - + destinationDomain Ordináta tartomány - + - - + + @@ -832,15 +832,15 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Címke helyzete - + displayMode Megjelenítési mód - + - + @@ -848,13 +848,13 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Címke X helyzete - + drawPoints Pontok megjelenítése - + drawDashedLines Szaggatott vonalak megjelenítése @@ -891,25 +891,25 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Egység használata - + x X - + y Y - + pointStyle Pontstílus - + probabilities Valószínűségek listája @@ -957,12 +957,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. repartition - + Repartition Elosztás - + Repartition functions Elosztási függvények @@ -1014,22 +1014,22 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. update - + An update for LogarithPlotter (v{}) is available. Elérhető a Logaritmus-ábrázoló ({} verzió) frissítése. - + No update available. Nincs telepíthető frissítés. - + Could not fetch update information: Server error {}. Nem sikerült lekérni a frissítési adatokat: Kiszolgálóhiba: {}. - + Could not fetch update information: {}. Nem sikerült lekérni a frissítési adatokat: {}. diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 898785b..cacb689 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Om @@ -279,7 +279,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. ListSetting - + + Add Entry @@ -507,12 +507,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. changelog - + Could not fetch changelog: Server error {}. - + Could not fetch update: {}. @@ -529,17 +529,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - + Note: Specify the probability for each value. @@ -554,7 +554,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + %1: @@ -594,12 +594,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. function - + Function Funksjon - + Functions Funksjoner @@ -790,12 +790,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. point - + Point Punkt - + Points Punkter @@ -803,26 +803,26 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. prop - + expression - + definitionDomain - + destinationDomain - + - - + + @@ -832,15 +832,15 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + displayMode - + - + @@ -848,13 +848,13 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + drawPoints - + drawDashedLines @@ -891,25 +891,25 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + x - + y - + pointStyle - + probabilities @@ -957,12 +957,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. repartition - + Repartition Distribusjon - + Repartition functions Distribusjonsfunksjoner @@ -1014,22 +1014,22 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. update - + An update for LogarithPlotter (v{}) is available. En ny versjon av LogartimePlotter (v{}) er tilgjengelig - + No update available. Ingen nye versjoner. - + Could not fetch update information: Server error {}. Fant ikke ut om det er noen nye versjoner. Tjenerfeil {}. - + Could not fetch update information: {}. Kunne ikke hente info om hvorvidt det er nye versjoner: {}. diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index d3888b9..d1dcea8 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter @@ -278,7 +278,7 @@ These settings can be changed at any time from the "Settings" menu. ListSetting - + + Add Entry @@ -506,12 +506,12 @@ These settings can be changed at any time from the "Settings" menu. changelog - + Could not fetch changelog: Server error {}. - + Could not fetch update: {}. @@ -528,17 +528,17 @@ These settings can be changed at any time from the "Settings" menu. comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - + Note: Specify the probability for each value. @@ -553,7 +553,7 @@ These settings can be changed at any time from the "Settings" menu. - + %1: @@ -593,12 +593,12 @@ These settings can be changed at any time from the "Settings" menu. function - + Function - + Functions @@ -766,12 +766,12 @@ These settings can be changed at any time from the "Settings" menu. point - + Point - + Points @@ -779,26 +779,26 @@ These settings can be changed at any time from the "Settings" menu. prop - + expression - + definitionDomain - + destinationDomain - + - - + + @@ -808,15 +808,15 @@ These settings can be changed at any time from the "Settings" menu. - + displayMode - + - + @@ -824,13 +824,13 @@ These settings can be changed at any time from the "Settings" menu. - + drawPoints - + drawDashedLines @@ -867,25 +867,25 @@ These settings can be changed at any time from the "Settings" menu. - + x - + y - + pointStyle - + probabilities @@ -933,12 +933,12 @@ These settings can be changed at any time from the "Settings" menu. repartition - + Repartition - + Repartition functions @@ -990,22 +990,22 @@ These settings can be changed at any time from the "Settings" menu. update - + An update for LogarithPlotter (v{}) is available. - + No update available. - + Could not fetch update information: Server error {}. - + Could not fetch update information: {}. diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 2ce7b94..56985e2 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -22,7 +22,7 @@ start_time = time() from PySide2.QtWidgets import QApplication from PySide2.QtQml import QQmlApplicationEngine -from PySide2.QtCore import QTranslator, QLocale +from PySide2.QtCore import Qt, QTranslator, QLocale from PySide2.QtGui import QIcon from tempfile import TemporaryDirectory @@ -89,6 +89,7 @@ def run(): app.setApplicationName("LogarithmPlotter") app.setOrganizationName("Ad5001") app.styleHints().setShowShortcutsInContextMenus(True) + app.setAttribute(Qt.AA_EnableHighDpiScaling) app.setWindowIcon(QIcon(path.realpath(path.join(getcwd(), "logarithmplotter.svg")))) # Installing translators diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index 35bc2dc..e036960 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -83,7 +83,7 @@ function functionToLatex(f, args) { * @param {string} vari - variable to convert * @returns {string} */ -function variableToLatex(vari) { +function variable(vari) { let unicodechars = ["α","β","γ","δ","ε","ζ","η", "π","θ","κ","λ","μ","ξ","ρ", "ς","σ","τ","φ","χ","ψ","ω", @@ -185,7 +185,7 @@ function expressionToLatex(tokens) { break; case ExprEval.IVAR: case ExprEval.IVARNAME: - nstack.push(variableToLatex(item.value.toString())); + nstack.push(variable(item.value.toString())); break; case ExprEval.IOP1: // Unary operator n1 = nstack.pop(); diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index c602224..0d03bb6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -20,10 +20,16 @@ .import "../utils.js" as Utils .import "../objects.js" as Objects +.import "../math/latex.js" as Latex // This file contains the default data to be imported from all other objects - +/** + * Creates a new name for an object, based on the \c allowedLetters. + * If variables with each of the allowedLetters is created, a subscript + * number is added to the name. + * @return {string} New unused name for a new object. + */ function getNewName(allowedLetters) { // Allows to get a new name, based on the allowed letters, // as well as adding a sub number when needs be. @@ -38,33 +44,70 @@ function getNewName(allowedLetters) { return ret } +/** + * Class to extend for every type of object that + * can be drawn on the canvas. + */ class DrawableObject { - // Class to extend for every type of object that - // can be drawn on the canvas. - - // Base name of the object. Needs to be constant over time. + /** + * Base name of the object. Needs to be constant over time. + * @return {string} Type of the object. + */ static type(){return 'Unknown'} - // (Potentially translated) name of the object to be shown to the user. + /** + * Translated name of the object to be shown to the user. + * @return {string} + */ static displayType(){return 'Unknown'} - // Label used for the list on the ObjectsList sidebar. + /** + * Translated name of the object in plural form to be shown to the user. + * @return {string} + */ static displayTypeMultiple(){return 'Unknowns'} - // Whether this object can be created by the user - // or are instantiated by other objects. + /** + * True if this object can be created by the user, false if it can only + * be instantiated by other objects + * @return {bool} + */ static createable() {return true} - // Properties are set with key as property name and - // value as it's type name (e.g 'Expression', 'string'...), - // an Enum for enumerations, an ObjectType for DrawableObjects - // with a specific type, a List instance for lists, a - // Dictionary instance for dictionaries... - // Used for property modifier in the sidebar. + + /** + * List of properties used in the Object Editor. + * + * Properties are set with key as property name and + * value as it's type name (e.g 'Expression', 'string'...), + * an Enum for enumerations, an ObjectType for DrawableObjects + * with a specific type, a List instance for lists, a + * Dictionary instance for dictionaries... + * + * If the property is to be translated, the key should be passed + * through the QT_TRANSLATE_NOOP macro in that form: + * [QT_TRANSLATE_NOOP('prop','key')] + * Enums that are translated should be indexed in parameters.js and + * then be linked directly here. + * + * @return {Dictionary} + */ static properties() {return {}} - // Whether the object can be executed (instance of ExecutableObject) + /** + * True if this object can be executed, so that an y value might be computed + * for an x value. Only ExecutableObjects have that property set to true. + * @return {bool} + */ static executable() {return false} + /** + * Base constructor for the object. + * @param {string} name - Name of the object + * @param {bool} visible - true if the object is visible, false otherwise. + * @param {color} color - Color of the object (can be string or QColor) + * @param {Enum} labelContent - One of 'null', 'name' or 'name + value' describing the content of the label. + * @constructor() + */ constructor(name, visible = true, color = null, labelContent = 'name + value') { if(color == null) color = Utils.getRandomColor() this.type = 'Unknown' @@ -75,19 +118,40 @@ class DrawableObject { this.requiredBy = [] } + /** + * Serilizes the object in an array that can be JSON serialized. + * These parameters will be re-entered in the constructor when restored. + * @return {array} + */ export() { // Should return what will be inputed as arguments when a file is loaded (serializable form) return [this.name, this.visible, this.color.toString(), this.labelContent] } + /** + * String representing the object that will be displayed to the user. + * It allows for 2 lines and translated text, but it shouldn't be too long. + * @return {string} + */ getReadableString() { return `${this.name} = Unknown` } - toLatexString() { + /** + * Latex markuped version of the readable string. + * Every non latin character should be passed as latex symbols and formulas + * should be in latex form. + * See ../latex.js for helper methods. + * @return {string} + */ + getLatexString() { return this.getReadableString() } + /** + * Readable string content of the label depending on the value of the \c latexContent. + * @return {string} + */ getLabel() { switch(this.labelContent) { case 'name': @@ -100,24 +164,37 @@ class DrawableObject { } } + /** + * Latex markup string content of the label depending on the value of the \c latexContent. + * Every non latin character should be passed as latex symbols and formulas + * should be in latex form. + * See ../latex.js for helper methods. + * @return {string} + */ getLatexLabel() { switch(this.labelContent) { case 'name': - return this.name + return Latex.variable(this.name) case 'name + value': - return this.toLatexString() + return this.getLatexString() case 'null': return '' } } + /** + * Callback method when one of the properties of the object is updated. + */ update() { for(var req of this.requiredBy) { req.update() } } + /** + * Callback method when the object is about to get deleted. + */ delete() { for(var toRemove of this.requiredBy) { toRemove.delete() @@ -125,28 +202,164 @@ class DrawableObject { } } + /** + * Abstract method. Draw the object onto the \c canvas with the 2D context \c ctx. + * @param {Canvas} canvas + * @param {Context2D} ctx + */ draw(canvas, ctx) {} + + /** + * Automaticly draw the label of the object on the \c canvas with the 2D context \c ctx. + * This method takes into account both the \c posX and \c posY of where the label + * should be displayed, including the \c labelPosition relative to it. + * @param {Canvas} canvas + * @param {Context2D} ctx + * @param {string|Enum} labelPosition - Position of the label relative to the marked position + * @param {number} posX - Component of the marked position on the x-axis + * @param {number} posY - Component of the marked position on the y-axis + */ + drawLabel(canvas, ctx, labelPosition, posX, posY) { + if(true) { // TODO: Check for user setting with Latex. + // With latex + let offset = 8 + let drawLblCb = function(canvas, ctx, ltxImg) { + switch(this.labelPosition) { + case 'center': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY-ltxImg.height/2, ltxImg.width, ltxImg.height) + break; + case 'top': + case 'above': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY-(ltxImg.height+offset), ltxImg.width, ltxImg.height) + break; + case 'bottom': + case 'below': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY+offset, ltxImg.width, ltxImg.height) + break; + case 'left': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+offset), posY-ltxImg.height/2, ltxImg.width, ltxImg.height) + break; + case 'right': + canvas.drawVisibleImage(ctx, ltxImg.source, posX+offset, posY-ltxImg.height/2, ltxImg.width, ltxImg.height) + break; + case 'top-left': + case 'above-left': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+offset), posY-(ltxImg.height+offset), ltxImg.width, ltxImg.height) + break; + case 'top-right': + case 'above-right': + canvas.drawVisibleImage(ctx, ltxImg.source, posX+offset, posY-(ltxImg.height+offset), ltxImg.width, ltxImg.height) + break; + case 'bottom-left': + case 'below-left': + canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+offset), posY+offset, ltxImg.width, ltxImg.height) + break; + case 'bottom-right': + case 'below-right': + canvas.drawVisibleImage(ctx, ltxImg.source, posX+offset, posY+offset, ltxImg.width, ltxImg.height) + break; + } + } + let ltxLabel = this.getLatexLabel(); + if(ltxLabel != "") + canvas.renderLatexImage(ltxLabel, this.color, drawLblCb.bind(this)) + //canvas.drawVisibleImage(ctx, ltxImg.source, posX, posY) + } else { + // Without latex + let text = this.getLabel() + ctx.font = `${canvas.textsize}px sans-serif` + let textSize = canvas.measureText(ctx, text) + let offset = 4 + switch(labelPosition) { + case 'center': + canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height/2) + break; + case 'top': + case 'above': + canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height-offset) + break; + case 'bottom': + case 'below': + canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY+offset) + break; + case 'left': + canvas.drawVisibleText(ctx, text, posX-textSize.width-offset, posY-textSize.height/2) + break; + case 'right': + canvas.drawVisibleText(ctx, text, posX+offset, posY-textSize.height/2) + break; + case 'top-left': + case 'above-left': + canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height-offset) + break; + case 'top-right': + case 'above-right': + canvas.drawVisibleText(ctx, text, posX+offset, posY-textSize.height-offset) + break; + case 'bottom-left': + case 'below-left': + canvas.drawVisibleText(ctx, text, posX-textSize.width-offset, posY+offset) + break; + case 'bottom-right': + case 'below-right': + canvas.drawVisibleText(ctx, text, posX+offset, posY+offset) + break; + } + } + } + toString() { return this.name; } } +/** + * Class to be extended for every object on which + * an y for a x can be computed with the execute function. + * If a value cannot be found during execute, it will + * return null. However, theses same x values will + * return false when passed to canExecute. + */ class ExecutableObject extends DrawableObject { - // Class to be extended for every class upon which we - // calculate an y for a x with the execute function. - // If a value cannot be found during execute, it should - // return null. However, theses values should - // return false when passed to canExecute. + /** + * Returns the corresponding y value for an x value. + * If the object isn't defined on the given x, then + * this function will return null. + * + * @param {number} x + * @returns {number|null} + */ execute(x = 1) {return 0} + /** + * Returns false if the object isn't defined on the given x, true otherwise. + * + * @param {number} x + * @returns {bool} + */ canExecute(x = 1) {return true} - // Simplify returns the simplified string of the expression. + /** + * Returns the simplified expression string for a given x. + * + * @param {number} x + * @returns {bool} + */ simplify(x = 1) {return '0'} - // Whether the object can be executed (instance of ExecutableObject) + + /** + * True if this object can be executed, so that an y value might be computed + * for an x value. Only ExecutableObjects have that property set to true. + * @return {bool} + */ static executable() {return true} } + +/** + * Registers the object \c obj in the object list. + * @param {DrawableObject} obj - Object to be registered. + */ function registerObject(obj) { // Registers an object to be used in LogarithmPlotter. // This function is called from autoload.js diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js index c640a8d..464ddda 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js @@ -29,18 +29,6 @@ class Function extends Common.ExecutableObject { static type(){return 'Function'} static displayType(){return qsTr('Function')} static displayTypeMultiple(){return qsTr('Functions')} - /*static properties() {return { - 'expression': 'Expression', - 'definitionDomain': 'Domain', - 'destinationDomain': 'Domain', - 'comment1': 'Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5}', - 'labelPosition': P.Enum.Position, - 'displayMode': new P.Enum('application', 'function'), - 'labelX': 'number', - 'comment2': 'The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...)', - 'drawPoints': 'boolean', - 'drawDashedLines': 'boolean' - }}*/ static properties() {return { [QT_TRANSLATE_NOOP('prop','expression')]: 'Expression', [QT_TRANSLATE_NOOP('prop','definitionDomain')]: 'Domain', @@ -88,11 +76,11 @@ class Function extends Common.ExecutableObject { } } - toLatexString() { + getLatexString() { if(this.displayMode == 'application') { - return `${Latex.variableToLatex(this.name)}:\\begin{array}{llll}${this.definitionDomain.latexMarkup} & \\rightarrow & ${this.destinationDomain.latexMarkup}\\\\x & \\mapsto & ${this.expression.latexMarkup}\\end{array}` + return `${Latex.variable(this.name)}:\\begin{array}{llll}${this.definitionDomain.latexMarkup} & \\rightarrow & ${this.destinationDomain.latexMarkup}\\\\x & \\mapsto & ${this.expression.latexMarkup}\\end{array}` } else { - return `\\begin{array}{l}${Latex.variableToLatex(this.name)}(x) = ${this.expression.latexMarkup}\\\\ D_{${this.name}} = ${this.definitionDomain.latexMarkup}\\end{array}` + return `\\begin{array}{l}${Latex.variable(this.name)}(x) = ${this.expression.latexMarkup}\\\\ D_{${this.name}} = ${this.definitionDomain.latexMarkup}\\end{array}` } } @@ -121,71 +109,7 @@ class Function extends Common.ExecutableObject { draw(canvas, ctx) { Function.drawFunction(canvas, ctx, this.expression, this.definitionDomain, this.destinationDomain, this.drawPoints, this.drawDashedLines) // Label - var text = this.getLabel() - ctx.font = `${canvas.textsize}px sans-serif` - var textSize = canvas.measureText(ctx, text) - var posX = canvas.x2px(this.labelX) - var posY = canvas.y2px(this.execute(this.labelX)) - - let drawLabel = function(canvas, ctx, ltxImg) { - switch(this.labelPosition) { - case 'above': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY-(ltxImg.height+10), ltxImg.width, ltxImg.height) - break; - case 'below': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY+10, ltxImg.width, ltxImg.height) - break; - case 'left': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY-ltxImg.height/2, ltxImg.width, ltxImg.height) - break; - case 'right': - canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY-ltxImg.height/2, ltxImg.width, ltxImg.height) - break; - case 'above-left': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY-(ltxImg.height+10), ltxImg.width, ltxImg.height) - break; - case 'above-right': - canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY-(ltxImg.height+10), ltxImg.width, ltxImg.height) - break; - case 'below-left': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY+10, ltxImg.width, ltxImg.height) - break; - case 'below-right': - canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY+10, ltxImg.width, ltxImg.height) - break; - } - } - let ltxLabel = this.getLatexLabel(); - if(ltxLabel != "") - canvas.renderLatexImage(ltxLabel, this.color, drawLabel.bind(this)) - //canvas.drawVisibleImage(ctx, ltxImg.source, posX, posY) - - /*switch(this.labelPosition) { - case 'above': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height) - break; - case 'below': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY+textSize.height) - break; - case 'left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height/2) - break; - case 'right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height/2) - break; - case 'above-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height) - break; - case 'above-right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height) - break; - case 'below-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY+textSize.height) - break; - case 'below-right': - canvas.drawVisibleText(ctx, text, posX, posY+textSize.height) - break; - }*/ + this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } static drawFunction(canvas, ctx, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js index 8d0543c..86b6dd3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js @@ -25,19 +25,13 @@ .import "../mathlib.js" as MathLib .import "../historylib.js" as HistoryLib .import "../parameters.js" as P +.import "../math/latex.js" as Latex + class GainBode extends Common.ExecutableObject { static type(){return 'Gain Bode'} static displayType(){return qsTr('Bode Magnitude')} static displayTypeMultiple(){return qsTr('Bode Magnitudes')} - /*static properties() {return { - 'om_0': new P.ObjectType('Point'), - 'pass': new P.Enum('high', 'low'), - 'gain': 'Expression', - 'labelPosition': new P.Enum('above', 'below', 'left', 'right', 'above-left', 'above-right', 'below-left', 'below-right'), - 'labelX': 'number', - 'omGraduation': 'boolean' - }}*/ static properties() {return { [QT_TRANSLATE_NOOP('prop','om_0')]: new P.ObjectType('Point'), [QT_TRANSLATE_NOOP('prop','pass')]: P.Enum.BodePass, @@ -81,6 +75,14 @@ class GainBode extends Common.ExecutableObject { return `${this.name}: ${pass}; ${this.om_0.name} = ${this.om_0.x}\n ${' '.repeat(this.name.length)}${this.gain.toString(true)} dB/dec` } + getLatexString() { + let pass = this.pass == "low" ? qsTr("low-pass") : qsTr("high-pass"); + return `\\mathrm{${Latex.variable(this.name)}:}\\begin{array}{l} + \\textrm{${pass}};${Latex.variable(this.om_0.name)} = ${this.om_0.x.latexMarkup} \\\\ + ${this.gain.latexMarkup}\\textrm{ dB/dec} + \\end{array}` + } + export() { return [this.name, this.visible, this.color.toString(), this.labelContent, this.om_0.name, this.pass.toString(), this.gain.toEditableString(), this.labelPosition, this.labelX, this.omGraduation] @@ -131,38 +133,9 @@ class GainBode extends Common.ExecutableObject { var dashPxSize = 10 for(var i = 0; i < canvas.canvasSize.height && this.omGraduation; i += dashPxSize*2) canvas.drawLine(ctx, xpos, i, xpos, i+dashPxSize) + // Label - var text = this.getLabel() - ctx.font = `${canvas.textsize}px sans-serif` - var textSize = canvas.measureText(ctx, text) - var posX = canvas.x2px(this.labelX) - var posY = canvas.y2px(this.execute(this.labelX)) - switch(this.labelPosition) { - case 'above': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height) - break; - case 'below': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY+textSize.height) - break; - case 'left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height/2) - break; - case 'right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height/2) - break; - case 'above-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height) - break; - case 'above-right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height) - break; - case 'below-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY+textSize.height) - break; - case 'below-right': - canvas.drawVisibleText(ctx, text, posX, posY+textSize.height) - break; - } + this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } update() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js index dd1fc1e..66ba301 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js @@ -29,12 +29,6 @@ class Point extends Common.DrawableObject { static displayType(){return qsTr('Point')} static displayTypeMultiple(){return qsTr('Points')} - /*static properties() {return { - 'x': 'Expression', - 'y': 'Expression', - 'labelPosition': new P.Enum('above', 'below', 'left', 'right', 'above-left', 'above-right', 'below-left', 'below-right'), - 'pointStyle': new P.Enum('●', '✕', '+'), - }}*/ static properties() {return { [QT_TRANSLATE_NOOP('prop','x')]: 'Expression', [QT_TRANSLATE_NOOP('prop','y')]: 'Expression', @@ -59,8 +53,8 @@ class Point extends Common.DrawableObject { return `${this.name} = (${this.x}, ${this.y})` } - toLatexString() { - return `${Latex.variableToLatex(this.name)} = \\left(${this.x.latexMarkup}, ${this.y.latexMarkup}\\right)` + getLatexString() { + return `${Latex.variable(this.name)} = \\left(${this.x.latexMarkup}, ${this.y.latexMarkup}\\right)` } export() { @@ -85,44 +79,6 @@ class Point extends Common.DrawableObject { ctx.fillRect(canvasX-1, canvasY-pointSize/2, 2, pointSize) break; } - - let drawLabel = function(canvas, ctx, ltxImg) { - switch(this.labelPosition) { - case 'top': - case 'above': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-ltxImg.width/2, canvasY-(ltxImg.height+10), ltxImg.width, ltxImg.height) - break; - case 'bottom': - case 'below': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-ltxImg.width/2, canvasY+10, ltxImg.width, ltxImg.height) - break; - case 'left': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+10), canvasY-ltxImg.height/2, ltxImg.width, ltxImg.height) - break; - case 'right': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+10, canvasY-ltxImg.height/2, ltxImg.width, ltxImg.height) - break; - case 'top-left': - case 'above-left': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+10), canvasY-(ltxImg.height+10), ltxImg.width, ltxImg.height) - break; - case 'top-right': - case 'above-right': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+10, canvasY-(ltxImg.height+10), ltxImg.width, ltxImg.height) - break; - case 'bottom-left': - case 'below-left': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+10), canvasY+10, ltxImg.width, ltxImg.height) - break; - case 'bottom-right': - case 'below-right': - canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+10, canvasY+10, ltxImg.width, ltxImg.height) - break; - } - } - let ltxLabel = this.getLatexLabel(); - if(ltxLabel != "") - canvas.renderLatexImage(ltxLabel, this.color, drawLabel.bind(this)) - //canvas.drawVisibleImage(ctx, ltxImg.source, canvasX, canvasY) + this.drawLabel(canvas, ctx, this.labelPosition, canvasX, canvasY) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js index ff6b12a..da8c4e1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js @@ -68,9 +68,9 @@ class RepartitionFunction extends Common.ExecutableObject { return `F_${this.name}(x) = P(${this.name} ≤ x)\n` + keys.map(idx => `P(${this.name}=${idx})=${this.probabilities[idx]}`).join("; ") } - toLatexString() { + getLatexString() { let keys = Object.keys(this.probabilities).sort((a,b) => a-b); - let varName = Latex.variableToLatex(this.name) + let varName = Latex.variable(this.name) return `\\begin{array}{l}F_{${varName}}(x) = P(${varName} \\le x)\\\\` + keys.map(idx => `P(${varName}=${idx})=${this.probabilities[idx]}`).join("; ") + '\\end{array}' } @@ -153,71 +153,7 @@ class RepartitionFunction extends Common.ExecutableObject { } // Label - var text = this.getLabel() - ctx.font = `${canvas.textsize}px sans-serif` - var textSize = canvas.measureText(ctx, text) - var posX = canvas.x2px(this.labelX) - var posY = canvas.y2px(this.execute(this.labelX)) - - let drawLabel = function(canvas, ctx, ltxImg) { - switch(this.labelPosition) { - case 'above': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY-(ltxImg.height+10), ltxImg.width, ltxImg.height) - break; - case 'below': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY+10, ltxImg.width, ltxImg.height) - break; - case 'left': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY-ltxImg.height/2, ltxImg.width, ltxImg.height) - break; - case 'right': - canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY-ltxImg.height/2, ltxImg.width, ltxImg.height) - break; - case 'above-left': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY-(ltxImg.height+10), ltxImg.width, ltxImg.height) - break; - case 'above-right': - canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY-(ltxImg.height+10), ltxImg.width, ltxImg.height) - break; - case 'below-left': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY+10, ltxImg.width, ltxImg.height) - break; - case 'below-right': - canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY+10, ltxImg.width, ltxImg.height) - break; - } - } - let ltxLabel = this.getLatexLabel(); - console.log(ltxLabel) - if(ltxLabel != "") - canvas.renderLatexImage(ltxLabel, this.color, drawLabel.bind(this)) - /* - switch(this.labelPosition) { - case 'above': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height) - break; - case 'below': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY+textSize.height) - break; - case 'left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height/2) - break; - case 'right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height/2) - break; - case 'above-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height) - break; - case 'above-right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height) - break; - case 'below-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY+textSize.height) - break; - case 'below-right': - canvas.drawVisibleText(ctx, text, posX, posY+textSize.height) - break; - }*/ + this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } } From 8251504fbe3cfa907cc510211e7084acaad94bd1 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 6 Mar 2022 18:31:03 +0100 Subject: [PATCH 09/26] Latex markup for sequences and bode phases --- .../LogarithmPlotter/js/math/sequence.js | 21 ++++++++- .../LogarithmPlotter/js/objs/phasebode.js | 44 +++---------------- .../LogarithmPlotter/js/objs/sequence.js | 23 ++++++++-- 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js index ced0cfa..ff97760 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js @@ -21,6 +21,8 @@ .import "common.js" as C .import "expression.js" as Expr .import "../utils.js" as Utils +.import "../math/latex.js" as Latex + /** * Represents mathematical object for sequences. @@ -32,9 +34,13 @@ class Sequence extends Expr.Expression { this.name = name this.baseValues = baseValues this.calcValues = Object.assign({}, baseValues) + this.latexValues = Object.assign({}, baseValues) for(var n in this.calcValues) - if(['string', 'number'].includes(typeof this.calcValues[n])) - this.calcValues[n] = C.parser.parse(this.calcValues[n].toString()).simplify().evaluate(C.evalVariables) + if(['string', 'number'].includes(typeof this.calcValues[n])) { + let parsed = C.parser.parse(this.calcValues[n].toString()).simplify() + this.latexValues[n] = Latex.expressionToLatex(parsed.tokens) + this.calcValues[n] = parsed.evaluate(C.evalVariables) + } this.valuePlus = parseInt(valuePlus) } @@ -75,4 +81,15 @@ class Sequence extends Expr.Expression { ).join('; ') return ret } + + toLatexString(forceSign=false) { + var str = this.latexMarkup + if(str[0] != '-' && forceSign) str = '+' + str + var subtxt = '_{n' + (this.valuePlus == 0 ? '' : '+' + this.valuePlus) + '}' + var ret = `\\begin{array}{l}${Latex.variable(this.name)}${subtxt} = ${str}${this.latexValues.length == 0 ? '' : "\n"}\\\\` + ret += Object.keys(this.latexValues).map( + n => `${this.name}_{${n}} = ${this.latexValues[n]}` + ).join('; ') + "\\end{array}" + return ret + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js index fa75ec5..bedf9c7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js @@ -23,19 +23,13 @@ .import "../mathlib.js" as MathLib .import "../historylib.js" as HistoryLib .import "../parameters.js" as P +.import "../math/latex.js" as Latex class PhaseBode extends Common.ExecutableObject { static type(){return 'Phase Bode'} static displayType(){return qsTr('Bode Phase')} static displayTypeMultiple(){return qsTr('Bode Phases')} - /*static properties() {return { - 'om_0': new P.ObjectType('Point'), - 'phase': 'Expression', - 'unit': new P.Enum('°', 'deg', 'rad'), - 'labelPosition': new P.Enum('above', 'below', 'left', 'right', 'above-left', 'above-right', 'below-left', 'below-right'), - 'labelX': 'number' - }}*/ static properties() {return { [QT_TRANSLATE_NOOP('prop','om_0')]: new P.ObjectType('Point'), [QT_TRANSLATE_NOOP('prop','phase')]: 'Expression', @@ -82,6 +76,10 @@ class PhaseBode extends Common.ExecutableObject { return `${this.name}: ${this.phase.toString(true)}${this.unit} at ${this.om_0.name} = ${this.om_0.x}` } + getLatexString() { + return `${Latex.variable(this.name)}: ${this.phase.latexMarkup}\\textrm{${this.unit} at }${Latex.variable(this.om_0.name)} = ${this.om_0.x.latexMarkup}` + } + execute(x=1) { if(typeof x == 'string') x = MathLib.executeExpression(x) if(x < this.om_0.x) { @@ -120,37 +118,7 @@ class PhaseBode extends Common.ExecutableObject { canvas.drawLine(ctx, Math.max(0, baseX), augmtY, canvas.canvasSize.width, augmtY) // Label - var text = this.getLabel() - ctx.font = `${canvas.textsize}px sans-serif` - var textSize = canvas.measureText(ctx, text) - var posX = canvas.x2px(this.labelX) - var posY = canvas.y2px(this.execute(this.labelX)) - switch(this.labelPosition) { - case 'above': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height) - break; - case 'below': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY+textSize.height) - break; - case 'left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height/2) - break; - case 'right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height/2) - break; - case 'above-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height) - break; - case 'above-right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height) - break; - case 'below-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY+textSize.height) - break; - case 'below-right': - canvas.drawVisibleText(ctx, text, posX, posY+textSize.height) - break; - } + this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } update() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js index 0e8989c..5ed7238 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js @@ -22,6 +22,7 @@ .import "function.js" as F .import "../mathlib.js" as MathLib .import "../parameters.js" as P +.import "../math/latex.js" as Latex class Sequence extends Common.ExecutableObject { @@ -76,11 +77,14 @@ class Sequence extends Common.ExecutableObject { ) } - getReadableString() { return this.sequence.toString() } + getLatexString() { + return this.sequence.toLatexString() + } + execute(x = 1) { if(x % 1 == 0) return this.sequence.execute(x) @@ -103,7 +107,17 @@ class Sequence extends Common.ExecutableObject { return this.getReadableString() case 'null': return '' - + } + } + + getLatexLabel() { + switch(this.labelContent) { + case 'name': + return `(${Latex.variable(this.name)}_n)` + case 'name + value': + return this.getLatexString() + case 'null': + return '' } } @@ -111,7 +125,8 @@ class Sequence extends Common.ExecutableObject { F.Function.drawFunction(canvas, ctx, this.sequence, canvas.logscalex ? MathLib.Domain.NE : MathLib.Domain.N, MathLib.Domain.R, this.drawPoints, this.drawDashedLines) // Label - var text = this.getLabel() + this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + /*var text = this.getLabel() ctx.font = `${canvas.textsize}px sans-serif` var textSize = canvas.measureText(ctx, text) var posX = canvas.x2px(this.labelX) @@ -141,7 +156,7 @@ class Sequence extends Common.ExecutableObject { case 'below-right': canvas.drawVisibleText(ctx, text, posX, posY+textSize.height) break; - } + }*/ } } From 2ce66df4ddb67d31ac69906a8dfedce5078de702 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 6 Mar 2022 23:34:59 +0100 Subject: [PATCH 10/26] Removed dependency on Sympy for subprocesses directly. New dependencies: latex, dvipng. Slight changes to default for fonts to avoid too many anti aliasing issues. Also adds proper checks for latex installation. --- LogarithmPlotter/logarithmplotter.py | 12 +- .../LogarithmPlotter/LogGraphCanvas.qml | 6 +- .../eu/ad5001/LogarithmPlotter/Settings.qml | 2 +- LogarithmPlotter/util/latex.py | 155 ++++++++++++++++-- linux/debian/control | 2 +- linux/debian/depends | 2 +- setup.py | 2 +- 7 files changed, 155 insertions(+), 26 deletions(-) diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 56985e2..70073ef 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -18,8 +18,6 @@ from time import time -start_time = time() - from PySide2.QtWidgets import QApplication from PySide2.QtQml import QQmlApplicationEngine from PySide2.QtCore import Qt, QTranslator, QLocale @@ -29,6 +27,9 @@ from tempfile import TemporaryDirectory from os import getcwd, chdir, environ, path, remove, close from platform import release as os_release from sys import platform, argv, version as sys_version, exit +from sys import path as sys_path + +start_time = time() # Create the temporary directory for saving copied screenshots and latex files tempdir = TemporaryDirectory() @@ -37,7 +38,6 @@ pwd = getcwd() chdir(path.dirname(path.realpath(__file__))) -from sys import path as sys_path if path.realpath(path.join(getcwd(), "..")) not in sys_path: sys_path.append(path.realpath(path.join(getcwd(), ".."))) @@ -85,11 +85,11 @@ def run(): icon_fallbacks.append(path.realpath(path.join(base_icon_path, "settings", "custom"))) QIcon.setFallbackSearchPaths(icon_fallbacks); + QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) app = QApplication(argv) app.setApplicationName("LogarithmPlotter") app.setOrganizationName("Ad5001") app.styleHints().setShowShortcutsInContextMenus(True) - app.setAttribute(Qt.AA_EnableHighDpiScaling) app.setWindowIcon(QIcon(path.realpath(path.join(getcwd(), "logarithmplotter.svg")))) # Installing translators @@ -109,7 +109,7 @@ def run(): engine = QQmlApplicationEngine() global tmpfile helper = Helper(pwd, tmpfile) - latex = Latex(tempdir, app.palette()) + latex = Latex(tempdir) engine.rootContext().setContextProperty("Helper", helper) engine.rootContext().setContextProperty("Latex", latex) engine.rootContext().setContextProperty("TestBuild", "--test-build" in argv) @@ -135,6 +135,8 @@ def run(): if platform == "darwin": macOSFileOpenHandler.init_graphics(engine.rootObjects()[0]) + latex.check_latex_install() + # Check for updates if config.getSetting("check_for_updates"): check_for_updates(__VERSION__, engine.rootObjects()[0]) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index a819da1..19b82e9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -200,7 +200,7 @@ Canvas { // Reset ctx.fillStyle = "#FFFFFF" ctx.strokeStyle = "#000000" - ctx.font = `${canvas.textsize-2}px sans-serif` + ctx.font = `${canvas.textsize}px sans-serif` ctx.fillRect(0,0,width,height) } @@ -257,12 +257,12 @@ Canvas { var axisxpx = y2px(0) // Y coordinate of X axis // Labels ctx.fillStyle = "#000000" - ctx.font = `${canvas.textsize+2}px sans-serif` + ctx.font = `${canvas.textsize}px sans-serif` ctx.fillText(ylabel, axisypx+10, 24) var textSize = ctx.measureText(xlabel).width ctx.fillText(xlabel, canvasSize.width-14-textSize, axisxpx-5) // Axis graduation labels - ctx.font = `${canvas.textsize-2}px sans-serif` + ctx.font = `${canvas.textsize-4}px sans-serif` var txtMinus = ctx.measureText('-').width if(showxgrad) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index 2115b6b..6bde410 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -99,7 +99,7 @@ ScrollView { Font size of the text that will be drawn into the canvas, provided from settings. \sa Settings */ - property double textsize: 14 + property double textsize: 18 /*! \qmlproperty bool Settings::logscalex true if the canvas should be in logarithmic mode, false otherwise. diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index 07b4b9d..e76fd3e 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -16,23 +16,156 @@ * along with this program. If not, see . """ -from PySide2.QtCore import QObject, Slot +from PySide2.QtCore import QObject, Slot, Property, QCoreApplication from PySide2.QtGui import QImage, QColor -from PySide2.QtWidgets import QApplication +from PySide2.QtWidgets import QApplication, QMessageBox -from os import path -from sympy import preview +from os import path, remove +from string import Template from tempfile import TemporaryDirectory +from subprocess import Popen, TimeoutExpired, PIPE +from platform import system +from shutil import which +""" +Searches for a valid Latex and DVIPNG (http://savannah.nongnu.org/projects/dvipng/) +installation and collects the binary path in the DVIPNG_PATH variable. +If not found, it will send an alert to the user. +""" +LATEX_PATH = which('latex') +DVIPNG_PATH = which('dvipng') +#subprocess.run(["ls", "-l", "/dev/null"], capture_output=True) + +DEFAULT_LATEX_DOC = Template(r""" +\documentclass[]{minimal} +\usepackage[utf8]{inputenc} +\usepackage{calligra} +\usepackage{amsfonts} + +\title{} +\author{} + +\begin{document} + +$$$$ $markup $$$$ + +\end{document} +""") + class Latex(QObject): - def __init__(self, tempdir: str, palette): + """ + Base class to convert Latex equations into PNG images with custom font color and size. + It doesn't have any python dependency, but requires a working latex installation and + dvipng to be installed on the system. + """ + def __init__(self, tempdir: TemporaryDirectory): QObject.__init__(self) self.tempdir = tempdir - self.palette = palette - fg = self.palette.windowText().color().convertTo(QColor.Rgb) + + def check_latex_install(self): + """ + Checks if the current latex installation is valid. + """ + if LATEX_PATH is None: + QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "No Latex installation found.\nIf you already have a latex distribution installed, make sure it's installed on your path.\nOtherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/.")) + elif DVIPNG_PATH is None: + QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "DVIPNG was not found. Make sure you include it from your Latex distribution.")) + + @Property(bool) + def latexSupported(self): + return LATEX_PATH is not None and DVIPNG_PATH is not None @Slot(str, float, QColor, result=str) - def render(self, latexstring, font_size, color = True): + def render(self, latex_markup: str, font_size: float, color: QColor = True) -> str: + """ + Renders a latex string into a png file. + """ + export_path = path.join(self.tempdir.name, f'{hash(latex_markup)}_{font_size}_{color.rgb()}') + print(export_path) + if self.latexSupported and not path.exists(export_path + ".png"): + # Generating file + try: + self.create_latex_doc(export_path, latex_markup) + self.convert_latex_to_dvi(export_path) + self.convert_dvi_to_png(export_path, font_size, color) + self.cleanup(export_path) + except Exception as e: # One of the processes failed. A message will be sent every time. + raise e + img = QImage(export_path + ".png"); + # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded + return f'{export_path}.png,{img.width()},{img.height()}' + + def create_latex_doc(self, export_path: str, latex_markup: str): + """ + Creates a temporary latex document with base file_hash as file name and a given expression markup latex_markup. + """ + ltx_path = export_path + ".tex" + f = open(export_path + ".tex", 'w') + f.write(DEFAULT_LATEX_DOC.substitute(markup = latex_markup)) + f.close() + + def convert_latex_to_dvi(self, export_path: str): + """ + Converts a DVI file to a PNG file. + """ + self.run([ + LATEX_PATH, + export_path + ".tex" + ]) + + + def convert_dvi_to_png(self, export_path: str, font_size: float, color: QColor): + """ + Converts a DVI file to a PNG file. + Documentation: https://linux.die.net/man/1/dvipng + """ + fg = color.convertTo(QColor.Rgb) + fg = f'rgb {fg.redF()} {fg.greenF()} {fg.blueF()}' + depth = int(font_size * 72.27 / 100) * 10 + self.run([ + DVIPNG_PATH, + '-T', 'tight', # Make sure image borders are as tight around the equation as possible to avoid blank space. + '--truecolor', # Make sure it's rendered in 24 bit colors. + '-D',f'{depth}', # Depth of the image + '-bg', 'Transparent', # Transparent background + '-fg',f'{fg}', # Foreground of the wanted color. + f'{export_path}.dvi', # Input file + '-o',f'{export_path}.png', # Output file + ]) + + def run(self, process: list): + """ + Runs a subprocess and handles exceptions and messages them to the user. + """ + proc = Popen(process, stdout=PIPE, stderr=PIPE, cwd=self.tempdir.name) + try: + out, err = proc.communicate(timeout=5) # 5 seconds is already FAR too long. + if proc.returncode != 0: + # Process errored + QMessageBox.warning(None, "LogarithmPlotter - Latex", + QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n{}\nPlease make sure your latex installation is correct and report a bug if so.") + .format(" ".join(process), proc.returncode, str(out, 'utf8')+"\n"+str(err,'utf8'))) + raise Exception(" ".join(process) + " process exited with return code " + str(proc.returncode) + ":\n" + str(out, 'utf8')+"\n"+str(err,'utf8')) + print(out) + except TimeoutExpired as e: + # Process timed out + proc.kill() + out, err = proc.communicate() + QMessageBox.warning(None, "LogarithmPlotter - Latex", + QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' took too long to finish:\n{}\nPlease make sure your latex installation is correct and report a bug if so.") + .format(" ".join(process), str(out, 'utf8')+"\n"+str(err,'utf8'))) + raise Exception(" ".join(process) + " process timed out:\n" + str(out, 'utf8')+"\n"+str(err,'utf8')) + + def cleanup(self, export_path): + """ + Removes Tex, auxiliary, logs and DVI temporary files. + """ + for i in [".tex", ".dvi", ".aux", ".log"]: + remove(export_path + i) + + + @Slot(str, float, QColor, result=str) + def render_legacy(self, latexstring, font_size, color = True): exprpath = path.join(self.tempdir.name, f'{hash(latexstring)}_{font_size}_{color.rgb()}.png') print("Rendering", latexstring, exprpath) if not path.exists(exprpath): @@ -49,9 +182,3 @@ class Latex(QObject): img = QImage(exprpath); # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded return f'{exprpath},{img.width()},{img.height()}' - - @Slot(str) - def copyLatexImageToClipboard(self, latexstring): - global tempfile - clipboard = QApplication.clipboard() - clipboard.setImage(self.render(latexstring)) diff --git a/linux/debian/control b/linux/debian/control index a4fe523..6379384 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -3,7 +3,7 @@ Source: logarithmplotter Version: 0.1.9 Architecture: all Maintainer: Ad5001 -Depends: python3, python3-pip, qml-module-qtquick-controls2 (>= 5.12.0), qml-module-qtmultimedia (>= 5.12.0), qml-module-qtgraphicaleffects (>= 5.12.0), qml-module-qtquick2 (>= 5.12.0), qml-module-qtqml-models2 (>= 5.12.0), qml-module-qtquick-controls (>= 5.12.0), python3-pyside2.qtcore (>= 5.12.0), python3-pyside2.qtqml (>= 5.12.0), python3-pyside2.qtgui (>= 5.12.0), python3-pyside2.qtquick (>= 5.12.0), python3-pyside2.qtwidgets (>= 5.12.0), python3-pyside2.qtmultimedia (>= 5.12.0), python3-pyside2.qtnetwork (>= 5.12.0), python3-sympy +Depends: python3, python3-pip, qml-module-qtquick-controls2 (>= 5.12.0), qml-module-qtmultimedia (>= 5.12.0), qml-module-qtgraphicaleffects (>= 5.12.0), qml-module-qtquick2 (>= 5.12.0), qml-module-qtqml-models2 (>= 5.12.0), qml-module-qtquick-controls (>= 5.12.0), python3-pyside2.qtcore (>= 5.12.0), python3-pyside2.qtqml (>= 5.12.0), python3-pyside2.qtgui (>= 5.12.0), python3-pyside2.qtquick (>= 5.12.0), python3-pyside2.qtwidgets (>= 5.12.0), python3-pyside2.qtmultimedia (>= 5.12.0), python3-pyside2.qtnetwork (>= 5.12.0), texlive-latex-base, dvipng Build-Depends: debhelper (>=11~), dh-python, dpkg-dev (>= 1.16.1~), python-setuptools, python3-all-dev (>=3.6) Section: science diff --git a/linux/debian/depends b/linux/debian/depends index 725059d..53dcda3 100644 --- a/linux/debian/depends +++ b/linux/debian/depends @@ -1 +1 @@ -python3-pip, qml-module-qtquick-controls2 (>= 5.12.0), qml-module-qtmultimedia (>= 5.12.0), qml-module-qtgraphicaleffects (>= 5.12.0), qml-module-qtquick2 (>= 5.12.0), qml-module-qtqml-models2 (>= 5.12.0), qml-module-qtquick-controls (>= 5.12.0), python3-pyside2.qtcore (>= 5.12.0), python3-pyside2.qtqml (>= 5.12.0), python3-pyside2.qtgui (>= 5.12.0), python3-pyside2.qtquick (>= 5.12.0), python3-pyside2.qtwidgets (>= 5.12.0), python3-pyside2.qtmultimedia (>= 5.12.0), python3-pyside2.qtnetwork (>= 5.12.0), python3-sympy +python3-pip, qml-module-qtquick-controls2 (>= 5.12.0), qml-module-qtmultimedia (>= 5.12.0), qml-module-qtgraphicaleffects (>= 5.12.0), qml-module-qtquick2 (>= 5.12.0), qml-module-qtqml-models2 (>= 5.12.0), qml-module-qtquick-controls (>= 5.12.0), python3-pyside2.qtcore (>= 5.12.0), python3-pyside2.qtqml (>= 5.12.0), python3-pyside2.qtgui (>= 5.12.0), python3-pyside2.qtquick (>= 5.12.0), python3-pyside2.qtwidgets (>= 5.12.0), python3-pyside2.qtmultimedia (>= 5.12.0), python3-pyside2.qtnetwork (>= 5.12.0), texlive-latex-base, dvipng diff --git a/setup.py b/setup.py index b7817bf..20568b5 100644 --- a/setup.py +++ b/setup.py @@ -127,7 +127,7 @@ if sys.platform == 'linux': os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/logplotter.svg') setuptools.setup( - install_requires=([] if "FLATPAK_INSTALL" in os.environ else ["PySide2", "sympy"]), + install_requires=([] if "FLATPAK_INSTALL" in os.environ else ["PySide2"]), python_requires='>=3.8', name='logarithmplotter', From ec90779912b81f59707cb938d8db2f26864b647b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 6 Mar 2022 23:36:10 +0100 Subject: [PATCH 11/26] Changing build process to reflect changes. --- ci/drone.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ci/drone.yml b/ci/drone.yml index 82dbc36..4856628 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -14,7 +14,7 @@ steps: - name: Linux test image: ad5001/ubuntu-pyside2-xvfb:hirsute-5.15.2 commands: - - pip3 install sympy + - apt install texlive-latex-base dvipng - xvfb-run python3 run.py --test-build --no-check-for-updates - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test2.lpf @@ -25,7 +25,6 @@ steps: image: ad5001/ubuntu-pyside2-xvfb-wine:win7-5.15.2 commands: - # For some reason, launching GUI apps with wine, even with xvfb-run, fails. - - pip install sympy - xvfb-run python run.py --test-build --no-check-for-updates - xvfb-run python run.py --test-build --no-check-for-updates ./ci/test1.lpf - xvfb-run python run.py --test-build --no-check-for-updates ./ci/test2.lpf From 06bb00cc172037efa31d37fce2530ca11622e5fd Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 7 Mar 2022 00:11:12 +0100 Subject: [PATCH 12/26] Latex for sums, fixing bugs related to expression simplification. Also removing some debug and unused code. --- .../ad5001/LogarithmPlotter/js/math/latex.js | 16 ++++++-- .../LogarithmPlotter/js/objs/phasebode.js | 2 +- .../LogarithmPlotter/js/objs/sequence.js | 31 -------------- .../js/objs/sommegainsbode.js | 41 +++---------------- .../js/objs/sommephasesbode.js | 37 +++-------------- LogarithmPlotter/util/latex.py | 5 +-- 6 files changed, 28 insertions(+), 104 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index e036960..5d73a16 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -20,6 +20,7 @@ .import "../expr-eval.js" as ExprEval + /** * Puts element within parenthesis. * @@ -32,14 +33,20 @@ function par(elem) { /** * Checks if the element contains at least one of the elements of - * the string array contents , and returns the parenthesis version if so. + * the string array contents, but not at the first position of the string, + * and returns the parenthesis version if so. * * @param {string} elem - element to put within parenthesis. * @param {Array} contents - Array of elements to put within parenthesis. * @returns {string} */ function parif(elem, contents) { - return contents.some(x => elem.toString().includes(x)) ? par(elem) : elem + elem = elem.toString() + if(elem[0] != "(" && elem[elem.length-1] != ")" && contents.some(x => elem.indexOf(x) > 0)) + return par(elem) + if(elem[0] == "(" && elem[elem.length-1] == ")") + return elem.substr(1, elem.length-2) + return elem } @@ -154,7 +161,10 @@ function expressionToLatex(tokens) { nstack.push(par(n1) + f + par(n2)); break; case '*': - nstack.push(parif(n1,['+','-']) + " \\times " + parif(n2,['+','-'])); + if(n2 == "\\pi" || n2 == "e" || n2 == "x" || n2 == "n") + nstack.push(parif(n1,['+','-']) + n2) + else + nstack.push(parif(n1,['+','-']) + " \\times " + parif(n2,['+','-'])); break; case '/': nstack.push("\\frac{" + n1 + "}{" + n2 + "}"); diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js index bedf9c7..4413de8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js @@ -55,7 +55,7 @@ class PhaseBode extends Common.ExecutableObject { om_0.name = Common.getNewName('ω') om_0.color = this.color om_0.labelContent = 'name' - om_0.labelPosition = this.phase.execute() >= 0 ? 'bottom' : 'top' + om_0.labelPosition = this.phase.execute() >= 0 ? 'above' : 'below' HistoryLib.history.addToHistory(new HistoryLib.CreateNewObject(om_0.name, 'Point', om_0.export())) labelPosition = 'below' } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js index 5ed7238..484b7a4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js @@ -126,37 +126,6 @@ class Sequence extends Common.ExecutableObject { // Label this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) - /*var text = this.getLabel() - ctx.font = `${canvas.textsize}px sans-serif` - var textSize = canvas.measureText(ctx, text) - var posX = canvas.x2px(this.labelX) - var posY = canvas.y2px(this.execute(this.labelX)) - switch(this.labelPosition) { - case 'above': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height) - break; - case 'below': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY+textSize.height) - break; - case 'left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height/2) - break; - case 'right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height/2) - break; - case 'above-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height) - break; - case 'above-right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height) - break; - case 'below-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY+textSize.height) - break; - case 'below-right': - canvas.drawVisibleText(ctx, text, posX, posY+textSize.height) - break; - }*/ } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js index 20c17ba..8f5854c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js @@ -23,6 +23,7 @@ .import "../objects.js" as Objects .import "../mathlib.js" as MathLib .import "../parameters.js" as P +.import "../math/latex.js" as Latex class SommeGainsBode extends Common.DrawableObject { @@ -30,10 +31,6 @@ class SommeGainsBode extends Common.DrawableObject { static displayType(){return qsTr('Bode Magnitudes Sum')} static displayTypeMultiple(){return qsTr('Bode Magnitudes Sum')} static createable() {return false} - /*static properties() {return { - 'labelPosition': new P.Enum('above', 'below', 'left', 'right', 'above-left', 'above-right', 'below-left', 'below-right'), - 'labelX': 'number' - }}*/ static properties() {return { [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', @@ -56,6 +53,10 @@ class SommeGainsBode extends Common.DrawableObject { return `${this.name} = ${Objects.getObjectsName('Gain Bode').join(' + ')}` } + getLatexString() { + return `${Latex.variable(this.name)} = ${Objects.getObjectsName('Gain Bode').map(Latex.variable).join(' + ')}` + } + execute(x = 0) { for(var [dbfn, inDrawDom] of this.cachedParts) { if(inDrawDom.includes(x)) { @@ -136,37 +137,7 @@ class SommeGainsBode extends Common.DrawableObject { F.Function.drawFunction(canvas, ctx, dbfn, inDrawDom, MathLib.Domain.R) if(inDrawDom.includes(this.labelX)) { // Label - var text = this.getLabel() - ctx.font = `${canvas.textsize}px sans-serif` - var textSize = canvas.measureText(ctx, text) - var posX = canvas.x2px(this.labelX) - var posY = canvas.y2px(dbfn.execute(this.labelX)) - switch(this.labelPosition) { - case 'above': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height) - break; - case 'below': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY+textSize.height) - break; - case 'left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height/2) - break; - case 'right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height/2) - break; - case 'above-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height) - break; - case 'above-right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height) - break; - case 'below-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY+textSize.height) - break; - case 'below-right': - canvas.drawVisibleText(ctx, text, posX, posY+textSize.height) - break; - } + this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js index 98a5fcc..bfa6c4b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js @@ -22,6 +22,7 @@ .import "../objects.js" as Objects .import "../mathlib.js" as MathLib .import "../parameters.js" as P +.import "../math/latex.js" as Latex class SommePhasesBode extends Common.ExecutableObject { @@ -55,6 +56,10 @@ class SommePhasesBode extends Common.ExecutableObject { return `${this.name} = ${Objects.getObjectsName('Phase Bode').join(' + ')}` } + getLatexString() { + return `${Latex.variable(this.name)} = ${Objects.getObjectsName('Phase Bode').map(Latex.variable).join(' + ')}` + } + execute(x=1) { if(typeof x == 'string') x = MathLib.executeExpression(x) for(var i = 0; i < this.om0xList.length-1; i++) { @@ -122,37 +127,7 @@ class SommePhasesBode extends Common.ExecutableObject { } // Label - var text = this.getLabel() - ctx.font = `${canvas.textsize}px sans-serif` - var textSize = canvas.measureText(ctx, text) - var posX = canvas.x2px(this.labelX) - var posY = canvas.y2px(this.execute(this.labelX)) - switch(this.labelPosition) { - case 'above': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height) - break; - case 'below': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY+textSize.height) - break; - case 'left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height/2) - break; - case 'right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height/2) - break; - case 'above-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height) - break; - case 'above-right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height) - break; - case 'below-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY+textSize.height) - break; - case 'below-right': - canvas.drawVisibleText(ctx, text, posX, posY+textSize.height) - break; - } + this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } } diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index e76fd3e..17b2efe 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -81,8 +81,8 @@ class Latex(QObject): Renders a latex string into a png file. """ export_path = path.join(self.tempdir.name, f'{hash(latex_markup)}_{font_size}_{color.rgb()}') - print(export_path) if self.latexSupported and not path.exists(export_path + ".png"): + print("Rendering", latex_markup, export_path) # Generating file try: self.create_latex_doc(export_path, latex_markup) @@ -90,7 +90,7 @@ class Latex(QObject): self.convert_dvi_to_png(export_path, font_size, color) self.cleanup(export_path) except Exception as e: # One of the processes failed. A message will be sent every time. - raise e + pass img = QImage(export_path + ".png"); # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded return f'{export_path}.png,{img.width()},{img.height()}' @@ -146,7 +146,6 @@ class Latex(QObject): QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n{}\nPlease make sure your latex installation is correct and report a bug if so.") .format(" ".join(process), proc.returncode, str(out, 'utf8')+"\n"+str(err,'utf8'))) raise Exception(" ".join(process) + " process exited with return code " + str(proc.returncode) + ":\n" + str(out, 'utf8')+"\n"+str(err,'utf8')) - print(out) except TimeoutExpired as e: # Process timed out proc.kill() From 07ae71de3673d8006a24a4e10f363e8524bbb7a1 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 7 Mar 2022 01:37:23 +0100 Subject: [PATCH 13/26] DVI files are no longer remade unless there is a change in the formula --- .../LogarithmPlotter/js/objs/function.js | 3 ++- LogarithmPlotter/util/latex.py | 24 +++++++++++-------- ci/test2.lpf | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js index 464ddda..44dc1f4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js @@ -78,7 +78,8 @@ class Function extends Common.ExecutableObject { getLatexString() { if(this.displayMode == 'application') { - return `${Latex.variable(this.name)}:\\begin{array}{llll}${this.definitionDomain.latexMarkup} & \\rightarrow & ${this.destinationDomain.latexMarkup}\\\\x & \\mapsto & ${this.expression.latexMarkup}\\end{array}` + return `${Latex.variable(this.name)}:\\begin{array}{llll}${this.definitionDomain.latexMarkup}\\textrm{ } & \\rightarrow & \\textrm{ }${this.destinationDomain.latexMarkup}\\\\ + x\\textrm{ } & \\mapsto & \\textrm{ }${this.expression.latexMarkup}\\end{array}` } else { return `\\begin{array}{l}${Latex.variable(this.name)}(x) = ${this.expression.latexMarkup}\\\\ D_{${this.name}} = ${this.definitionDomain.latexMarkup}\\end{array}` } diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index 17b2efe..1f4c098 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -80,17 +80,21 @@ class Latex(QObject): """ Renders a latex string into a png file. """ - export_path = path.join(self.tempdir.name, f'{hash(latex_markup)}_{font_size}_{color.rgb()}') + markup_hash = hash(latex_markup) + export_path = path.join(self.tempdir.name, f'{markup_hash}_{font_size}_{color.rgb()}') if self.latexSupported and not path.exists(export_path + ".png"): print("Rendering", latex_markup, export_path) # Generating file try: - self.create_latex_doc(export_path, latex_markup) - self.convert_latex_to_dvi(export_path) - self.convert_dvi_to_png(export_path, font_size, color) - self.cleanup(export_path) + latex_path = path.join(self.tempdir.name, str(markup_hash)) + # If the formula is just recolored or the font is just changed, no need to recreate the DVI. + if not path.exists(latex_path + ".dvi"): + self.create_latex_doc(latex_path, latex_markup) + self.convert_latex_to_dvi(latex_path) + self.cleanup(latex_path) + self.convert_dvi_to_png(latex_path, export_path, font_size, color) except Exception as e: # One of the processes failed. A message will be sent every time. - pass + raise e img = QImage(export_path + ".png"); # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded return f'{export_path}.png,{img.width()},{img.height()}' @@ -114,7 +118,7 @@ class Latex(QObject): ]) - def convert_dvi_to_png(self, export_path: str, font_size: float, color: QColor): + def convert_dvi_to_png(self, dvi_path: str, export_path: str, font_size: float, color: QColor): """ Converts a DVI file to a PNG file. Documentation: https://linux.die.net/man/1/dvipng @@ -129,7 +133,7 @@ class Latex(QObject): '-D',f'{depth}', # Depth of the image '-bg', 'Transparent', # Transparent background '-fg',f'{fg}', # Foreground of the wanted color. - f'{export_path}.dvi', # Input file + f'{dvi_path}.dvi', # Input file '-o',f'{export_path}.png', # Output file ]) @@ -157,9 +161,9 @@ class Latex(QObject): def cleanup(self, export_path): """ - Removes Tex, auxiliary, logs and DVI temporary files. + Removes auxiliary, logs and Tex temporary files. """ - for i in [".tex", ".dvi", ".aux", ".log"]: + for i in [".tex", ".aux", ".log"]: remove(export_path + i) diff --git a/ci/test2.lpf b/ci/test2.lpf index f443606..c9470d4 100644 --- a/ci/test2.lpf +++ b/ci/test2.lpf @@ -1 +1 @@ -LPFv1{"xzoom":300,"yzoom":22,"xmin":0.5,"ymax":22,"xaxisstep":"4","yaxisstep":"4","xaxislabel":"","yaxislabel":"","logscalex":true,"linewidth":2,"showxgrad":true,"showygrad":true,"textsize":14,"history":[[["CreateNewObject",["g","Function",["g",true,"#697F4E","name + value","x","ℝ⁺*","ℝ","application","above",1,true,true]]],["EditedProperty",["g","Function","expression","x","(x ^ 3)",true]],["CreateNewObject",["h","Function",["h",true,"#0CA920","name + value","x","ℝ⁺*","ℝ","application","above",1,true,true]]],["EditedProperty",["h","Function","expression","x","Integrate(\"x^3\", x)",true]],["EditedProperty",["h","Function","expression","Integrate(\"x^3\", x)","integral(0, x, \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(0, x, \"t^3\", \"t\")","integral(0, x, \"t^3\", \"t\")",true]],["EditedProperty",["g","Function","labelX",1,2,false]],["EditedProperty",["g","Function","displayMode","application","function",false]],["EditedProperty",["g","Function","labelPosition","above","above-left",false]],["EditedProperty",["g","Function","labelX",2,1.5,false]],["EditedProperty",["g","Function","labelPosition","above-left","above",false]],["EditedProperty",["h","Function","expression","integral(0, x, \"t^3\", \"t\")","integral((x + 1), x, \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral((x + 1), x, \"t^3\", \"t\")","integral(x, (x + 1), \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(x, (x + 1), \"t^3\", \"t\")","integral(0, (x + 1), \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(0, (x + 1), \"t^3\", \"t\")","integral(0, x, \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(0, x, \"t^3\", \"t\")","integral(0, (x + 0), \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(0, (x + 0), \"t^3\", \"t\")","integral(1, x, \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(1, x, \"t^3\", \"t\")","integral(x, 0, \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(x, 0, \"t^3\", \"t\")","integral(x, (x + 1), \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(x, (x + 1), \"t^3\", \"t\")","integral(x, 1, \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(x, 1, \"t^3\", \"t\")","integral(0, x, \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","displayMode","application","function",false]],["EditedProperty",["h","Function","displayMode","function","application",false]],["EditedProperty",["h","Function","labelX",1,2,false]],["EditedProperty",["h","Function","labelPosition","above","below",false]],["EditedProperty",["h","Function","labelPosition","below","below-right",false]],["EditedProperty",["h","Function","expression","integral(0, x, \"t^3\", \"t\")","integral(0, (x - 1), \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(0, (x - 1), \"t^3\", \"t\")","integral(0, (x - 0), \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(0, (x - 0), \"t^3\", \"t\")","integral(0, (x + 0.01), \"t^3\", \"t\")",true]]],[]],"width":1027,"height":594,"objects":{"Function":[["f",true,"#8F6027","name + value","derivative(\"t^3\", \"t\", x)","ℝ⁺*","ℝ","application","above-left",2,true,true],["g",true,"#697F4E","name + value","(x ^ 3)","ℝ⁺*","ℝ","function","above",1.5,true,true],["h",true,"#0CA920","name + value","integral(0, (x + 0.01), \"t^3\", \"t\")","ℝ⁺*","ℝ","application","below-right",2,true,true]]},"type":"logplotv1"} \ No newline at end of file +LPFv1{"xzoom":300,"yzoom":22,"xmin":0.5,"ymax":22,"xaxisstep":"4","yaxisstep":"4","xaxislabel":"","yaxislabel":"","logscalex":true,"linewidth":2,"showxgrad":true,"showygrad":true,"textsize":20,"history":[[["CreateNewObject",["g","Function",["g",true,"#697F4E","name + value","x","ℝ⁺*","ℝ","application","above",1,true,true]]],["EditedProperty",["g","Function","expression","x","(x ^ 3)",true]],["CreateNewObject",["h","Function",["h",true,"#0CA920","name + value","x","ℝ⁺*","ℝ","application","above",1,true,true]]],["EditedProperty",["h","Function","expression","x","Integrate(\"x^3\", x)",true]],["EditedProperty",["h","Function","expression","Integrate(\"x^3\", x)","integral(0, x, \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(0, x, \"t^3\", \"t\")","integral(0, x, \"t^3\", \"t\")",true]],["EditedProperty",["g","Function","labelX",1,2,false]],["EditedProperty",["g","Function","displayMode","application","function",false]],["EditedProperty",["g","Function","labelPosition","above","above-left",false]],["EditedProperty",["g","Function","labelX",2,1.5,false]],["EditedProperty",["g","Function","labelPosition","above-left","above",false]],["EditedProperty",["h","Function","expression","integral(0, x, \"t^3\", \"t\")","integral((x + 1), x, \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral((x + 1), x, \"t^3\", \"t\")","integral(x, (x + 1), \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(x, (x + 1), \"t^3\", \"t\")","integral(0, (x + 1), \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(0, (x + 1), \"t^3\", \"t\")","integral(0, x, \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(0, x, \"t^3\", \"t\")","integral(0, (x + 0), \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(0, (x + 0), \"t^3\", \"t\")","integral(1, x, \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(1, x, \"t^3\", \"t\")","integral(x, 0, \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(x, 0, \"t^3\", \"t\")","integral(x, (x + 1), \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(x, (x + 1), \"t^3\", \"t\")","integral(x, 1, \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(x, 1, \"t^3\", \"t\")","integral(0, x, \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","displayMode","application","function",false]],["EditedProperty",["h","Function","displayMode","function","application",false]],["EditedProperty",["h","Function","labelX",1,2,false]],["EditedProperty",["h","Function","labelPosition","above","below",false]],["EditedProperty",["h","Function","labelPosition","below","below-right",false]],["EditedProperty",["h","Function","expression","integral(0, x, \"t^3\", \"t\")","integral(0, (x - 1), \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(0, (x - 1), \"t^3\", \"t\")","integral(0, (x - 0), \"t^3\", \"t\")",true]],["EditedProperty",["h","Function","expression","integral(0, (x - 0), \"t^3\", \"t\")","integral(0, (x + 0.01), \"t^3\", \"t\")",true]]],[]],"width":1027,"height":594,"objects":{"Function":[["f",true,"#8F6027","name + value","derivative(\"t^3\", \"t\", x)","ℝ⁺*","ℝ","application","above-left",2,true,true],["g",true,"#697F4E","name + value","(x ^ 3)","ℝ⁺*","ℝ","function","above",1.5,true,true],["h",true,"#0CA920","name + value","integral(0, (x + 0.01), \"t^3\", \"t\")","ℝ⁺*","ℝ","application","below-right",2,true,true]]},"type":"logplotv1"} \ No newline at end of file From 12ecf3b19b6fcd8e965278e82b6fe1c1e4e65db5 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 7 Mar 2022 02:46:38 +0100 Subject: [PATCH 14/26] Adding LatexExpression, LaTeX integration for texts (needs a comment tho) - Simplified label rendering for both Latex and normal mode - Texts now can integrate latex expressions in latex mode - There is now a toggle for texts to use normal fonts or integrate latex - Updated translation sources. --- LogarithmPlotter/i18n/lp_de.ts | 133 +++++++++++------ LogarithmPlotter/i18n/lp_en.ts | 133 +++++++++++------ LogarithmPlotter/i18n/lp_es.ts | 133 +++++++++++------ LogarithmPlotter/i18n/lp_fr.ts | 133 +++++++++++------ LogarithmPlotter/i18n/lp_hu.ts | 133 +++++++++++------ LogarithmPlotter/i18n/lp_nb_NO.ts | 133 +++++++++++------ LogarithmPlotter/i18n/lp_template.ts | 133 +++++++++++------ .../Setting/LatexExpression.qml | 28 ++++ .../ad5001/LogarithmPlotter/js/objs/common.js | 134 ++++++++---------- .../ad5001/LogarithmPlotter/js/objs/text.js | 66 ++++----- LogarithmPlotter/util/latex.py | 4 +- 11 files changed, 722 insertions(+), 441 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/LatexExpression.qml diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 5fc986d..f6184d1 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Über LogarithmPlotter @@ -529,12 +529,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Beispiel: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) @@ -544,7 +544,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. - + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… @@ -607,22 +607,24 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" gainbode - + Bode Magnitude Bode-Magnitude - + Bode Magnitudes Bode-Magnituden - + + low-pass Tiefpass - + + high-pass Hochpass @@ -654,6 +656,38 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Der Name von %1 %2 wurde in %3 geändert. + + latex + + + No Latex installation found. +If you already have a latex distribution installed, make sure it's installed on your path. +Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. + + + + + DVIPNG was not found. Make sure you include it from your Latex distribution. + + + + + An exception occured within the creation of the latex formula. +Process '{}' ended with a non-zero return code {}: + +{} +Please make sure your latex installation is correct and report a bug if so. + + + + + An exception occured within the creation of the latex formula. +Process '{}' took too long to finish: +{} +Please make sure your latex installation is correct and report a bug if so. + + + name @@ -781,12 +815,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" phasebode - + Bode Phase Bode-Phase - + Bode Phases Bode-Phasen @@ -807,108 +841,108 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" prop - + expression Ausdruck - + definitionDomain Definitionsbereich - + destinationDomain Reichweite - - - - + + + + - - - + + + labelPosition Position des Etiketts - + displayMode Anzeigemodus - - - + + + - - - + + + labelX X-Position des Etiketts - - + + drawPoints Unentschiedene Punkte - - + + drawDashedLines Gestrichelte Linien anzeigen - - + + om_0 ω₀ - + pass Pass - + gain Größenordnung - + omGraduation Teilung auf ω zeigen - + phase Phase - + unit Einheit - + x X - + y Y - + pointStyle Punkt-Stil @@ -922,6 +956,11 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" text Inhalt + + + disableLatex + + targetElement @@ -948,12 +987,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Wertposition des Ziels - + defaultExpression Standardausdruck - + baseValues Initialisierungswerte @@ -978,12 +1017,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" sequence - + Sequence Folge - + Sequences Folgen @@ -991,8 +1030,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" sommegainsbode - + Bode Magnitudes Sum Bode-Magnituden Summe @@ -1000,8 +1039,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" sommephasesbode - + Bode Phases Sum Bode-Phasen Summe diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index fd9567a..9d07cde 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter About LogarithmPlotter @@ -529,12 +529,12 @@ These settings can be changed at any time from the "Settings" menu. comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) @@ -544,7 +544,7 @@ These settings can be changed at any time from the "Settings" menu.Note: Specify the probability for each value. - + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… @@ -607,22 +607,24 @@ These settings can be changed at any time from the "Settings" menu. gainbode - + Bode Magnitude Bode Magnitude - + Bode Magnitudes Bode Magnitudes - + + low-pass low-pass - + + high-pass high-pass @@ -654,6 +656,38 @@ These settings can be changed at any time from the "Settings" menu.Name of %1 %2 changed to %3. + + latex + + + No Latex installation found. +If you already have a latex distribution installed, make sure it's installed on your path. +Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. + + + + + DVIPNG was not found. Make sure you include it from your Latex distribution. + + + + + An exception occured within the creation of the latex formula. +Process '{}' ended with a non-zero return code {}: + +{} +Please make sure your latex installation is correct and report a bug if so. + + + + + An exception occured within the creation of the latex formula. +Process '{}' took too long to finish: +{} +Please make sure your latex installation is correct and report a bug if so. + + + name @@ -781,12 +815,12 @@ These settings can be changed at any time from the "Settings" menu. phasebode - + Bode Phase Bode Phase - + Bode Phases Bode Phases @@ -807,108 +841,108 @@ These settings can be changed at any time from the "Settings" menu. prop - + expression Expression - + definitionDomain Domain - + destinationDomain Range - - - - + + + + - - - + + + labelPosition Label position - + displayMode Display mode - - - + + + - - - + + + labelX Label's X position - - + + drawPoints Show points - - + + drawDashedLines Show dashed lines - - + + om_0 ω₀ - + pass Pass - + gain Magnitude gain - + omGraduation Show graduation on ω₀ - + phase Phase - + unit Unit to use - + x X - + y Y - + pointStyle Point style @@ -922,6 +956,11 @@ These settings can be changed at any time from the "Settings" menu.text Content + + + disableLatex + + targetElement @@ -948,12 +987,12 @@ These settings can be changed at any time from the "Settings" menu.Target's value position - + defaultExpression Default expression - + baseValues Initialisation values @@ -978,12 +1017,12 @@ These settings can be changed at any time from the "Settings" menu. sequence - + Sequence Sequence - + Sequences Sequences @@ -991,8 +1030,8 @@ These settings can be changed at any time from the "Settings" menu. sommegainsbode - + Bode Magnitudes Sum Bode Magnitudes Sum @@ -1000,8 +1039,8 @@ These settings can be changed at any time from the "Settings" menu. sommephasesbode - + Bode Phases Sum Bode Phases Sum diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index fe30649..4af05f8 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Sobre LogarithmPlotter @@ -528,12 +528,12 @@ These settings can be changed at any time from the "Settings" menu. comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) @@ -543,7 +543,7 @@ These settings can be changed at any time from the "Settings" menu. - + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... @@ -606,26 +606,60 @@ These settings can be changed at any time from the "Settings" menu. gainbode - + Bode Magnitude - + Bode Magnitudes - + + low-pass - + + high-pass + + latex + + + No Latex installation found. +If you already have a latex distribution installed, make sure it's installed on your path. +Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. + + + + + DVIPNG was not found. Make sure you include it from your Latex distribution. + + + + + An exception occured within the creation of the latex formula. +Process '{}' ended with a non-zero return code {}: + +{} +Please make sure your latex installation is correct and report a bug if so. + + + + + An exception occured within the creation of the latex formula. +Process '{}' took too long to finish: +{} +Please make sure your latex installation is correct and report a bug if so. + + + name @@ -753,12 +787,12 @@ These settings can be changed at any time from the "Settings" menu. phasebode - + Bode Phase - + Bode Phases @@ -779,108 +813,108 @@ These settings can be changed at any time from the "Settings" menu. prop - + expression - + definitionDomain - + destinationDomain - - - - + + + + - - - + + + labelPosition - + displayMode - - - + + + - - - + + + labelX - - + + drawPoints - - + + drawDashedLines - - + + om_0 - + pass - + gain - + omGraduation - + phase - + unit - + x - + y - + pointStyle @@ -894,6 +928,11 @@ These settings can be changed at any time from the "Settings" menu.text + + + disableLatex + + targetElement @@ -920,12 +959,12 @@ These settings can be changed at any time from the "Settings" menu. - + defaultExpression - + baseValues @@ -946,12 +985,12 @@ These settings can be changed at any time from the "Settings" menu. sequence - + Sequence - + Sequences @@ -959,8 +998,8 @@ These settings can be changed at any time from the "Settings" menu. sommegainsbode - + Bode Magnitudes Sum @@ -968,8 +1007,8 @@ These settings can be changed at any time from the "Settings" menu. sommephasesbode - + Bode Phases Sum diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 42ef942..1038ab0 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter À propos de LogarithmPlotter @@ -537,12 +537,12 @@ These settings can always be changed at any time from the "Settings" m comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Par exemple : R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) @@ -552,7 +552,7 @@ These settings can always be changed at any time from the "Settings" m Note : Spécifiez la probabilité pour chaque valeur. - + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… @@ -616,22 +616,24 @@ These settings can always be changed at any time from the "Settings" m gainbode - + Bode Magnitude Gain de Bode - + Bode Magnitudes Gains de Bode - + + low-pass passe-bas - + + high-pass passe-haut @@ -663,6 +665,38 @@ These settings can always be changed at any time from the "Settings" m Le nom de %1 %2 a été changé en %3. + + latex + + + No Latex installation found. +If you already have a latex distribution installed, make sure it's installed on your path. +Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. + + + + + DVIPNG was not found. Make sure you include it from your Latex distribution. + + + + + An exception occured within the creation of the latex formula. +Process '{}' ended with a non-zero return code {}: + +{} +Please make sure your latex installation is correct and report a bug if so. + + + + + An exception occured within the creation of the latex formula. +Process '{}' took too long to finish: +{} +Please make sure your latex installation is correct and report a bug if so. + + + name @@ -790,12 +824,12 @@ These settings can always be changed at any time from the "Settings" m phasebode - + Bode Phase Phase de Bode - + Bode Phases Phases de Bode @@ -816,108 +850,108 @@ These settings can always be changed at any time from the "Settings" m prop - + expression Expression - + definitionDomain Domaine de définition - + destinationDomain Portée - - - - + + + + - - - + + + labelPosition Position de l'étiquette - + displayMode Mode d'affichage - - - + + + - - - + + + labelX Position en X de l'étiquette - - + + drawPoints Afficher les points - - + + drawDashedLines Afficher les pointillés - - + + om_0 ω₀ - + pass Passe - + gain Gain - + omGraduation Afficher la graduation sur ω₀ - + phase Phase - + unit Unité de la phase - + x X - + y Y - + pointStyle Style du point @@ -931,6 +965,11 @@ These settings can always be changed at any time from the "Settings" m text Contenu + + + disableLatex + + targetElement @@ -957,12 +996,12 @@ These settings can always be changed at any time from the "Settings" m Position de la valeur de la cible - + defaultExpression Expression - + baseValues Valeurs d'initialisation @@ -987,12 +1026,12 @@ These settings can always be changed at any time from the "Settings" m sequence - + Sequence Suite - + Sequences Suites @@ -1000,8 +1039,8 @@ These settings can always be changed at any time from the "Settings" m sommegainsbode - + Bode Magnitudes Sum Sommes des gains de Bode @@ -1009,8 +1048,8 @@ These settings can always be changed at any time from the "Settings" m sommephasesbode - + Bode Phases Sum Somme des phases de Bode diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 0ee9d08..e9d34a2 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter LogarithmPlotter névjegye @@ -529,12 +529,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Példák: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) @@ -544,7 +544,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Megjegyzés: Adja meg az egyes értékek valószínűségét. - + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … @@ -607,22 +607,24 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. gainbode - + Bode Magnitude Bode-nagyságrend - + Bode Magnitudes Bode-nagyságrendek - + + low-pass aluláteresztő - + + high-pass felüláteresztő @@ -650,6 +652,38 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. %1 %2 rejtve. + + latex + + + No Latex installation found. +If you already have a latex distribution installed, make sure it's installed on your path. +Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. + + + + + DVIPNG was not found. Make sure you include it from your Latex distribution. + + + + + An exception occured within the creation of the latex formula. +Process '{}' ended with a non-zero return code {}: + +{} +Please make sure your latex installation is correct and report a bug if so. + + + + + An exception occured within the creation of the latex formula. +Process '{}' took too long to finish: +{} +Please make sure your latex installation is correct and report a bug if so. + + + name @@ -777,12 +811,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. phasebode - + Bode Phase Bode-fázis - + Bode Phases Bode-fázisok @@ -803,108 +837,108 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. prop - + expression Kifejezés - + definitionDomain Abszcissza tartomány - + destinationDomain Ordináta tartomány - - - - + + + + - - - + + + labelPosition Címke helyzete - + displayMode Megjelenítési mód - - - + + + - - - + + + labelX Címke X helyzete - - + + drawPoints Pontok megjelenítése - - + + drawDashedLines Szaggatott vonalak megjelenítése - - + + om_0 ω₀ - + pass Áteresztő - + gain Nagyságrend nyeresége - + omGraduation ω₀ érettségi megjelenítése - + phase Fázis - + unit Egység használata - + x X - + y Y - + pointStyle Pontstílus @@ -918,6 +952,11 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. text Tartalom + + + disableLatex + + targetElement @@ -944,12 +983,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Cél értékpozíciója - + defaultExpression Alapértelmezett kifejezés - + baseValues Kezdeményezési értékek @@ -970,12 +1009,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. sequence - + Sequence Sorozat - + Sequences Sorozatok @@ -983,8 +1022,8 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. sommegainsbode - + Bode Magnitudes Sum Bode-nagyságrendek összege @@ -992,8 +1031,8 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. sommephasesbode - + Bode Phases Sum Bode-fázisok összege diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index cacb689..4426396 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Om @@ -529,12 +529,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) @@ -544,7 +544,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... @@ -607,22 +607,24 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. gainbode - + Bode Magnitude Bode-magnitude - + Bode Magnitudes Bode-magnituder - + + low-pass lavpass - + + high-pass høypass @@ -650,6 +652,38 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.%1 %2 skjult. + + latex + + + No Latex installation found. +If you already have a latex distribution installed, make sure it's installed on your path. +Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. + + + + + DVIPNG was not found. Make sure you include it from your Latex distribution. + + + + + An exception occured within the creation of the latex formula. +Process '{}' ended with a non-zero return code {}: + +{} +Please make sure your latex installation is correct and report a bug if so. + + + + + An exception occured within the creation of the latex formula. +Process '{}' took too long to finish: +{} +Please make sure your latex installation is correct and report a bug if so. + + + name @@ -777,12 +811,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. phasebode - + Bode Phase Bode-fase - + Bode Phases Bode-faser @@ -803,108 +837,108 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. prop - + expression - + definitionDomain - + destinationDomain - - - - + + + + - - - + + + labelPosition - + displayMode - - - + + + - - - + + + labelX - - + + drawPoints - - + + drawDashedLines - - + + om_0 - + pass - + gain - + omGraduation - + phase - + unit - + x - + y - + pointStyle @@ -918,6 +952,11 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.text + + + disableLatex + + targetElement @@ -944,12 +983,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + defaultExpression - + baseValues @@ -970,12 +1009,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. sequence - + Sequence Følge - + Sequences Følger @@ -983,8 +1022,8 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. sommegainsbode - + Bode Magnitudes Sum Bode-magnitudesum @@ -992,8 +1031,8 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. sommephasesbode - + Bode Phases Sum Bode-fasesum diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index d1dcea8..7099743 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter @@ -528,12 +528,12 @@ These settings can be changed at any time from the "Settings" menu. comment - + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) @@ -543,7 +543,7 @@ These settings can be changed at any time from the "Settings" menu. - + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... @@ -606,26 +606,60 @@ These settings can be changed at any time from the "Settings" menu. gainbode - + Bode Magnitude - + Bode Magnitudes - + + low-pass - + + high-pass + + latex + + + No Latex installation found. +If you already have a latex distribution installed, make sure it's installed on your path. +Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. + + + + + DVIPNG was not found. Make sure you include it from your Latex distribution. + + + + + An exception occured within the creation of the latex formula. +Process '{}' ended with a non-zero return code {}: + +{} +Please make sure your latex installation is correct and report a bug if so. + + + + + An exception occured within the creation of the latex formula. +Process '{}' took too long to finish: +{} +Please make sure your latex installation is correct and report a bug if so. + + + name @@ -753,12 +787,12 @@ These settings can be changed at any time from the "Settings" menu. phasebode - + Bode Phase - + Bode Phases @@ -779,108 +813,108 @@ These settings can be changed at any time from the "Settings" menu. prop - + expression - + definitionDomain - + destinationDomain - - - - + + + + - - - + + + labelPosition - + displayMode - - - + + + - - - + + + labelX - - + + drawPoints - - + + drawDashedLines - - + + om_0 - + pass - + gain - + omGraduation - + phase - + unit - + x - + y - + pointStyle @@ -894,6 +928,11 @@ These settings can be changed at any time from the "Settings" menu.text + + + disableLatex + + targetElement @@ -920,12 +959,12 @@ These settings can be changed at any time from the "Settings" menu. - + defaultExpression - + baseValues @@ -946,12 +985,12 @@ These settings can be changed at any time from the "Settings" menu. sequence - + Sequence - + Sequences @@ -959,8 +998,8 @@ These settings can be changed at any time from the "Settings" menu. sommegainsbode - + Bode Magnitudes Sum @@ -968,8 +1007,8 @@ These settings can be changed at any time from the "Settings" menu. sommephasesbode - + Bode Phases Sum diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/LatexExpression.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/LatexExpression.qml new file mode 100644 index 0000000..bc8897c --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/LatexExpression.qml @@ -0,0 +1,28 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2022 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +import QtQuick 2.12 +import QtQuick.Controls 2.12 + +Image { + id: expr + property string expression + + src: Latex.render(expression).split(',')[0] +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index 0d03bb6..599766d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -219,47 +219,15 @@ class DrawableObject { * @param {string|Enum} labelPosition - Position of the label relative to the marked position * @param {number} posX - Component of the marked position on the x-axis * @param {number} posY - Component of the marked position on the y-axis + * @param {bool} forceText - Force the rendering of the label as text. */ - drawLabel(canvas, ctx, labelPosition, posX, posY) { - if(true) { // TODO: Check for user setting with Latex. + drawLabel(canvas, ctx, labelPosition, posX, posY, forceText = false) { + let offset + if(!forceText && true) { // TODO: Check for user setting with Latex. // With latex - let offset = 8 let drawLblCb = function(canvas, ctx, ltxImg) { - switch(this.labelPosition) { - case 'center': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY-ltxImg.height/2, ltxImg.width, ltxImg.height) - break; - case 'top': - case 'above': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY-(ltxImg.height+offset), ltxImg.width, ltxImg.height) - break; - case 'bottom': - case 'below': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY+offset, ltxImg.width, ltxImg.height) - break; - case 'left': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+offset), posY-ltxImg.height/2, ltxImg.width, ltxImg.height) - break; - case 'right': - canvas.drawVisibleImage(ctx, ltxImg.source, posX+offset, posY-ltxImg.height/2, ltxImg.width, ltxImg.height) - break; - case 'top-left': - case 'above-left': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+offset), posY-(ltxImg.height+offset), ltxImg.width, ltxImg.height) - break; - case 'top-right': - case 'above-right': - canvas.drawVisibleImage(ctx, ltxImg.source, posX+offset, posY-(ltxImg.height+offset), ltxImg.width, ltxImg.height) - break; - case 'bottom-left': - case 'below-left': - canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+offset), posY+offset, ltxImg.width, ltxImg.height) - break; - case 'bottom-right': - case 'below-right': - canvas.drawVisibleImage(ctx, ltxImg.source, posX+offset, posY+offset, ltxImg.width, ltxImg.height) - break; - } + this.drawLabelDivergence(labelPosition, 8, ltxImg, posX, posY, + (x,y) => canvas.drawVisibleImage(ctx, ltxImg.source, x, y, ltxImg.width, ltxImg.height)) } let ltxLabel = this.getLatexLabel(); if(ltxLabel != "") @@ -269,43 +237,59 @@ class DrawableObject { // Without latex let text = this.getLabel() ctx.font = `${canvas.textsize}px sans-serif` - let textSize = canvas.measureText(ctx, text) - let offset = 4 - switch(labelPosition) { - case 'center': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height/2) - break; - case 'top': - case 'above': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height-offset) - break; - case 'bottom': - case 'below': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY+offset) - break; - case 'left': - canvas.drawVisibleText(ctx, text, posX-textSize.width-offset, posY-textSize.height/2) - break; - case 'right': - canvas.drawVisibleText(ctx, text, posX+offset, posY-textSize.height/2) - break; - case 'top-left': - case 'above-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height-offset) - break; - case 'top-right': - case 'above-right': - canvas.drawVisibleText(ctx, text, posX+offset, posY-textSize.height-offset) - break; - case 'bottom-left': - case 'below-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width-offset, posY+offset) - break; - case 'bottom-right': - case 'below-right': - canvas.drawVisibleText(ctx, text, posX+offset, posY+offset) - break; - } + this.drawLabelDivergence(labelPosition, 4, canvas.measureText(ctx, text), posX, posY, + (x,y) => canvas.drawVisibleText(ctx, text, x, y)) + } + } + + + /** + * Applicates a \c drawFunction with two position arguments depending on + * both the \c posX and \c posY of where the label should be displayed, + * and the \c labelPosition which declares the label should be displayed + * relatively to that position. + * @param {string|Enum} labelPosition - Position of the label relative to the marked position + * @param {number} offset - Margin between the position and the object to be drawn + * @param {Dictionary} size - Size of the label item, containing two properties, "width" and "height" + * @param {number} posX - Component of the marked position on the x-axis + * @param {number} posY - Component of the marked position on the y-axis + * @param {function} drawFunction - Function with two arguments (x, y) that will be called to draw the label + */ + drawLabelDivergence(labelPosition, offset, size, posX, posY, drawFunction) { + switch(labelPosition) { + case 'center': + drawFunction(posX-size.width/2, posY-size.height/2) + break; + case 'top': + case 'above': + drawFunction(posX-size.width/2, posY-size.height-offset) + break; + case 'bottom': + case 'below': + drawFunction(posX-size.width/2, posY+offset) + break; + case 'left': + drawFunction(posX-size.width-offset, posY-size.height/2) + break; + case 'right': + drawFunction(posX+offset, posY-size.height/2) + break; + case 'top-left': + case 'above-left': + drawFunction(posX-size.width, posY-size.height-offset) + break; + case 'top-right': + case 'above-right': + drawFunction(posX+offset, posY-size.height-offset) + break; + case 'bottom-left': + case 'below-left': + drawFunction(posX-size.width-offset, posY+offset) + break; + case 'bottom-right': + case 'below-right': + drawFunction(posX+offset, posY+offset) + break; } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js index 92d27f5..edfa9f5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js @@ -37,11 +37,12 @@ class Text extends Common.DrawableObject { [QT_TRANSLATE_NOOP('prop','x')]: 'Expression', [QT_TRANSLATE_NOOP('prop','y')]: 'Expression', [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Positioning, - [QT_TRANSLATE_NOOP('prop','text')]: 'string' + [QT_TRANSLATE_NOOP('prop','text')]: 'string', + [QT_TRANSLATE_NOOP('prop','disableLatex')]: 'boolean' }} constructor(name = null, visible = true, color = null, labelContent = 'null', - x = 1, y = 0, labelPosition = 'center', text = 'New text') { + x = 1, y = 0, labelPosition = 'center', text = 'New text', disableLatex = false) { if(name == null) name = Common.getNewName('t') super(name, visible, color, labelContent) this.type = 'Point' @@ -51,50 +52,45 @@ class Text extends Common.DrawableObject { this.y = y this.labelPosition = labelPosition this.text = text + this.disableLatex = disableLatex } getReadableString() { return `${this.name} = "${this.text}"` } + latexMarkupText() { + let txt = this.text + let i + for(i = 0; txt.includes('$$'); i++) + if(i & 0x01) // Every odd number + txt = txt.replace('$$', '\\textrm{') + else + txt = txt.replace('$$', '}') + if(i & 0x01) // Finished by a } + txt += "{" + return txt + } + + getLatexString() { + return `${Latex.variable(this.name)} = "\\textrm{${this.latexMarkupText()}}"` + } + export() { return [this.name, this.visible, this.color.toString(), this.labelContent, this.x.toEditableString(), this.y.toEditableString(), this.labelPosition, this.text] } + getLabel() { + return this.text + } + + getLatexLabel() { + return `\\textrm{${this.latexMarkupText()}}` + } + draw(canvas, ctx) { - var [canvasX, canvasY] = [canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())] - ctx.font = `${canvas.textsize}px sans-serif` - var textSize = ctx.measureText(this.text).width - switch(this.labelPosition) { - case 'center': - canvas.drawVisibleText(ctx, this.text, canvasX-textSize/2, canvasY+4) - break; - case 'top': - canvas.drawVisibleText(ctx, this.text, canvasX-textSize/2, canvasY-16) - break; - case 'bottom': - canvas.drawVisibleText(ctx, this.text, canvasX-textSize/2, canvasY+16) - break; - case 'left': - canvas.drawVisibleText(ctx, this.text, canvasX-textSize-5, canvasY+4) - break; - case 'right': - canvas.drawVisibleText(ctx, this.text, canvasX+5, canvasY+4) - break; - case 'top-left': - canvas.drawVisibleText(ctx, this.text, canvasX-textSize-5, canvasY-16) - break; - case 'top-right': - canvas.drawVisibleText(ctx, this.text, canvasX+5, canvasY-16) - break; - case 'bottom-left': - canvas.drawVisibleText(ctx, this.text, canvasX-textSize-5, canvasY+16) - break; - case 'bottom-right': - canvas.drawVisibleText(ctx, this.text, canvasX+5, canvasY+16) - break; - - } + let yOffset = this.disableLatex ? canvas.textsize-4 : 0 + this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())+yOffset, this.disableLatex) } } diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index 1f4c098..7822f49 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -143,11 +143,11 @@ class Latex(QObject): """ proc = Popen(process, stdout=PIPE, stderr=PIPE, cwd=self.tempdir.name) try: - out, err = proc.communicate(timeout=5) # 5 seconds is already FAR too long. + out, err = proc.communicate(timeout=2) # 2 seconds is already FAR too long. if proc.returncode != 0: # Process errored QMessageBox.warning(None, "LogarithmPlotter - Latex", - QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n{}\nPlease make sure your latex installation is correct and report a bug if so.") + QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n\n{}\nPlease make sure your latex installation is correct and report a bug if so.") .format(" ".join(process), proc.returncode, str(out, 'utf8')+"\n"+str(err,'utf8'))) raise Exception(" ".join(process) + " process exited with return code " + str(proc.returncode) + ":\n" + str(out, 'utf8')+"\n"+str(err,'utf8')) except TimeoutExpired as e: From 6539ca8caaa92122108d9c6dd8a6846e5cb0387a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 7 Mar 2022 02:50:50 +0100 Subject: [PATCH 15/26] Fixing linux tests --- ci/drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/drone.yml b/ci/drone.yml index 4856628..d699291 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -14,7 +14,7 @@ steps: - name: Linux test image: ad5001/ubuntu-pyside2-xvfb:hirsute-5.15.2 commands: - - apt install texlive-latex-base dvipng + - apt install -y texlive-latex-base dvipng - xvfb-run python3 run.py --test-build --no-check-for-updates - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test2.lpf From 7723107ff6f578f8f2c9e08d6a7daf19b781a8f4 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 7 Mar 2022 01:53:43 +0000 Subject: [PATCH 16/26] Translated using Weblate (English) Currently translated at 100.0% (184 of 184 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 9d07cde..f74aba6 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -663,12 +663,14 @@ These settings can be changed at any time from the "Settings" menu.No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + No Latex installation found. +If you already have a latex distribution installed, make sure it's installed on your path. +Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. DVIPNG was not found. Make sure you include it from your Latex distribution. - + DVIPNG was not found. Make sure you include it from your Latex distribution. @@ -677,7 +679,11 @@ Process '{}' ended with a non-zero return code {}: {} Please make sure your latex installation is correct and report a bug if so. - + An exception occurred within the creation of the latex formula. +Process '{}' ended with a non-zero return code {}: + +{} +Please make sure your latex installation is correct and report a bug if so. @@ -685,7 +691,10 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occurred within the creation of the latex formula. +Process '{}' took too long to finish: +{} +Please make sure your latex installation is correct and report a bug if so. @@ -959,7 +968,7 @@ Please make sure your latex installation is correct and report a bug if so. disableLatex - + Disable latex rendering for this text From b72bbeab4f2655c6feb2673ffd418dac47952a15 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 7 Mar 2022 01:58:39 +0000 Subject: [PATCH 17/26] Translated using Weblate (French) Currently translated at 100.0% (184 of 184 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 1038ab0..6993ce0 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -672,12 +672,14 @@ These settings can always be changed at any time from the "Settings" m No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + Aucune installation de Latex trouvée. +Si vous avez déjà installé une distribution Latex, assurez-vous qu'elle est installée sur votre PATH. +Sinon, vous pouvez télécharger une distribution Latex comme TeX Live à l'adresse https://tug.org/texlive/. DVIPNG was not found. Make sure you include it from your Latex distribution. - + DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution Latex. @@ -686,7 +688,11 @@ Process '{}' ended with a non-zero return code {}: {} Please make sure your latex installation is correct and report a bug if so. - + Une exception s'est produite lors de la création de la formule latex. +Le processus '{}' s'est terminé par un code de retour non nul {} : + +{} +Vérifiez que votre installation de latex est correcte et signalez un bogue si c'est le cas. @@ -694,7 +700,10 @@ Please make sure your latex installation is correct and report a bug if so. - + Une exception s'est produite lors de la création de la formule latex. +Le processus '{}' a mis trop de temps à se terminer : +{} +Vérifiez que votre installation de latex est correcte et signalez un bogue si c'est le cas. @@ -968,7 +977,7 @@ Please make sure your latex installation is correct and report a bug if so. disableLatex - + Désactiver le rendu latex pour ce texte From 4c9c9668bb29ba0d15f2698f440e22f825229dbc Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 7 Mar 2022 03:10:51 +0100 Subject: [PATCH 18/26] Adding comment to disableLatex, allowing for symbols in content. --- .../qml/eu/ad5001/LogarithmPlotter/js/objs/text.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js index edfa9f5..c5dd846 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js @@ -21,6 +21,8 @@ .import "common.js" as Common .import "../mathlib.js" as MathLib .import "../parameters.js" as P +.import "../math/latex.js" as Latex + class Text extends Common.DrawableObject { @@ -38,7 +40,11 @@ class Text extends Common.DrawableObject { [QT_TRANSLATE_NOOP('prop','y')]: 'Expression', [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Positioning, [QT_TRANSLATE_NOOP('prop','text')]: 'string', - [QT_TRANSLATE_NOOP('prop','disableLatex')]: 'boolean' + 'comment1': QT_TRANSLATE_NOOP( + 'comment', + 'If you have latex enabled, you can use use latex markup in between $$ to create equations.' + ), + [QT_TRANSLATE_NOOP('prop','disableLatex')]: 'boolean' }} constructor(name = null, visible = true, color = null, labelContent = 'null', @@ -60,7 +66,7 @@ class Text extends Common.DrawableObject { } latexMarkupText() { - let txt = this.text + let txt = Latex.variable(this.text) let i for(i = 0; txt.includes('$$'); i++) if(i & 0x01) // Every odd number From 2691ba687f264f48f0159ecf9efcd994e3ce5bda Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 7 Mar 2022 15:06:40 +0100 Subject: [PATCH 19/26] Changed a few serif text to sans serif. --- .../qml/eu/ad5001/LogarithmPlotter/js/objs/function.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js | 4 ++-- .../qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/text.js | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js index 44dc1f4..b1a98b8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js @@ -81,7 +81,7 @@ class Function extends Common.ExecutableObject { return `${Latex.variable(this.name)}:\\begin{array}{llll}${this.definitionDomain.latexMarkup}\\textrm{ } & \\rightarrow & \\textrm{ }${this.destinationDomain.latexMarkup}\\\\ x\\textrm{ } & \\mapsto & \\textrm{ }${this.expression.latexMarkup}\\end{array}` } else { - return `\\begin{array}{l}${Latex.variable(this.name)}(x) = ${this.expression.latexMarkup}\\\\ D_{${this.name}} = ${this.definitionDomain.latexMarkup}\\end{array}` + return `\\begin{array}{l}${Latex.variable(this.name)}(x) = ${this.expression.latexMarkup}\\\\ textD_{${this.name}} = ${this.definitionDomain.latexMarkup}\\end{array}` } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js index 86b6dd3..ff8236c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js @@ -78,8 +78,8 @@ class GainBode extends Common.ExecutableObject { getLatexString() { let pass = this.pass == "low" ? qsTr("low-pass") : qsTr("high-pass"); return `\\mathrm{${Latex.variable(this.name)}:}\\begin{array}{l} - \\textrm{${pass}};${Latex.variable(this.om_0.name)} = ${this.om_0.x.latexMarkup} \\\\ - ${this.gain.latexMarkup}\\textrm{ dB/dec} + \\textsf{${pass}};${Latex.variable(this.om_0.name)} = ${this.om_0.x.latexMarkup} \\\\ + ${this.gain.latexMarkup}\\textsf{ dB/dec} \\end{array}` } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js index 4413de8..e3d7be0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js @@ -77,7 +77,7 @@ class PhaseBode extends Common.ExecutableObject { } getLatexString() { - return `${Latex.variable(this.name)}: ${this.phase.latexMarkup}\\textrm{${this.unit} at }${Latex.variable(this.om_0.name)} = ${this.om_0.x.latexMarkup}` + return `${Latex.variable(this.name)}: ${this.phase.latexMarkup}\\textsf{${this.unit} at }${Latex.variable(this.om_0.name)} = ${this.om_0.x.latexMarkup}` } execute(x=1) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js index c5dd846..a46e840 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js @@ -70,7 +70,7 @@ class Text extends Common.DrawableObject { let i for(i = 0; txt.includes('$$'); i++) if(i & 0x01) // Every odd number - txt = txt.replace('$$', '\\textrm{') + txt = txt.replace('$$', '\\textsf{') else txt = txt.replace('$$', '}') if(i & 0x01) // Finished by a } @@ -79,7 +79,7 @@ class Text extends Common.DrawableObject { } getLatexString() { - return `${Latex.variable(this.name)} = "\\textrm{${this.latexMarkupText()}}"` + return `${Latex.variable(this.name)} = "\\textsf{${this.latexMarkupText()}}"` } export() { @@ -91,7 +91,7 @@ class Text extends Common.DrawableObject { } getLatexLabel() { - return `\\textrm{${this.latexMarkupText()}}` + return `\\textsf{${this.latexMarkupText()}}` } draw(canvas, ctx) { From 166d1a2485a26b4cafd3306eb1c66325cd5a7097 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 7 Mar 2022 17:20:24 +0100 Subject: [PATCH 20/26] X Cursor Latex implementation Also a few bugfixes and added documentation --- .../LogarithmPlotter/LogGraphCanvas.qml | 8 ++ .../LogarithmPlotter/js/math/expression.js | 2 +- .../ad5001/LogarithmPlotter/js/math/latex.js | 4 +- .../LogarithmPlotter/js/math/sequence.js | 2 +- .../ad5001/LogarithmPlotter/js/objs/common.js | 87 ++++++++------ .../LogarithmPlotter/js/objs/function.js | 2 +- .../LogarithmPlotter/js/objs/xcursor.js | 112 ++++++++---------- 7 files changed, 117 insertions(+), 100 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 19b82e9..2e50d88 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -157,7 +157,15 @@ Canvas { */ property int drawMaxX: Math.ceil(Math.max(Math.abs(xmin), Math.abs(px2x(canvasSize.width)))/xaxisstep1) + /*! + \qmlproperty var LogGraphCanvas::imageLoaders + Dictionary of format {image: [callback.image data]} containing data for defered image loading. + */ property var imageLoaders: {} + /*! + \qmlproperty var LogGraphCanvas::ctx + Cache for the 2D context so that it may be used asynchronously. + */ property var ctx Component.onCompleted: imageLoaders = {} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js index ed2bee9..58c4528 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js @@ -31,7 +31,7 @@ class Expression { this.calc = C.parser.parse(expr).simplify() this.cached = this.isConstant() this.cachedValue = this.cached ? this.calc.evaluate(C.evalVariables) : null - this.latexMarkup = Latex.expressionToLatex(this.calc.tokens) + this.latexMarkup = Latex.expression(this.calc.tokens) } isConstant() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index 5d73a16..d5b30e6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -125,7 +125,7 @@ function variable(vari) { * @param {Array} tokens - expr-eval tokens list * @returns {string} */ -function expressionToLatex(tokens) { +function expression(tokens) { var nstack = []; var n1, n2, n3; var f, args, argCount; @@ -239,7 +239,7 @@ function expressionToLatex(tokens) { nstack.push('[' + args.join(', ') + ']'); break; case ExprEval.IEXPR: - nstack.push('(' + expressionToLatex(item.value) + ')'); + nstack.push('(' + expression(item.value) + ')'); break; case ExprEval.IENDSTATEMENT: break; diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js index ff97760..cdee74c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js @@ -38,7 +38,7 @@ class Sequence extends Expr.Expression { for(var n in this.calcValues) if(['string', 'number'].includes(typeof this.calcValues[n])) { let parsed = C.parser.parse(this.calcValues[n].toString()).simplify() - this.latexValues[n] = Latex.expressionToLatex(parsed.tokens) + this.latexValues[n] = Latex.expression(parsed.tokens) this.calcValues[n] = parsed.evaluate(C.evalVariables) } this.valuePlus = parseInt(valuePlus) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index 599766d..956ecf6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -209,45 +209,12 @@ class DrawableObject { */ draw(canvas, ctx) {} - - /** - * Automaticly draw the label of the object on the \c canvas with the 2D context \c ctx. - * This method takes into account both the \c posX and \c posY of where the label - * should be displayed, including the \c labelPosition relative to it. - * @param {Canvas} canvas - * @param {Context2D} ctx - * @param {string|Enum} labelPosition - Position of the label relative to the marked position - * @param {number} posX - Component of the marked position on the x-axis - * @param {number} posY - Component of the marked position on the y-axis - * @param {bool} forceText - Force the rendering of the label as text. - */ - drawLabel(canvas, ctx, labelPosition, posX, posY, forceText = false) { - let offset - if(!forceText && true) { // TODO: Check for user setting with Latex. - // With latex - let drawLblCb = function(canvas, ctx, ltxImg) { - this.drawLabelDivergence(labelPosition, 8, ltxImg, posX, posY, - (x,y) => canvas.drawVisibleImage(ctx, ltxImg.source, x, y, ltxImg.width, ltxImg.height)) - } - let ltxLabel = this.getLatexLabel(); - if(ltxLabel != "") - canvas.renderLatexImage(ltxLabel, this.color, drawLblCb.bind(this)) - //canvas.drawVisibleImage(ctx, ltxImg.source, posX, posY) - } else { - // Without latex - let text = this.getLabel() - ctx.font = `${canvas.textsize}px sans-serif` - this.drawLabelDivergence(labelPosition, 4, canvas.measureText(ctx, text), posX, posY, - (x,y) => canvas.drawVisibleText(ctx, text, x, y)) - } - } - - /** * Applicates a \c drawFunction with two position arguments depending on * both the \c posX and \c posY of where the label should be displayed, * and the \c labelPosition which declares the label should be displayed * relatively to that position. + * * @param {string|Enum} labelPosition - Position of the label relative to the marked position * @param {number} offset - Margin between the position and the object to be drawn * @param {Dictionary} size - Size of the label item, containing two properties, "width" and "height" @@ -255,7 +222,7 @@ class DrawableObject { * @param {number} posY - Component of the marked position on the y-axis * @param {function} drawFunction - Function with two arguments (x, y) that will be called to draw the label */ - drawLabelDivergence(labelPosition, offset, size, posX, posY, drawFunction) { + drawPositionDivergence(labelPosition, offset, size, posX, posY, drawFunction) { switch(labelPosition) { case 'center': drawFunction(posX-size.width/2, posY-size.height/2) @@ -293,6 +260,56 @@ class DrawableObject { } } + /** + * Automaticly draw text (by default the label of the object on the \c canvas with + * the 2D context \c ctx depending on user settings. + * This method takes into account both the \c posX and \c posY of where the label + * should be displayed, including the \c labelPosition relative to it. + * The text is get both through the \c getLatexFunction and \c getTextFunction + * depending on whether to use latex. + * Then, it's displayed using the \c drawFunctionLatex (x,y,imageData) and + * \c drawFunctionText (x,y,text) depending on whether to use latex. + * + * @param {Canvas} canvas + * @param {Context2D} ctx + * @param {string|Enum} labelPosition - Position of the label relative to the marked position + * @param {number} posX - Component of the marked position on the x-axis + * @param {number} posY - Component of the marked position on the y-axis + * @param {bool} forceText - Force the rendering of the label as text + * @param {function|null} getLatexFunction - Function (no argument) to get the latex markup to be displayed + * @param {function|null} getTextFunction - Function (no argument) to get the text to be displayed + * @param {function|null} drawFunctionLatex - Function (x,y,imageData) to display the latex image + * @param {function|null} drawFunctionText - Function (x,y,text) to display the text + */ + drawLabel(canvas, ctx, labelPosition, posX, posY, forceText = false, + getLatexFunction = null, getTextFunction = null, drawFunctionLatex = null, drawFunctionText = null) { + // Default functions + if(getLatexFunction == null) + getLatexFunction = this.getLatexLabel.bind(this) + if(getTextFunction == null) + getTextFunction = this.getLabel.bind(this) + if(drawFunctionLatex == null) + drawFunctionLatex = (x,y,ltxImg) => canvas.drawVisibleImage(ctx, ltxImg.source, x, y, ltxImg.width, ltxImg.height) + if(drawFunctionText == null) + drawFunctionText = (x,y,text) => canvas.drawVisibleText(ctx, text, x, textSize.height+5) + // Drawing the label + let offset + if(!forceText && true) { // TODO: Check for user setting with Latex. + // With latex + let drawLblCb = function(canvas, ctx, ltxImg) { + this.drawPositionDivergence(labelPosition, 8, ltxImg, posX, posY, (x,y) => drawFunctionLatex(x,y,ltxImg)) + } + let ltxLabel = getLatexFunction(); + if(ltxLabel != "") + canvas.renderLatexImage(ltxLabel, this.color, drawLblCb.bind(this)) + } else { + // Without latex + let text = getTextFunction() + ctx.font = `${canvas.textsize}px sans-serif` + this.drawPositionDivergence(labelPosition, 4, canvas.measureText(ctx, text), posX, posY, (x,y) => drawFunctionText(x,y,text)) + } + } + toString() { return this.name; } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js index b1a98b8..44dc1f4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js @@ -81,7 +81,7 @@ class Function extends Common.ExecutableObject { return `${Latex.variable(this.name)}:\\begin{array}{llll}${this.definitionDomain.latexMarkup}\\textrm{ } & \\rightarrow & \\textrm{ }${this.destinationDomain.latexMarkup}\\\\ x\\textrm{ } & \\mapsto & \\textrm{ }${this.expression.latexMarkup}\\end{array}` } else { - return `\\begin{array}{l}${Latex.variable(this.name)}(x) = ${this.expression.latexMarkup}\\\\ textD_{${this.name}} = ${this.definitionDomain.latexMarkup}\\end{array}` + return `\\begin{array}{l}${Latex.variable(this.name)}(x) = ${this.expression.latexMarkup}\\\\ D_{${this.name}} = ${this.definitionDomain.latexMarkup}\\end{array}` } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js index e81c1a3..56c6fe4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js @@ -22,27 +22,14 @@ .import "../objects.js" as Objects .import "../mathlib.js" as MathLib .import "../parameters.js" as P +.import "../math/latex.js" as Latex + class XCursor extends Common.DrawableObject { static type(){return 'X Cursor'} static displayType(){return qsTr('X Cursor')} static displayTypeMultiple(){return qsTr('X Cursors')} - /*static properties() { - return { - 'x': 'Expression', - 'targetElement': new P.ObjectType('ExecutableObject'), - 'labelPosition': new P.Enum('left', 'right'), - 'approximate': 'boolean', - 'rounding': 'number', - 'displayStyle': new P.Enum( - '— — — — — — —', - '⸺⸺⸺⸺⸺⸺', - '• • • • • • • • • •' - ), - 'targetValuePosition' : new P.Enum('Next to target', 'With label', 'Hidden') - } - }*/ static properties() {return { [QT_TRANSLATE_NOOP('prop','x')]: 'Expression', [QT_TRANSLATE_NOOP('prop','targetElement')]: new P.ObjectType('ExecutableObject'), @@ -87,6 +74,13 @@ class XCursor extends Common.DrawableObject { return `${this.name} = ${this.x.toString()}\n${this.getTargetValueLabel()}` } + getLatexString() { + if(this.targetElement == null) return `${Latex.variable(this.name)} = ${this.x.latexMarkup}` + return `\\begin{array}{l} + ${Latex.variable(this.name)} = ${this.x.latexMarkup} \\\\ + ${this.getTargetValueLatexLabel()}` + } + getTargetValueLabel() { var t = this.targetElement var approx = '' @@ -98,6 +92,18 @@ class XCursor extends Common.DrawableObject { (this.approximate ? ' ≈ ' + approx : '') } + getTargetValueLatexLabel() { + var t = this.targetElement + var approx = '' + if(this.approximate) { + approx = t.execute(this.x.execute()) + approx = approx.toPrecision(this.rounding + Math.round(approx).toString().length) + } + let simpl = t.simplify(this.x.toEditableString()) + return `${Latex.variable(t.name)}(${Latex.variable(this.name)}) = ${simpl.tokens ? Latex.expression(simpl.tokens) : simpl}` + + (this.approximate ? ' \\simeq ' + approx : '') + } + getLabel() { switch(this.labelContent) { case 'name': @@ -118,8 +124,28 @@ class XCursor extends Common.DrawableObject { } } + getLatexLabel() { + switch(this.labelContent) { + case 'name': + return Latex.variable(this.name) + break; + case 'name + value': + switch(this.targetValuePosition) { + case 'Next to target': + case 'Hidden': + return `${Latex.variable(this.name)} = ${this.x.latexMarkup}` + break; + case 'With label': + return this.getLatexString() + break; + } + case 'null': + return '' + } + } + draw(canvas, ctx) { - var xpos = canvas.x2px(this.x.execute()) + let xpos = canvas.x2px(this.x.execute()) switch(this.displayStyle) { case '— — — — — — —': var dashPxSize = 10 @@ -139,52 +165,18 @@ class XCursor extends Common.DrawableObject { break; } - // Label - var text = this.getLabel() - ctx.font = `${canvas.textsize}px sans-serif` - var textSize = canvas.measureText(ctx, text) - - switch(this.labelPosition) { - case 'left': - case 'above-left': - case 'below-left': - case 'below': - case 'above': - canvas.drawVisibleText(ctx, text, xpos-textSize.width-5, textSize.height+5) - break; - case 'right': - case 'above-right': - case 'below-right': - canvas.drawVisibleText(ctx, text, xpos+5, textSize.height+5) - break; - } + // Drawing label at the top of the canvas. + this.drawLabel(canvas, ctx, this.labelPosition, xpos, 0, false, null, null, + (x,y,ltxImg) => canvas.drawVisibleImage(ctx, ltxImg.source, x, 5, ltxImg.width, ltxImg.height), + (x,y,text) => canvas.drawVisibleText(ctx, text, x, textSize.height+5)) + // Drawing label at the position of the target element. if(this.targetValuePosition == 'Next to target' && this.targetElement != null) { - var text = this.getTargetValueLabel() - var textSize = canvas.measureText(ctx, text) - var ypox = canvas.y2px(this.targetElement.execute(this.x.execute())) - switch(this.labelPosition) { - case 'left': - case 'below': - case 'above': - canvas.drawVisibleText(ctx, text, xpos-textSize.width-5, ypox+textSize.height) - break; - case 'above-left': - canvas.drawVisibleText(ctx, text, xpos-textSize.width-5, ypox+textSize.height+12) - break; - case 'below-left': - canvas.drawVisibleText(ctx, text, xpos-textSize.width-5, ypox+textSize.height-12) - break; - case 'right': - canvas.drawVisibleText(ctx, text, xpos+5, ypox+textSize.height) - break; - case 'above-right': - canvas.drawVisibleText(ctx, text, xpos+5, ypox+textSize.height+12) - break; - case 'below-right': - canvas.drawVisibleText(ctx, text, xpos+5, ypox+textSize.height-12) - break; - } + let ypos = canvas.y2px(this.targetElement.execute(this.x.execute())) + this.drawLabel(canvas, ctx, this.labelPosition, xpos, ypos, false, + this.getTargetValueLatexLabel.bind(this), this.getTargetValueLabel.bind(this), + (x,y,ltxImg) => canvas.drawVisibleImage(ctx, ltxImg.source, x, y, ltxImg.width, ltxImg.height), + (x,y,text) => canvas.drawVisibleText(ctx, text, x, y)) } } } From 7120e3a781f3665ed88dafaa144b2a4b59db70fa Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 7 Mar 2022 17:25:30 +0100 Subject: [PATCH 21/26] Fixing timeout on build. --- LogarithmPlotter/util/latex.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index 7822f49..f0a76e0 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -26,6 +26,7 @@ from tempfile import TemporaryDirectory from subprocess import Popen, TimeoutExpired, PIPE from platform import system from shutil import which +from sys import argv """ Searches for a valid Latex and DVIPNG (http://savannah.nongnu.org/projects/dvipng/) @@ -67,9 +68,15 @@ class Latex(QObject): Checks if the current latex installation is valid. """ if LATEX_PATH is None: - QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "No Latex installation found.\nIf you already have a latex distribution installed, make sure it's installed on your path.\nOtherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/.")) + if "--test-build" in argv: + print("No Latex installation found.") + else: + QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "No Latex installation found.\nIf you already have a latex distribution installed, make sure it's installed on your path.\nOtherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/.")) elif DVIPNG_PATH is None: - QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "DVIPNG was not found. Make sure you include it from your Latex distribution.")) + if "--test-build" in argv: + print("DVIPNG not found.") + else: + QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "DVIPNG was not found. Make sure you include it from your Latex distribution.")) @Property(bool) def latexSupported(self): From 27759362cb1035ad235afca9b38c9c8e5f638477 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 7 Mar 2022 20:28:50 +0100 Subject: [PATCH 22/26] Toggle for latex setting --- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 17 +++++++++++++++++ .../ad5001/LogarithmPlotter/LogGraphCanvas.qml | 7 ++++--- .../LogarithmPlotter/Popup/GreetScreen.qml | 18 ++++++++++++++++-- .../ad5001/LogarithmPlotter/js/math/latex.js | 5 +++++ .../ad5001/LogarithmPlotter/js/objs/common.js | 11 ++++++----- .../ad5001/LogarithmPlotter/js/objs/xcursor.js | 4 ++-- LogarithmPlotter/util/config.py | 1 + 7 files changed, 51 insertions(+), 12 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 194b058..7e5ef9c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -22,6 +22,8 @@ import QtQuick.Dialogs 1.3 import eu.ad5001.MixedMenu 1.1 import "js/objects.js" as Objects import "js/historylib.js" as HistoryLib +import "js/math/latex.js" as Latex + /*! \qmltype AppMenuBar @@ -139,6 +141,21 @@ MenuBar { onTriggered: Helper.setSettingBool("reset_redo_stack", checked) icon.name: 'timeline' } + + Action { + id: enableLatexSetting + text: qsTr("Enable LaTeX rendering") + checkable: true + checked: Helper.getSettingBool("enable_latex") + onTriggered: { + Helper.setSettingBool("enable_latex", checked) + Latex.enabled = checked + drawCanvas.requestPaint() + } + icon.name: 'Expression' + + Component.onCompleted: Latex.enabled = checked + } } Menu { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 2e50d88..e35950a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -355,10 +355,11 @@ Canvas { Return format: dictionary {"width": width, "height": height} */ function measureText(ctx, text) { - var theight = 0 - var twidth = 0 + let theight = 0 + let twidth = 0 + let defaultHeight = ctx.measureText("M").width // Approximate but good enough! text.split("\n").forEach(function(txt, i){ - theight += canvas.textsize + theight += defaultHeight if(ctx.measureText(txt).width > twidth) twidth = ctx.measureText(txt).width }) return {'width': twidth, 'height': theight} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index e99cd17..15c1587 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -18,6 +18,7 @@ import QtQuick 2.12 import QtQuick.Controls 2.12 +import "../js/math/latex.js" as Latex /*! \qmltype GreetScreen @@ -101,7 +102,7 @@ Popup { text: qsTr('Check for updates on startup (requires online connectivity)') onClicked: { Helper.setSettingBool("check_for_updates", checked) - checkForUpdatesMenuSetting.checked = checked + //checkForUpdatesMenuSetting.checked = checked } } @@ -113,7 +114,20 @@ Popup { text: qsTr('Reset redo stack when a new action is added to history') onClicked: { Helper.setSettingBool("reset_redo_stack", checked) - resetRedoStackMenuSetting.checked = checked + //resetRedoStackMenuSetting.checked = checked + } + } + + CheckBox { + id: enableLatexSetting + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: resetRedoStackSetting.bottom + checked: Helper.getSettingBool("enable_latex") + text: qsTr('Enable LaTeX rendering') + onClicked: { + Helper.setSettingBool("enable_latex", checked) + Latex.enabled = checked + drawCanvas.requestPaint() } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index d5b30e6..4c57b07 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -21,6 +21,11 @@ .import "../expr-eval.js" as ExprEval +/** + * true if latex has been enabled by the user, false otherwise. + */ +var enabled = false + /** * Puts element within parenthesis. * diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index 956ecf6..3864b2f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -279,7 +279,7 @@ class DrawableObject { * @param {function|null} getLatexFunction - Function (no argument) to get the latex markup to be displayed * @param {function|null} getTextFunction - Function (no argument) to get the text to be displayed * @param {function|null} drawFunctionLatex - Function (x,y,imageData) to display the latex image - * @param {function|null} drawFunctionText - Function (x,y,text) to display the text + * @param {function|null} drawFunctionText - Function (x,y,text,textSize) to display the text */ drawLabel(canvas, ctx, labelPosition, posX, posY, forceText = false, getLatexFunction = null, getTextFunction = null, drawFunctionLatex = null, drawFunctionText = null) { @@ -291,13 +291,13 @@ class DrawableObject { if(drawFunctionLatex == null) drawFunctionLatex = (x,y,ltxImg) => canvas.drawVisibleImage(ctx, ltxImg.source, x, y, ltxImg.width, ltxImg.height) if(drawFunctionText == null) - drawFunctionText = (x,y,text) => canvas.drawVisibleText(ctx, text, x, textSize.height+5) + drawFunctionText = (x,y,text,textSize) => canvas.drawVisibleText(ctx, text, x, y+textSize.height) // Positioned from left bottom // Drawing the label let offset - if(!forceText && true) { // TODO: Check for user setting with Latex. + if(!forceText && Latex.enabled) { // TODO: Check for user setting with Latex. // With latex let drawLblCb = function(canvas, ctx, ltxImg) { - this.drawPositionDivergence(labelPosition, 8, ltxImg, posX, posY, (x,y) => drawFunctionLatex(x,y,ltxImg)) + this.drawPositionDivergence(labelPosition, 8+ctx.lineWidth/2, ltxImg, posX, posY, (x,y) => drawFunctionLatex(x,y,ltxImg)) } let ltxLabel = getLatexFunction(); if(ltxLabel != "") @@ -306,7 +306,8 @@ class DrawableObject { // Without latex let text = getTextFunction() ctx.font = `${canvas.textsize}px sans-serif` - this.drawPositionDivergence(labelPosition, 4, canvas.measureText(ctx, text), posX, posY, (x,y) => drawFunctionText(x,y,text)) + let textSize = canvas.measureText(ctx, text) + this.drawPositionDivergence(labelPosition, 8+ctx.lineWidth/2, textSize, posX, posY, (x,y) => drawFunctionText(x,y,text,textSize)) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js index 56c6fe4..52c989f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js @@ -168,7 +168,7 @@ class XCursor extends Common.DrawableObject { // Drawing label at the top of the canvas. this.drawLabel(canvas, ctx, this.labelPosition, xpos, 0, false, null, null, (x,y,ltxImg) => canvas.drawVisibleImage(ctx, ltxImg.source, x, 5, ltxImg.width, ltxImg.height), - (x,y,text) => canvas.drawVisibleText(ctx, text, x, textSize.height+5)) + (x,y,text,textSize) => canvas.drawVisibleText(ctx, text, x, textSize.height+5)) // Drawing label at the position of the target element. if(this.targetValuePosition == 'Next to target' && this.targetElement != null) { @@ -176,7 +176,7 @@ class XCursor extends Common.DrawableObject { this.drawLabel(canvas, ctx, this.labelPosition, xpos, ypos, false, this.getTargetValueLatexLabel.bind(this), this.getTargetValueLabel.bind(this), (x,y,ltxImg) => canvas.drawVisibleImage(ctx, ltxImg.source, x, y, ltxImg.width, ltxImg.height), - (x,y,text) => canvas.drawVisibleText(ctx, text, x, y)) + (x,y,text,textSize) => canvas.drawVisibleText(ctx, text, x, y+textSize.height)) } } } diff --git a/LogarithmPlotter/util/config.py b/LogarithmPlotter/util/config.py index ce59163..ecaa214 100644 --- a/LogarithmPlotter/util/config.py +++ b/LogarithmPlotter/util/config.py @@ -26,6 +26,7 @@ DEFAULT_SETTINGS = { "check_for_updates": True, "reset_redo_stack": True, "last_install_greet": "0", + "enable_latex": True } # Create config directory From 3e7b36a4202c5816e9c40ec9f78ae2340f49c5e3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 7 Mar 2022 20:40:37 +0100 Subject: [PATCH 23/26] Changing version to v0.2.0 instead of v0.1.9 Due to Latex being a big change. --- LogarithmPlotter/__init__.py | 2 +- linux/debian/control | 2 +- scripts/package-macosx.sh | 2 +- snapcraft.yaml | 2 +- win/installer.nsi | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index 9a008ad..69c5368 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -17,7 +17,7 @@ """ from shutil import which -__VERSION__ = "0.1.9" +__VERSION__ = "0.2.0" is_release = False diff --git a/linux/debian/control b/linux/debian/control index 6379384..1f05813 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -1,6 +1,6 @@ Package: logarithmplotter Source: logarithmplotter -Version: 0.1.9 +Version: 0.2.0 Architecture: all Maintainer: Ad5001 Depends: python3, python3-pip, qml-module-qtquick-controls2 (>= 5.12.0), qml-module-qtmultimedia (>= 5.12.0), qml-module-qtgraphicaleffects (>= 5.12.0), qml-module-qtquick2 (>= 5.12.0), qml-module-qtqml-models2 (>= 5.12.0), qml-module-qtquick-controls (>= 5.12.0), python3-pyside2.qtcore (>= 5.12.0), python3-pyside2.qtqml (>= 5.12.0), python3-pyside2.qtgui (>= 5.12.0), python3-pyside2.qtquick (>= 5.12.0), python3-pyside2.qtwidgets (>= 5.12.0), python3-pyside2.qtmultimedia (>= 5.12.0), python3-pyside2.qtnetwork (>= 5.12.0), texlive-latex-base, dvipng diff --git a/scripts/package-macosx.sh b/scripts/package-macosx.sh index c61cfcf..070a164 100644 --- a/scripts/package-macosx.sh +++ b/scripts/package-macosx.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." -VERSION=0.1.9 +VERSION=0.2.0 title="LogarithmPlotter v${VERSION} Setup" finalDMGName="LogarithmPlotter-v${VERSION}-setup.dmg" applicationName=LogarithmPlotter diff --git a/snapcraft.yaml b/snapcraft.yaml index 49ba0e7..fa09925 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,6 +1,6 @@ name: logarithmplotter title: LogarithmPlotter -version: '0.1.9' +version: '0.2.0' summary: 2D logarithmic-scaled plotter software to create asymptotic Bode plots confinement: strict base: core20 diff --git a/win/installer.nsi b/win/installer.nsi index 6b67417..1d2c260 100644 --- a/win/installer.nsi +++ b/win/installer.nsi @@ -11,7 +11,7 @@ Unicode True !define PROG_ID "LogarithmPlotter.File.1" !define DEV_NAME "Ad5001" !define WEBSITE "https://apps.ad5001.eu/logarithmplotter" -!define VERSION_SHORT "0.1.9" +!define VERSION_SHORT "0.2.0" !define APP_VERSION "${VERSION_SHORT}.0" !define COPYRIGHT "Ad5001 (c) 2022" !define DESCRIPTION "Create graphs with logarithm scales." From 86f3399a539b1670913448afb9f45f538fa08be9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 9 Mar 2022 00:28:42 +0100 Subject: [PATCH 24/26] Fixing a lot of snap issues, updating translations - Files are now properly opened in snapcraft - Added latex dependencies to snapcraft (tho it's buggy atm) - Added changelog to snapcraft --- LogarithmPlotter/i18n/lp_de.ts | 115 ++++++++------ LogarithmPlotter/i18n/lp_en.ts | 115 ++++++++------ LogarithmPlotter/i18n/lp_es.ts | 145 ++++++++++-------- LogarithmPlotter/i18n/lp_fr.ts | 115 ++++++++------ LogarithmPlotter/i18n/lp_hu.ts | 137 +++++++++-------- LogarithmPlotter/i18n/lp_nb_NO.ts | 145 ++++++++++-------- LogarithmPlotter/i18n/lp_template.ts | 145 ++++++++++-------- .../launcher/launch-logarithmplotter | 12 +- setup.py | 2 +- snapcraft.yaml | 10 +- 10 files changed, 531 insertions(+), 410 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index f6184d1..27f5bca 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -33,112 +33,117 @@ AppMenuBar - + &File &Datei - + &Load... &Laden… - + &Save &Speichern - + Save &As... Speichern &Unter… - + &Quit &Ausfahrt - + &Edit &Bearbeiten - + &Undo &Lösen - + &Redo &Wiederherstellen - + &Copy plot Grafik &Kopieren - + &Create &Erstellen - + &Settings &Einstellungen - + Check for updates on startup Beim Starten auf Updates prüfen - + Reset redo stack automaticly Wiederherstellen-Stapel automatisch zurücksetzen - + + Enable LaTeX rendering + + + + &Help &Hilfe - + &Source code &Quellcode - + &Report a bug Fehler &Melden - + &User manual &Benutzerhandbuch - + &Changelog &Changelog - + &Help translating! &Hilfe beim Übersetzen! - + &About &Übrigens - + Save unsaved changes? Änderungen speichern? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Diese Grafik enthält ungespeicherte Änderungen. Dadurch gehen alle ungespeicherten Daten verloren. Fortfahren? @@ -211,44 +216,49 @@ GreetScreen - + Welcome to LogarithmPlotter Willkommen bei LogarithmPlotter - + Version %1 Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Nehmen Sie sich ein paar Sekunden Zeit, um LogarithmPlotter zu konfigurieren. Diese Einstellungen können jederzeit über das Menü "Einstellungen" geändert werden. - + Check for updates on startup (requires online connectivity) Beim Start nach Updates suchen (Online-Verbindung erforderlich) - + Reset redo stack when a new action is added to history Redo-Stapel zurücksetzen, wenn eine neue Aktion zur Historie hinzugefügt wird - + + Enable LaTeX rendering + + + + User manual Benutzerhandbuch - + Changelog Changelog - + Done Schließen @@ -548,6 +558,11 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… + + + If you have latex enabled, you can use use latex markup in between $$ to create equations. + + control @@ -659,19 +674,19 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -680,7 +695,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -864,8 +879,8 @@ Please make sure your latex installation is correct and report a bug if so. - - + + labelPosition Position des Etiketts @@ -930,14 +945,14 @@ Please make sure your latex installation is correct and report a bug if so. - - + + x X - + y Y @@ -952,37 +967,37 @@ Please make sure your latex installation is correct and report a bug if so.Wahrscheinlichkeiten - + text Inhalt - + disableLatex - + targetElement Zielobjekt - + approximate Ungefähren Wert anzeigen - + rounding Rundung - + displayStyle Stil - + targetValuePosition Wertposition des Ziels @@ -1048,12 +1063,12 @@ Please make sure your latex installation is correct and report a bug if so. text - + Text Text - + Texts Texte @@ -1099,12 +1114,12 @@ Please make sure your latex installation is correct and report a bug if so. xcursor - + X Cursor X Zeiger - + X Cursors X Zeiger diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index f74aba6..e7e90ae 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -33,112 +33,117 @@ AppMenuBar - + &File &File - + &Load... &Open… - + &Save &Save - + Save &As... Save &As… - + &Quit &Quit - + &Edit &Edit - + &Undo &Undo - + &Redo &Redo - + &Copy plot &Copy plot - + &Create &Create - + &Settings &Settings - + Check for updates on startup Check for updates on startup - + Reset redo stack automaticly Reset redo stack automatically - + + Enable LaTeX rendering + + + + &Help &Help - + &Source code &Source code - + &Report a bug &Report a bug - + &User manual &User manual - + &Changelog &Changelog - + &Help translating! &Help translating! - + &About &About - + Save unsaved changes? Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -211,44 +216,49 @@ GreetScreen - + Welcome to LogarithmPlotter Welcome to LogarithmPlotter - + Version %1 Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history Reset redo stack when a new action is added to history - + + Enable LaTeX rendering + + + + User manual User manual - + Changelog Changelog - + Done Done @@ -548,6 +558,11 @@ These settings can be changed at any time from the "Settings" menu.Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… + + + If you have latex enabled, you can use use latex markup in between $$ to create equations. + + control @@ -659,7 +674,7 @@ These settings can be changed at any time from the "Settings" menu. latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -668,12 +683,12 @@ If you already have a latex distribution installed, make sure it's installe Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -686,7 +701,7 @@ Process '{}' ended with a non-zero return code {}: Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -873,8 +888,8 @@ Please make sure your latex installation is correct and report a bug if so. - - + + labelPosition Label position @@ -939,14 +954,14 @@ Please make sure your latex installation is correct and report a bug if so. - - + + x X - + y Y @@ -961,37 +976,37 @@ Please make sure your latex installation is correct and report a bug if so.Probabilities list - + text Content - + disableLatex Disable latex rendering for this text - + targetElement Object to target - + approximate Show approximate value - + rounding Rounding - + displayStyle Display style - + targetValuePosition Target's value position @@ -1057,12 +1072,12 @@ Please make sure your latex installation is correct and report a bug if so. text - + Text Text - + Texts Texts @@ -1108,12 +1123,12 @@ Please make sure your latex installation is correct and report a bug if so. xcursor - + X Cursor X Cursor - + X Cursors X Cursors diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 4af05f8..d17ef46 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -33,112 +33,117 @@ AppMenuBar - + &File &Archivo - + &Load... &Abrir… - + &Save &Guardar - + Save &As... Guardar &como… - + &Quit &Salida - + &Edit &Editar - + &Undo &Cancelar - + &Redo &Reiniciar - + &Copy plot &Copiar el gráfico - + &Create &Crear - + &Settings &Ajustes - + Check for updates on startup - + Reset redo stack automaticly - - - &Help - - - &Source code - - - - - &Report a bug - - - - - &User manual + Enable LaTeX rendering + &Help + + + + + &Source code + + + + + &Report a bug + + + + + &User manual + + + + &Changelog - + &Help translating! - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -211,43 +216,48 @@ GreetScreen - + Welcome to LogarithmPlotter - + Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history - - User manual - - - - - Changelog + + Enable LaTeX rendering + User manual + + + + + Changelog + + + + Done @@ -547,6 +557,11 @@ These settings can be changed at any time from the "Settings" menu.Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... + + + If you have latex enabled, you can use use latex markup in between $$ to create equations. + + control @@ -631,19 +646,19 @@ These settings can be changed at any time from the "Settings" menu. latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -652,7 +667,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -836,8 +851,8 @@ Please make sure your latex installation is correct and report a bug if so. - - + + labelPosition @@ -902,14 +917,14 @@ Please make sure your latex installation is correct and report a bug if so. - - + + x - + y @@ -924,37 +939,37 @@ Please make sure your latex installation is correct and report a bug if so. - + text - + disableLatex - + targetElement - + approximate - + rounding - + displayStyle - + targetValuePosition @@ -1016,12 +1031,12 @@ Please make sure your latex installation is correct and report a bug if so. text - + Text - + Texts @@ -1067,12 +1082,12 @@ Please make sure your latex installation is correct and report a bug if so. xcursor - + X Cursor - + X Cursors diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 6993ce0..32830c4 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -33,113 +33,118 @@ AppMenuBar - + &File &Fichier - + &Load... &Ouvrir… - + &Save &Sauvegarder - + Save &As... Sauvegarde &Sous… - + &Quit &Quitter - + &Edit &Édition - + &Undo &Annuler - + &Redo &Rétablir - + &Copy plot &Copier le graphe - + &Create &Créer - + &Settings &Paramètres - + Check for updates on startup Vérifier la présence de mise à jour au démarrage - + Reset redo stack automaticly Légèrement long, et pas forcément très compréhensible. Réinitialiser la pile d'action "Rétablir" automatiquement - + + Enable LaTeX rendering + + + + &Help &Aide - + &Source code &Code source - + &Report a bug &Rapport de bug - + &User manual Manuel d'&utilisation - + &Changelog &Historique des modifications - + &Help translating! &Aider à la traduction ! - + &About &À propos - + Save unsaved changes? Sauvegarder les modifications ? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ce graphe contient des modifications non sauvegardées. En faisant cela, toutes les données non sauvegardées seront perdues. Continuer ? @@ -213,34 +218,39 @@ GreetScreen - + Welcome to LogarithmPlotter Bienvenue sur LogarithmPlotter - + Version %1 Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Prenez quelques secondes pour configurer LogarithmPlotter. Ces paramètres peuvent être modifiés à tout moment à partir du menu "Paramètres". - + + Enable LaTeX rendering + + + + User manual Manuel d'utilisation - + Changelog Historique des modifications - + Done Fermer @@ -251,12 +261,12 @@ These settings can always be changed at any time from the "Settings" m These settings can always be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) Vérifier les mises à jour au démarrage (nécessite d'être connecté à internet) - + Reset redo stack when a new action is added to history Réinitialiser la pile d'action "Rétablir" lorsqu'une nouvelle action est ajoutée à l'historique @@ -557,6 +567,11 @@ These settings can always be changed at any time from the "Settings" m Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… + + + If you have latex enabled, you can use use latex markup in between $$ to create equations. + + control @@ -668,7 +683,7 @@ These settings can always be changed at any time from the "Settings" m latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -677,12 +692,12 @@ Si vous avez déjà installé une distribution Latex, assurez-vous qu'elle Sinon, vous pouvez télécharger une distribution Latex comme TeX Live à l'adresse https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution Latex. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -695,7 +710,7 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de latex est correcte et signalez un bogue si c'est le cas. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -882,8 +897,8 @@ Vérifiez que votre installation de latex est correcte et signalez un bogue si c - - + + labelPosition Position de l'étiquette @@ -948,14 +963,14 @@ Vérifiez que votre installation de latex est correcte et signalez un bogue si c - - + + x X - + y Y @@ -970,37 +985,37 @@ Vérifiez que votre installation de latex est correcte et signalez un bogue si c Liste de probabilités - + text Contenu - + disableLatex Désactiver le rendu latex pour ce texte - + targetElement Objet à cibler - + approximate Afficher la valeur approximative - + rounding Arrondi - + displayStyle Style d'affichage - + targetValuePosition Position de la valeur de la cible @@ -1066,12 +1081,12 @@ Vérifiez que votre installation de latex est correcte et signalez un bogue si c text - + Text Texte - + Texts Textes @@ -1117,12 +1132,12 @@ Vérifiez que votre installation de latex est correcte et signalez un bogue si c xcursor - + X Cursor Curseur X - + X Cursors Curseurs X diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index e9d34a2..91ba500 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -33,112 +33,117 @@ AppMenuBar - + &File &Fájl - + &Load... &Betöltés… - + &Save &Mentés - + Save &As... Me&ntés másként… - + &Quit &Kilépés - + &Edit S&zerkesztés - + &Undo &Visszavonás - + &Redo &Ismétlés - + &Copy plot Ábra má&solása - + &Create &Létrehozás - + &Settings &Beállítások - + Check for updates on startup Frissítések keresése indításkor - + Reset redo stack automaticly Ismétlési verem önműködő visszaállítása - - - &Help - &Súgó - - &Source code - &Forráskód - - - - &Report a bug - &Hiba bejelentése - - - - &User manual + Enable LaTeX rendering + &Help + &Súgó + + + + &Source code + &Forráskód + + + + &Report a bug + &Hiba bejelentése + + + + &User manual + + + + &Changelog &Változásnapló - + &Help translating! &Segítség a fordításban! - + &About &Névjegy - + Save unsaved changes? Menti a változtatásokat? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ez az ábra nem mentett változtatásokat tartalmaz. Ezzel az összes nem mentett adat elveszik. Folytatja? @@ -211,44 +216,49 @@ GreetScreen - + Welcome to LogarithmPlotter Isten hozott a LogarithmPlotter! - + Version %1 %1 verzió - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Szánjon néhány másodpercet a LogarithmPlotter beállításához. Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - + Check for updates on startup (requires online connectivity) Frissítések keresése indításkor (online kapcsolat szükséges) - + Reset redo stack when a new action is added to history Ismétlési verem alaphelyzet visszaállítása, ha új műveletet adnak az előzményekhez - + + Enable LaTeX rendering + + + + User manual - + Changelog Változásnapló - + Done Kész @@ -548,6 +558,11 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … + + + If you have latex enabled, you can use use latex markup in between $$ to create equations. + + control @@ -655,19 +670,19 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -676,7 +691,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -860,8 +875,8 @@ Please make sure your latex installation is correct and report a bug if so. - - + + labelPosition Címke helyzete @@ -926,14 +941,14 @@ Please make sure your latex installation is correct and report a bug if so. - - + + x X - + y Y @@ -948,37 +963,37 @@ Please make sure your latex installation is correct and report a bug if so.Valószínűségek listája - + text Tartalom - + disableLatex - + targetElement Tárgycél - + approximate Hozzávetőleges érték megjelenítése - + rounding Kerekítés - + displayStyle Megjelenítési stílus - + targetValuePosition Cél értékpozíciója @@ -1040,12 +1055,12 @@ Please make sure your latex installation is correct and report a bug if so. text - + Text Szöveg - + Texts Szövegek @@ -1091,12 +1106,12 @@ Please make sure your latex installation is correct and report a bug if so. xcursor - + X Cursor X kurzor - + X Cursors X kurzorok diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 4426396..85ade3d 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -33,112 +33,117 @@ AppMenuBar - + &File &Fil - + &Load... &Last inn … - + &Save &Lagre - + Save &As... Lagre &som … - + &Quit &Avslutt - + &Edit &Rediger - + &Undo &Angre - + &Redo &Gjenta - + &Copy plot &Kopier plott - + &Create &Opprett - + &Settings &Innstillinger - + Check for updates on startup Se etter nye versjoner ved programstart - + Reset redo stack automaticly Tilbakestill angrehistorikk automatisk - - - &Help - &Hjelp - - &Source code - - - - - &Report a bug - - - - - &User manual + Enable LaTeX rendering + &Help + &Hjelp + + + + &Source code + + + + + &Report a bug + + + + + &User manual + + + + &Changelog - + &Help translating! - + &About &Om - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -211,44 +216,49 @@ GreetScreen - + Welcome to LogarithmPlotter Velkommen til LogarithmPlotter - + Version %1 Versjon %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Sett opp LogarithmPlotter. Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + Check for updates on startup (requires online connectivity) Se etter nye versjoner ved programstart. (Krever tilkobling til Internett.) - + Reset redo stack when a new action is added to history Tilbakesitll angrehistorikk når en ny handling legges til - - User manual - - - - - Changelog + + Enable LaTeX rendering + User manual + + + + + Changelog + + + + Done @@ -548,6 +558,11 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... + + + If you have latex enabled, you can use use latex markup in between $$ to create equations. + + control @@ -655,19 +670,19 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -676,7 +691,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -860,8 +875,8 @@ Please make sure your latex installation is correct and report a bug if so. - - + + labelPosition @@ -926,14 +941,14 @@ Please make sure your latex installation is correct and report a bug if so. - - + + x - + y @@ -948,37 +963,37 @@ Please make sure your latex installation is correct and report a bug if so. - + text - + disableLatex - + targetElement - + approximate - + rounding - + displayStyle - + targetValuePosition @@ -1040,12 +1055,12 @@ Please make sure your latex installation is correct and report a bug if so. text - + Text Tekst - + Texts Tekster @@ -1091,12 +1106,12 @@ Please make sure your latex installation is correct and report a bug if so. xcursor - + X Cursor X-peker - + X Cursors X-pekere diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 7099743..aacd4e5 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -33,112 +33,117 @@ AppMenuBar - + &File - + &Load... - + &Save - + Save &As... - + &Quit - + &Edit - + &Undo - + &Redo - + &Copy plot - + &Create - + &Settings - + Check for updates on startup - + Reset redo stack automaticly - - - &Help - - - &Source code - - - - - &Report a bug - - - - - &User manual + Enable LaTeX rendering + &Help + + + + + &Source code + + + + + &Report a bug + + + + + &User manual + + + + &Changelog - + &Help translating! - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -211,43 +216,48 @@ GreetScreen - + Welcome to LogarithmPlotter - + Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history - - User manual - - - - - Changelog + + Enable LaTeX rendering + User manual + + + + + Changelog + + + + Done @@ -547,6 +557,11 @@ These settings can be changed at any time from the "Settings" menu.Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... + + + If you have latex enabled, you can use use latex markup in between $$ to create equations. + + control @@ -631,19 +646,19 @@ These settings can be changed at any time from the "Settings" menu. latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -652,7 +667,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -836,8 +851,8 @@ Please make sure your latex installation is correct and report a bug if so. - - + + labelPosition @@ -902,14 +917,14 @@ Please make sure your latex installation is correct and report a bug if so. - - + + x - + y @@ -924,37 +939,37 @@ Please make sure your latex installation is correct and report a bug if so. - + text - + disableLatex - + targetElement - + approximate - + rounding - + displayStyle - + targetValuePosition @@ -1016,12 +1031,12 @@ Please make sure your latex installation is correct and report a bug if so. text - + Text - + Texts @@ -1067,12 +1082,12 @@ Please make sure your latex installation is correct and report a bug if so. xcursor - + X Cursor - + X Cursors diff --git a/linux/snapcraft/launcher/launch-logarithmplotter b/linux/snapcraft/launcher/launch-logarithmplotter index 55fc9b4..d23e4ce 100755 --- a/linux/snapcraft/launcher/launch-logarithmplotter +++ b/linux/snapcraft/launcher/launch-logarithmplotter @@ -10,5 +10,13 @@ set \ # GTK theme integration (we have Qt fetch the GTK theme mirroring the host Qt theme...) #export QT_QPA_PLATFORMTHEME=kde -# Finally run the next part of the command chain -${@} --no-check-for-updates +# Check if the last parameter is a file, and if so, add the argument "--no-checks-for-updates" BEFORE it. +last="${@:$#}" # last parameter +length=$(($#-1)) +args=("${@:1:$length}") # all parameters except the last + +if [ -f "$last" ]; then + ${args} --no-check-for-updates "$last" +else + ${@} --no-check-for-updates +fi diff --git a/setup.py b/setup.py index 20568b5..e3fb347 100644 --- a/setup.py +++ b/setup.py @@ -145,7 +145,7 @@ setuptools.setup( classifiers=CLASSIFIERS, zip_safe=False, - packages=["LogarithmPlotter"], + packages=["LogarithmPlotter", "LogarithmPlotter.util"], package_data={ 'LogarithmPlotter':package_data(), diff --git a/snapcraft.yaml b/snapcraft.yaml index fa09925..9124698 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -79,6 +79,9 @@ parts: source: . stage-packages: - breeze-icon-theme + # Latex dependencies + - texlive-latex-base + - dvipng # Additional dependencies - libxcomposite1 - libxcursor1 @@ -131,7 +134,7 @@ parts: - libxcb-render-util0 - libdouble-conversion3 - libpcre2-16-0 - snapcraft-preload: # Fixes error related to multiprocessing on python. + snapcraft-preload: source: https://github.com/sergiusens/snapcraft-preload.git plugin: cmake cmake-parameters: @@ -142,6 +145,11 @@ parts: - g++-multilib stage-packages: - lib32stdc++6 + changelog: + source: . + plugin: dump + organize: + CHANGELOG.md: lib/python3.8/site-packages/LogarithmPlotter/CHANGELOG.md apps: logarithmplotter: From f77b1ce33135f7b0b7402f19a62f2fd74ea83d2b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 2 Apr 2022 16:39:21 +0200 Subject: [PATCH 25/26] Fixing snapcraft --- .../launcher/launch-logarithmplotter | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/linux/snapcraft/launcher/launch-logarithmplotter b/linux/snapcraft/launcher/launch-logarithmplotter index d23e4ce..7f8b61e 100755 --- a/linux/snapcraft/launcher/launch-logarithmplotter +++ b/linux/snapcraft/launcher/launch-logarithmplotter @@ -8,15 +8,24 @@ set \ -o pipefail # GTK theme integration (we have Qt fetch the GTK theme mirroring the host Qt theme...) +# Currently broken with portals #export QT_QPA_PLATFORMTHEME=kde # Check if the last parameter is a file, and if so, add the argument "--no-checks-for-updates" BEFORE it. -last="${@:$#}" # last parameter -length=$(($#-1)) -args=("${@:1:$length}") # all parameters except the last -if [ -f "$last" ]; then - ${args} --no-check-for-updates "$last" +length=$(($#-1)) + +echo "Len: $length" + +if [ $length -gt 0 ]; then + last="${@:$#}" # last parameter + args=("${@:1:$length}") # all parameters except the last + + if [ -f "$last" ]; then + ${args} --no-check-for-updates "$last" + else + ${@} --no-check-for-updates + fi else ${@} --no-check-for-updates fi From eef42655e5f876e7ec5f5c77e59d79ef13d258c8 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 2 Apr 2022 18:20:04 +0200 Subject: [PATCH 26/26] Trying to fix build --- LogarithmPlotter/util/latex.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index f0a76e0..0ce5b91 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -68,14 +68,12 @@ class Latex(QObject): Checks if the current latex installation is valid. """ if LATEX_PATH is None: - if "--test-build" in argv: - print("No Latex installation found.") - else: + print("No Latex installation found.") + if "--test-build" not in argv: QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "No Latex installation found.\nIf you already have a latex distribution installed, make sure it's installed on your path.\nOtherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/.")) elif DVIPNG_PATH is None: - if "--test-build" in argv: - print("DVIPNG not found.") - else: + print("DVIPNG not found.") + if "--test-build" not in argv: QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "DVIPNG was not found. Make sure you include it from your Latex distribution.")) @Property(bool)