> ## 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.

# Collaboration Workflow for LaTeX Projects

> Master team collaboration in LaTeX. Learn version control, cloud platforms, change tracking, commenting systems, and best practices for multi-author documents.

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>;
};

Learn professional collaboration techniques for LaTeX projects. This guide covers version control integration, real-time collaboration platforms, change tracking, review workflows, and team coordination strategies.

<Info>
  **Prerequisites**: Basic LaTeX and Git knowledge\
  **Time to complete**: 30-35 minutes\
  **Difficulty**: Intermediate to Advanced\
  **What you'll learn**: Git workflows, cloud collaboration, change tracking, review processes, and team coordination
</Info>

## Collaboration Overview

### Collaboration Methods

<CardGroup cols={2}>
  <Card title="Version Control" icon="code-branch">
    Git-based workflows for technical teams
  </Card>

  <Card title="Cloud Platforms" icon="cloud">
    Real-time editing with LaTeX Cloud Studio
  </Card>

  <Card title="Change Tracking" icon="file-lines">
    Built-in LaTeX revision tools
  </Card>

  <Card title="Review Systems" icon="comments">
    Comments and annotations for feedback
  </Card>
</CardGroup>

### Choosing the Right Approach

<Tabs>
  <Tab title="Technical Teams">
    **Best for**: Developers, researchers, technical writers

    * Git/GitHub workflow
    * Pull request reviews
    * CI/CD automation
    * Maximum control
  </Tab>

  <Tab title="Academic Teams">
    **Best for**: Professors, students, researchers

    * Cloud platforms
    * Real-time collaboration
    * Built-in commenting
    * Easy onboarding
  </Tab>

  <Tab title="Mixed Teams">
    **Best for**: Cross-functional teams

    * Hybrid approach
    * Cloud editing + Git backup
    * Multiple review channels
    * Flexible workflows
  </Tab>
</Tabs>

## Git-Based Collaboration

### Repository Structure

<CodeGroup>
  ```bash project-structure.sh theme={null}
  # Initialize collaborative LaTeX project
  git init latex-project
  cd latex-project

  # Create standard structure
  mkdir -p {chapters,figures,styles,build}
  touch .gitignore README.md CONTRIBUTING.md

  # .gitignore for LaTeX
  cat > .gitignore << 'EOF'
  # LaTeX temporary files
  *.aux
  *.lof
  *.log
  *.lot
  *.fls
  *.out
  *.toc
  *.fmt
  *.fot
  *.cb
  *.cb2
  .*.lb

  # Bibliography
  *.bbl
  *.bcf
  *.blg
  *-blx.aux
  *-blx.bib
  *.run.xml

  # Build artifacts
  build/
  *.pdf
  !figures/*.pdf
  !templates/*.pdf

  # Editors
  .vscode/
  *.swp
  *~
  .DS_Store

  # LaTeX editors
  *.synctex.gz
  *.synctex.gz(busy)
  *.pdfsync
  EOF

  # Initial commit
  git add .
  git commit -m "Initial project structure"
  ```

  ```markdown README.md theme={null}
  # Collaborative LaTeX Project

  ## Project Structure
  ```

  .
  ├── main.tex           # Main document
  ├── chapters/          # Chapter files
  │   ├── ch1-intro.tex
  │   ├── ch2-methods.tex
  │   └── ch3-results.tex
  ├── figures/           # Images and diagrams
  ├── styles/            # Custom styles
  │   └── project.sty
  ├── references.bib     # Bibliography
  └── Makefile          # Build automation

  ```

  ## Collaboration Guidelines

  ### Branch Strategy
  - `main` - Stable, reviewed content
  - `develop` - Integration branch
  - `feature/*` - New content
  - `fix/*` - Corrections
  - `review/*` - Under review

  ### Commit Messages
  ```

  type(scope): description

  * feat: New content
  * fix: Corrections
  * style: Formatting
  * docs: Documentation
  * refactor: Restructuring

  ````

  ### Pull Request Process
  1. Create feature branch
  2. Make changes
  3. Push and create PR
  4. Request review
  5. Address feedback
  6. Merge when approved

  ## Building
  ```bash
  make        # Build PDF
  make clean  # Clean artifacts
  make watch  # Auto-rebuild
  ````

  ````
  </CodeGroup>

  ### Branching Strategies

  <CodeGroup>
  ```bash git-workflow.sh
  # Feature branch workflow
  git checkout -b feature/methodology-chapter
  # Make changes to chapters/methodology.tex
  git add chapters/methodology.tex
  git commit -m "feat(methodology): Add data collection section"
  git push -u origin feature/methodology-chapter

  # Create pull request for review
  gh pr create --title "Add methodology chapter" \
    --body "This PR adds the complete methodology chapter including:
    - Data collection procedures
    - Analysis methods
    - Validation approach
    
    Closes #15"

  # Reviewer checks out PR
  git fetch origin
  git checkout -b review/methodology origin/feature/methodology-chapter
  make  # Build and review PDF

  # After approval
  git checkout main
  git merge --no-ff feature/methodology-chapter
  git push origin main
  ````

  ```bash parallel-development.sh theme={null}
  # Multiple authors working simultaneously

  # Author A: Introduction
  git checkout -b feature/introduction
  # Edit chapters/introduction.tex
  git add chapters/introduction.tex
  git commit -m "feat(intro): Add research background"

  # Author B: Results  
  git checkout -b feature/results
  # Edit chapters/results.tex
  git add chapters/results.tex figures/results/*
  git commit -m "feat(results): Add experimental data"

  # Integration manager
  git checkout develop
  git merge feature/introduction
  git merge feature/results
  # Resolve any conflicts
  make  # Test build
  git push origin develop
  ```
</CodeGroup>

### Merge Conflict Resolution

<CodeGroup>
  ```latex conflict-resolution.tex theme={null}
  % Common conflict scenario
  <<<<<<< HEAD
  \section{Results}
  Our experimental results show a 95\% accuracy rate.
  =======
  \section{Experimental Results}
  The experiments demonstrate 94.8\% accuracy.
  >>>>>>> feature/results

  % Resolution approach
  \section{Experimental Results}
  Our experimental results show a 94.8\% accuracy rate.

  % Best practices:
  % 1. Communicate about sections
  % 2. Use semantic line breaks
  % 3. One sentence per line
  % 4. Regular integration
  ```

  ```bash semantic-linebreaks.tex theme={null}
  % Bad: Hard to merge
  \section{Introduction}
  This research investigates machine learning applications in healthcare. We propose a novel approach that combines deep learning with traditional statistical methods. Our results show significant improvements.

  % Good: Easy to merge
  \section{Introduction}
  This research investigates machine learning applications in healthcare.
  We propose a novel approach that combines deep learning with traditional statistical methods.
  Our results show significant improvements.

  % Each sentence on its own line
  % Easier diffs and merges
  % Clear change history
  ```
</CodeGroup>

<RenderedOutput title="Expected effect">
  <Info>
    This code group documents a multi-step workflow across LaTeX and another file or command language. The blocks work together in a project, so there is no single standalone LaTeX page that would honestly represent the whole group.
  </Info>
</RenderedOutput>

## Cloud Collaboration

### LaTeX Cloud Studio Features

<Info>
  **LaTeX Cloud Studio** provides real-time collaboration features:

  * Simultaneous editing
  * Live preview updates
  * Integrated chat
  * Version history
  * Comment threads
  * Change suggestions
</Info>

### Real-time Collaboration Setup

<LatexSource filename="cloud-project-setup.tex" source={"% Project structure for cloud collaboration\n% main.tex\n\\documentclass{article}\n\n% Enable collaboration features\n\\usepackage{changes}  % Track changes\n\\usepackage{todonotes} % Comments and todos\n\n% Define authors\n\\definechangesauthor[name={Alice}, color=blue]{AA}\n\\definechangesauthor[name={Bob}, color=red]{BB}\n\\definechangesauthor[name={Carol}, color=green]{CC}\n\n\\begin{document}\n\n\\title{Collaborative Research Paper}\n\\author{Alice A. \\and Bob B. \\and Carol C.}\n\\maketitle\n\n% Include sections maintained by different authors\n\\input{sections/introduction}    % Alice\n\\input{sections/methodology}     % Bob\n\\input{sections/results}        % Carol\n\\input{sections/conclusion}     % All\n\n\\end{document}"} />

<RenderedOutput title="Expected effect">
  <Info>
    This excerpt depends on project files such as images, bibliography data, or included TeX sources that are not part of this standalone code box. Its exact output is project-specific, so no fabricated preview is shown.
  </Info>
</RenderedOutput>

<LatexSource filename="collaborative-editing.tex" source={"% sections/methodology.tex\n\\section{Methodology}\n\n% Bob's addition\n\\added[id=BB]{We employed a mixed-methods approach combining\nquantitative analysis with qualitative interviews.}\n\n% Alice's comment\n\\todo[inline, author=Alice]{Should we mention the sample size here?}\n\n% Carol's suggestion\n\\replaced[id=CC]{participants}{subjects}\n\n% Highlighting changes\n\\deleted[id=AA]{The old methodology was limited.}\n\\added[id=AA]{Our comprehensive methodology addresses previous limitations.}"} />

<RenderedOutput title="Expected effect">
  <Info>
    This code is a contextual or intentionally partial LaTeX excerpt, not a self-contained compilable document. Its visible result depends on the surrounding document, so the documentation shows the expected role without inventing a standalone preview.
  </Info>
</RenderedOutput>

### Managing Permissions

<Tabs>
  <Tab title="View Only">
    <LatexSource filename="example.tex" source={"% For reviewers and readers\n% - Can view document\n% - Can add comments\n% - Cannot edit content\n% - Can download PDF"} />

    <RenderedOutput title="Expected effect">
      <Info>
        This is setup or structural LaTeX code. It changes available commands or document behavior, but it does not produce meaningful standalone page content by itself.
      </Info>
    </RenderedOutput>
  </Tab>

  <Tab title="Can Edit">
    <LatexSource filename="example.tex" source={"% For co-authors\n% - Full editing rights\n% - Can add/remove content\n% - Can modify structure\n% - Can invite others"} />

    <RenderedOutput title="Expected effect">
      <Info>
        This is setup or structural LaTeX code. It changes available commands or document behavior, but it does not produce meaningful standalone page content by itself.
      </Info>
    </RenderedOutput>
  </Tab>

  <Tab title="Can Comment">
    <LatexSource filename="example.tex" source={"% For reviewers\n% - Can view document\n% - Can add comments\n% - Can suggest changes\n% - Cannot directly edit"} />

    <RenderedOutput title="Expected effect">
      <Info>
        This is setup or structural LaTeX code. It changes available commands or document behavior, but it does not produce meaningful standalone page content by itself.
      </Info>
    </RenderedOutput>
  </Tab>
</Tabs>

## Change Tracking

### The changes Package

<LatexSource filename="changes-package.tex" source={"\\documentclass{article}\n\\usepackage{changes}\n\n% Setup authors\n\\definechangesauthor[name={John}, color=blue]{JD}\n\\definechangesauthor[name={Jane}, color=red]{JS}\n\n% Configure display\n\\setaddedmarkup{\\textcolor{#1}{\\uline{#2}}}\n\\setdeletedmarkup{\\textcolor{#1}{\\sout{#2}}}\n\n\\begin{document}\n\n\\section{Introduction}\n\n% Track additions\n\\added[id=JD]{This new section provides important context.}\n\n% Track deletions\n\\deleted[id=JS]{Remove this outdated information.}\n\n% Track replacements\n\\replaced[id=JD]{modern approach}{old method}\n\n% Comments\n\\comment[id=JS]{Need citation here}\n\n% Highlight text\n\\highlight{Important finding that needs review}\n\n\\end{document}"} />

<RenderedOutput title="Expected effect">
  <Info>
    This code is a contextual or intentionally partial LaTeX excerpt, not a self-contained compilable document. Its visible result depends on the surrounding document, so the documentation shows the expected role without inventing a standalone preview.
  </Info>
</RenderedOutput>

<LatexSource filename="change-management.tex" source={"% Accept/reject changes workflow\n\\usepackage[final]{changes} % Accept all changes\n% or\n\\usepackage[draft]{changes} % Show all changes\n\n% Selective display\n\\setauthormarkup{JD}{\\textcolor{blue}{#1}}\n\\setauthormarkup{JS}{\\textcolor{red}{#1}}\n\n% List all changes\n\\listofchanges\n\n% Summary statistics\n\\begin{tabular}{lcc}\n\\toprule\nAuthor & Added & Deleted \\\\\n\\midrule\nJohn & 247 words & 89 words \\\\\nJane & 192 words & 134 words \\\\\n\\bottomrule\n\\end{tabular}"} />

<RenderedOutput title="Expected effect">
  <Info>
    This code is a contextual or intentionally partial LaTeX excerpt, not a self-contained compilable document. Its visible result depends on the surrounding document, so the documentation shows the expected role without inventing a standalone preview.
  </Info>
</RenderedOutput>

### Manual Change Tracking

<LatexSource filename="revision-colors.tex" source={"% Simple revision tracking with colors\n\\usepackage{xcolor}\n\\usepackage{soul}\n\n% Define revision commands\n\\newcommand{\\rev}[1]{\\textcolor{blue}{#1}}\n\\newcommand{\\del}[1]{\\textcolor{red}{\\sout{#1}}}\n\\newcommand{\\note}[1]{\\marginpar{\\textcolor{orange}{\\footnotesize #1}}}\n\n% Usage\n\\rev{This text was added in revision 2.}\n\\del{This text should be removed.}\n\\note{Check this reference}\n\n% Version-specific content\n\\newif\\ifdraft\n\\drafttrue  % or \\draftfalse\n\n\\ifdraft\n  \\newcommand{\\draftonly}[1]{#1}\n\\else\n  \\newcommand{\\draftonly}[1]{}\n\\fi"} />

<RenderedOutput title="Expected effect">
  <Info>
    This code is a contextual or intentionally partial LaTeX excerpt, not a self-contained compilable document. Its visible result depends on the surrounding document, so the documentation shows the expected role without inventing a standalone preview.
  </Info>
</RenderedOutput>

<LatexSource filename="diff-visualization.tex" source={"% Showing differences between versions\n\\usepackage{listings}\n\\usepackage{xcolor}\n\n\\lstdefinestyle{diff}{\n    basicstyle=\\ttfamily\\small,\n    morecomment=[f][\\color{blue}]{+},\n    morecomment=[f][\\color{red}]{-},\n    morecomment=[f][\\color{gray}]{@}\n}\n\n\\begin{lstlisting}[style=diff]\n@@ -15,7 +15,7 @@\n The experiment used the following parameters:\n-Temperature: 25°C\n+Temperature: 27°C\n Pressure: 1 atm\n-Duration: 60 minutes\n+Duration: 90 minutes\n\\end{lstlisting}"} />

<RenderedOutput title="Expected effect">
  <Info>
    This code is a contextual or intentionally partial LaTeX excerpt, not a self-contained compilable document. Its visible result depends on the surrounding document, so the documentation shows the expected role without inventing a standalone preview.
  </Info>
</RenderedOutput>

## Review Workflows

### Comment Systems

<LatexSource filename="todo-notes.tex" source={"\\usepackage[colorinlistoftodos]{todonotes}\n\n% Configure todo notes\n\\setuptodonotes{\n    inline,\n    color=yellow!40,\n    size=\\footnotesize\n}\n\n% Different comment types\n\\newcommand{\\alice}[1]{\\todo[color=blue!40, inline]{Alice: #1}}\n\\newcommand{\\bob}[1]{\\todo[color=red!40, inline]{Bob: #1}}\n\\newcommand{\\review}[1]{\\todo[color=green!40, inline]{Review: #1}}\n\n% Usage in document\n\\section{Results}\nOur findings indicate significant improvement.\n\\alice{Need to add specific percentages here}\n\nThe control group showed no change.\n\\bob{Should we include the p-value?}\n\n\\review{This section needs more detail about methodology}\n\n% List all todos\n\\listoftodos[Notes for revision]"} />

<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_how_to_collaboration_workflow">
  <LatexPreview src="/images/rendered/learn-latex-how-to-collaboration-workflow-10/page-1.svg" alt="Compiled PDF page 1 from todo-notes.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={612} height={792} />
</RenderedOutput>

<LatexSource filename="margin-comments.tex" source={"% Margin comments for review\n\\usepackage{marginnote}\n\\usepackage{xcolor}\n\n% Review commands\n\\newcounter{commentnum}\n\\newcommand{\\comment}[2]{%\n    \\stepcounter{commentnum}%\n    \\marginnote{%\n        \\tiny\\textcolor{red}{[\\thecommentnum] #1: #2}%\n    }%\n    \\textsuperscript{\\textcolor{red}{\\thecommentnum}}%\n}\n\n% Usage\nThe results \\comment{Reviewer1}{Clarify which results} demonstrate\nour hypothesis was correct.\n\n% Alternative: pdfcomment package\n\\usepackage{pdfcomment}\n\\pdfcomment[author={Jane Doe}, color=yellow]{\n    This paragraph needs supporting evidence.\n}"} />

<RenderedOutput title="Rendered output">
  <LatexPreview src="/images/rendered/learn-latex-how-to-collaboration-workflow-11/page-1.svg" alt="Compiled PDF page 1 from margin-comments.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={612} height={792} />
</RenderedOutput>

### Code Review for LaTeX

<CodeGroup>
  ```yaml latex-review-checklist.yml theme={null}
  # .github/pull_request_template.md
  ## LaTeX Document Review Checklist

  ### Content Review
  - [ ] Content is accurate and complete
  - [ ] All sections are properly structured
  - [ ] References are correctly cited
  - [ ] Figures and tables are referenced

  ### Technical Review  
  - [ ] Document compiles without errors
  - [ ] No undefined references
  - [ ] No overfull/underfull boxes
  - [ ] Images are optimized

  ### Style Review
  - [ ] Consistent formatting throughout
  - [ ] Proper use of environments
  - [ ] Correct math notation
  - [ ] Clear and concise writing

  ### Bibliography
  - [ ] All citations have entries
  - [ ] BibTeX entries are complete
  - [ ] Citation style is consistent

  ### Final Checks
  - [ ] Spell check completed
  - [ ] Grammar check completed
  - [ ] PDF output looks correct
  - [ ] Version number updated
  ```

  ```yaml github-actions.yml theme={null}
  # .github/workflows/latex-build.yml
  name: Build LaTeX document

  on:
    pull_request:
      branches: [ main ]
    push:
      branches: [ main ]

  jobs:
    build:
      runs-on: ubuntu-latest
      
      steps:
      - uses: actions/checkout@v2
      
      - name: Compile LaTeX
        uses: xu-cheng/latex-action@v2
        with:
          root_file: main.tex
          
      - name: Check for errors
        run: |
          ! grep -E "(Warning|Error|Undefined)" main.log
          
      - name: Upload PDF
        uses: actions/upload-artifact@v2
        with:
          name: document
          path: main.pdf
  ```
</CodeGroup>

## Communication Tools

### Project Documentation

<CodeGroup>
  ````markdown CONTRIBUTING.md theme={null}
  # Contributing Guidelines

  ## Communication Channels
  - **Slack**: #latex-project for daily communication
  - **GitHub Issues**: Bug reports and feature requests
  - **Weekly Meetings**: Thursdays 2 PM UTC

  ## Writing Style Guide
  1. **Voice**: Active voice preferred
  2. **Tense**: Present tense for methods
  3. **Terminology**: See glossary.tex
  4. **Citations**: Author-year format

  ## LaTeX Conventions
  ### File Naming
  - Chapters: `ch01-introduction.tex`
  - Figures: `fig-chapter-description.pdf`
  - Tables: `tab-chapter-description.tex`

  ### Labels
  - Sections: `sec:chapter:section`
  - Figures: `fig:chapter:name`
  - Tables: `tab:chapter:name`
  - Equations: `eq:chapter:name`

  ### Code Style
  ```latex
  % Good
  \begin{figure}[htbp]
      \centering
      \includegraphics[width=0.8\textwidth]{figure}
      \caption{Clear description}
      \label{fig:chapter:example}
  \end{figure}

  % Bad
  \begin{figure}[h]
  \includegraphics{figure}
  \caption{Fig}
  \end{figure}
  ````

  ## Review Process

  1. Create feature branch
  2. Make changes following guidelines
  3. Run `make check` before committing
  4. Create PR with description
  5. Address reviewer feedback
  6. Squash and merge when approved

  ````

  ```latex project-glossary.tex
  % glossary.tex - Shared terminology
  \usepackage{glossaries}
  \makeglossaries

  % Define common terms
  \newglossaryentry{ml}{
      name=machine learning,
      description={A subset of AI that enables systems to learn from data}
  }

  \newglossaryentry{api}{
      name=API,
      description={Application Programming Interface}
  }

  % Usage in documents
  We use \gls{ml} techniques to process the data through our \gls{api}.

  % Print glossary
  \printglossary[title=Terminology]
  ````
</CodeGroup>

<RenderedOutput title="Expected effect">
  <Info>
    This code group documents a multi-step workflow across LaTeX and another file or command language. The blocks work together in a project, so there is no single standalone LaTeX page that would honestly represent the whole group.
  </Info>
</RenderedOutput>

### Meeting Templates

<CodeGroup>
  ```markdown meeting-template.md theme={null}
  # LaTeX Project Meeting - [Date]

  ## Attendees
  - [ ] Alice (Lead Author)
  - [ ] Bob (Methods)
  - [ ] Carol (Analysis)
  - [ ] Dave (Review)

  ## Agenda
  1. Progress updates (10 min)
  2. Blockers and issues (10 min)
  3. Review assignments (15 min)
  4. Next steps (10 min)

  ## Progress Updates
  ### Alice
  - Completed introduction revision
  - TODO: Address Bob's comments

  ### Bob
  - Methodology section 80% complete
  - Blocked: Need data from Carol

  ## Action Items
  | Task | Owner | Due Date |
  |------|-------|----------|
  | Revise introduction | Alice | Friday |
  | Provide data tables | Carol | Wednesday |
  | Review methodology | Dave | Next Monday |

  ## Next Meeting
  Date: [Next week same time]
  Focus: Results section review
  ```
</CodeGroup>

## Conflict Resolution

### Handling Disagreements

<Tabs>
  <Tab title="Content Conflicts">
    <LatexSource filename="example.tex" source={"% Document alternatives\n\\usepackage{comment}\n\n% Version A\n\\begin{comment}\nAlice's version:\nThe results clearly demonstrate...\n\\end{comment}\n\n% Version B\nBob's version:\nThe results suggest...\n\n% Resolution meeting needed\n\\todo[inline]{DISCUSS: Strong vs cautious language}"} />

    <RenderedOutput title="Expected effect">
      <Info>
        This code is a contextual or intentionally partial LaTeX excerpt, not a self-contained compilable document. Its visible result depends on the surrounding document, so the documentation shows the expected role without inventing a standalone preview.
      </Info>
    </RenderedOutput>
  </Tab>

  <Tab title="Style Conflicts">
    <LatexSource filename="example.tex" source={"% Create style guide\n% styles/project-style.sty\n\\ProvidesPackage{project-style}\n\n% Agreed conventions\n\\newcommand{\\term}[1]{\\textit{#1}}\n\\newcommand{\\important}[1]{\\textbf{#1}}\n\\newcommand{\\citation}[1]{\\citep{#1}}\n\n% Enforce consistency\n\\let\\it\\undefined  % Disable \\it\n\\let\\bf\\undefined  % Disable \\bf"} />

    <RenderedOutput title="Expected effect">
      <Info>
        This is document setup or preamble code. It changes the behavior of a containing document but does not produce an honest standalone page by itself.
      </Info>
    </RenderedOutput>
  </Tab>

  <Tab title="Technical Conflicts">
    <LatexSource filename="example.tex" source={"% Use feature flags\n\\newif\\ifusemethod\n\\usemethodtrue  % or false\n\n\\ifusemethod\n    % Method A implementation\n    \\input{methods/approach-a}\n\\else\n    % Method B implementation\n    \\input{methods/approach-b}\n\\fi"} />

    <RenderedOutput title="Expected effect">
      <Info>
        This excerpt depends on project files such as images, bibliography data, or included TeX sources that are not part of this standalone code box. Its exact output is project-specific, so no fabricated preview is shown.
      </Info>
    </RenderedOutput>
  </Tab>
</Tabs>

## Best Practices

### Collaboration Guidelines

<Tip>
  ✅ **Successful collaboration checklist**:

  * [ ] Clear role assignments
  * [ ] Regular communication schedule
  * [ ] Documented conventions
  * [ ] Version control setup
  * [ ] Automated builds
  * [ ] Review process defined
  * [ ] Conflict resolution plan
  * [ ] Backup strategy
  * [ ] Deadline tracking
  * [ ] Progress monitoring
</Tip>

### Common Pitfalls

<Warning>
  **Avoid these collaboration mistakes**:

  1. **No clear ownership** - Assign section owners
  2. **Infrequent integration** - Merge daily
  3. **Poor communication** - Regular check-ins
  4. **Inconsistent style** - Document conventions
  5. **Missing reviews** - Mandatory peer review
  6. **No backup plan** - Multiple backups
  7. **Deadline confusion** - Shared calendar
</Warning>

## Complete Collaboration Example

<CodeGroup>
  ```bash setup-collaboration.sh theme={null}
  #!/bin/bash
  # Complete collaboration setup

  # 1. Initialize repository
  git init latex-collaborative-paper
  cd latex-collaborative-paper

  # 2. Create structure
  mkdir -p {chapters,figures,reviews,builds}
  mkdir -p .github/workflows

  # 3. Setup Git hooks
  cat > .git/hooks/pre-commit << 'EOF'
  #!/bin/bash
  # Check for LaTeX errors before commit
  make check
  EOF
  chmod +x .git/hooks/pre-commit

  # 4. Create main document
  cat > main.tex << 'EOF'
  \documentclass[12pt]{article}
  \usepackage{changes}
  \usepackage{todonotes}

  % Define authors
  \definechangesauthor[name={Alice}, color=blue]{AA}
  \definechangesauthor[name={Bob}, color=red]{BB}

  \title{Collaborative Research Paper}
  \author{Alice \and Bob}

  \begin{document}
  \maketitle

  \input{chapters/introduction}
  \input{chapters/methods}
  \input{chapters/results}
  \input{chapters/conclusion}

  \bibliographystyle{plain}
  \bibliography{references}

  \end{document}
  EOF

  # 5. Create Makefile
  cat > Makefile << 'EOF'
  .PHONY: all clean check watch

  all: main.pdf

  main.pdf: main.tex chapters/*.tex
  	pdflatex main
  	bibtex main
  	pdflatex main
  	pdflatex main

  check:
  	@echo "Checking for errors..."
  	@! grep -i "error\|warning\|undefined" main.log

  clean:
  	rm -f *.aux *.log *.out *.toc *.bbl *.blg

  watch:
  	latexmk -pvc -pdf main.tex
  EOF

  # 6. Setup CI/CD
  cat > .github/workflows/build.yml << 'EOF'
  name: Build and Check
  on: [push, pull_request]

  jobs:
    build:
      runs-on: ubuntu-latest
      steps:
      - uses: actions/checkout@v2
      - uses: xu-cheng/latex-action@v2
        with:
          root_file: main.tex
      - uses: actions/upload-artifact@v2
        with:
          name: PDF
          path: main.pdf
  EOF

  echo "Collaboration environment ready!"
  ```
</CodeGroup>

## Next Steps

Continue with advanced LaTeX workflows:

<CardGroup cols={2}>
  <Card title="Using Templates" icon="copy" href="/learn/latex/how-to/using-templates">
    Create reusable document templates
  </Card>

  <Card title="Fixing Errors" icon="bug" href="/learn/latex/how-to/fixing-compilation-errors">
    Debug compilation issues
  </Card>

  <Card title="Large Documents" icon="file-code" href="/learn/latex/how-to/large-documents">
    Manage complex projects
  </Card>

  <Card title="Research Papers" icon="file-medical" href="/learn/latex/how-to/writing-research-paper">
    Write academic papers
  </Card>
</CardGroup>

***

<Info>
  **Remember**: Good collaboration is about communication, consistency, and clear processes. Establish conventions early and document everything. Regular integration and reviews prevent major conflicts.
</Info>
