Releases: Saiki77/easy-tikz
Releases · Saiki77/easy-tikz
Release list
3.19.6
Community-directory review pass: resolves every error and warning from the
Obsidian plugin review bot. No new features; one real bug fix fell out of it.
Changed
- Math expressions are now compiled by a built-in parser instead of
new Function. The old compiler passed user expressions tonew Function(JavaScript's cousin ofeval), which flagged the plugin for "dynamic code execution" and made static review impossible. The new recursive-descent parser compiles the same language - numbers,x/y,+ - * / % ^ **, comparisons/ternaries for piecewise functions, all the bare Math names (sin,atan2,min, …), constants (PI,E, …), andMath.foo(...)member access - into plain closures, so no dynamically generated code runs at all. Two side effects are strict improvements:-x^2now parses as-(x^2)(the old compiler rejected it outright), and syntax errors carry positions ("Expected ')' … at position 5"). Verified against a 62-case regression suite covering every built-in template, operator precedence, piecewise logic, and error timing. - Requires Obsidian 1.13.0 or newer (was 1.4.0). The settings tab now uses the declarative settings API - entries appear in Obsidian's settings search - and sliders rely on 1.13's always-visible inline value instead of the deprecated
setDynamicTooltip(). Users on older Obsidian versions keep 3.19.5 viaversions.json. - The editor modal no longer injects a
<style>element. It used to carry a bundled copy of the stylesheet and add it todocument.headon open; thestyles.cssthat ships with the plugin (and that Obsidian loads automatically) is now the single source. Also drops theesbuild-plugin-inline-importbuild dependency and shrinksmain.jsby ~10 KB.
Fixed
- "Save as" template naming now works. Both Save-as buttons called
window.prompt(), which Electron does not implement - the call returned nothing and no template was ever saved on desktop. Replaced with a small in-app naming modal (pre-filled with the expression, Enter to confirm).
Housekeeping
Review-bot compliance details, no behavior changes intended:
- DOM nodes are created with Obsidian's
createEl/createDiv/createSvghelpers instead ofdocument.createElement(NS). - Static inline-style writes replaced with CSS classes (new
.tikz-hiddenutility) or the sanctionedsetCssStyles()helper; the 3D surface pool toggles visibility via the SVGdisplayattribute. Labels that end up inside the exported SVG intentionally keep inline styles so exports survive serialization. setTimeout/requestAnimationFramecalls go throughwindow.for popout-window safety.- NaN checks spelled as
Number.isNaN(x)/Number.isFinite(x)instead ofx !== xself-comparisons. SettingsManager.getValueis typed<T = unknown>(wasany), the lasteslint-disableis gone,TikzSetting.defaultValue/insertTexttakeunknown, and a dozen now-redundant type assertions were dropped.- Toolchain:
tsconfiglib bumped to ES2020 (fixesObject.entries/fromEntriesresolving as error-typed), TypeScript 4.4 → 5.9,obsidiantypings 0.15 → 1.13.
3.19.5
Fixed
- Annotation text now renders LaTeX markup instead of showing it literally. Labels entered on the Annotations tab (2D and 3D, SVG and canvas) were inserted as raw text, so expressions like
$f(x,y,\mu)$showed up with the dollar signs and backslashes still in them. They now run throughstripLatex(), the same helper already used for chart titles. - Expanded
stripLatex()LaTeX coverage. Beyond the original handful of Greek-letter macros, it now expands\frac{}{}and\sqrt[n]{}, converts^/_to Unicode super/subscripts where a mapping exists, resolves a large set of operator/relation/arrow/set-theory symbol macros (\times,\leq,\to,\in, …), special-cases^\circas a degree sign, and strips\left/\rightsizing and$math-mode delimiters. - Axis range fields (xmin/xmax/ymin/ymax/…) rejected every attempt to type a leading
-. The field validated and reverted its value on every keystroke, so the instant you typed-to start a negative bound,Number("-")failed the check and the input was wiped before the next digit landed - negative bounds could only be pasted in, never typed. Validation now only reverts invalid input on blur, matching the pattern already used for the tangent-point field. - All plot text now uses a single consistent font. Axis tick numbers, 3D axis labels, and coordinate/tool labels (2D and 3D, SVG and canvas) previously rendered in the monospace font while the title, annotations, and legend used the regular text font. Everything in the plot itself now uses
var(--font-text). The Code tab's generated-TikZ textarea and the Reference tab's code snippets are unaffected - those display literal source code and stay monospace on purpose. - Annotation cards disappeared from the editor on reopen, even though the labels kept rendering on the graph.
buildAnnotationsTab()had no hydration step - unlike the Functions tab, which seeds a card per saved function, the Annotations tab'saddCard()never accepted a seed and was only ever called blank from the "+ Add label" button. So every fresh modal open (e.g. reopening after Save changes, or clicking a rendered chart to edit it) started with zero cards regardless of saved data; the graph still showed the labels because the renderer readssettings.annotationsdirectly, independent of the UI. Existing annotations are now hydrated into cards on open, and the Text field (which never called.setValue()) now shows its saved value too.
Added
- Custom legend labels for functions. Each function card's Legend toggle now reveals a "Legend label" field; when set, it's used verbatim for the
\addlegendentry{...}in both the exported TikZ and the live SVG preview (which also runs it throughstripLatex()). Leaving it blank keeps the previous auto-generated label derived from the expression. - Real LaTeX rendering (via Obsidian's built-in MathJax) for title, annotation, and legend-label text in the 2D live preview. When one of these fields is a single
$...$or\(...\)wrapped expression, it's now typeset withrenderMath()/finishRenderMath()(the same engine Obsidian uses for$...$in notes) and embedded via<foreignObject>, instead of thestripLatex()Unicode approximation - so\frac{}{},\sqrt[n]{}, matrices, accents (\vec,\hat),\binom{}{}, and anything else valid LaTeX now render correctly instead of degrading to flattened or garbled text. Plain prose, mixed text, and unwrapped macros still use the lightweightstripLatex()path (new file:src/mathlabel.ts). 3D preview and the default (non-custom) legend label derived from a function's expression are unaffected, since raw expression syntax isn't valid LaTeX. - Lock pan/zoom toggle for the 2D preview. New padlock icon in the floating action strip (right edge of the preview). Dragging or scrolling on the canvas silently rewrites xmin/xmax/ymin/ymax, which could undo carefully-tuned axis ranges from an incidental click near the plot (e.g. while dragging an annotation). Locking disables the pan/zoom axis writes without affecting annotation dragging or 3D rotation. Per-session only; resets to unlocked next time the editor opens.
Notes
- MathJax-rendered labels apply to the live preview only. "Copy as SVG" / "Copy as PNG" exports replace them with the
stripLatex()Unicode approximation, since a standalone SVG can't carry MathJax's document-level stylesheet (and<foreignObject>content would break PNG rasterization). - Obsidian loads MathJax lazily; the editor now triggers that load on open and re-renders once it's ready, so
$...$labels typeset correctly even when nothing else in the vault has rendered math yet.
3.19.3
Fixed
- Command palette entry registered. Previously the plugin only added a ribbon icon, so users who hide the ribbon (or just prefer Cmd/Ctrl+P) had no way to launch the editor. Adds an
Easy TikZ: Open editorcommand viaaddCommand({ id: 'open-editor', ... }). Reported in #2 by @playerofgames.
3.19.2
Changed
- Minor wording cleanup across the README, CHANGELOG, release-post templates, marketing card text, and source-file comments. No runtime change.
3.19.1
Changed
- Dropped the
builtin-modulesdev dependency. Replaced with the Node standard-library importimport { builtinModules as builtins } from "node:module"insideesbuild.config.mjs. The package was a thin wrapper around a list Node already exposes; one fewer dependency to audit. Resolves the Obsidian community-plugin validator's "'builtin-modules' should be replaced with an alternative package" warning.
Fixed
- Removed
::-webkit-scrollbarfrom the tab bar styling. The standardscrollbar-width: thinrule already does the job in every modern browser Obsidian ships on; the WebKit-prefixed selectors only customised the colour and added an Obsidian-validator warning about partial support. - Replaced
!importantwith chained-class specificity in the three modal-overriding rules..tikz-modal.tikz-modal { … }and.tikz-modal.tikz-modal .modal-content { … }(0,2,0 / 0,3,0) reliably beat Obsidian's default.modal/.modal-content(0,1,0) selectors without!important, which is the recommended pattern.
3.19.0
Changed
minAppVersionbumped from0.15.0to1.4.0. The plugin's styling relies on CSScolor-mix()(Chromium 111+), the 3D renderer onaspect-ratioandResizeObserver, and the modal on Obsidian'ssetIconLucide icons — all available in Obsidian 1.4 and later. The old floor was vestigial and would have caused the community-plugin submission validator to reject the manifest as incompatible with declared APIs.
Added
docs/submission/directory with everything needed to open the
Community Plugin submission PR againstobsidianmd/obsidian-releases—
step-by-step guide, the exactcommunity-plugins.jsonentry to paste,
and a pre-filled PR description with all the checklist boxes pre-ticked.
Closes the "Could not find or validate a manifest" loop with explicit
troubleshooting for the most common rejections.
3.18.8
Changed
- README + docs refresh. Replaced the stale 2.x screenshots with five SVG-rendered marketing cards (hero, 2D plots, 3D surfaces, inline rendering, composable tools) matching the look of the Easy Git README. Restructured the README around quick-start → plot → tools → inline rendering → export → plugin settings, dropped the redundant Features grid, and added a clear "click any rendered chart to edit" loop description.
3.18.6
Fixed
- Click-to-edit no longer loses your functions. When the modal opened from an inline
easy-tikzchart, the Functions tab created a fresh blank card every time instead of populating cards from the saved state. The chart kept rendering correctly (the persistedfunctionswere still inSettingsManager), but the Expression / y(t) / Tangent-point inputs were empty — so if you touched any field, the now-blank Expression got committed and wiped the function. Fixed both 2D and 3D:addFunctionCard(seed?)accepts a saved function and merges it on top of the defaults.- The Expression, y(t), and Tangent-point inputs now call
setValue(state.…)(they only hadsetPlaceholderbefore). populateFunctionsTabloopssettings.functions/settings.functions3Dand creates one card per saved entry, falling through to a single blank card on a fresh modal.- Fill / Tangent / Parametric reveal their sub-rows when the seed has those toggles on (previously the toggle showed on but the dependent inputs stayed hidden until you flipped it off and back on).
3.18.5
Fixed
- Expressions like
-1*x,2*pi,sin(pi/4),-xnow work in tool coordinate fields.parseCoord(used by every Tools-tab numeric field — vertical/horizontal line, rectangle, circle, segment, brace, 3D point/plane) was runningparseFloatfirst and accepting any prefix that parsed as a number — so-1*xreturned-1,2*pireturned2, etc. The expression evaluator was never reached. Now we evaluate as a math expression first and only fall back toparseFloatif evaluation fails. - "Area between" no longer connects across asymptotes with a diagonal line. When either function went non-finite (or beyond the y-clamp) inside the requested domain,
drawAreaBetweenskipped the bad samples but the resulting polygon still drew a line between the last good point and the next one — visible as a stray diagonal cutting through the plot. The renderer now splits the fill into separate closed polygons, one per contiguous finite segment.
3.18.4
Fixed
- 3D +/− zoom overlay reappears when opening the modal in 3D mode. The overlay's initial
display: nonewas set in its builder, butupdate3DVisibilityhad already run during left-panel construction (before the right-panel overlays existed) so its visibility flip never reached this element. Now the builder readsis3D()directly when creating the overlay, andonOpencallsupdate3DVisibilityone more time after every panel and overlay is built. Click-to-edit on a saved 3D chart now shows the zoom buttons from the first frame.