> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/fi/tietopankki/064-how-does-overleaf-compile-my-project.md).

# Miten Overleaf kääntää projektini?

## LaTeX-käännöksen automatisointi

Tukemaan ominaisuuksia, kuten sisällysluetteloa, kuvien luetteloita, viittauksia, sanastoja, hakemistoa ja bibliografisia viittauksia, LaTeX käyttää monivaiheista ladontaprosessia: yhdessä vaiheessa (käännöksessä) tuotettu data kirjoitetaan tiedosto(i)hin ja sitä käytetään syötteenä kaikissa myöhemmissä vaiheissa, joita saatetaan tarvita. Seuraava video näyttää, mitä tapahtuu joka kerta, kun napsautat Overleaf-projektissasi “Recompile”-painiketta:

{% embed url="<https://videos.ctfassets.net/nrgyaltdicpt/Uo3I2FXEI8H6aFPBZq171/e2139f9575a4db6955dc2278dc08283c/latexmk-ol.mp4>" %}

Kun tehdään manuaalinen käännös, on yleensä ilmeistä, jos toinen LaTeX-ajokerta (vaihe) on tarpeen, mutta LaTeX-käännöksen automatisointi tuo mukanaan useita vaikeuksia. Yksi automaattisten ratkaisujen keskeinen haaste on määrittää *kuinka monta* LaTeX-vaihetta (käännöstä) tarvitaan kaikkien tietoriippuvuuksien ratkaisemiseksi ja siten varmistamaan, että lopullinen ladottu asiakirja on ajan tasalla ja täydellinen. Toinen monimutkaisuus on tunnistaa oikein ulkoiset ohjelmat, jotka on suoritettava asiakirjan sisällön osien esikäsittelyä varten — kuten BibTeX/BibLaTeX:n ajaminen viiteluetteloiden tuottamiseksi tai erityisempien grafiikkasovellusten, kuten [MetaPost](https://tug.org/metapost.html) tai [Asymptote](https://asymptote.sourceforge.io/).

## latexmkin esittely

Yksi vakiintunut paketti käännöksen automatisointiin on [`latexmk`](https://ctan.org/pkg/latexmk?lang=en)suuri Perl-skripti, joka sisältyy TeX Liveen ja jota Overleaf käyttää LaTeX-projektiisi kääntämiseen. `latexmk` käynnistää automaattisesti tarvittavan määrän LaTeX-ajokertoja ja suorittaa ulkoiset (apu)ohjelmat, joita tarvitaan asiakirjasi sisällön osien käsittelyyn.

### latexmkin mukauttaminen

Vaikka `latexmk` on erittäin monipuolinen, erilaiset LaTeX-käännösympäristöt ja valtava asiakirjatyyppien kirjo tekevät siitä epäkäytännöllisen `latexmk` yrittää tarjota automaattisia ratkaisuja, jotka tukevat täysin kaikkien mahdollisten LaTeX-asiakirjojen tarpeita. Sen sijaan `latexmk` voidaan mukauttaa asetustiedostojen avulla *toteutettuna **Perl***:

* järjestelmänlaajuinen asetustiedosto, joka on tarkoitettu tietylle laskentaympäristölle/alustalle, ja
* käyttäjäkohtainen asetustiedosto, joka käsittelee asiakirjakohtaiset vaatimukset

Se [`latexmkin käyttöohje`](http://mirrors.ctan.org/support/latexmk/latexmk.pdf) antaa lisätietoja asetustiedostojen asentamisesta ja käytöstä.

## Overleafin LatexMk-tiedosto

Overleafin “järjestelmänlaajuinen” asetustiedosto noudattaa `latexmk` käytäntöjä (Linuxissa): sen nimi on `**LatexMk**` ja sijaitsee kansiossa `/usr/local/share/latexmk/`. **Huomaa**: tuo tiedosto luetaan *ennen kuin* ennen kuin mitään käyttäjäkohtaisia asetustiedostoja.

Käyttäjäkohtaisten asetustiedostojen nimen on oltava `latexmkrc` ja ne on lisättävä Overleaf-projektiisi, jotta voidaan tarjota mukautettuja sääntöjä, jotka vastaavat Overleafin LaTeX-projektisi/asiakirjasi erityisvaatimuksia.

Overleafin `LatexMk` tiedosto sisältää koodia Overleaf-kohtaista käsittelyä varten sekä säännöt sanastoille, nimikkeistölle ja muille yleisesti käytetyille paketeille. Overleafin `LatexMk` tiedosto voi vaihdella jonkin verran TeX Live -julkaisujen välillä, jotta siinä voidaan ottaa huomioon TeX Liveen itseensä tehtävät paketti- ja työkalupäivitykset sekä muutokset.

### LaTeXin käännöstilan vaihtaminen

Oletusarvoisesti Overleaf ohjaa latexmk:ta käyttämään käännöstilaa, jota me (Overleaf) kutsumme nimellä **Yritä kääntää virheistä huolimatta**. Tässä käännöstilassa LaTeX-kääntäjä ei pysähdy, vaikka se kohtaa [LaTeX-käännösvirheitä](/latex/fi/latexin-perusteet/05-errors.md); PDF saattaa muodostua, vaikka siinä olisi virheellistä tulosta. Usein käännösvirheet voivat olla liian vakavia tai liian lukuisia, jotta LaTeX-kääntäjä voisi korjata ne, joten se saattaa silti “jättää kesken” tuottamatta PDF:ää.

Voit vaihtaa LaTeX-käännöstilan niin, että käännös pysähtyy välittömästi ensimmäiseen virheeseen törmättäessä: katso ohjeartikkelia [Ensimmäinen virhe -käännöstilan käyttäminen](/latex/fi/tietopankki/149-using-the-stop-on-first-error-compilation-mode.md) saadakseen lisätietoja.

### Kuinka pääset käsiksi kopioon Overleafin LatexMk-tiedostosta

Seuraava linkki avaa projektin, joka latoo Overleafin `LatexMk` tiedoston, jota käytetään projektisi LaTeX-kääntäjän ja TeX Live -version kanssa, ja tekee sen myös ladattavaksi:

```latex
\documentclass[a4paper]{article}
\usepackage[margin=1cm]{geometry}
\usepackage{verbatim,shellesc}
\ShellEscape{cp /usr/local/share/latexmk/LatexMk ./LatexMk}
\begin{document}
\section*{Tietoja tästä projektista}
Tämä projekti tarjoaa pääsyn Overleafin käyttämään järjestelmän \texttt{LatexMk}-alustustiedostoon (konfiguraatiotiedostoon).  \texttt{LatexMk} on Perl-skripti, joka voi hieman vaihdella projektissa valitun \TeX{} Live -version ja kääntäjän mukaan. Jos sinun täytyy olla 100\% varma siitä, mitä  \texttt{LatexMk}-versiota käytetään, lisää tämän projektin koodi projektiisi ja käännä se niin, että \texttt{LatexMk}-listaus ladotaan ja tehdään ladattavaksi yhtenä tulostiedostoista.
\section*{\texttt{LatexMk}-tiedoston listaus}
\verbatiminput{./LatexMk}
\end{document}
```

[Avaa tämä koodi Overleafissä.](https://www.overleaf.com/docs?engine=\&snip_name=Display+Overleaf+latexmkrc+file\&snip=%5Cdocumentclass%5Ba4paper%5D%7Barticle%7D%0A%5Cusepackage%5Bmargin%3D1cm%5D%7Bgeometry%7D%0A%5Cusepackage%7Bverbatim%2Cshellesc%7D%0A%5CShellEscape%7Bcp+%2Fusr%2Flocal%2Fshare%2Flatexmk%2FLatexMk+.%2FLatexMk%7D%0A%5Cbegin%7Bdocument%7D%0A%5Csection%2A%7BAbout+this+project%7D%0AThis+project+provides+access+to+the+system+%5Ctexttt%7BLatexMk%7D+initialization+%28configuration%29+file+used+by+Overleaf.++%5Ctexttt%7BLatexMk%7D+is+a+Perl+script+which+may+vary+slightly+according+to+the+%5CTeX%7B%7D+Live+version+and+compiler+chosen+for+the+project.+If+you+need+to+be+100%5C%25+certain+which++%5Ctexttt%7BLatexMk%7D+is+being+used%2C+add+code+from+this+project+to+your+project+and+compile+to+typeset+a+listing+of+%5Ctexttt%7BLatexMk%7D+and+make+it+available+for+download+as+one+of+the+output+files.%0A%5Csection%2A%7BListing+the+%5Ctexttt%7BLatexMk%7D+file%7D%0A%5Cverbatiminput%7B.%2FLatexMk%7D%0A%5Cend%7Bdocument%7D)

Kun yllä oleva projekti on käännetty, `LatexMk` tiedosto voidaan ladata **Lokit ja tulostiedostot** painikkeesta, kuten seuraavassa lyhyessä videoleikkeessä näkyy:

{% embed url="<https://videos.ctfassets.net/nrgyaltdicpt/1re6AeMUF2EQnlZ8Cse5ke/ae6ee91fa7e2b2efa8ffb27ad8bab1a0/latexmkrc.mp4>" %}

### Muita huomioita ja neuvoja

Jos haluat asettaa tai tarkistaa TeX Live -version, jota käytetään projektisi kääntämiseen, katso tämä [Overleaf-blogikirjoitus](https://www.overleaf.com/blog/new-feature-select-your-tex-live-compiler-version#How-Switch) tai seuraava kuva:

![Overleafin TeX Live -version valitseminen](/files/0d469df0d4131e49c3617b28d1430ebf9aa08813)

Jos haluat rakentaa Overleaf-projektisi offline-tilassa käyttäen latexmk:ta, kannattaa käyttää kopiota Overleafin LatexMk-tiedostosta, jotta varmistat sen käyttävän Overleafin rakennusprosessia — huomaa, että Overleafin työn nimi on asetettu arvoon output.

Overleaf kääntää projektit käyttäen latexmkin `-cd` komentorivivalitsinta, ja käännös suoritetaan aina projektin juurihakemistosta. Huomaa, että jotkin `latexmk` valitsimet eivät ole yhteensopivia Overleafin kanssa — erityisesti, jos asetat `$preview_continuous_mode` tai `$output_dir` valitsimet, se saattaa rikkoa esikatselun Overleafissä.

Lisätietoja `latexmkrc` tiedostoista saat artikkelin [Kuinka käyttää latexmkrc-tiedostoa Overleafin kanssa](/latex/fi/syvalliset-artikkelit/28-how-to-use-latexmkrc-with-overleaf.md) jossa on hyödyllisiä vinkkejä ja niksejä ystävällisiltä Overleafin TeX-asiantuntijoiltamme.

## Luettelo Overleafin LatexMk-tiedostosta (2023)

Kätevyyden vuoksi seuraava listaus näyttää Overleafin `LatexMk` tiedoston sellaisena kuin sitä käytettiin TeX Live 2023:ssa—käytä yllä olevaa linkkiä päästäksesi uusimpaan versioon.

```perl
# Asetukset
$xdvipdfmx = "xdvipdfmx -z 6 -i dvipdfmx-unsafe.cfg -o %D %O %S";

# Kiertotapa, joka sallii pstricksin läpinäkyvyyden (https://github.com/overleaf/issues/issues/3449)
$dvipdf = "dvipdf -dNOSAFER -dALLOWPSTRANSPARENCY %O %S %D";

###############################
# PDF-tiedoston jälkikäsittely #
###############################

$compiling_cmd = "internal overleaf_pre_process %T %D";
$success_cmd = "internal overleaf_post_process %T %D";
$failure_cmd = $success_cmd;

# vastaa -gt-valitsinta. Käytetään estämään latexmk:tä ohittamasta uudelleenkäännöstä
# output.log- ja output.pdf-tiedostojen
$go_mode = 3;

# vastaa -bibtex-valitsinta. Aja bibtex aina, kun bbl-tiedostot ovat
# vanhentuneita.
$bibtex_use = 2;

my $ORIG_PDF_AGE;

sub overleaf_pre_process {
    my $source_file = $_[0];
    my $output_file = $_[1];

    # hae olemassa olevan PDF:n ikä, jos se on olemassa
    $ORIG_PDF_AGE = -M $output_file
}

sub overleaf_post_process {
    my $source_file = $_[0];
    my $output_file = $_[1];
    my $source_without_ext = $source_file =~ s/\.tex$//r;
    my $output_without_ext = $output_file =~ s/\.pdf$//r;

    # Etsi knitrin concordance-tiedosto
    my $concordance_file = "${source_without_ext}-concordance.tex";
    if (-e $concordance_file) {
        print "Paikataan synctex-tiedostoa knitrille...\n";
        system("patchSynctex.R", $source_without_ext, $output_without_ext);
    }

    # Palaa aikaisin, jos PDF-tiedostoa ei ole olemassa tai sitä ei päivitetty
    my $NEW_PDF_AGE = -M $output_file;
    return if !defined($NEW_PDF_AGE);
    return if defined($ORIG_PDF_AGE) && $NEW_PDF_AGE == $ORIG_PDF_AGE;

    # Selvitä, missä qpdf on
    $qpdf //= "/usr/bin/qpdf";
    $qpdf = $ENV{QPDF} if defined($ENV{QPDF}) && -x $ENV{QPDF};
    return if ! -x $qpdf;
    $qpdf_opts //= "--linearize --newline-before-endstream";
    $qpdf_opts = $ENV{QPDF_OPTS} if defined($ENV{QPDF_OPTS});

    # Aja qpdf
    my $optimised_file = "${output_file}.opt";
    system($qpdf, split(' ', $qpdf_opts), $output_file, $optimised_file);
    $qpdf_exit_code = ($? >> 8);
    print "qpdf:n poistumiskoodi=$qpdf_exit_code\n";

    # Korvaa tulostiedosto, jos qpdf onnistui
    # qpdf palauttaa 0:n onnistumisesta, 3:n varoituksista (PDF-tuloste luodaan silti)
    return if !($qpdf_exit_code == 0 || $qpdf_exit_code == 3);
    print "Nimetään optimoitu tiedosto uudelleen muotoon $output_file\n";
    rename($optimised_file, $output_file);

    print "Poimitaan xref-taulukko tiedostolle $output_file\n";
    my $xref_file = "${output_file}xref";
    system("$qpdf --show-xref ${output_file} > ${xref_file}");
    $qpdf_xref_exit_code = ($? >> 8);
    print "qpdf --show-xref poistumiskoodi=$qpdf_xref_exit_code\n";
}

##############
# Sanastot #
##############
add_cus_dep( 'glo', 'gls', 0, 'glo2gls' );
add_cus_dep( 'acn', 'acr', 0, 'glo2gls');  # Overleaf v1:stä
sub glo2gls {
    system("makeglossaries $_[0]");
}

#############
# makeindex #
#############
@ist = glob("*.ist");
if (scalar(@ist) > 0) {
    $makeindex = "makeindex -s $ist[0] %O -o %D %S";
}

################
# nimikkeistö #
################
add_cus_dep("nlo", "nls", 0, "nlo2nls");
sub nlo2nls {
        system("makeindex $_[0].nlo -s nomencl.ist -o $_[0].nls -t $_[0].nlg");
}

#########
# Knitr #
#########
add_cus_dep( 'Rtex', 'tex', 0, 'do_knitr');
add_cus_dep( 'Rnw', 'tex', 0, 'do_knitr');
sub do_knitr {
    Run_subst(qq{Rscript -e '
        library("knitr");
        opts_knit\$set(concordance=T);
        knitr::knit(%S, output=%D);
        '}
    );
}

##########
# feynmf #
##########
push(@file_not_found, '^feynmf: Files .* and (.*) not found:$');
add_cus_dep("mf", "tfm", 0, "mf_to_tfm");
sub mf_to_tfm { system("mf '\\mode:=laserjet; input $_[0]'"); }

push(@file_not_found, '^feynmf: Label file (.*) not found:$');
add_cus_dep("mf", "t1", 0, "mf_to_label1");
sub mf_to_label1 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t1"); }
add_cus_dep("mf", "t2", 0, "mf_to_label2");
sub mf_to_label2 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t2"); }
add_cus_dep("mf", "t3", 0, "mf_to_label3");
sub mf_to_label3 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t3"); }
add_cus_dep("mf", "t4", 0, "mf_to_label4");
sub mf_to_label4 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t4"); }
add_cus_dep("mf", "t5", 0, "mf_to_label5");
sub mf_to_label5 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t5"); }
add_cus_dep("mf", "t6", 0, "mf_to_label6");
sub mf_to_label6 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t6"); }
add_cus_dep("mf", "t7", 0, "mf_to_label7");
sub mf_to_label7 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t7"); }
add_cus_dep("mf", "t8", 0, "mf_to_label8");
sub mf_to_label8 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t8"); }
add_cus_dep("mf", "t9", 0, "mf_to_label9");
sub mf_to_label9 { system("mf '\\mode:=laserjet; input $_[0]' && touch $_[0].t9"); }

##########
# feynmp #
##########
push(@file_not_found, '^dvipdf: Could not find figure file (.*); continuing.$');
add_cus_dep("mp", "1", 0, "mp_to_eps");
sub mp_to_eps {
    system("mpost $_[0]");
    return 0;
}

#############
# asymptote #
#############

sub asy {return system("asy \"$_[0]\"");}
add_cus_dep("asy","eps",0,"asy");
add_cus_dep("asy","pdf",0,"asy");
add_cus_dep("asy","tex",0,"asy");

#############
# metapost  #  # Overleaf v1:stä
#############
add_cus_dep('mp', '1', 0, 'mpost');
sub mpost {
    my $file = $_[0];
    my ($name, $path) = fileparse($file);
    pushd($path);
    my $return = system "mpost $name";
    popd();
    return $return;
}

##########
# chktex #
##########
unlink 'output.chktex' if -f 'output.chktex';
if (defined $ENV{'CHKTEX_OPTIONS'}) {
    use File::Basename;
    use Cwd;

    # tunnista päätiedosto
    my $target = $ARGV[-1];
    my $file = basename($target);

    if ($file =~ /\.tex$/) {
        # vaihda hakemistoa rajoitetun laajuuden ajaksi
        my $orig_dir = cwd();
        my $subdir = dirname($target);
        chdir($subdir);
        # aja chktex pää­tiedostolle
        $status = system("/usr/local/bin/run-chktex.sh", $orig_dir, $file);
        # palaa alkuperäiseen hakemistoon
        chdir($orig_dir);

        # VALIDATE-tilassa poistumme aina chktexin ajamisen jälkeen
        # muuten poistumme, jos EXIT_ON_ERROR on asetettu

        if ($ENV{'CHKTEX_EXIT_ON_ERROR'} || $ENV{'CHKTEX_VALIDATE'}) {
            # chktex ei salli meidän käsitellä virhetietoja poistumistilan kautta
            # joten etsitään ne tulosteesta
            open(my $fh, "<", "output.chktex");
            my $errors = 0;
            {
                local $/ = "\n";
                while(<$fh>) {
                    if (/^\S+:\d+:\d+: Error:/) {
                        $errors++;
                        print;
                    }
                }
            }
            close($fh);
            exit(1) if $errors > 0;
            exit(0) if $ENV{'CHKTEX_VALIDATE'};
        }
    }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/fi/tietopankki/064-how-does-overleaf-compile-my-project.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
