> ## Documentation Index
> Fetch the complete documentation index at: https://resources.latex-cloud-studio.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Pseudocode in LaTeX: algorithm, algorithmicx, and algpseudocode

> Write pseudocode in LaTeX with algorithm and algpseudocode. Copy a working example with line numbers, loops, procedures, captions, and error fixes.

export const RenderedOutput = ({title = "Rendered output", ctaHref, ctaLabel = "Open LaTeX Cloud Studio", children}) => {
  const [isExpanded, setIsExpanded] = useState(false);
  const trackEditorCta = () => {
    const target = new URL(ctaHref, window.location.href);
    globalThis.posthog?.capture?.("docs_app_cta_clicked", {
      source_page: window.location.pathname,
      source_section: "rendered_output",
      cta_variant: "first_compiled_example",
      target_url: target.toString(),
      target_utm_source: target.searchParams.get("utm_source"),
      target_utm_medium: target.searchParams.get("utm_medium"),
      target_utm_campaign: target.searchParams.get("utm_campaign"),
      target_utm_content: target.searchParams.get("utm_content")
    }, {
      transport: "sendBeacon",
      send_instantly: true
    });
  };
  return <details className="rendered-output" onToggle={event => setIsExpanded(event.currentTarget.open)}>
      <summary className="rendered-output__summary">
        <span className="rendered-output__title">{title}</span>
        <span className="rendered-output__hint" aria-hidden="true">View compiled result</span>
      </summary>
      {isExpanded && <div className="rendered-output__content">
          {children}
          {ctaHref && <aside className="rendered-output__cta" aria-label="Continue in the LaTeX editor">
              <span>
                <strong>Ready to use this syntax?</strong>
                Continue in the browser editor when you want to adapt the example in a real project.
              </span>
              <a href={ctaHref} onClick={trackEditorCta}>{ctaLabel}<span aria-hidden="true"> →</span></a>
            </aside>}
        </div>}
    </details>;
};

export const LatexSource = ({filename, source}) => {
  const [copyStatus, setCopyStatus] = useState("Copy");
  const copySource = async () => {
    try {
      await navigator.clipboard.writeText(source);
      setCopyStatus("Copied");
    } catch {
      setCopyStatus("Select and copy");
    }
  };
  return <figure className="latex-source">
      <figcaption className="latex-source__header">
        <span className="latex-source__filename">{filename}</span>
        <button type="button" className="latex-source__copy" onClick={copySource} aria-live="polite">
          {copyStatus}
        </button>
      </figcaption>
      <pre className="latex-source__pre" aria-label={`LaTeX source: ${filename}`} tabIndex="0">
        <code className="language-latex">{source}</code>
      </pre>
    </figure>;
};

export const LatexPreview = ({src, alt, caption, width, height}) => {
  const minZoom = 1;
  const maxZoom = 3;
  const zoomStep = 0.5;
  const measureSvgContent = async (assetSrc, pageWidth, pageHeight) => {
    const cacheKey = "__latexCloudSvgContentBoxCache";
    const contentBoxCache = globalThis[cacheKey] ?? new Map();
    globalThis[cacheKey] = contentBoxCache;
    if (contentBoxCache.has(assetSrc)) return contentBoxCache.get(assetSrc);
    const measurement = (async () => {
      const assetUrl = new URL(assetSrc, window.location.href);
      if (assetUrl.origin !== window.location.origin) {
        throw new Error("Rendered output must use a same-origin SVG asset.");
      }
      const response = await fetch(assetUrl, {
        credentials: "same-origin"
      });
      if (!response.ok) throw new Error(`Rendered output request failed with ${response.status}.`);
      const source = await response.text();
      const documentNode = new DOMParser().parseFromString(source, "image/svg+xml");
      if (documentNode.querySelector("parsererror")) throw new Error("Rendered output is not valid SVG.");
      const sourceSvg = documentNode.documentElement;
      sourceSvg.querySelectorAll("script, foreignObject").forEach(node => node.remove());
      [sourceSvg, ...sourceSvg.querySelectorAll("*")].forEach(node => {
        [...node.attributes].forEach(attribute => {
          if ((/^on/i).test(attribute.name)) node.removeAttribute(attribute.name);
          if ((attribute.name === "href" || attribute.name === "xlink:href") && !attribute.value.startsWith("#")) {
            node.removeAttribute(attribute.name);
          }
        });
      });
      const measurementHost = document.createElement("div");
      measurementHost.className = "latex-preview__measurement-host";
      const measuredSvg = document.importNode(sourceSvg, true);
      measuredSvg.setAttribute("aria-hidden", "true");
      measurementHost.appendChild(measuredSvg);
      document.body.appendChild(measurementHost);
      try {
        const measuredElements = [...measuredSvg.children].filter(node => !["defs", "desc", "metadata", "style", "title"].includes(node.tagName.toLowerCase()));
        const elementBounds = measuredElements.map(node => node.getBBox()).filter(box => [box.x, box.y, box.width, box.height].every(Number.isFinite) && box.width > 0 && box.height > 0);
        if (elementBounds.length === 0) {
          throw new Error("Rendered output has no measurable visible content.");
        }
        const sortedBounds = [...elementBounds].sort((left, right) => left.y - right.y);
        const clusterGap = pageHeight * 0.045;
        const clusters = [];
        sortedBounds.forEach(box => {
          const current = clusters[clusters.length - 1];
          if (!current || box.y - current.bottom > clusterGap) {
            clusters.push({
              boxes: [box],
              bottom: box.y + box.height
            });
            return;
          }
          current.boxes.push(box);
          current.bottom = Math.max(current.bottom, box.y + box.height);
        });
        const contentClusters = clusters.filter(cluster => {
          const clusterBox = cluster.boxes.reduce((combined, box) => {
            const right = Math.max(combined.x + combined.width, box.x + box.width);
            const bottom = Math.max(combined.y + combined.height, box.y + box.height);
            const x = Math.min(combined.x, box.x);
            const y = Math.min(combined.y, box.y);
            return {
              x,
              y,
              width: right - x,
              height: bottom - y
            };
          });
          const centerY = clusterBox.y + clusterBox.height / 2;
          const isMarginFurniture = cluster.boxes.length <= 2 && clusterBox.width < pageWidth * 0.2 && clusterBox.height < pageHeight * 0.04 && (centerY < pageHeight * 0.08 || centerY > pageHeight * 0.8);
          return !isMarginFurniture;
        });
        const visibleBounds = (contentClusters.length > 0 ? contentClusters : clusters).flatMap(cluster => cluster.boxes);
        const bounds = visibleBounds.reduce((combined, box) => {
          const right = Math.max(combined.x + combined.width, box.x + box.width);
          const bottom = Math.max(combined.y + combined.height, box.y + box.height);
          const x = Math.min(combined.x, box.x);
          const y = Math.min(combined.y, box.y);
          return {
            x,
            y,
            width: right - x,
            height: bottom - y
          };
        });
        const clampValue = (value, minimum, maximum) => Math.min(maximum, Math.max(minimum, value));
        const padding = Math.max(8, Math.min(pageWidth, pageHeight) * 0.025);
        const x = clampValue(bounds.x - padding, 0, pageWidth);
        const y = clampValue(bounds.y - padding, 0, pageHeight);
        const right = clampValue(bounds.x + bounds.width + padding, 0, pageWidth);
        const bottom = clampValue(bounds.y + bounds.height + padding, 0, pageHeight);
        return {
          x,
          y,
          width: right - x,
          height: bottom - y
        };
      } finally {
        measurementHost.remove();
      }
    })();
    contentBoxCache.set(assetSrc, measurement);
    measurement.catch(() => contentBoxCache.delete(assetSrc));
    return measurement;
  };
  const renderPreviewAsset = ({contentBox: assetContentBox, loading}) => {
    if (!assetContentBox) {
      return <img className="latex-preview__asset" src={src} alt={alt} width={width} height={height} loading={loading} draggable="false" />;
    }
    return <svg className="latex-preview__asset" viewBox={`${assetContentBox.x} ${assetContentBox.y} ${assetContentBox.width} ${assetContentBox.height}`} preserveAspectRatio="xMidYMid meet" role="img" aria-label={alt}>
        <image href={src} x="0" y="0" width={width} height={height} />
      </svg>;
  };
  const [isOpen, setIsOpen] = useState(false);
  const [frameMode, setFrameMode] = useState("content");
  const [viewMode, setViewMode] = useState("fit");
  const [zoom, setZoom] = useState(minZoom);
  const [contentBox, setContentBox] = useState(null);
  const [measurementStatus, setMeasurementStatus] = useState("loading");
  const dialogRef = useRef(null);
  const closeButtonRef = useRef(null);
  const viewportRef = useRef(null);
  const previousFocusRef = useRef(null);
  const dragRef = useRef(null);
  useEffect(() => {
    let isCurrent = true;
    setMeasurementStatus("loading");
    measureSvgContent(src, width, height).then(box => {
      if (!isCurrent) return;
      setContentBox(box);
      setMeasurementStatus("ready");
    }).catch(() => {
      if (!isCurrent) return;
      setContentBox(null);
      setFrameMode("page");
      setMeasurementStatus("error");
    });
    return () => {
      isCurrent = false;
    };
  }, [height, src, width]);
  const closeViewer = useCallback(() => {
    setIsOpen(false);
  }, []);
  const openViewer = () => {
    previousFocusRef.current = document.activeElement;
    setFrameMode(contentBox ? "content" : "page");
    setViewMode("fit");
    setZoom(minZoom);
    setIsOpen(true);
  };
  const applyZoom = useCallback(nextZoom => {
    const boundedZoom = Math.min(maxZoom, Math.max(minZoom, nextZoom));
    setViewMode("custom");
    setZoom(boundedZoom);
  }, []);
  const zoomIn = useCallback(() => {
    applyZoom(viewMode === "fit" ? minZoom + zoomStep : zoom + zoomStep);
  }, [applyZoom, viewMode, zoom]);
  const zoomOut = useCallback(() => {
    applyZoom(viewMode === "fit" ? minZoom : zoom - zoomStep);
  }, [applyZoom, viewMode, zoom]);
  useEffect(() => {
    if (!isOpen) return undefined;
    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    closeButtonRef.current?.focus();
    return () => {
      document.body.style.overflow = previousOverflow;
      previousFocusRef.current?.focus?.();
    };
  }, [isOpen]);
  useEffect(() => {
    if (!isOpen) return undefined;
    const handleKeyDown = event => {
      if (event.key === "Escape") {
        event.preventDefault();
        closeViewer();
        return;
      }
      if ((event.key === "+" || event.key === "=") && !event.metaKey && !event.ctrlKey) {
        event.preventDefault();
        zoomIn();
        return;
      }
      if (event.key === "-" && !event.metaKey && !event.ctrlKey) {
        event.preventDefault();
        zoomOut();
        return;
      }
      if (event.key !== "Tab" || !dialogRef.current) return;
      const focusable = [...dialogRef.current.querySelectorAll('button:not([disabled]), a[href], [tabindex]:not([tabindex="-1"])')];
      if (focusable.length === 0) return;
      const first = focusable[0];
      const last = focusable[focusable.length - 1];
      if (event.shiftKey && document.activeElement === first) {
        event.preventDefault();
        last.focus();
      } else if (!event.shiftKey && document.activeElement === last) {
        event.preventDefault();
        first.focus();
      }
    };
    window.addEventListener("keydown", handleKeyDown);
    return () => {
      window.removeEventListener("keydown", handleKeyDown);
    };
  }, [closeViewer, isOpen, zoomIn, zoomOut]);
  const startDrag = event => {
    if (event.button !== 0 || !viewportRef.current) return;
    const viewport = viewportRef.current;
    dragRef.current = {
      pointerId: event.pointerId,
      x: event.clientX,
      y: event.clientY,
      scrollLeft: viewport.scrollLeft,
      scrollTop: viewport.scrollTop
    };
    viewport.setPointerCapture(event.pointerId);
    viewport.dataset.dragging = "true";
  };
  const continueDrag = event => {
    const drag = dragRef.current;
    const viewport = viewportRef.current;
    if (!drag || !viewport || drag.pointerId !== event.pointerId) return;
    viewport.scrollLeft = drag.scrollLeft - (event.clientX - drag.x);
    viewport.scrollTop = drag.scrollTop - (event.clientY - drag.y);
  };
  const stopDrag = event => {
    const viewport = viewportRef.current;
    if (viewport?.hasPointerCapture(event.pointerId)) viewport.releasePointerCapture(event.pointerId);
    if (viewport) delete viewport.dataset.dragging;
    dragRef.current = null;
  };
  const activeContentBox = frameMode === "content" ? contentBox : null;
  const activeWidth = activeContentBox?.width ?? width;
  const activeHeight = activeContentBox?.height ?? height;
  const activeRatio = activeWidth / activeHeight;
  const inlineContentBox = measurementStatus === "ready" ? contentBox : null;
  const inlineWidth = inlineContentBox?.width ?? width;
  const inlineHeight = inlineContentBox?.height ?? height;
  const inlineGeometry = {
    aspectRatio: `${inlineWidth} / ${inlineHeight}`,
    maxWidth: `${30 * inlineWidth / inlineHeight}rem`
  };
  const imageStyle = viewMode === "fit" ? {
    aspectRatio: `${activeWidth} / ${activeHeight}`,
    width: "100%",
    maxWidth: `${Math.max(16, activeRatio * 78)}dvh`
  } : {
    aspectRatio: `${activeWidth} / ${activeHeight}`,
    width: `${zoom * 100}%`,
    maxWidth: "none"
  };
  const zoomLabel = viewMode === "fit" ? frameMode === "content" ? "Fit content" : "Full page" : `${Math.round(zoom * 100)}%`;
  return <figure className="latex-preview">
      <button type="button" className="latex-preview__trigger" onClick={openViewer} aria-haspopup="dialog" aria-label={`Open zoomable preview: ${alt}`}>
        <span className="latex-preview__page" style={inlineGeometry}>
          {measurementStatus === "loading" ? <span className="latex-preview__loading" role="status">Preparing compiled output…</span> : renderPreviewAsset({
    src,
    alt,
    width,
    height,
    contentBox: inlineContentBox,
    loading: "lazy"
  })}
        </span>
        <span className="latex-preview__trigger-label" aria-hidden="true">
          <span className="latex-preview__trigger-icon">⌕</span>
          Open viewer
        </span>
      </button>
      <figcaption className="latex-preview__caption">
        <span>
          {caption}
          {measurementStatus === "error" && <span className="latex-preview__status" role="status"> Content fit is unavailable; the complete vector page is shown.</span>}
        </span>
        <a href={src} target="_blank" rel="noreferrer" className="latex-preview__source-link">Open SVG</a>
      </figcaption>

      {isOpen && <div className="latex-preview__backdrop" onMouseDown={event => {
    if (event.target === event.currentTarget) closeViewer();
  }}>
          <section ref={dialogRef} className="latex-preview__dialog" role="dialog" aria-modal="true" aria-label={`Rendered LaTeX viewer: ${alt}`}>
            <header className="latex-preview__toolbar">
              <div className="latex-preview__identity">
                <span className="latex-preview__eyebrow">Compiled LaTeX</span>
                <span className="latex-preview__filename">{alt}</span>
              </div>
              <div className="latex-preview__controls" aria-label="Preview controls">
                <button type="button" className={frameMode === "content" && viewMode === "fit" ? "is-active" : undefined} disabled={!contentBox} onClick={() => {
    setFrameMode("content");
    setViewMode("fit");
    setZoom(minZoom);
  }}>
                  Fit content
                </button>
                <button type="button" className={frameMode === "page" && viewMode === "fit" ? "is-active" : undefined} onClick={() => {
    setFrameMode("page");
    setViewMode("fit");
    setZoom(minZoom);
  }}>
                  Full page
                </button>
                <span className="latex-preview__zoom-group">
                  <button type="button" onClick={zoomOut} disabled={viewMode === "fit" || zoom <= minZoom} aria-label="Zoom out">−</button>
                  <output aria-live="polite" aria-label="Current zoom">{zoomLabel}</output>
                  <button type="button" onClick={zoomIn} disabled={viewMode !== "fit" && zoom >= maxZoom} aria-label="Zoom in">+</button>
                </span>
                <a href={src} target="_blank" rel="noreferrer">Open SVG</a>
                <button ref={closeButtonRef} type="button" className="latex-preview__close" onClick={closeViewer} aria-label="Close rendered LaTeX viewer">
                  Close
                </button>
              </div>
            </header>
            <div ref={viewportRef} className="latex-preview__viewport" data-view-mode={viewMode} onPointerDown={startDrag} onPointerMove={continueDrag} onPointerUp={stopDrag} onPointerCancel={stopDrag}>
              <span className="latex-preview__dialog-page" style={imageStyle}>
                {renderPreviewAsset({
    src,
    alt,
    width,
    height,
    contentBox: activeContentBox
  })}
              </span>
            </div>
            <footer className="latex-preview__viewer-note">
              Compiler-generated vector output · Use +/− to zoom · Drag to pan · Esc to close
            </footer>
          </section>
        </div>}
    </figure>;
};

To write pseudocode in LaTeX, load `algorithm` for the numbered float and `algpseudocode` for commands such as `\State`, `\If`, `\For`, and `\Procedure`. Put an `algorithmic` block inside `algorithm` when you need both formatted steps and a caption.

<Info>
  **Quick answer**: `algorithm` controls caption, numbering, and float placement; `algpseudocode` supplies the readable pseudocode syntax. The complete example below uses both and compiles with pdfLaTeX.

  **Related topics**: [Algorithms, complexity, and CS notation](/learn/latex/specialized-notation/algorithms) | [Code listings and minted](/learn/latex/formatting/code-listings-minted)
</Info>

## Minimal Working Pseudocode Example

The optional `[1]` after `\begin{algorithmic}` enables a line number on every line. Remove it when the algorithm should be unnumbered.

<LatexSource filename="pseudocode-setup.tex" source={"\\documentclass{article}\n\\usepackage{algorithm}\n\\usepackage{algpseudocode}\n\n\\begin{document}\n\n\\begin{algorithm}\n\\caption{Linear Search}\n\\begin{algorithmic}[1]\n\\For{$i = 1$ \\textbf{to} $n$}\n    \\If{$A[i] = x$}\n        \\State \\Return $i$\n    \\EndIf\n\\EndFor\n\\State \\Return \\textsc{not found}\n\\end{algorithmic}\n\\end{algorithm}\n\n\\end{document}"} />

<RenderedOutput title="Rendered output" ctaHref="https://app.latex-cloud-studio.com/?utm_source=resources&utm_medium=rendered_output&utm_campaign=docs_open_app&utm_content=learn_latex_specialized_notation_pseudocode">
  <LatexPreview src="/images/rendered/learn-latex-specialized-notation-pseudocode-01/page-1.svg" alt="Compiled PDF page 1 from pseudocode-setup.tex" caption="Generated from the shown source with pdfLaTeX in the pinned LaTeXCloud TeX Live 2026 environment." width={595.276} height={841.89} />
</RenderedOutput>

## What Each Pseudocode Package Does

| Package or environment | Purpose                                                      | Use it when...                                             |
| ---------------------- | ------------------------------------------------------------ | ---------------------------------------------------------- |
| `algorithm`            | Creates a floating wrapper with caption and algorithm number | The pseudocode needs a caption, label, or float placement  |
| `algorithmicx`         | Provides the extensible pseudocode framework                 | You need a base for a specific pseudocode style            |
| `algpseudocode`        | Loads the common `algorithmicx` style and commands           | You want `\State`, `\If`, `\For`, `\While`, and procedures |
| `algorithm2e`          | Provides a separate all-in-one syntax and visual style       | A publisher or template explicitly requires it             |

<Warning>
  The `algorithmic`, `algpseudocode`, and `algorithm2e` interfaces are not interchangeable. Choose one command family for a document instead of mixing their syntax.
</Warning>

## Common Pseudocode Commands

| Command                               | Meaning                               |
| ------------------------------------- | ------------------------------------- |
| `\State`                              | Add one instruction                   |
| `\If` / `\ElsIf` / `\Else` / `\EndIf` | Create a conditional block            |
| `\For` / `\EndFor`                    | Create a for-loop                     |
| `\While` / `\EndWhile`                | Create a while-loop                   |
| `\Procedure` / `\EndProcedure`        | Define a named procedure              |
| `\Function` / `\EndFunction`          | Define a function with a return value |
| `\Call`                               | Format a procedure or function call   |
| `\Return`                             | Format a returned value               |

<LatexSource filename="pseudocode-commands.tex" source={"\\begin{algorithmic}[1]\n\\Procedure{BinarySearch}{$A, x$}\n    \\State $left \\gets 1$\n    \\State $right \\gets \\Call{length}{A}$\n    \\While{$left \\leq right$}\n        \\State $mid \\gets \\lfloor (left + right) / 2 \\rfloor$\n        \\If{$A[mid] = x$}\n            \\State \\Return $mid$\n        \\ElsIf{$A[mid] < x$}\n            \\State $left \\gets mid + 1$\n        \\Else\n            \\State $right \\gets mid - 1$\n        \\EndIf\n    \\EndWhile\n    \\State \\Return \\textsc{not found}\n\\EndProcedure\n\\end{algorithmic}"} />

<RenderedOutput title="Rendered output">
  <LatexPreview src="/images/rendered/learn-latex-specialized-notation-pseudocode-02/page-1.svg" alt="Compiled PDF page 1 from pseudocode-commands.tex" caption="Generated from the shown source with pdfLaTeX in the pinned LaTeXCloud TeX Live 2026 environment. The visible fragment is compiled inside the documented minimal article wrapper." width={595.276} height={841.89} />
</RenderedOutput>

## Numbered Lines and Procedures

The optional number in `\begin{algorithmic}[1]` controls the line-number interval. Use `[1]` for every line, `[2]` for every second line, or omit the option for no line numbers. Use `\Procedure` for a named block of steps and `\Function` when the block conceptually returns a value.

## `algorithm` vs `algorithmicx` vs `algpseudocode`

* `algorithm` is only the outer float; it does not define `\State` or `\If`.
* `algorithmicx` is the framework on which several pseudocode styles are built.
* `algpseudocode` is the commonly used `algorithmicx` style that defines the commands shown on this page.
* For most papers and assignments, load `algorithm` and `algpseudocode` together.

## Captions, Labels, and Float Placement

Place `\caption` inside `algorithm` and add `\label` immediately after it when you need a cross-reference. Because `algorithm` is a float, LaTeX may move it to a suitable position. A placement option such as `[htbp]` expresses a preference; it does not guarantee an exact location.

If the publisher controls algorithm styling, start with its class or template before selecting packages. Some journal classes define their own algorithm environment or disallow conflicting packages.

## Alternatives

| If you need...                                      | Better choice                                                          |
| --------------------------------------------------- | ---------------------------------------------------------------------- |
| Structured, language-neutral algorithm steps        | `algorithm` + `algpseudocode`                                          |
| A publisher-required ruled or boxed algorithm style | `algorithm2e`, if the template specifies it                            |
| Real compilable source code                         | [`listings` or `minted`](/learn/latex/formatting/code-listings-minted) |
| A short mathematical definition                     | An `equation`, `align`, or cases environment                           |

## Common Errors

| Error or symptom                             | Cause                                          | Fix                                                        |
| -------------------------------------------- | ---------------------------------------------- | ---------------------------------------------------------- |
| `Environment algorithm undefined`            | The float package is missing                   | Load `\usepackage{algorithm}`                              |
| `Environment algorithmic undefined`          | No pseudocode style is loaded                  | Load `\usepackage{algpseudocode}`                          |
| `Undefined control sequence \State`          | The document loaded a different command family | Use `algpseudocode` commands consistently                  |
| `\caption` does not work                     | The block is not inside an `algorithm` float   | Wrap `algorithmic` in `algorithm`                          |
| Algorithm floats away from the paragraph     | Normal float placement is active               | Use a sensible placement preference and let LaTeX paginate |
| Commands conflict after adding `algorithm2e` | Two incompatible interfaces are loaded         | Keep one pseudocode package family                         |

## Pseudocode Writing Practices

* Describe the algorithm rather than the syntax of one programming language.
* Use consistent capitalization for commands, variables, and procedure names.
* Keep each `\State` focused on one logical action.
* Add line numbers when the surrounding text refers to specific steps.
* Use a caption that explains the algorithm's purpose, not merely “Pseudocode.”

## When to Use This Page vs the Algorithms Guide

Use this page when you specifically need to format pseudocode. Use the broader [algorithms guide](/learn/latex/specialized-notation/algorithms) when you also need complexity notation, graph notation, or other computer-science symbols.

## Try Pseudocode in LaTeX Cloud Studio

<CardGroup cols={2}>
  <Card title="Compile the pseudocode example" icon="cloud" href="https://app.latex-cloud-studio.com/?utm_source=resources&utm_medium=card&utm_campaign=docs_open_app&utm_content=pseudocode_open_app">
    Paste the complete example into the browser editor and adapt the procedure, caption, and line numbering.
  </Card>

  <Card title="Compare real code listings" icon="code" href="/learn/latex/formatting/code-listings-minted">
    Use listings or minted when the document should show source code instead of language-neutral pseudocode.
  </Card>
</CardGroup>
