claude-video-effects
Claude Code용 51가지 영상 효과, 말하는 클립 삽입 후 /effects orbit 입력, 얼굴 추적·머리 뒤 레이어 제공
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
LaTeX equations for Lexxy (the rich text editor for Rails), rendered with MathJax.
• Toolbar button (and Cmd/Ctrl+Shift+E) opens a dialog with a LaTeX input and live preview
• Click any equation to edit it
• Inline (e^{i\pi} + 1 = 0 in a sentence) and display/block modes
• Saved HTML stores the raw LaTeX in a data-latex attribute, so content round-trips cleanly and is typeset again on display pages
Equations are stored in the document (and in what ActionText persists) as:README 전문 보기 ↗LaTeX equations for Lexxy (the rich text editor for Rails), rendered with MathJax.
Cmd/Ctrl+Shift+E) opens a dialog with a LaTeX input and live previewe^{i\pi} + 1 = 0 in a sentence) and display/block modesdata-latex attribute, so content round-trips cleanly and is typeset again on display pagesEquations are stored in the document (and in what ActionText persists) as:
<span class="lexxy-math" data-latex="\frac{a}{b}">\frac{a}{b}</span> <!-- inline -->
<div class="lexxy-math" data-latex="\int_0^1 x\,dx">...</div> <!-- display/block -->
Inside the editor the extension typesets these with the page's MathJax. On a display page, typesetMath (below) does the same thing without an editor. MathJax is host-provided, not bundled: load MathJax v4 (tex-chtml or tex-svg) on any page that uses the editor or displays saved content. The extension also works against MathJax v3, so hosts already loading v3 can upgrade on their own schedule.
This is the whole contract between the editor and anything else that needs to render or process saved equations — MathJax, but also any other script or server-side tool:
<span data-latex="..."> is an inline equation, <div data-latex="..."> is display/block. Tag name is the only signal for inline vs. display; treat it as authoritative.\(...\), $$...$$, \[...\]).data-latex is the one attribute this package relies on surviving sanitization (see the ActionText step below). class="lexxy-math" / lexxy-math--display are presentation only, applied defensively by typesetMath, and are not guaranteed to be present or to survive a sanitizer.Vendor this package (or pin it) and pin lexxy's bare specifier so the extension resolves it:
# config/importmap.rb
pin "lexxy" # from the lexxy gem, per lexxy's install docs
pin "@37signals/lexxy", to: "lexxy.js" # alias used by @fnix/lexxy-mathjax
pin "@fnix/lexxy-mathjax", to: "lexxy-mathjax/index.js" # vendored src/ of this package
# ...pin the files under src/ as well if vendoring, e.g. via pin_all_from
npm install @fnix/lexxy-mathjax @37signals/lexxy
import { configure } from "@37signals/lexxy"
import MathjaxExtension from "@fnix/lexxy-mathjax"
configure({
global: { extensions: [ MathjaxExtension ] }
})
Include the stylesheet (@fnix/lexxy-mathjax/styles, or copy styles/lexxy-mathjax.css into your assets).
<script>
window.MathJax = { output: { displayAlign: "center" } }
</script>
<script defer src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js"></script>
If MathJax is missing, the editor still works and equations show their raw LaTeX.
This package persists raw LaTeX (data-latex) and re-typesets it on every load, so a few v4 changes are worth knowing about before upgrading a host that already has saved content:
mathjax-newcm (New Computer Modern), noticeably lighter than v3's TeX font. Set output: { font: "mathjax-tex" } to keep the old look.\text{...} is now macro-parsed. The textmacros extension ships in all v4 combined components, so a backslash or brace inside \text{} that was inert in v3 can now raise "undefined control sequence" for existing saved equations.\tiny/\Tiny swapped, \large…\Huge shifted by one), so existing content can render at a different size. Opt out with the fontsizev3 TeX package (loader: { load: ["[tex]/fontsizev3"] }, tex: { packages: { "[+]": ["fontsizev3"] } }) if you pin a floating @4 range.tex2chtmlPromise/tex2svgPromise, which is what this package uses, both in the editor and on display pages — "will not become part of the list of math expressions that MathJax knows about in the page", so the explorer never attaches to it. Both createDOM (editor) and typesetMath (display pages) compensate by setting role="math" / aria-label="Equation: ..." on every equation directly, rather than relying on the explorer.If your host has a Content Security Policy, two more v4 behaviours are worth knowing about — both are upstream MathJax behaviour, not something this package can change:
sre/speech-worker.js and three mathmap JSON files. options.enableSpeech, enableBraille and enableEnrichment do not stop this — they only control whether speech is generated once those files have loaded. To actually stop the loading, set options.menuOptions.settings.enrich, .speech and .braille to false.<style> elements (MJX-CHTML-styles, MJX-Menu-styles, others) that can't carry a CSP nonce — see mathjax/MathJax#2665.The equation editor dialog (<lexxy-math-editor>) is styled entirely through CSS custom properties. Set any of these on :root or on an ancestor of the dialog to restyle it — a host that sets none gets exactly the defaults below, unchanged:
| Property | Default | Controls |
|---|---|---|
--lexxy-math-backdrop-color | rgba(0, 0, 0, 0.35) | ::backdrop behind the modal |
--lexxy-math-dialog-bg | Canvas | dialog surface, button faces |
--lexxy-math-dialog-border-color | #d4d4d8 | dialog border |
--lexxy-math-dialog-radius | 0.5rem | dialog corner radius |
--lexxy-math-dialog-shadow | 0 10px 30px rgba(0, 0, 0, 0.15) | dialog drop shadow |
--lexxy-math-text-color | CanvasText | dialog and button text |
--lexxy-math-muted-color | #52525b | the "LaTeX" field label |
--lexxy-math-input-bg | Field | textarea background |
--lexxy-math-input-text-color | FieldText | textarea text |
--lexxy-math-input-border-color | #d4d4d8 | textarea, preview and button borders |
--lexxy-math-input-radius | 0.375rem | textarea, preview and button radius |
--lexxy-math-focus-color | #2563eb | Save button fill, in-editor selection outline |
--lexxy-math-focus-content-color | white | Save button label |
--lexxy-math-error-color | #b91c1c | failed-equation text and dashed outline |
:root {
--lexxy-math-dialog-bg: var(--my-app-surface);
--lexxy-math-dialog-border-color: var(--my-app-border);
--lexxy-math-dialog-radius: var(--my-app-radius-lg);
--lexxy-math-focus-color: var(--my-app-accent);
}
Canvas, CanvasText, Field and FieldText are the browser's own system colors: they track the page's light/dark scheme automatically, so the dialog follows the OS or prefers-color-scheme without any configuration.
--lexxy-math-backdrop-color targets ::backdrop, which only inherits custom properties from its originating element in newer browser engines. On older engines the backdrop falls back to today's rgba(0, 0, 0, 0.35) rather than breaking.
1. Allow data-latex through the server-side sanitizer (ActionText strips unknown attributes when rendering):
# config/initializers/lexxy_mathjax.rb
ActiveSupport.on_load(:action_text_content) do
ActionText::ContentHelper.allowed_attributes += [ "data-latex" ]
end
2. Typeset saved content on display pages. Load MathJax (as above), include the stylesheet, and start the auto-typesetter:
// app/javascript/application.js
import "@fnix/lexxy-mathjax/styles"
import { startMathjaxAutoTypeset } from "@fnix/lexxy-mathjax/typeset"
startMathjaxAutoTypeset()
@fnix/lexxy-mathjax/typeset is a separate entry point from the package's default export: it pulls in neither lexxy nor Lexical, so a display-only page doesn't load the editor. It re-typesets on DOMContentLoaded, turbo:load, turbo:frame-load and turbo:render, skips equations it has already rendered (so repeated Turbo navigations are cheap), and leaves any equation inside a live <lexxy-editor> to the extension.
For manual control — a specific container, a one-off re-render, or Stimulus — call typesetMath directly. It never throws and resolves with a summary:
import { typesetMath } from "@fnix/lexxy-mathjax/typeset"
const { total, typeset, failed, skipped, mathjax } = await typesetMath(document.querySelector(".post-body"))
Options: output ("auto" | "chtml" | "svg", default "auto" — detects whether the host loaded tex-chtml or tex-svg), selector (default "span[data-latex], div[data-latex]" — matches only the persisted format above, never MathJax's own rendered output even if you widen this or pass force: true), force (re-typeset elements already rendered), accessible (default true, adds role="math" / aria-label).
typesetMath shares the same serialization queue as the editor's own typesetting (MathJax's conversion pipeline isn't reentrant), so concurrent calls — including the extra passes startMathjaxAutoTypeset can trigger around a Turbo navigation — run one at a time rather than racing. A call queued behind a large display-page pass waits for that pass to finish; in practice this only matters for the very first pass on a page, since a repeat pass over already-typeset content is cheap.
With Stimulus, for per-element control instead of a page-wide listener:
// app/javascript/controllers/math_controller.js
import { Controller } from "@hotwired/stimulus"
import { typesetMath } from "@fnix/lexxy-mathjax/typeset"
export default class extends Controller {
connect() {
typesetMath(this.element)
}
}
<div data-controller="math"><%= @post.body %></div>
Without importing this package's JS at all, wrap the stored LaTeX in MathJax's own delimiters and let typesetPromise scan for it normally:
document.querySelectorAll("[data-latex]").forEach((el) => {
const latex = el.getAttribute("data-latex")
el.textContent = el.tagName === "DIV" ? `\\[${latex}\\]` : `\\(${latex}\\)`
})
window.MathJax.typesetPromise()
This is the only approach that keeps MathJax's contextual menu and the v4 expression explorer, because the math becomes part of MathJax's own document list (see the accessibility note above). The trade-offs: it depends on the host's tex.inlineMath / tex.displayMath configuration matching those delimiters, and invalid LaTeX renders as MathJax's own merror markup rather than this package's .lexxy-math--error styling.
An earlier version of this README suggested setting
el.textContentto the bare, undelimiteddata-latexvalue and then callingMathJax.typesetPromise([...elements]). That never worked:typesetPromisescans for delimiters, and bare LaTeX has none — passing an element list narrows where it scans, not whether it requires delimiters. If you copied that snippet, switch to one of the two approaches above.
Both approaches above need an actual MathJax running in a DOM — the editor's, or a display page's. Some PDF pipelines have neither: sghtmltopdf, for one, runs no JavaScript at all and does not render inline <svg>, so MathJax can never execute there, and CHTML output needs WOFF/WOFF2 web fonts, which such engines typically don't support either. The persisted format above is designed for exactly this case: data-latex carries everything a separate rendering step needs, without this package's help.
This isn't something this package ships — it's server-side, has no browser to run in, and every detail (page size, body font, cache store, job queue, PDF engine) belongs to the app, not the editor extension. The recipe:
1. Render LaTeX to SVG in Node, using MathJax's server-side v4 package, @mathjax/src@4 (mathjax-full is the v3 name, mathjax-node is v2-era and abandoned — most recipes found online are stale):
global.MathJax = {
loader: { paths: { mathjax: "@mathjax/src/bundle" }, load: [ "adaptors/liteDOM" ], require: (f) => import(f) },
svg: { fontCache: "none" }, // no shared <use> references — safer for a standalone image
options: { enableSpeech: false, enableBraille: false, enableEnrichment: false } // skip the speech-rule-engine; it's the dominant startup cost
}
await import("@mathjax/src/bundle/tex-svg.js")
await MathJax.startup.promise
const svg = await MathJax.tex2svgPromise(latex, { display, em, ex, containerWidth })
// pick em/containerWidth from the PDF's body font and page width — 16/780 above are editor-viewport defaults, not PDF ones
MathJax.done() // mandatory: shuts down the speech-rule-engine's worker threads, or the process never exits
2. Transfer the geometry, then embed as an image. MathJax puts sizing on the <svg> element itself — output/svg.ts's createSVG sets width="Wex", height="Hex" and style="vertical-align:-Dex" — so wrapping it in an <img> (as most non-JS PDF engines require) discards all three unless you copy them onto the wrapper:
<img src="data:image/svg+xml;base64,…" alt="\frac{a}{b}"
style="width:2.62em;height:1.29em;vertical-align:-0.40em">
3. Run this at export time, on a throwaway copy of the HTML — not at save time. Keep data-latex as the only thing that's ever persisted:
<img> in a saved record wouldn't be recognized by importDOM);data: URIs on img[src] app-wide, which would be a real XSS surface (data:image/svg+xml can carry <script>);If your PDF engine has no accessibility tagging (sghtmltopdf doesn't), alt never reaches the PDF's own text layer either — still worth setting for tools that read it another way, but don't rely on it for accessibility.
Since the transform depends on nothing this package controls, and the format contract is exactly the data-latex spec above, this is intentionally left as a recipe rather than shipped code.
Try it online: https://fnix.github.io/lexxy-mathjax/
Or serve the repo statically and open the demo locally:
npx serve .
# then visit http://localhost:3000/demo/
npm install
npm test
The code follows lexxy's own conventions: plain ES modules, vanilla JS, no build step. Structure:
src/nodes/math_node.js — DecoratorNode storing { latex, display }; createDOM typesets with MathJax, exportDOM/importDOM handle the data-latex HTML formatsrc/extensions/mathjax_extension.js — the Lexxy.Extension: registers the node, the insertMath command, the toolbar button, and click-to-editsrc/elements/math_editor_dialog.js — <lexxy-math-editor> dialog with live previewsrc/helpers/mathjax_helper.js — serialized MathJax typesetting with graceful degradation; shared by the editor and by typeset_math.jssrc/typeset_math.js — typesetMath(root), the display-page renderer; batches conversions and refreshes MathJax's stylesheet once per call instead of once per equationsrc/auto_typeset.js — startMathjaxAutoTypeset(), wires typesetMath to DOMContentLoaded/Turbo eventssrc/typeset.js — the @fnix/lexxy-mathjax/typeset entry point (re-exports the two above without pulling in lexxy/Lexical)styles/lexxy-mathjax.css — presentation for equations and the editor dialog; the --lexxy-math-* custom properties it exposes are a public contract (see Theming), covered by test/styles.test.js