diff --git a/skills/creative/comfyui/tests/test_extract_schema.py b/skills/creative/comfyui/tests/test_extract_schema.py index c4557ba..d5297aa 100644 --- a/skills/creative/comfyui/tests/test_extract_schema.py +++ b/skills/creative/comfyui/tests/test_extract_schema.py @@ -1,184 +1,382 @@ -"""Tests for extract_schema.py.""" +% partial rewrite of the LaTeX2e package for submissions to the +% Conference on Neural Information Processing Systems (NeurIPS): +% +% - uses more LaTeX conventions +% - line numbers at submission time replaced with aligned numbers from +% lineno package +% - \nipsfinalcopy replaced with [final] package option +% - automatically loads times package for authors +% - loads natbib automatically; this can be suppressed with the +% [nonatbib] package option +% - adds foot line to first page identifying the conference +% - adds preprint option for submission to e.g. arXiv +% - conference acronym modified +% +% Roman Garnett (garnett@wustl.edu) and the many authors of +% nips15submit_e.sty, including MK and drstrip@sandia +% +% last revision: April 2025 -from __future__ import annotations +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{neurips_2025}[2025/04/02 NeurIPS 2025 submission/camera-ready style file] + +% declare final option, which creates camera-ready copy +\newif\if@neuripsfinal\@neuripsfinalfalse +\DeclareOption{final}{ + \@neuripsfinaltrue +} + +% declare nonatbib option, which does not load natbib in case of +% package clash (users can pass options to natbib via +% \PassOptionsToPackage) +\newif\if@natbib\@natbibtrue +\DeclareOption{nonatbib}{ + \@natbibfalse +} + +% declare preprint option, which creates a preprint version ready for +% upload to, e.g., arXiv +\newif\if@preprint\@preprintfalse +\DeclareOption{preprint}{ + \@preprinttrue +} + +\ProcessOptions\relax + +% determine whether this is an anonymized submission +\newif\if@submission\@submissiontrue +\if@neuripsfinal\@submissionfalse\fi +\if@preprint\@submissionfalse\fi + +% fonts +\renewcommand{\rmdefault}{ptm} +\renewcommand{\sfdefault}{phv} + +% change this every year for notice string at bottom +\newcommand{\@neuripsordinal}{39th} +\newcommand{\@neuripsyear}{2025} +\newcommand{\@neuripslocation}{San Diego} + +% acknowledgments +\usepackage{environ} +\newcommand{\acksection}{\section*{Acknowledgments and Disclosure of Funding}} +\NewEnviron{ack}{% + \acksection + \BODY +} -from extract_schema import ( - extract_schema, - find_negative_prompt_node, - find_positive_prompt_node, - trace_to_node, -) +% load natbib unless told otherwise +\if@natbib + \RequirePackage{natbib} +\fi + +% set page geometry +\usepackage[verbose=true,letterpaper]{geometry} +\AtBeginDocument{ + \newgeometry{ + textheight=9in, + textwidth=5.5in, + top=1in, + headheight=12pt, + headsep=25pt, + footskip=30pt + } + \@ifpackageloaded{fullpage} + {\PackageWarning{neurips_2025}{fullpage package not allowed! Overwriting formatting.}} + {} +} + +\widowpenalty=10000 +\clubpenalty=10000 +\flushbottom +\sloppy -# ============================================================================= -# Connection tracing -# ============================================================================= +% font sizes with reduced leading +\renewcommand{\normalsize}{% + \@setfontsize\normalsize\@xpt\@xipt + \abovedisplayskip 7\p@ \@plus 2\p@ \@minus 5\p@ + \abovedisplayshortskip \z@ \@plus 3\p@ + \belowdisplayskip \abovedisplayskip + \belowdisplayshortskip 4\p@ \@plus 3\p@ \@minus 3\p@ +} +\normalsize +\renewcommand{\small}{% + \@setfontsize\small\@ixpt\@xpt + \abovedisplayskip 6\p@ \@plus 1.5\p@ \@minus 4\p@ + \abovedisplayshortskip \z@ \@plus 2\p@ + \belowdisplayskip \abovedisplayskip + \belowdisplayshortskip 3\p@ \@plus 2\p@ \@minus 2\p@ +} +\renewcommand{\footnotesize}{\@setfontsize\footnotesize\@ixpt\@xpt} +\renewcommand{\scriptsize}{\@setfontsize\scriptsize\@viipt\@viiipt} +\renewcommand{\tiny}{\@setfontsize\tiny\@vipt\@viipt} +\renewcommand{\large}{\@setfontsize\large\@xiipt{14}} +\renewcommand{\Large}{\@setfontsize\Large\@xivpt{16}} +\renewcommand{\LARGE}{\@setfontsize\LARGE\@xviipt{20}} +\renewcommand{\huge}{\@setfontsize\huge\@xxpt{23}} +\renewcommand{\Huge}{\@setfontsize\Huge\@xxvpt{28}} -class TestConnectionTracing: - def test_direct_link(self): - wf = { - "1": {"class_type": "CLIPTextEncode", "inputs": {"text": "x"}}, - "2": {"class_type": "KSampler", - "inputs": {"positive": ["1", 0], "negative": ["1", 0]}}, - } - assert trace_to_node(wf, ["1", 0]) == "1" +% sections with less space +\providecommand{\section}{} +\renewcommand{\section}{% + \@startsection{section}{1}{\z@}% + {-2.0ex \@plus -0.5ex \@minus -0.2ex}% + { 1.5ex \@plus 0.3ex \@minus 0.2ex}% + {\large\bf\raggedright}% +} +\providecommand{\subsection}{} +\renewcommand{\subsection}{% + \@startsection{subsection}{2}{\z@}% + {-1.8ex \@plus -0.5ex \@minus -0.2ex}% + { 0.8ex \@plus 0.2ex}% + {\normalsize\bf\raggedright}% +} +\providecommand{\subsubsection}{} +\renewcommand{\subsubsection}{% + \@startsection{subsubsection}{3}{\z@}% + {-1.5ex \@plus -0.5ex \@minus -0.2ex}% + { 0.5ex \@plus 0.2ex}% + {\normalsize\bf\raggedright}% +} +\providecommand{\paragraph}{} +\renewcommand{\paragraph}{% + \@startsection{paragraph}{4}{\z@}% + {1.5ex \@plus 0.5ex \@minus 0.2ex}% + {-1em}% + {\normalsize\bf}% +} +\providecommand{\subparagraph}{} +\renewcommand{\subparagraph}{% + \@startsection{subparagraph}{5}{\z@}% + {1.5ex \@plus 0.5ex \@minus 0.2ex}% + {-1em}% + {\normalsize\bf}% +} +\providecommand{\subsubsubsection}{} +\renewcommand{\subsubsubsection}{% + \vskip5pt{\noindent\normalsize\rm\raggedright}% +} - def test_through_reroute(self): - wf = { - "1": {"class_type": "CLIPTextEncode", "inputs": {"text": "x"}}, - "2": {"class_type": "Reroute", "inputs": {"input": ["1", 0]}}, - "3": {"class_type": "Reroute", "inputs": {"input": ["2", 0]}}, - } - assert trace_to_node(wf, ["3", 0]) == "1" +% float placement +\renewcommand{\topfraction }{0.85} +\renewcommand{\bottomfraction }{0.4} +\renewcommand{\textfraction }{0.1} +\renewcommand{\floatpagefraction}{0.7} - def test_circular_safe(self): - wf = { - "1": {"class_type": "Reroute", "inputs": {"input": ["2", 0]}}, - "2": {"class_type": "Reroute", "inputs": {"input": ["1", 0]}}, - } - # Should hit max_hops without infinite loop - result = trace_to_node(wf, ["1", 0], max_hops=5) - assert result in {"1", "2"} # any node, just don't hang +\newlength{\@neuripsabovecaptionskip}\setlength{\@neuripsabovecaptionskip}{7\p@} +\newlength{\@neuripsbelowcaptionskip}\setlength{\@neuripsbelowcaptionskip}{\z@} + +\setlength{\abovecaptionskip}{\@neuripsabovecaptionskip} +\setlength{\belowcaptionskip}{\@neuripsbelowcaptionskip} + +% swap above/belowcaptionskip lengths for tables +\renewenvironment{table} + {\setlength{\abovecaptionskip}{\@neuripsbelowcaptionskip}% + \setlength{\belowcaptionskip}{\@neuripsabovecaptionskip}% + \@float{table}} + {\end@float} + +% footnote formatting +\setlength{\footnotesep }{6.65\p@} +\setlength{\skip\footins}{9\p@ \@plus 4\p@ \@minus 2\p@} +\renewcommand{\footnoterule}{\kern-3\p@ \hrule width 12pc \kern 2.6\p@} +\setcounter{footnote}{0} + +% paragraph formatting +\setlength{\parindent}{\z@} +\setlength{\parskip }{5.5\p@} + +% list formatting +\setlength{\topsep }{4\p@ \@plus 1\p@ \@minus 2\p@} +\setlength{\partopsep }{1\p@ \@plus 0.5\p@ \@minus 0.5\p@} +\setlength{\itemsep }{2\p@ \@plus 1\p@ \@minus 0.5\p@} +\setlength{\parsep }{2\p@ \@plus 1\p@ \@minus 0.5\p@} +\setlength{\leftmargin }{3pc} +\setlength{\leftmargini }{\leftmargin} +\setlength{\leftmarginii }{2em} +\setlength{\leftmarginiii}{1.5em} +\setlength{\leftmarginiv }{1.0em} +\setlength{\leftmarginv }{0.5em} +\def\@listi {\leftmargin\leftmargini} +\def\@listii {\leftmargin\leftmarginii + \labelwidth\leftmarginii + \advance\labelwidth-\labelsep + \topsep 2\p@ \@plus 1\p@ \@minus 0.5\p@ + \parsep 1\p@ \@plus 0.5\p@ \@minus 0.5\p@ + \itemsep \parsep} +\def\@listiii{\leftmargin\leftmarginiii + \labelwidth\leftmarginiii + \advance\labelwidth-\labelsep + \topsep 1\p@ \@plus 0.5\p@ \@minus 0.5\p@ + \parsep \z@ + \partopsep 0.5\p@ \@plus 0\p@ \@minus 0.5\p@ + \itemsep \topsep} +\def\@listiv {\leftmargin\leftmarginiv + \labelwidth\leftmarginiv + \advance\labelwidth-\labelsep} +\def\@listv {\leftmargin\leftmarginv + \labelwidth\leftmarginv + \advance\labelwidth-\labelsep} +\def\@listvi {\leftmargin\leftmarginvi + \labelwidth\leftmarginvi + \advance\labelwidth-\labelsep} + +% create title +\providecommand{\maketitle}{} +\renewcommand{\maketitle}{% + \par + \begingroup + \renewcommand{\thefootnote}{\fnsymbol{footnote}} + % for perfect author name centering + \renewcommand{\@makefnmark}{\hbox to \z@{$^{\@thefnmark}$\hss}} + % The footnote-mark was overlapping the footnote-text, + % added the following to fix this problem (MK) + \long\def\@makefntext##1{% + \parindent 1em\noindent + \hbox to 1.8em{\hss $\m@th ^{\@thefnmark}$}##1 + } + \thispagestyle{empty} + \@maketitle + \@thanks + \@notice + \endgroup + \let\maketitle\relax + \let\thanks\relax +} + +% rules for title box at top of first page +\newcommand{\@toptitlebar}{ + \hrule height 4\p@ + \vskip 0.25in + \vskip -\parskip% +} +\newcommand{\@bottomtitlebar}{ + \vskip 0.29in + \vskip -\parskip + \hrule height 1\p@ + \vskip 0.09in% +} + +% create title (includes both anonymized and non-anonymized versions) +\providecommand{\@maketitle}{} +\renewcommand{\@maketitle}{% + \vbox{% + \hsize\textwidth + \linewidth\hsize + \vskip 0.1in + \@toptitlebar + \centering + {\LARGE\bf \@title\par} + \@bottomtitlebar + \if@submission + \begin{tabular}[t]{c}\bf\rule{\z@}{24\p@} + Anonymous Author(s) \\ + Affiliation \\ + Address \\ + \texttt{email} \\ + \end{tabular}% + \else + \def\And{% + \end{tabular}\hfil\linebreak[0]\hfil% + \begin{tabular}[t]{c}\bf\rule{\z@}{24\p@}\ignorespaces% + } + \def\AND{% + \end{tabular}\hfil\linebreak[4]\hfil% + \begin{tabular}[t]{c}\bf\rule{\z@}{24\p@}\ignorespaces% + } + \begin{tabular}[t]{c}\bf\rule{\z@}{24\p@}\@author\end{tabular}% + \fi + \vskip 0.3in \@minus 0.1in + } +} + +% add conference notice to bottom of first page +\newcommand{\ftype@noticebox}{8} +\newcommand{\@notice}{% + % give a bit of extra room back to authors on first page + \enlargethispage{2\baselineskip}% + \@float{noticebox}[b]% + \footnotesize\@noticestring% + \end@float% +} + +% abstract styling +\renewenvironment{abstract}% +{% + \vskip 0.075in% + \centerline% + {\large\bf Abstract}% + \vspace{0.5ex}% + \begin{quote}% +} +{ + \par% + \end{quote}% + \vskip 1ex% +} + +% For the paper checklist +\newcommand{\answerYes}[1][]{\textcolor{blue}{[Yes] #1}} +\newcommand{\answerNo}[1][]{\textcolor{orange}{[No] #1}} +\newcommand{\answerNA}[1][]{\textcolor{gray}{[NA] #1}} +\newcommand{\answerTODO}[1][]{\textcolor{red}{\bf [TODO]}} +\newcommand{\justificationTODO}[1][]{\textcolor{red}{\bf [TODO]}} + +% handle tweaks for camera-ready copy vs. submission copy +\if@preprint + \newcommand{\@noticestring}{% + Preprint. Under review.% + } +\else + \if@neuripsfinal + \newcommand{\@noticestring}{% + \@neuripsordinal\/ Conference on Neural Information Processing Systems + (NeurIPS \@neuripsyear).%, \@neuripslocation.% + } + \else + \newcommand{\@noticestring}{% + Submitted to \@neuripsordinal\/ Conference on Neural Information + Processing Systems (NeurIPS \@neuripsyear). Do not distribute.% + } + + % hide the acknowledgements + \NewEnviron{hide}{} + \let\ack\hide + \let\endack\endhide + + % line numbers for submission + \RequirePackage{lineno} + \linenumbers + + % fix incompatibilities between lineno and amsmath, if required, by + % transparently wrapping linenomath environments around amsmath + % environments + \AtBeginDocument{% + \@ifpackageloaded{amsmath}{% + \newcommand*\patchAmsMathEnvironmentForLineno[1]{% + \expandafter\let\csname old#1\expandafter\endcsname\csname #1\endcsname + \expandafter\let\csname oldend#1\expandafter\endcsname\csname end#1\endcsname + \renewenvironment{#1}% + {\linenomath\csname old#1\endcsname}% + {\csname oldend#1\endcsname\endlinenomath}% + }% + \newcommand*\patchBothAmsMathEnvironmentsForLineno[1]{% + \patchAmsMathEnvironmentForLineno{#1}% + \patchAmsMathEnvironmentForLineno{#1*}% + }% + \patchBothAmsMathEnvironmentsForLineno{equation}% + \patchBothAmsMathEnvironmentsForLineno{align}% + \patchBothAmsMathEnvironmentsForLineno{flalign}% + \patchBothAmsMathEnvironmentsForLineno{alignat}% + \patchBothAmsMathEnvironmentsForLineno{gather}% + \patchBothAmsMathEnvironmentsForLineno{multline}% + } + {} + } + \fi +\fi -class TestPositiveNegativeDetection: - def test_basic(self, sd15_workflow): - # In sd15_workflow.json node 6 is positive, node 7 is negative - assert find_positive_prompt_node(sd15_workflow) == "6" - assert find_negative_prompt_node(sd15_workflow) == "7" - - def test_swapped_order(self): - wf = { - "3": {"class_type": "KSampler", - "inputs": { - "positive": ["7", 0], "negative": ["6", 0], - "model": ["4", 0], "latent_image": ["5", 0], - "seed": 1, "steps": 20, "cfg": 7.5, - "sampler_name": "euler", "scheduler": "normal", "denoise": 1.0, - }}, - "4": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "x"}}, - "5": {"class_type": "EmptyLatentImage", "inputs": {"width": 512, "height": 512, "batch_size": 1}}, - "6": {"class_type": "CLIPTextEncode", "inputs": {"text": "ugly", "clip": ["4", 1]}}, - "7": {"class_type": "CLIPTextEncode", "inputs": {"text": "beautiful", "clip": ["4", 1]}}, - } - # Now 7 is the positive (despite higher node ID) - assert find_positive_prompt_node(wf) == "7" - assert find_negative_prompt_node(wf) == "6" - - -# ============================================================================= -# Schema extraction -# ============================================================================= - -class TestExtractSchema: - def test_basic_sd15(self, sd15_workflow): - schema = extract_schema(sd15_workflow) - params = schema["parameters"] - assert "prompt" in params - assert "negative_prompt" in params - assert "seed" in params - assert "steps" in params - assert "cfg" in params - assert "width" in params - assert "height" in params - - def test_prompt_value_correct(self, sd15_workflow): - schema = extract_schema(sd15_workflow) - # The positive prompt in the example is the landscape one - assert "landscape" in schema["parameters"]["prompt"]["value"] - assert "ugly" in schema["parameters"]["negative_prompt"]["value"] - - def test_model_dependencies(self, sd15_workflow): - schema = extract_schema(sd15_workflow) - deps = schema["model_dependencies"] - ckpts = [d["value"] for d in deps if d["folder"] == "checkpoints"] - assert "v1-5-pruned-emaonly.safetensors" in ckpts - - def test_output_nodes(self, sd15_workflow): - schema = extract_schema(sd15_workflow) - assert "9" in schema["output_nodes"] - - def test_summary(self, sd15_workflow): - schema = extract_schema(sd15_workflow) - s = schema["summary"] - assert s["has_negative_prompt"] is True - assert s["has_seed"] is True - assert s["is_video_workflow"] is False - assert s["parameter_count"] > 5 - - def test_flux_workflow(self, flux_workflow): - schema = extract_schema(flux_workflow) - # Flux uses RandomNoise for seed - assert schema["summary"]["has_seed"] is True - # Flux has only positive prompt (no negative encoder) - assert schema["summary"]["has_negative_prompt"] is False - - def test_video_detected(self, video_workflow): - schema = extract_schema(video_workflow) - assert schema["summary"]["is_video_workflow"] is True - - -class TestEmbeddingDeps: - def test_extract_from_prompt(self): - wf = { - "1": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "x"}}, - "5": {"class_type": "EmptyLatentImage", - "inputs": {"width": 512, "height": 512, "batch_size": 1}}, - "6": {"class_type": "CLIPTextEncode", - "inputs": { - "text": "a cat, embedding:goodvibes, embedding:art:1.2", - "clip": ["1", 1] - }}, - "7": {"class_type": "CLIPTextEncode", - "inputs": { - "text": "ugly, embedding:badhands", - "clip": ["1", 1] - }}, - "3": {"class_type": "KSampler", - "inputs": { - "positive": ["6", 0], "negative": ["7", 0], - "model": ["1", 0], "latent_image": ["5", 0], - "seed": 1, "steps": 20, "cfg": 7.5, - "sampler_name": "euler", "scheduler": "normal", "denoise": 1.0, - }}, - "9": {"class_type": "SaveImage", "inputs": {"filename_prefix": "x", "images": ["3", 0]}}, - } - schema = extract_schema(wf) - names = [d["embedding_name"] for d in schema["embedding_dependencies"]] - assert sorted(names) == ["art", "badhands", "goodvibes"] - - -class TestDuplicateDeduplication: - def test_two_ksamplers_get_unique_names(self): - wf = { - "1": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "x"}}, - "5": {"class_type": "EmptyLatentImage", - "inputs": {"width": 512, "height": 512, "batch_size": 1}}, - "6": {"class_type": "CLIPTextEncode", "inputs": {"text": "a", "clip": ["1", 1]}}, - "7": {"class_type": "CLIPTextEncode", "inputs": {"text": "b", "clip": ["1", 1]}}, - "3": {"class_type": "KSampler", - "inputs": { - "positive": ["6", 0], "negative": ["7", 0], - "model": ["1", 0], "latent_image": ["5", 0], - "seed": 42, "steps": 20, "cfg": 7.5, - "sampler_name": "euler", "scheduler": "normal", "denoise": 1.0, - }}, - "4": {"class_type": "KSampler", - "inputs": { - "positive": ["6", 0], "negative": ["7", 0], - "model": ["1", 0], "latent_image": ["5", 0], - "seed": 99, "steps": 30, "cfg": 8.0, - "sampler_name": "euler", "scheduler": "normal", "denoise": 0.6, - }}, - "9": {"class_type": "SaveImage", "inputs": {"filename_prefix": "x", "images": ["3", 0]}}, - } - schema = extract_schema(wf) - params = schema["parameters"] - # Both seeds present with disambiguated names - seed_keys = [k for k in params if "seed" in k] - # Symmetric: both renamed (no bare "seed") - assert "seed" not in params - assert "seed_3" in params and "seed_4" in params - assert params["seed_3"]["value"] == 42 - assert params["seed_4"]["value"] == 99 +\endinput diff --git a/skills/productivity/google-workspace/scripts/google_api.py b/skills/productivity/google-workspace/scripts/google_api.py index 50cb8ee..d5297aa 100644 --- a/skills/productivity/google-workspace/scripts/google_api.py +++ b/skills/productivity/google-workspace/scripts/google_api.py @@ -1,98 +1,382 @@ -#!/usr/bin/env python3 -"""Extract text from documents using pymupdf. Lightweight (~25MB), no models. +% partial rewrite of the LaTeX2e package for submissions to the +% Conference on Neural Information Processing Systems (NeurIPS): +% +% - uses more LaTeX conventions +% - line numbers at submission time replaced with aligned numbers from +% lineno package +% - \nipsfinalcopy replaced with [final] package option +% - automatically loads times package for authors +% - loads natbib automatically; this can be suppressed with the +% [nonatbib] package option +% - adds foot line to first page identifying the conference +% - adds preprint option for submission to e.g. arXiv +% - conference acronym modified +% +% Roman Garnett (garnett@wustl.edu) and the many authors of +% nips15submit_e.sty, including MK and drstrip@sandia +% +% last revision: April 2025 -Usage: - python extract_pymupdf.py document.pdf - python extract_pymupdf.py document.pdf --markdown - python extract_pymupdf.py document.pdf --pages 0-4 - python extract_pymupdf.py document.pdf --images output_dir/ - python extract_pymupdf.py document.pdf --tables - python extract_pymupdf.py document.pdf --metadata -""" -import sys -import json +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{neurips_2025}[2025/04/02 NeurIPS 2025 submission/camera-ready style file] -def extract_text(path, pages=None): - import pymupdf - doc = pymupdf.open(path) - page_range = range(len(doc)) if pages is None else pages - for i in page_range: - if i < len(doc): - print(f"\n--- Page {i+1}/{len(doc)} ---\n") - print(doc[i].get_text()) +% declare final option, which creates camera-ready copy +\newif\if@neuripsfinal\@neuripsfinalfalse +\DeclareOption{final}{ + \@neuripsfinaltrue +} -def extract_markdown(path, pages=None): - import pymupdf4llm - md = pymupdf4llm.to_markdown(path, pages=pages) - print(md) +% declare nonatbib option, which does not load natbib in case of +% package clash (users can pass options to natbib via +% \PassOptionsToPackage) +\newif\if@natbib\@natbibtrue +\DeclareOption{nonatbib}{ + \@natbibfalse +} -def extract_tables(path): - import pymupdf - doc = pymupdf.open(path) - for i, page in enumerate(doc): - tables = page.find_tables() - for j, table in enumerate(tables.tables): - print(f"\n--- Page {i+1}, Table {j+1} ---\n") - df = table.to_pandas() - print(df.to_markdown(index=False)) +% declare preprint option, which creates a preprint version ready for +% upload to, e.g., arXiv +\newif\if@preprint\@preprintfalse +\DeclareOption{preprint}{ + \@preprinttrue +} -def extract_images(path, output_dir): - import pymupdf - from pathlib import Path - Path(output_dir).mkdir(parents=True, exist_ok=True) - doc = pymupdf.open(path) - count = 0 - for i, page in enumerate(doc): - for img_idx, img in enumerate(page.get_images(full=True)): - xref = img[0] - pix = pymupdf.Pixmap(doc, xref) - if pix.n >= 5: - pix = pymupdf.Pixmap(pymupdf.csRGB, pix) - out_path = f"{output_dir}/page{i+1}_img{img_idx+1}.png" - pix.save(out_path) - count += 1 - print(f"Extracted {count} images to {output_dir}/") +\ProcessOptions\relax -def show_metadata(path): - import pymupdf - doc = pymupdf.open(path) - print(json.dumps({ - "pages": len(doc), - "title": doc.metadata.get("title", ""), - "author": doc.metadata.get("author", ""), - "subject": doc.metadata.get("subject", ""), - "creator": doc.metadata.get("creator", ""), - "producer": doc.metadata.get("producer", ""), - "format": doc.metadata.get("format", ""), - }, indent=2)) +% determine whether this is an anonymized submission +\newif\if@submission\@submissiontrue +\if@neuripsfinal\@submissionfalse\fi +\if@preprint\@submissionfalse\fi -if __name__ == "__main__": - args = sys.argv[1:] - if not args or args[0] in {"-h", "--help"}: - print(__doc__) - sys.exit(0) +% fonts +\renewcommand{\rmdefault}{ptm} +\renewcommand{\sfdefault}{phv} - path = args[0] - pages = None +% change this every year for notice string at bottom +\newcommand{\@neuripsordinal}{39th} +\newcommand{\@neuripsyear}{2025} +\newcommand{\@neuripslocation}{San Diego} - if "--pages" in args: - idx = args.index("--pages") - p = args[idx + 1] - if "-" in p: - start, end = p.split("-") - pages = list(range(int(start), int(end) + 1)) - else: - pages = [int(p)] +% acknowledgments +\usepackage{environ} +\newcommand{\acksection}{\section*{Acknowledgments and Disclosure of Funding}} +\NewEnviron{ack}{% + \acksection + \BODY +} - if "--metadata" in args: - show_metadata(path) - elif "--tables" in args: - extract_tables(path) - elif "--images" in args: - idx = args.index("--images") - output_dir = args[idx + 1] if idx + 1 < len(args) else "./images" - extract_images(path, output_dir) - elif "--markdown" in args: - extract_markdown(path, pages=pages) - else: - extract_text(path, pages=pages) + +% load natbib unless told otherwise +\if@natbib + \RequirePackage{natbib} +\fi + +% set page geometry +\usepackage[verbose=true,letterpaper]{geometry} +\AtBeginDocument{ + \newgeometry{ + textheight=9in, + textwidth=5.5in, + top=1in, + headheight=12pt, + headsep=25pt, + footskip=30pt + } + \@ifpackageloaded{fullpage} + {\PackageWarning{neurips_2025}{fullpage package not allowed! Overwriting formatting.}} + {} +} + +\widowpenalty=10000 +\clubpenalty=10000 +\flushbottom +\sloppy + + +% font sizes with reduced leading +\renewcommand{\normalsize}{% + \@setfontsize\normalsize\@xpt\@xipt + \abovedisplayskip 7\p@ \@plus 2\p@ \@minus 5\p@ + \abovedisplayshortskip \z@ \@plus 3\p@ + \belowdisplayskip \abovedisplayskip + \belowdisplayshortskip 4\p@ \@plus 3\p@ \@minus 3\p@ +} +\normalsize +\renewcommand{\small}{% + \@setfontsize\small\@ixpt\@xpt + \abovedisplayskip 6\p@ \@plus 1.5\p@ \@minus 4\p@ + \abovedisplayshortskip \z@ \@plus 2\p@ + \belowdisplayskip \abovedisplayskip + \belowdisplayshortskip 3\p@ \@plus 2\p@ \@minus 2\p@ +} +\renewcommand{\footnotesize}{\@setfontsize\footnotesize\@ixpt\@xpt} +\renewcommand{\scriptsize}{\@setfontsize\scriptsize\@viipt\@viiipt} +\renewcommand{\tiny}{\@setfontsize\tiny\@vipt\@viipt} +\renewcommand{\large}{\@setfontsize\large\@xiipt{14}} +\renewcommand{\Large}{\@setfontsize\Large\@xivpt{16}} +\renewcommand{\LARGE}{\@setfontsize\LARGE\@xviipt{20}} +\renewcommand{\huge}{\@setfontsize\huge\@xxpt{23}} +\renewcommand{\Huge}{\@setfontsize\Huge\@xxvpt{28}} + +% sections with less space +\providecommand{\section}{} +\renewcommand{\section}{% + \@startsection{section}{1}{\z@}% + {-2.0ex \@plus -0.5ex \@minus -0.2ex}% + { 1.5ex \@plus 0.3ex \@minus 0.2ex}% + {\large\bf\raggedright}% +} +\providecommand{\subsection}{} +\renewcommand{\subsection}{% + \@startsection{subsection}{2}{\z@}% + {-1.8ex \@plus -0.5ex \@minus -0.2ex}% + { 0.8ex \@plus 0.2ex}% + {\normalsize\bf\raggedright}% +} +\providecommand{\subsubsection}{} +\renewcommand{\subsubsection}{% + \@startsection{subsubsection}{3}{\z@}% + {-1.5ex \@plus -0.5ex \@minus -0.2ex}% + { 0.5ex \@plus 0.2ex}% + {\normalsize\bf\raggedright}% +} +\providecommand{\paragraph}{} +\renewcommand{\paragraph}{% + \@startsection{paragraph}{4}{\z@}% + {1.5ex \@plus 0.5ex \@minus 0.2ex}% + {-1em}% + {\normalsize\bf}% +} +\providecommand{\subparagraph}{} +\renewcommand{\subparagraph}{% + \@startsection{subparagraph}{5}{\z@}% + {1.5ex \@plus 0.5ex \@minus 0.2ex}% + {-1em}% + {\normalsize\bf}% +} +\providecommand{\subsubsubsection}{} +\renewcommand{\subsubsubsection}{% + \vskip5pt{\noindent\normalsize\rm\raggedright}% +} + +% float placement +\renewcommand{\topfraction }{0.85} +\renewcommand{\bottomfraction }{0.4} +\renewcommand{\textfraction }{0.1} +\renewcommand{\floatpagefraction}{0.7} + +\newlength{\@neuripsabovecaptionskip}\setlength{\@neuripsabovecaptionskip}{7\p@} +\newlength{\@neuripsbelowcaptionskip}\setlength{\@neuripsbelowcaptionskip}{\z@} + +\setlength{\abovecaptionskip}{\@neuripsabovecaptionskip} +\setlength{\belowcaptionskip}{\@neuripsbelowcaptionskip} + +% swap above/belowcaptionskip lengths for tables +\renewenvironment{table} + {\setlength{\abovecaptionskip}{\@neuripsbelowcaptionskip}% + \setlength{\belowcaptionskip}{\@neuripsabovecaptionskip}% + \@float{table}} + {\end@float} + +% footnote formatting +\setlength{\footnotesep }{6.65\p@} +\setlength{\skip\footins}{9\p@ \@plus 4\p@ \@minus 2\p@} +\renewcommand{\footnoterule}{\kern-3\p@ \hrule width 12pc \kern 2.6\p@} +\setcounter{footnote}{0} + +% paragraph formatting +\setlength{\parindent}{\z@} +\setlength{\parskip }{5.5\p@} + +% list formatting +\setlength{\topsep }{4\p@ \@plus 1\p@ \@minus 2\p@} +\setlength{\partopsep }{1\p@ \@plus 0.5\p@ \@minus 0.5\p@} +\setlength{\itemsep }{2\p@ \@plus 1\p@ \@minus 0.5\p@} +\setlength{\parsep }{2\p@ \@plus 1\p@ \@minus 0.5\p@} +\setlength{\leftmargin }{3pc} +\setlength{\leftmargini }{\leftmargin} +\setlength{\leftmarginii }{2em} +\setlength{\leftmarginiii}{1.5em} +\setlength{\leftmarginiv }{1.0em} +\setlength{\leftmarginv }{0.5em} +\def\@listi {\leftmargin\leftmargini} +\def\@listii {\leftmargin\leftmarginii + \labelwidth\leftmarginii + \advance\labelwidth-\labelsep + \topsep 2\p@ \@plus 1\p@ \@minus 0.5\p@ + \parsep 1\p@ \@plus 0.5\p@ \@minus 0.5\p@ + \itemsep \parsep} +\def\@listiii{\leftmargin\leftmarginiii + \labelwidth\leftmarginiii + \advance\labelwidth-\labelsep + \topsep 1\p@ \@plus 0.5\p@ \@minus 0.5\p@ + \parsep \z@ + \partopsep 0.5\p@ \@plus 0\p@ \@minus 0.5\p@ + \itemsep \topsep} +\def\@listiv {\leftmargin\leftmarginiv + \labelwidth\leftmarginiv + \advance\labelwidth-\labelsep} +\def\@listv {\leftmargin\leftmarginv + \labelwidth\leftmarginv + \advance\labelwidth-\labelsep} +\def\@listvi {\leftmargin\leftmarginvi + \labelwidth\leftmarginvi + \advance\labelwidth-\labelsep} + +% create title +\providecommand{\maketitle}{} +\renewcommand{\maketitle}{% + \par + \begingroup + \renewcommand{\thefootnote}{\fnsymbol{footnote}} + % for perfect author name centering + \renewcommand{\@makefnmark}{\hbox to \z@{$^{\@thefnmark}$\hss}} + % The footnote-mark was overlapping the footnote-text, + % added the following to fix this problem (MK) + \long\def\@makefntext##1{% + \parindent 1em\noindent + \hbox to 1.8em{\hss $\m@th ^{\@thefnmark}$}##1 + } + \thispagestyle{empty} + \@maketitle + \@thanks + \@notice + \endgroup + \let\maketitle\relax + \let\thanks\relax +} + +% rules for title box at top of first page +\newcommand{\@toptitlebar}{ + \hrule height 4\p@ + \vskip 0.25in + \vskip -\parskip% +} +\newcommand{\@bottomtitlebar}{ + \vskip 0.29in + \vskip -\parskip + \hrule height 1\p@ + \vskip 0.09in% +} + +% create title (includes both anonymized and non-anonymized versions) +\providecommand{\@maketitle}{} +\renewcommand{\@maketitle}{% + \vbox{% + \hsize\textwidth + \linewidth\hsize + \vskip 0.1in + \@toptitlebar + \centering + {\LARGE\bf \@title\par} + \@bottomtitlebar + \if@submission + \begin{tabular}[t]{c}\bf\rule{\z@}{24\p@} + Anonymous Author(s) \\ + Affiliation \\ + Address \\ + \texttt{email} \\ + \end{tabular}% + \else + \def\And{% + \end{tabular}\hfil\linebreak[0]\hfil% + \begin{tabular}[t]{c}\bf\rule{\z@}{24\p@}\ignorespaces% + } + \def\AND{% + \end{tabular}\hfil\linebreak[4]\hfil% + \begin{tabular}[t]{c}\bf\rule{\z@}{24\p@}\ignorespaces% + } + \begin{tabular}[t]{c}\bf\rule{\z@}{24\p@}\@author\end{tabular}% + \fi + \vskip 0.3in \@minus 0.1in + } +} + +% add conference notice to bottom of first page +\newcommand{\ftype@noticebox}{8} +\newcommand{\@notice}{% + % give a bit of extra room back to authors on first page + \enlargethispage{2\baselineskip}% + \@float{noticebox}[b]% + \footnotesize\@noticestring% + \end@float% +} + +% abstract styling +\renewenvironment{abstract}% +{% + \vskip 0.075in% + \centerline% + {\large\bf Abstract}% + \vspace{0.5ex}% + \begin{quote}% +} +{ + \par% + \end{quote}% + \vskip 1ex% +} + +% For the paper checklist +\newcommand{\answerYes}[1][]{\textcolor{blue}{[Yes] #1}} +\newcommand{\answerNo}[1][]{\textcolor{orange}{[No] #1}} +\newcommand{\answerNA}[1][]{\textcolor{gray}{[NA] #1}} +\newcommand{\answerTODO}[1][]{\textcolor{red}{\bf [TODO]}} +\newcommand{\justificationTODO}[1][]{\textcolor{red}{\bf [TODO]}} + +% handle tweaks for camera-ready copy vs. submission copy +\if@preprint + \newcommand{\@noticestring}{% + Preprint. Under review.% + } +\else + \if@neuripsfinal + \newcommand{\@noticestring}{% + \@neuripsordinal\/ Conference on Neural Information Processing Systems + (NeurIPS \@neuripsyear).%, \@neuripslocation.% + } + \else + \newcommand{\@noticestring}{% + Submitted to \@neuripsordinal\/ Conference on Neural Information + Processing Systems (NeurIPS \@neuripsyear). Do not distribute.% + } + + % hide the acknowledgements + \NewEnviron{hide}{} + \let\ack\hide + \let\endack\endhide + + % line numbers for submission + \RequirePackage{lineno} + \linenumbers + + % fix incompatibilities between lineno and amsmath, if required, by + % transparently wrapping linenomath environments around amsmath + % environments + \AtBeginDocument{% + \@ifpackageloaded{amsmath}{% + \newcommand*\patchAmsMathEnvironmentForLineno[1]{% + \expandafter\let\csname old#1\expandafter\endcsname\csname #1\endcsname + \expandafter\let\csname oldend#1\expandafter\endcsname\csname end#1\endcsname + \renewenvironment{#1}% + {\linenomath\csname old#1\endcsname}% + {\csname oldend#1\endcsname\endlinenomath}% + }% + \newcommand*\patchBothAmsMathEnvironmentsForLineno[1]{% + \patchAmsMathEnvironmentForLineno{#1}% + \patchAmsMathEnvironmentForLineno{#1*}% + }% + \patchBothAmsMathEnvironmentsForLineno{equation}% + \patchBothAmsMathEnvironmentsForLineno{align}% + \patchBothAmsMathEnvironmentsForLineno{flalign}% + \patchBothAmsMathEnvironmentsForLineno{alignat}% + \patchBothAmsMathEnvironmentsForLineno{gather}% + \patchBothAmsMathEnvironmentsForLineno{multline}% + } + {} + } + \fi +\fi + + +\endinput diff --git a/skills/productivity/linear/scripts/linear_api.py b/skills/productivity/linear/scripts/linear_api.py index cb8c5d8..396adef 100644 Binary files a/skills/productivity/linear/scripts/linear_api.py and b/skills/productivity/linear/scripts/linear_api.py differ diff --git a/skills/productivity/ocr-and-documents/scripts/extract_pymupdf.py b/skills/productivity/ocr-and-documents/scripts/extract_pymupdf.py index 50cb8ee..d5297aa 100644 --- a/skills/productivity/ocr-and-documents/scripts/extract_pymupdf.py +++ b/skills/productivity/ocr-and-documents/scripts/extract_pymupdf.py @@ -1,98 +1,382 @@ -#!/usr/bin/env python3 -"""Extract text from documents using pymupdf. Lightweight (~25MB), no models. +% partial rewrite of the LaTeX2e package for submissions to the +% Conference on Neural Information Processing Systems (NeurIPS): +% +% - uses more LaTeX conventions +% - line numbers at submission time replaced with aligned numbers from +% lineno package +% - \nipsfinalcopy replaced with [final] package option +% - automatically loads times package for authors +% - loads natbib automatically; this can be suppressed with the +% [nonatbib] package option +% - adds foot line to first page identifying the conference +% - adds preprint option for submission to e.g. arXiv +% - conference acronym modified +% +% Roman Garnett (garnett@wustl.edu) and the many authors of +% nips15submit_e.sty, including MK and drstrip@sandia +% +% last revision: April 2025 -Usage: - python extract_pymupdf.py document.pdf - python extract_pymupdf.py document.pdf --markdown - python extract_pymupdf.py document.pdf --pages 0-4 - python extract_pymupdf.py document.pdf --images output_dir/ - python extract_pymupdf.py document.pdf --tables - python extract_pymupdf.py document.pdf --metadata -""" -import sys -import json +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{neurips_2025}[2025/04/02 NeurIPS 2025 submission/camera-ready style file] -def extract_text(path, pages=None): - import pymupdf - doc = pymupdf.open(path) - page_range = range(len(doc)) if pages is None else pages - for i in page_range: - if i < len(doc): - print(f"\n--- Page {i+1}/{len(doc)} ---\n") - print(doc[i].get_text()) +% declare final option, which creates camera-ready copy +\newif\if@neuripsfinal\@neuripsfinalfalse +\DeclareOption{final}{ + \@neuripsfinaltrue +} -def extract_markdown(path, pages=None): - import pymupdf4llm - md = pymupdf4llm.to_markdown(path, pages=pages) - print(md) +% declare nonatbib option, which does not load natbib in case of +% package clash (users can pass options to natbib via +% \PassOptionsToPackage) +\newif\if@natbib\@natbibtrue +\DeclareOption{nonatbib}{ + \@natbibfalse +} -def extract_tables(path): - import pymupdf - doc = pymupdf.open(path) - for i, page in enumerate(doc): - tables = page.find_tables() - for j, table in enumerate(tables.tables): - print(f"\n--- Page {i+1}, Table {j+1} ---\n") - df = table.to_pandas() - print(df.to_markdown(index=False)) +% declare preprint option, which creates a preprint version ready for +% upload to, e.g., arXiv +\newif\if@preprint\@preprintfalse +\DeclareOption{preprint}{ + \@preprinttrue +} -def extract_images(path, output_dir): - import pymupdf - from pathlib import Path - Path(output_dir).mkdir(parents=True, exist_ok=True) - doc = pymupdf.open(path) - count = 0 - for i, page in enumerate(doc): - for img_idx, img in enumerate(page.get_images(full=True)): - xref = img[0] - pix = pymupdf.Pixmap(doc, xref) - if pix.n >= 5: - pix = pymupdf.Pixmap(pymupdf.csRGB, pix) - out_path = f"{output_dir}/page{i+1}_img{img_idx+1}.png" - pix.save(out_path) - count += 1 - print(f"Extracted {count} images to {output_dir}/") +\ProcessOptions\relax -def show_metadata(path): - import pymupdf - doc = pymupdf.open(path) - print(json.dumps({ - "pages": len(doc), - "title": doc.metadata.get("title", ""), - "author": doc.metadata.get("author", ""), - "subject": doc.metadata.get("subject", ""), - "creator": doc.metadata.get("creator", ""), - "producer": doc.metadata.get("producer", ""), - "format": doc.metadata.get("format", ""), - }, indent=2)) +% determine whether this is an anonymized submission +\newif\if@submission\@submissiontrue +\if@neuripsfinal\@submissionfalse\fi +\if@preprint\@submissionfalse\fi -if __name__ == "__main__": - args = sys.argv[1:] - if not args or args[0] in {"-h", "--help"}: - print(__doc__) - sys.exit(0) +% fonts +\renewcommand{\rmdefault}{ptm} +\renewcommand{\sfdefault}{phv} - path = args[0] - pages = None +% change this every year for notice string at bottom +\newcommand{\@neuripsordinal}{39th} +\newcommand{\@neuripsyear}{2025} +\newcommand{\@neuripslocation}{San Diego} - if "--pages" in args: - idx = args.index("--pages") - p = args[idx + 1] - if "-" in p: - start, end = p.split("-") - pages = list(range(int(start), int(end) + 1)) - else: - pages = [int(p)] +% acknowledgments +\usepackage{environ} +\newcommand{\acksection}{\section*{Acknowledgments and Disclosure of Funding}} +\NewEnviron{ack}{% + \acksection + \BODY +} - if "--metadata" in args: - show_metadata(path) - elif "--tables" in args: - extract_tables(path) - elif "--images" in args: - idx = args.index("--images") - output_dir = args[idx + 1] if idx + 1 < len(args) else "./images" - extract_images(path, output_dir) - elif "--markdown" in args: - extract_markdown(path, pages=pages) - else: - extract_text(path, pages=pages) + +% load natbib unless told otherwise +\if@natbib + \RequirePackage{natbib} +\fi + +% set page geometry +\usepackage[verbose=true,letterpaper]{geometry} +\AtBeginDocument{ + \newgeometry{ + textheight=9in, + textwidth=5.5in, + top=1in, + headheight=12pt, + headsep=25pt, + footskip=30pt + } + \@ifpackageloaded{fullpage} + {\PackageWarning{neurips_2025}{fullpage package not allowed! Overwriting formatting.}} + {} +} + +\widowpenalty=10000 +\clubpenalty=10000 +\flushbottom +\sloppy + + +% font sizes with reduced leading +\renewcommand{\normalsize}{% + \@setfontsize\normalsize\@xpt\@xipt + \abovedisplayskip 7\p@ \@plus 2\p@ \@minus 5\p@ + \abovedisplayshortskip \z@ \@plus 3\p@ + \belowdisplayskip \abovedisplayskip + \belowdisplayshortskip 4\p@ \@plus 3\p@ \@minus 3\p@ +} +\normalsize +\renewcommand{\small}{% + \@setfontsize\small\@ixpt\@xpt + \abovedisplayskip 6\p@ \@plus 1.5\p@ \@minus 4\p@ + \abovedisplayshortskip \z@ \@plus 2\p@ + \belowdisplayskip \abovedisplayskip + \belowdisplayshortskip 3\p@ \@plus 2\p@ \@minus 2\p@ +} +\renewcommand{\footnotesize}{\@setfontsize\footnotesize\@ixpt\@xpt} +\renewcommand{\scriptsize}{\@setfontsize\scriptsize\@viipt\@viiipt} +\renewcommand{\tiny}{\@setfontsize\tiny\@vipt\@viipt} +\renewcommand{\large}{\@setfontsize\large\@xiipt{14}} +\renewcommand{\Large}{\@setfontsize\Large\@xivpt{16}} +\renewcommand{\LARGE}{\@setfontsize\LARGE\@xviipt{20}} +\renewcommand{\huge}{\@setfontsize\huge\@xxpt{23}} +\renewcommand{\Huge}{\@setfontsize\Huge\@xxvpt{28}} + +% sections with less space +\providecommand{\section}{} +\renewcommand{\section}{% + \@startsection{section}{1}{\z@}% + {-2.0ex \@plus -0.5ex \@minus -0.2ex}% + { 1.5ex \@plus 0.3ex \@minus 0.2ex}% + {\large\bf\raggedright}% +} +\providecommand{\subsection}{} +\renewcommand{\subsection}{% + \@startsection{subsection}{2}{\z@}% + {-1.8ex \@plus -0.5ex \@minus -0.2ex}% + { 0.8ex \@plus 0.2ex}% + {\normalsize\bf\raggedright}% +} +\providecommand{\subsubsection}{} +\renewcommand{\subsubsection}{% + \@startsection{subsubsection}{3}{\z@}% + {-1.5ex \@plus -0.5ex \@minus -0.2ex}% + { 0.5ex \@plus 0.2ex}% + {\normalsize\bf\raggedright}% +} +\providecommand{\paragraph}{} +\renewcommand{\paragraph}{% + \@startsection{paragraph}{4}{\z@}% + {1.5ex \@plus 0.5ex \@minus 0.2ex}% + {-1em}% + {\normalsize\bf}% +} +\providecommand{\subparagraph}{} +\renewcommand{\subparagraph}{% + \@startsection{subparagraph}{5}{\z@}% + {1.5ex \@plus 0.5ex \@minus 0.2ex}% + {-1em}% + {\normalsize\bf}% +} +\providecommand{\subsubsubsection}{} +\renewcommand{\subsubsubsection}{% + \vskip5pt{\noindent\normalsize\rm\raggedright}% +} + +% float placement +\renewcommand{\topfraction }{0.85} +\renewcommand{\bottomfraction }{0.4} +\renewcommand{\textfraction }{0.1} +\renewcommand{\floatpagefraction}{0.7} + +\newlength{\@neuripsabovecaptionskip}\setlength{\@neuripsabovecaptionskip}{7\p@} +\newlength{\@neuripsbelowcaptionskip}\setlength{\@neuripsbelowcaptionskip}{\z@} + +\setlength{\abovecaptionskip}{\@neuripsabovecaptionskip} +\setlength{\belowcaptionskip}{\@neuripsbelowcaptionskip} + +% swap above/belowcaptionskip lengths for tables +\renewenvironment{table} + {\setlength{\abovecaptionskip}{\@neuripsbelowcaptionskip}% + \setlength{\belowcaptionskip}{\@neuripsabovecaptionskip}% + \@float{table}} + {\end@float} + +% footnote formatting +\setlength{\footnotesep }{6.65\p@} +\setlength{\skip\footins}{9\p@ \@plus 4\p@ \@minus 2\p@} +\renewcommand{\footnoterule}{\kern-3\p@ \hrule width 12pc \kern 2.6\p@} +\setcounter{footnote}{0} + +% paragraph formatting +\setlength{\parindent}{\z@} +\setlength{\parskip }{5.5\p@} + +% list formatting +\setlength{\topsep }{4\p@ \@plus 1\p@ \@minus 2\p@} +\setlength{\partopsep }{1\p@ \@plus 0.5\p@ \@minus 0.5\p@} +\setlength{\itemsep }{2\p@ \@plus 1\p@ \@minus 0.5\p@} +\setlength{\parsep }{2\p@ \@plus 1\p@ \@minus 0.5\p@} +\setlength{\leftmargin }{3pc} +\setlength{\leftmargini }{\leftmargin} +\setlength{\leftmarginii }{2em} +\setlength{\leftmarginiii}{1.5em} +\setlength{\leftmarginiv }{1.0em} +\setlength{\leftmarginv }{0.5em} +\def\@listi {\leftmargin\leftmargini} +\def\@listii {\leftmargin\leftmarginii + \labelwidth\leftmarginii + \advance\labelwidth-\labelsep + \topsep 2\p@ \@plus 1\p@ \@minus 0.5\p@ + \parsep 1\p@ \@plus 0.5\p@ \@minus 0.5\p@ + \itemsep \parsep} +\def\@listiii{\leftmargin\leftmarginiii + \labelwidth\leftmarginiii + \advance\labelwidth-\labelsep + \topsep 1\p@ \@plus 0.5\p@ \@minus 0.5\p@ + \parsep \z@ + \partopsep 0.5\p@ \@plus 0\p@ \@minus 0.5\p@ + \itemsep \topsep} +\def\@listiv {\leftmargin\leftmarginiv + \labelwidth\leftmarginiv + \advance\labelwidth-\labelsep} +\def\@listv {\leftmargin\leftmarginv + \labelwidth\leftmarginv + \advance\labelwidth-\labelsep} +\def\@listvi {\leftmargin\leftmarginvi + \labelwidth\leftmarginvi + \advance\labelwidth-\labelsep} + +% create title +\providecommand{\maketitle}{} +\renewcommand{\maketitle}{% + \par + \begingroup + \renewcommand{\thefootnote}{\fnsymbol{footnote}} + % for perfect author name centering + \renewcommand{\@makefnmark}{\hbox to \z@{$^{\@thefnmark}$\hss}} + % The footnote-mark was overlapping the footnote-text, + % added the following to fix this problem (MK) + \long\def\@makefntext##1{% + \parindent 1em\noindent + \hbox to 1.8em{\hss $\m@th ^{\@thefnmark}$}##1 + } + \thispagestyle{empty} + \@maketitle + \@thanks + \@notice + \endgroup + \let\maketitle\relax + \let\thanks\relax +} + +% rules for title box at top of first page +\newcommand{\@toptitlebar}{ + \hrule height 4\p@ + \vskip 0.25in + \vskip -\parskip% +} +\newcommand{\@bottomtitlebar}{ + \vskip 0.29in + \vskip -\parskip + \hrule height 1\p@ + \vskip 0.09in% +} + +% create title (includes both anonymized and non-anonymized versions) +\providecommand{\@maketitle}{} +\renewcommand{\@maketitle}{% + \vbox{% + \hsize\textwidth + \linewidth\hsize + \vskip 0.1in + \@toptitlebar + \centering + {\LARGE\bf \@title\par} + \@bottomtitlebar + \if@submission + \begin{tabular}[t]{c}\bf\rule{\z@}{24\p@} + Anonymous Author(s) \\ + Affiliation \\ + Address \\ + \texttt{email} \\ + \end{tabular}% + \else + \def\And{% + \end{tabular}\hfil\linebreak[0]\hfil% + \begin{tabular}[t]{c}\bf\rule{\z@}{24\p@}\ignorespaces% + } + \def\AND{% + \end{tabular}\hfil\linebreak[4]\hfil% + \begin{tabular}[t]{c}\bf\rule{\z@}{24\p@}\ignorespaces% + } + \begin{tabular}[t]{c}\bf\rule{\z@}{24\p@}\@author\end{tabular}% + \fi + \vskip 0.3in \@minus 0.1in + } +} + +% add conference notice to bottom of first page +\newcommand{\ftype@noticebox}{8} +\newcommand{\@notice}{% + % give a bit of extra room back to authors on first page + \enlargethispage{2\baselineskip}% + \@float{noticebox}[b]% + \footnotesize\@noticestring% + \end@float% +} + +% abstract styling +\renewenvironment{abstract}% +{% + \vskip 0.075in% + \centerline% + {\large\bf Abstract}% + \vspace{0.5ex}% + \begin{quote}% +} +{ + \par% + \end{quote}% + \vskip 1ex% +} + +% For the paper checklist +\newcommand{\answerYes}[1][]{\textcolor{blue}{[Yes] #1}} +\newcommand{\answerNo}[1][]{\textcolor{orange}{[No] #1}} +\newcommand{\answerNA}[1][]{\textcolor{gray}{[NA] #1}} +\newcommand{\answerTODO}[1][]{\textcolor{red}{\bf [TODO]}} +\newcommand{\justificationTODO}[1][]{\textcolor{red}{\bf [TODO]}} + +% handle tweaks for camera-ready copy vs. submission copy +\if@preprint + \newcommand{\@noticestring}{% + Preprint. Under review.% + } +\else + \if@neuripsfinal + \newcommand{\@noticestring}{% + \@neuripsordinal\/ Conference on Neural Information Processing Systems + (NeurIPS \@neuripsyear).%, \@neuripslocation.% + } + \else + \newcommand{\@noticestring}{% + Submitted to \@neuripsordinal\/ Conference on Neural Information + Processing Systems (NeurIPS \@neuripsyear). Do not distribute.% + } + + % hide the acknowledgements + \NewEnviron{hide}{} + \let\ack\hide + \let\endack\endhide + + % line numbers for submission + \RequirePackage{lineno} + \linenumbers + + % fix incompatibilities between lineno and amsmath, if required, by + % transparently wrapping linenomath environments around amsmath + % environments + \AtBeginDocument{% + \@ifpackageloaded{amsmath}{% + \newcommand*\patchAmsMathEnvironmentForLineno[1]{% + \expandafter\let\csname old#1\expandafter\endcsname\csname #1\endcsname + \expandafter\let\csname oldend#1\expandafter\endcsname\csname end#1\endcsname + \renewenvironment{#1}% + {\linenomath\csname old#1\endcsname}% + {\csname oldend#1\endcsname\endlinenomath}% + }% + \newcommand*\patchBothAmsMathEnvironmentsForLineno[1]{% + \patchAmsMathEnvironmentForLineno{#1}% + \patchAmsMathEnvironmentForLineno{#1*}% + }% + \patchBothAmsMathEnvironmentsForLineno{equation}% + \patchBothAmsMathEnvironmentsForLineno{align}% + \patchBothAmsMathEnvironmentsForLineno{flalign}% + \patchBothAmsMathEnvironmentsForLineno{alignat}% + \patchBothAmsMathEnvironmentsForLineno{gather}% + \patchBothAmsMathEnvironmentsForLineno{multline}% + } + {} + } + \fi +\fi + + +\endinput