mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-12-23 08:47:50 +00:00
feat: add c alias for compile command (#2261)
Some checks failed
tinymist::auto_tag / auto-tag (push) Has been cancelled
tinymist::ci / Duplicate Actions Detection (push) Has been cancelled
tinymist::ci / Check Clippy, Formatting, Completion, Documentation, and Tests (Linux) (push) Has been cancelled
tinymist::ci / Check Minimum Rust version and Tests (Windows) (push) Has been cancelled
tinymist::ci / prepare-build (push) Has been cancelled
tinymist::gh_pages / build-gh-pages (push) Has been cancelled
tinymist::ci / announce (push) Has been cancelled
tinymist::ci / build (push) Has been cancelled
Some checks failed
tinymist::auto_tag / auto-tag (push) Has been cancelled
tinymist::ci / Duplicate Actions Detection (push) Has been cancelled
tinymist::ci / Check Clippy, Formatting, Completion, Documentation, and Tests (Linux) (push) Has been cancelled
tinymist::ci / Check Minimum Rust version and Tests (Windows) (push) Has been cancelled
tinymist::ci / prepare-build (push) Has been cancelled
tinymist::gh_pages / build-gh-pages (push) Has been cancelled
tinymist::ci / announce (push) Has been cancelled
tinymist::ci / build (push) Has been cancelled
Adds `c` as an alias for the `compile` subcommand to match `typst-cli` behavior where `c = compile`. ## Changes - Added `#[clap(alias = "c")]` attribute to the `Compile` command variant - Added test coverage for `tinymist c --help` and actual compilation via alias ## Usage ```bash # Both commands now work identically tinymist compile input.typ output.pdf tinymist c input.typ output.pdf ``` <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>Support command alias `c` in tinymist-cli</issue_title> > <issue_description>### Motivation > > As `typst-cli` has a alias `c = compile`, `tinymist compile` receives exactly same arguments as `typst compile`, it will be suprise if the alias itself is not supported. > > May not also applies to other subcommands. > > If this is feasible, I'd be willing to write a PR. This should be easy. > > ### Description > > _No response_ > > ### More Examples/Questions > > _No response_</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> - Fixes Myriad-Dreamin/tinymist#2259 <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/Myriad-Dreamin/tinymist/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Myriad-Dreamin <35292584+Myriad-Dreamin@users.noreply.github.com>
This commit is contained in:
parent
391d40ce42
commit
0714d19e29
12 changed files with 207 additions and 36 deletions
|
|
@ -89,6 +89,7 @@ enum Commands {
|
|||
#[cfg(feature = "preview")]
|
||||
Preview(tinymist::tool::preview::PreviewCliArgs),
|
||||
/// Run compile command like `typst-cli compile`
|
||||
#[clap(alias = "c")]
|
||||
Compile(CompileArgs),
|
||||
|
||||
/// Generate completion script to stdout
|
||||
|
|
|
|||
|
|
@ -363,10 +363,8 @@ export async function openPreviewInWebView({
|
|||
html = html.replace("preview-arg:state:", `preview-arg:state:${previewStateEncoded}`);
|
||||
// Forwards the localhost port to the external URL. Since WebSocket runs over HTTP, it should be fine.
|
||||
// https://code.visualstudio.com/api/advanced-topics/remote-extensions#forwarding-localhost
|
||||
let wsURI = await vscode.env.asExternalUri(
|
||||
vscode.Uri.parse(`http://127.0.0.1:${dataPlanePort}`),
|
||||
);
|
||||
let wsURIString = wsURI.toString().replace(/^http/, "ws")
|
||||
let wsURI = await vscode.env.asExternalUri(vscode.Uri.parse(`http://127.0.0.1:${dataPlanePort}`));
|
||||
let wsURIString = wsURI.toString().replace(/^http/, "ws");
|
||||
html = html.replace("ws://127.0.0.1:23625", wsURIString);
|
||||
|
||||
// Sets the HTML content to the webview panel.
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ export async function loadHTMLFile(context: vscode.ExtensionContext, relativePat
|
|||
export class DisposeList {
|
||||
disposes: (() => void)[] = [];
|
||||
disposed = false;
|
||||
constructor() { }
|
||||
constructor() {}
|
||||
add(d: (() => void) | vscode.Disposable) {
|
||||
if (this.disposed) {
|
||||
// console.error("disposed", this.taskId, "for", this.filePath);
|
||||
|
|
|
|||
|
|
@ -93,6 +93,141 @@ fn test_help_lsp() {
|
|||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_help_compile_alias() {
|
||||
apply_common_filters!();
|
||||
insta_cmd::assert_cmd_snapshot!(cli().arg("c").arg("--help"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
Run compile command like `typst-cli compile`
|
||||
|
||||
Usage: tinymist compile [OPTIONS] <INPUT> [OUTPUT]
|
||||
|
||||
Arguments:
|
||||
<INPUT>
|
||||
Specify the path to input Typst file
|
||||
|
||||
[OUTPUT]
|
||||
Provide the path to output file (PDF, PNG, SVG, or HTML). Use `-` to write output to
|
||||
stdout.
|
||||
|
||||
For output formats emitting one file per page (PNG & SVG), a page number template must be
|
||||
present if the source document renders to multiple pages. Use `{p}` for page numbers,
|
||||
`{0p}` for zero padded page numbers and `{t}` for page count. For example,
|
||||
`page-{0p}-of-{t}.png` creates `page-01-of-10.png`, `page-02-of-10.png`, and so on.
|
||||
|
||||
Options:
|
||||
--name <NAME>
|
||||
Give a task name to the document
|
||||
|
||||
--root <DIR>
|
||||
Configure the project root (for absolute paths). If the path is relative, it will be
|
||||
resolved relative to the current working directory (PWD)
|
||||
|
||||
[env: TYPST_ROOT=REDACTED]
|
||||
|
||||
--font-path <DIR>
|
||||
Add additional directories that are recursively searched for fonts.
|
||||
|
||||
If multiple paths are specified, they are separated by the system's path separator (`:` on
|
||||
Unix-like systems and `;` on Windows).
|
||||
|
||||
[env: TYPST_FONT_PATHS=REDACTED]
|
||||
|
||||
--ignore-system-fonts
|
||||
Ensure system fonts won't be searched, unless explicitly included via `--font-path`
|
||||
|
||||
--package-path <DIR>
|
||||
Specify a custom path to local packages, defaults to system-dependent location
|
||||
|
||||
[env: TYPST_PACKAGE_PATH=REDACTED]
|
||||
|
||||
--package-cache-path <DIR>
|
||||
Specify a custom path to package cache, defaults to system-dependent location
|
||||
|
||||
[env: TYPST_PACKAGE_CACHE_PATH=REDACTED]
|
||||
|
||||
--when <WHEN>
|
||||
Configure when to run the task
|
||||
|
||||
Possible values:
|
||||
- never: Never watch to run task
|
||||
- onSave: Run task on saving the document, i.e. on `textDocument/didSave`
|
||||
events
|
||||
- onType: Run task on typing, i.e. on `textDocument/didChange` events
|
||||
- onDocumentHasTitle: *DEPRECATED* Run task when a document has a title and on saved,
|
||||
which is useful to filter out template files
|
||||
- script: Checks by running a typst script
|
||||
|
||||
-f, --format <FORMAT>
|
||||
Specify the format of the output file, inferred from the extension by default
|
||||
|
||||
Possible values:
|
||||
- pdf: Export to PDF
|
||||
- png: Export to PNG
|
||||
- svg: Export to SVG
|
||||
- html: Export to HTML
|
||||
|
||||
--pages <PAGES>
|
||||
Specify which pages to export. When unspecified, all pages are exported.
|
||||
|
||||
Pages to export are separated by commas, and can be either simple page numbers (e.g. '2,5'
|
||||
to export only pages 2 and 5) or page ranges (e.g. '2,3-6,8-' to export page 2, pages 3 to
|
||||
6 (inclusive), page 8 and any pages after it).
|
||||
|
||||
Page numbers are one-indexed and correspond to physical page numbers in the document
|
||||
(therefore not being affected by the document's page counter).
|
||||
|
||||
--pdf-standard <STANDARD>
|
||||
Specify the PDF standards that Typst will enforce conformance with.
|
||||
|
||||
If multiple standards are specified, they are separated by commas.
|
||||
|
||||
Possible values:
|
||||
- 1.4: PDF 1.4
|
||||
- 1.5: PDF 1.5
|
||||
- 1.6: PDF 1.6
|
||||
- 1.7: PDF 1.7
|
||||
- 2.0: PDF 2.0
|
||||
- a-1b: PDF/A-1b
|
||||
- a-1a: PDF/A-1a
|
||||
- a-2b: PDF/A-2b
|
||||
- a-2u: PDF/A-2u
|
||||
- a-2a: PDF/A-2a
|
||||
- a-3b: PDF/A-3b
|
||||
- a-3u: PDF/A-3u
|
||||
- a-3a: PDF/A-3a
|
||||
- a-4: PDF/A-4
|
||||
- a-4f: PDF/A-4f
|
||||
- a-4e: PDF/A-4e
|
||||
- ua-1: PDF/UA-1
|
||||
|
||||
--no-pdf-tags
|
||||
By default, even when not producing a `PDF/UA-1` document, a tagged PDF document is
|
||||
written to provide a baseline of accessibility. In some circumstances (for example when
|
||||
trying to reduce the size of a document) it can be desirable to disable tagged PDF
|
||||
|
||||
--ppi <PPI>
|
||||
Specify the PPI (pixels per inch) to use for PNG export
|
||||
|
||||
[default: 144]
|
||||
|
||||
--save-lock
|
||||
Save the compilation arguments to the lock file. If `--lockfile` is not set, the lock file
|
||||
will be saved in the cwd
|
||||
|
||||
--lockfile <LOCKFILE>
|
||||
Specify the path to the lock file. If the path is set, the lockfile will be saved
|
||||
(--save-lock)
|
||||
|
||||
-h, --help
|
||||
Print help (see a summary with '-h')
|
||||
|
||||
----- stderr -----
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_help_compile() {
|
||||
apply_common_filters!();
|
||||
|
|
@ -448,3 +583,37 @@ fn test_compile() {
|
|||
})
|
||||
.expect("test should succeed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_compile_alias() {
|
||||
const INPUT_REL: &str = "tests/workspaces/individuals/tiny.typ";
|
||||
|
||||
std::env::set_var("RUST_BACKTRACE", "full");
|
||||
let cwd = GIT_ROOT.clone();
|
||||
let root = cwd.join("target/e2e/tinymist-cli");
|
||||
|
||||
std::env::set_current_dir(&cwd).expect("should change current directory");
|
||||
tinymist_std::fs::paths::temp_dir_in(root, |tmp| {
|
||||
let abs_out = tmp.clean();
|
||||
let rel_out = abs_out.strip_prefix(&cwd).expect("path should be stripped");
|
||||
|
||||
assert!(cwd.is_absolute(), "cwd should be absolute {cwd:?}");
|
||||
assert!(abs_out.is_absolute(), "abs_out should be absolute {abs_out:?}");
|
||||
assert!(rel_out.is_relative(), "rel_out should be relative {rel_out:?}");
|
||||
|
||||
// Test the 'c' alias with relative INPUT and OUTPUT
|
||||
insta_cmd::assert_cmd_snapshot!(cli().arg("c").arg(INPUT_REL).arg(rel_out.join("test_alias.pdf")), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
");
|
||||
|
||||
let output = rel_out.join("test_alias.pdf");
|
||||
assert!(output.exists(), "output file should exist: {output:?}");
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.expect("test should succeed");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,9 +114,7 @@ const TemplateList = (packages: State<PackageMeta[]>, catState: FilterState) =>
|
|||
button(
|
||||
{
|
||||
class: van.derive(() => {
|
||||
const activatingCls = catState.getIsFavorite("preview", item.name)
|
||||
? " active"
|
||||
: "";
|
||||
const activatingCls = catState.getIsFavorite("preview", item.name) ? " active" : "";
|
||||
return "toggle-btn tinymist-template-action" + activatingCls;
|
||||
}),
|
||||
title: van.derive(() =>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
import { triggerRipple } from "./typst-animation.mjs";
|
||||
import { PreviewMode, TypstDomHookedElement, TypstDomWindowElement, type GConstructor, type TypstDocumentContext } from "./typst-doc.mjs";
|
||||
import {
|
||||
PreviewMode,
|
||||
TypstDomHookedElement,
|
||||
TypstDomWindowElement,
|
||||
type GConstructor,
|
||||
type TypstDocumentContext,
|
||||
} from "./typst-doc.mjs";
|
||||
|
||||
const enum SourceMappingType {
|
||||
Text = 0,
|
||||
|
|
@ -107,7 +113,8 @@ export function resolveSourceLeaf(
|
|||
|
||||
export function installEditorJumpToHandler(
|
||||
windowElem: TypstDomWindowElement,
|
||||
docRoot: TypstDomHookedElement) {
|
||||
docRoot: TypstDomHookedElement,
|
||||
) {
|
||||
const getNthBackgroundRect = (elem: Element, pageNumber: string) => {
|
||||
let curElem: Element | null = elem;
|
||||
while (curElem) {
|
||||
|
|
@ -210,7 +217,7 @@ export function installEditorJumpToHandler(
|
|||
docRoot.addEventListener("click", sourceMappingHandler);
|
||||
}
|
||||
|
||||
export interface TypstDebugJumpDocument { }
|
||||
export interface TypstDebugJumpDocument {}
|
||||
|
||||
export function provideDebugJumpDoc<TBase extends GConstructor<TypstDocumentContext>>(
|
||||
Base: TBase,
|
||||
|
|
@ -228,12 +235,7 @@ export function provideDebugJumpDoc<TBase extends GConstructor<TypstDocumentCont
|
|||
}
|
||||
}
|
||||
|
||||
scrollTo(
|
||||
pageWidth: number,
|
||||
pageNo: number,
|
||||
innerLeft: number,
|
||||
innerTop: number,
|
||||
) {
|
||||
scrollTo(pageWidth: number, pageNo: number, innerLeft: number, innerTop: number) {
|
||||
const scrollElem = this.hookedElem.parentElement!;
|
||||
|
||||
if (this.previewMode === PreviewMode.Slide) {
|
||||
|
|
@ -270,8 +272,7 @@ export function provideDebugJumpDoc<TBase extends GConstructor<TypstDocumentCont
|
|||
// for double-column layout
|
||||
// console.log('occupied adjustment', widthOccupied, page);
|
||||
|
||||
const xOffsetAdjsut =
|
||||
xOffset > pageAdjust ? pageAdjust : pageAdjustLeft;
|
||||
const xOffsetAdjsut = xOffset > pageAdjust ? pageAdjust : pageAdjustLeft;
|
||||
|
||||
scrollElem.scrollTo({
|
||||
behavior: "smooth",
|
||||
|
|
@ -320,4 +321,3 @@ export function provideDebugJumpDoc<TBase extends GConstructor<TypstDocumentCont
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -636,8 +636,7 @@ export function provideSvgDoc<
|
|||
const computedRevScale = containerWidth ? this.docWidth / containerWidth : 1;
|
||||
// respect current scale ratio
|
||||
const revScale = computedRevScale / this.currentScaleRatio;
|
||||
const left =
|
||||
(this.windowElem.offsetLeft - containerBRect.left) * revScale;
|
||||
const left = (this.windowElem.offsetLeft - containerBRect.left) * revScale;
|
||||
const top = (this.windowElem.offsetTop - containerBRect.top) * revScale;
|
||||
const width = this.windowElem.clientWidth * revScale;
|
||||
const height = this.windowElem.clientHeight * revScale;
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class GenElem {
|
|||
public tag: string,
|
||||
public container: HTMLElement,
|
||||
public additions?: Record<string, any>,
|
||||
) { }
|
||||
) {}
|
||||
|
||||
push(child: GenNode) {
|
||||
this.children.push(child);
|
||||
|
|
@ -88,7 +88,10 @@ class GenContext {
|
|||
allElemList: GenElem[] = [];
|
||||
windowElem: TypstDomWindowElement;
|
||||
|
||||
constructor(public pages: CanvasPage[], windowElem: TypstDomWindowElement) {
|
||||
constructor(
|
||||
public pages: CanvasPage[],
|
||||
windowElem: TypstDomWindowElement,
|
||||
) {
|
||||
this.insertionPoint = new GenElem("outline", document.createElement("div"));
|
||||
this.parent = this.insertionPoint;
|
||||
this.windowElem = windowElem;
|
||||
|
|
@ -174,7 +177,7 @@ export function patchOutlineEntry(
|
|||
prev: HTMLDivElement,
|
||||
pages: CanvasPage[],
|
||||
items: OutlineItemData[],
|
||||
windowElem: TypstDomWindowElement
|
||||
windowElem: TypstDomWindowElement,
|
||||
) {
|
||||
const ctx = new GenContext(pages, windowElem);
|
||||
// the root element of the generated outline
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ function retrieveWsArgs() {
|
|||
/// `buildWs` returns a object, which keeps track of websocket
|
||||
/// connections.
|
||||
function buildWs() {
|
||||
let previousDispose = Promise.resolve(() => { });
|
||||
let previousDispose = Promise.resolve(() => {});
|
||||
/// `nextWs` will always hold a global unique websocket connection
|
||||
/// to the preview backend.
|
||||
function nextWs(nextWsArgs) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import { PreviewMode } from "typst-dom/typst-doc.mjs";
|
||||
import { TypstPreviewDocument as TypstDocument, TypstDomHookedElement, TypstDomWindowElement } from "typst-dom/index.preview.mjs";
|
||||
import {
|
||||
TypstPreviewDocument as TypstDocument,
|
||||
TypstDomHookedElement,
|
||||
TypstDomWindowElement,
|
||||
} from "typst-dom/index.preview.mjs";
|
||||
import {
|
||||
rendererBuildInfo,
|
||||
createTypstRenderer,
|
||||
|
|
@ -33,7 +37,7 @@ export async function wsMain({ url, previewMode, isContentPreview }: WsArgs) {
|
|||
if (hookedElem) {
|
||||
hookedElem.innerHTML = "";
|
||||
}
|
||||
return () => { };
|
||||
return () => {};
|
||||
}
|
||||
const windowElem = document.getElementById("typst-container")! as TypstDomWindowElement;
|
||||
|
||||
|
|
@ -89,7 +93,6 @@ export async function wsMain({ url, previewMode, isContentPreview }: WsArgs) {
|
|||
}),
|
||||
);
|
||||
|
||||
|
||||
const focusInput = () => {
|
||||
const inpPageSelector = document.getElementById("typst-page-selector") as
|
||||
| HTMLSelectElement
|
||||
|
|
@ -183,9 +186,9 @@ export async function wsMain({ url, previewMode, isContentPreview }: WsArgs) {
|
|||
// https://stackoverflow.com/questions/3464876/javascript-get-window-x-y-position-for-scroll
|
||||
let top = () => {
|
||||
let doc = document.documentElement;
|
||||
return (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)
|
||||
return (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
|
||||
};
|
||||
const scrollDelta = 50
|
||||
const scrollDelta = 50;
|
||||
|
||||
switch (e.key) {
|
||||
case "ArrowLeft":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue