diff --git a/packages/preview/classic-ppgsi/0.1.0/LICENSE b/packages/preview/classic-ppgsi/0.1.0/LICENSE new file mode 100644 index 0000000000..5c8c9ec641 --- /dev/null +++ b/packages/preview/classic-ppgsi/0.1.0/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Gabriel Francisco dos Santos Silva + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/preview/classic-ppgsi/0.1.0/README.md b/packages/preview/classic-ppgsi/0.1.0/README.md new file mode 100644 index 0000000000..0c986ff870 --- /dev/null +++ b/packages/preview/classic-ppgsi/0.1.0/README.md @@ -0,0 +1,88 @@ +# classic-ppgsi + +A dissertation/thesis template for **PPgSI–EACH–USP** (Graduate Program in +Information Systems, University of São Paulo) in [Typst](https://typst.app) — +a 1:1 port of the `abntex2ppgsi` LaTeX class, compliant with ABNT NBR 14724 and +the program's specific adjustments. Document content is in Brazilian Portuguese. + +![Template cover page](thumbnail.png) + +## Usage + +```sh +typst init @preview/classic-ppgsi +``` + +This scaffolds a project from `template/main.typ`, including `referencias.bib` +and the example `assets/`. Then compile: + +```sh +typst compile main.typ +``` + +The entrypoint imports the package and configures the whole document via `thesis`: + +```typ +#import "@preview/classic-ppgsi:0.1.0" as ppgsi + +#show: ppgsi.thesis.with( + title: "Título do trabalho: subtítulo do trabalho", + title-en: "Work title: work subtitle", + // particles (de, da, dos) go in `given` so the inverted reference reads "TAL, Fulano de" + author: (given: "Fulano de", surname: "Tal"), + advisor: [Orientador: Prof. Dr. Fulano de Tal], + bibliography: read("referencias.bib"), + catalog-card: image("assets/ficha-1.png", width: 100%, height: 100%, fit: "contain"), + abstract: ( + pt-br: (body: [Resumo...], keywords: ("palavra1", "palavra2")), + en-us: (body: [Abstract...], keywords: ("keyword1", "keyword2")), + ), + // + siglas, símbolos, banca, dedicatória, epígrafe, etc. +) + += Introdução +... +``` + +## Features + +- Complete front matter: cover, title page, catalog card, errata, approval sheet, + dedication, acknowledgments, epigraph, abstract (pt/en), lists of + illustrations/tables, list of acronyms and symbols, table of contents. +- ABNT-style illustrations: `figure`, `table`, `frame` (quadro), `algorithm`, + `code`, with caption on top and a source line. The source defaults to the + thesis author and year (`source: auto`); pass content to cite another work, + or `none` to omit. +- Long direct quotations (`quote`) with the 4 cm ABNT indent. +- Author–date citations and references via a built-in engine (`cite`, `prose`, + `references`) — see `biblio.typ`. +- Appendices and annexes with independent letters: drop the `appendix` / `annex` + marker, then write the chapter and its sections with native Typst headings + (`=`/`==`/`===`); inner sections are numbered automatically and kept out of the + table of contents. +- Bilingual abstract as a single object (`abstract: (pt-br: ..., en-us: ...)`), + reused (with `title`/`author`/`keywords`) in the PDF metadata. +- The work's own ABNT reference at the top of each abstract is generated + automatically from `author`, `title`/`title-en`, year, page count, `degree` + and institution (`citation: auto` by default; override with content or `none`). +- Validation of mandatory ABNT elements on compile (toggle with `validate: false`). +- Integrated ecosystem packages: acronyms (`@key`, via + [glossy](https://typst.app/universe/package/glossy)), code highlighting + ([codly](https://typst.app/universe/package/codly)), checklists + ([cheq](https://typst.app/universe/package/cheq)), data plots + ([lilaq](https://typst.app/universe/package/lilaq)) and diagrams + ([cetz](https://typst.app/universe/package/cetz)). + +The USP logo ships with the package (the `logo` parameter), so you don't need to +provide it. The catalog card (`catalog-card`) is specific to each work and must +come from your own project. + +## Development + +`build.sh` registers this repository in Typst's local package cache +(`@preview/classic-ppgsi`), compiles `template/main.typ`, and produces +`build/main.pdf`, per-page PNGs, and `thumbnail.png`. + +## License + +[MIT](LICENSE). diff --git a/packages/preview/classic-ppgsi/0.1.0/assets/usp_logo.jpg b/packages/preview/classic-ppgsi/0.1.0/assets/usp_logo.jpg new file mode 100644 index 0000000000..8c1e0cff93 Binary files /dev/null and b/packages/preview/classic-ppgsi/0.1.0/assets/usp_logo.jpg differ diff --git a/packages/preview/classic-ppgsi/0.1.0/biblio.typ b/packages/preview/classic-ppgsi/0.1.0/biblio.typ new file mode 100644 index 0000000000..38b8d7a1f1 --- /dev/null +++ b/packages/preview/classic-ppgsi/0.1.0/biblio.typ @@ -0,0 +1,432 @@ +// ============================================================================ +// biblio.typ — motor próprio de citações + bibliografia ABNT (abntex2-alf) +// +// Substitui bibliography()+CSL do Typst para obter o que o motor nativo não +// permite: backref ("Citado na(s) página(s): …"), caixa correta na forma +// narrativa (\citeonline) e sufixo de desambiguação a/b/c compartilhado entre +// as formas parentética e narrativa. A SAÍDA replica o abntex2-alf 1:1. +// ============================================================================ + +#let _CM = +#let _blue = rgb(41, 5, 195) // \definecolor{blue}{RGB}{41,5,195} do modelo + +// --------------------------------------------------------------------------- +// PARSER BibTeX (subconjunto: @tipo{chave, campo = {valor} | "valor" | token}) +// --------------------------------------------------------------------------- + +#let _strip-comments(s) = s.split("\n").filter(l => not l.trim().starts-with("%")).join("\n") + +#let _is-ws(c) = c == " " or c == "\t" or c == "\n" or c == "\r" + +#let _skip-ws(cp, i) = { + while i < cp.len() and _is-ws(cp.at(i)) { i += 1 } + i +} + +#let _read-braced(cp, i) = { + // pré: cp.at(i) == "{". Devolve (interior, índice-após-"}"). + let depth = 1 + let out = "" + i += 1 + while i < cp.len() and depth > 0 { + let c = cp.at(i) + if c == "{" { depth += 1; out += c } + else if c == "}" { depth -= 1; if depth > 0 { out += c } } + else { out += c } + i += 1 + } + (out, i) +} + +#let _read-quoted(cp, i) = { + // pré: cp.at(i) == "\"". Devolve (interior, índice-após-"\""). + let out = "" + let depth = 0 + i += 1 + while i < cp.len() { + let c = cp.at(i) + if c == "\"" and depth == 0 { i += 1; break } + if c == "{" { depth += 1 } + if c == "}" { depth -= 1 } + out += c + i += 1 + } + (out, i) +} + +#let _read-bare(cp, i) = { + let out = "" + while i < cp.len() and not (cp.at(i) in (",", "}")) { out += cp.at(i); i += 1 } + (out.trim(), i) +} + +#let _read-value(cp, i) = { + i = _skip-ws(cp, i) + let c = cp.at(i, default: "") + if c == "{" { _read-braced(cp, i) } + else if c == "\"" { _read-quoted(cp, i) } + else { _read-bare(cp, i) } +} + +#let _read-token(cp, i, stops) = { + let out = "" + while i < cp.len() and not (cp.at(i) in stops) { out += cp.at(i); i += 1 } + (out, i) +} + +#let _parse-bib(content) = { + let cp = _strip-comments(content).clusters() + let n = cp.len() + let i = 0 + let entries = (:) + while i < n { + // próximo "@" + while i < n and cp.at(i) != "@" { i += 1 } + if i >= n { break } + i += 1 // pula "@" + let parts = _read-token(cp, i, ("{", "(")) // tipo + let etype = lower(parts.at(0).trim()) + i = parts.at(1) + if i >= n { break } + i += 1 // pula "{" + i = _skip-ws(cp, i) + let kp = _read-token(cp, i, (",", "}")) // chave + let key = kp.at(0).trim() + i = kp.at(1) + if cp.at(i, default: "") == "," { i += 1 } + let fields = (:) + while i < n { + i = _skip-ws(cp, i) + if cp.at(i, default: "") == "}" { i += 1; break } + let np = _read-token(cp, i, ("=", ",", "}")) // nome do campo + let name = lower(np.at(0).trim()) + i = np.at(1) + if cp.at(i, default: "") != "=" { + // entrada malformada / sem "=" — aborta este campo + if cp.at(i, default: "") == "," { i += 1 } + continue + } + i += 1 // pula "=" + let vp = _read-value(cp, i) + i = vp.at(1) + if name != "" { fields.insert(name, vp.at(0).trim()) } + i = _skip-ws(cp, i) + if cp.at(i, default: "") == "," { i += 1 } + } + if key != "" { entries.insert(key, (type: etype, fields: fields)) } + } + entries +} + +// --------------------------------------------------------------------------- +// AUTORES +// --------------------------------------------------------------------------- + +#let _split-authors(field) = field.split(regex("\s+and\s+")).map(s => s.trim()).filter(s => s != "") + +#let _name-parts(raw) = { + // devolve (family, given) + let nm = raw.trim() + if "," in nm { + let p = nm.split(",") + (p.at(0).trim(), p.slice(1).join(",").trim()) + } else { + let toks = nm.split(regex("\s+")).filter(t => t != "") + if toks.len() == 0 { ("", "") } + else if toks.len() == 1 { (toks.at(0), "") } + else { (toks.last(), toks.slice(0, toks.len() - 1).join(" ")) } + } +} + +#let _initials(given) = given.split(regex("\s+")).filter(t => t != "").map(t => upper(t.clusters().at(0, default: "")) + ".").join(" ") + +// "SOBRENOME, I. N." (lista da bibliografia) +#let _format-name(raw) = { + let np = _name-parts(raw) + let fam = upper(np.at(0)) + let ini = _initials(np.at(1)) + if ini == "" { fam } else { fam + ", " + ini } +} + +#let _authors-bib(field) = _split-authors(field).map(_format-name).join("; ") + +#let _families(field) = _split-authors(field).map(raw => _name-parts(raw).at(0)) + +#let _titlecase(s) = { + let t = lower(s) + if t.len() == 0 { t } else { upper(t.clusters().at(0)) + t.clusters().slice(1).join() } +} + +// Autor de citação: >3 autores → "Primeiro et al." (et al. itálico). +// caixa = "upper" (parentético) | "title" (narrativo). +#let _cite-authors(field, caixa: "upper", narrativo: false) = { + let fams = _families(field) + let aplica = if caixa == "upper" { f => upper(f) } else { f => _titlecase(f) } + if fams.len() == 0 { + [] + } else if fams.len() > 3 { + [#aplica(fams.at(0)) #emph[et al.]] + } else if narrativo { + // narrativo: "A", "A e B", "A, B e C" + if fams.len() == 1 { aplica(fams.at(0)) } + else { + let ini = fams.slice(0, fams.len() - 1).map(aplica).join(", ") + [#ini e #aplica(fams.last())] + } + } else { + // parentético: "A; B; C" + fams.map(aplica).join("; ") + } +} + +// --------------------------------------------------------------------------- +// DESAMBIGUAÇÃO (sufixo a/b/c por ordem de PRIMEIRA citação) +// --------------------------------------------------------------------------- + +#let _year(entry) = entry.fields.at("year", default: "") + +#let _ay-key(entry) = { + let fams = _families(entry.fields.at("author", default: "")) + lower(fams.at(0, default: "")) + "|" + _year(entry) +} + +#let _cite-order(markers) = { + let order = () + for m in markers { if m.value not in order { order.push(m.value) } } + order +} + +#let _suffixes(order, entries) = { + let groups = (:) + for k in order { + if k in entries { + let ay = _ay-key(entries.at(k)) + groups.insert(ay, groups.at(ay, default: ()) + (k,)) + } + } + let smap = (:) + for (ay, ks) in groups { + if ks.len() > 1 { + for (idx, k) in ks.enumerate() { smap.insert(k, numbering("a", idx + 1)) } + } + } + smap +} + +// --------------------------------------------------------------------------- +// ESTADO + MARCADORES +// --------------------------------------------------------------------------- + +#let _bibsrc = state("ppgsi-bibsrc", "") +#let register-bib(content) = _bibsrc.update(content) +#let _entries() = _parse-bib(_bibsrc.get()) +#let _mark(k) = [#metadata(k)] + +// --------------------------------------------------------------------------- +// CITAÇÕES PÚBLICAS +// --------------------------------------------------------------------------- + +// Parentética, fim de frase: "(AMENTA et al., 2002b; AMENTA et al., 2002c)" +#let cite(..keys) = { + let ks = keys.pos() + ks.map(_mark).join() + context { + let entries = _entries() + let smap = _suffixes(_cite-order(query(_CM)), entries) + let parts = ks.map(k => { + let e = entries.at(k) + text(fill: _blue)[#_cite-authors(e.fields.author, caixa: "upper"), #(_year(e) + smap.at(k, default: ""))] + }) + [(#parts.join[; ])] + } +} + +// Narrativa, meio de frase: "Amenta et al. (2002a)" +#let prose(key) = { + _mark(key) + context { + let entries = _entries() + let smap = _suffixes(_cite-order(query(_CM)), entries) + let e = entries.at(key) + text(fill: _blue)[#_cite-authors(e.fields.author, caixa: "title", narrativo: true) (#(_year(e) + smap.at(key, default: "")))] + } +} + +// --------------------------------------------------------------------------- +// FORMATAÇÃO DE ENTRADAS (por tipo, conforme abntex2-alf.bst) +// --------------------------------------------------------------------------- + +#let _g(f, name) = f.at(name, default: "") +#let _endash(s) = s.replace("-", "–") +#let _sentence(s) = _titlecase(s) + +// add.period$: só acrescenta "." se ainda não terminar em pontuação de sentença. +#let _dot(s) = if s == "" or s.ends-with(".") or s.ends-with("?") or s.ends-with("!") { s } else { s + "." } + +// "Local: Editora" com fallbacks ABNT. +#let _pub-addr(f) = { + let addr = _g(f, "address") + let pub = _g(f, "publisher") + let l = if addr != "" { addr } else { "[S.l.]" } + let e = if pub != "" { pub } else { "[s.n.]" } + if addr == "" and pub == "" { "[S.l.: s.n.]" } else { l + ": " + e } +} + +#let _edition(f) = { + let ed = _g(f, "edition") + if ed == "" { none } + else if ed.match(regex("^[0-9]")) != none { ed + ". ed." } else { ed } +} + +#let _vnp(f) = { + // ", v. X, n. Y, p. A–B" (só os presentes) + let out = [] + if _g(f, "volume") != "" { out += [, v. #_g(f, "volume")] } + if _g(f, "number") != "" { out += [, n. #_g(f, "number")] } + if _g(f, "pages") != "" { out += [, p. #_endash(_g(f, "pages"))] } + out +} + +#let _thesis-type(f, etype) = { + let custom = _g(f, "type") + if custom != "" { custom } + else if etype == "phdthesis" { "Tese (Doutorado)" } + else { "Dissertação (Mestrado)" } +} + +#let _emdash = " \u{2014} " + +#let _render-entry(entry) = { + let f = entry.fields + let t = entry.type + let aut = _authors-bib(_g(f, "author")) + let yr = _year(entry) + + if t == "article" { + let out = [#_dot(aut) #_sentence(_g(f, "title")). #emph(_g(f, "journal"))] + if _g(f, "publisher") != "" { out += [, #_g(f, "publisher")] } + if _g(f, "address") != "" { out += [, #_g(f, "address")] } + out += _vnp(f) + if yr != "" { out += [, #yr] } + out += [.] + out + + } else if t == "book" or t == "manual" or t == "techreport" or t == "booklet" { + let out = [#_dot(aut) #emph(_g(f, "title"))] + let ed = _edition(f) + if ed != none { out += [. #ed] } + if t == "book" { + out += [. #_pub-addr(f)] + if yr != "" { out += [, #yr] } + } else { + let addr = _g(f, "address") + out += [. #(if addr != "" { addr } else { "[S.l.]" })] + if yr != "" { out += [, #yr] } + } + if _g(f, "pages") != "" { out += [. #_g(f, "pages") p.] } + out += [.] + out + + } else if t == "inbook" or t == "incollection" { + let out = [#_dot(aut) #_sentence(_g(f, "title")). In: ] + if t == "inbook" { out += [#"______". ] } + else if _g(f, "editor") != "" { out += [#_authors-bib(_g(f, "editor")) (Ed.). ] } + out += [#emph(_g(f, "booktitle"))] + let ed = _edition(f) + if ed != none { out += [. #ed] } + out += [. #_pub-addr(f)] + if yr != "" { out += [, #yr] } + if _g(f, "chapter") != "" { out += [. cap. #_g(f, "chapter")] } + if _g(f, "pages") != "" { out += [, p. #_endash(_g(f, "pages"))] } + out += [.] + out + + } else if t == "inproceedings" or t == "conference" { + let out = [#_dot(aut) #_sentence(_g(f, "title")). In: ] + if _g(f, "organization") != "" { out += [#upper(_g(f, "organization")). ] } + else if _g(f, "editor") != "" { out += [#_authors-bib(_g(f, "editor")) (Ed.). ] } + out += [#emph(_g(f, "booktitle")). #_pub-addr(f)] + if yr != "" { out += [, #yr] } + if _g(f, "pages") != "" { out += [. p. #_endash(_g(f, "pages"))] } + out += [.] + out + + } else if t == "phdthesis" or t == "mastersthesis" { + let out = [#_dot(aut) #emph(_g(f, "title")).] + if _g(f, "pages") != "" { out += [ #_g(f, "pages") f.] } + out += [ #_thesis-type(f, t)#_emdash#_g(f, "school")] + if _g(f, "address") != "" { out += [, #_g(f, "address")] } + if yr != "" { out += [, #yr] } + out += [.] + out + + } else if t == "proceedings" { + let head = if _g(f, "editor") != "" { [#_authors-bib(_g(f, "editor")) (Ed.)] } else { upper(_g(f, "organization")) } + let out = [#head. #emph(_g(f, "title")). #_pub-addr(f)] + if yr != "" { out += [, #yr] } + if _g(f, "pages") != "" { out += [. #_g(f, "pages") p.] } + out += [.] + out + + } else { + // misc / default + let out = [#_dot(aut) #emph(_g(f, "title"))] + if _g(f, "howpublished") != "" { out += [. #_g(f, "howpublished")] } + if yr != "" { out += [, #yr] } + out += [.] + if _g(f, "url") != "" { out += [ Disponível em: <#_g(f, "url")>.] } + out + } +} + +// --------------------------------------------------------------------------- +// BACKREF +// --------------------------------------------------------------------------- + +#let _backref(markers, key) = { + // páginas distintas (valor exibido do contador) + local da 1ª ocorrência (p/ link) + let seen = (:) + for m in markers.filter(m => m.value == key) { + let p = counter(page).at(m.location()).first() + if str(p) not in seen { seen.insert(str(p), m.location()) } + } + let pages = seen.pairs().map(((k, v)) => (p: int(k), loc: v)).sorted(key: x => x.p) + let n = pages.len() + let plink(x) = link(x.loc, text(fill: _blue, str(x.p))) + if n == 0 { [Nenhuma citação no texto.] } + else if n == 1 { [Citado na página #plink(pages.at(0)).] } + else { + let ini = pages.slice(0, n - 1).map(plink).join(", ") + [Citado #n vezes nas páginas #ini e #plink(pages.last()).] + } +} + +// --------------------------------------------------------------------------- +// LISTA DE REFERÊNCIAS +// --------------------------------------------------------------------------- + +#let _padnum(n) = { + let s = str(n) + ("0" * (6 - s.len())) + s +} + +#let references() = { + heading(level: 1, numbering: none, supplement: none)[Referências] + context { + let entries = _entries() + let markers = query(_CM) + let order = _cite-order(markers) + let idx = (:) + for (n, k) in order.enumerate() { idx.insert(k, n) } + let cited = order.filter(k => k in entries) + let sorted = cited.sorted(key: k => { + let e = entries.at(k) + let sa = upper(_authors-bib(_g(e.fields, "author"))) + sa + "\u{1}" + _year(e) + "\u{1}" + lower(_g(e.fields, "title")) + "\u{1}" + _padnum(idx.at(k)) + }) + set par(leading: 0.65em, spacing: 1.3em, first-line-indent: 0pt, justify: true) + for k in sorted { + block(_render-entry(entries.at(k)) + " " + _backref(markers, k)) + } + } +} diff --git a/packages/preview/classic-ppgsi/0.1.0/lib.typ b/packages/preview/classic-ppgsi/0.1.0/lib.typ new file mode 100644 index 0000000000..e99a3cd2a6 --- /dev/null +++ b/packages/preview/classic-ppgsi/0.1.0/lib.typ @@ -0,0 +1,671 @@ +// ============================================================================ +// classic-ppgsi — porte 1:1 do modelo LaTeX abntex2ppgsi (PPgSI-EACH-USP) +// API pública em inglês; usar via namespace: #import "@preview/classic-ppgsi:0.1.0" as ppgsi +// ============================================================================ + +#import "biblio.typ": cite, prose, references, register-bib, _blue + +// Pacotes do ecossistema integrados ao template (re-exportados via namespace): +// ppgsi.lq → lilaq (gráficos de dados, dentro de ppgsi.figure) +// ppgsi.cetz → cetz (desenho/diagramas, dentro de ppgsi.figure) +// glossy/codly/cheq agem por show-rule no corpo (ver thesis()). +#import "@preview/glossy:0.9.1" as glossy +#import "@preview/codly:1.3.0" as codly +#import "@preview/cheq:0.4.0": checklist +#import "@preview/lilaq:0.6.0" as lq +#import "@preview/cetz:0.5.2" as cetz + +#let cm-dash = "\u{2002}\u{2013}\u{2002}" // " – " (espaco-en + travessao + espaco-en) + +// Modo da pos-textual: none | "appendix" | "annex". Os marcadores #appendix / +// #anexo trocam o modo e zeram o contador de headings; os show-rules a seguir +// renderizam os headings nativos (=, ==, ===) como "Apendice A – ...", "1", "1.1". +#let _backmatter = state("ppgsi-backmatter", none) +#let _back-rotulo = modo => if modo == "appendix" { "Apêndice" } else { "Anexo" } + +#let _heading-numbering = (..nums) => { + let n = nums.pos() + if n.len() <= 3 { numbering("1.1.1", ..n) } +} + +#let _chapter-mark(loc) = { + // capitulos numerados + back-matter (apendice/anexo/referencias, outlined); + // exclui pre-textuais (outlined:false), que nao tem cabecalho. + let chaps = query(heading.where(level: 1)).filter(h => ( + h.location().page() <= loc.page() and (h.numbering != none or h.outlined == true) + )) + if chaps.len() == 0 { return none } + let h = chaps.last() + let modo = _backmatter.at(h.location()) + if modo != none { + let letra = numbering("A", counter(heading).at(h.location()).first()) + [#_back-rotulo(modo) #letra#cm-dash#h.body] + } else if h.numbering != none { + let num = numbering("1", ..counter(heading).at(h.location())) + [Capítulo #num. #h.body] + } else { + h.body + } +} + +// Conteudo "single space" (resumo, fontes, ficha, citacoes, referencias). +#let _single(body) = { + set par(leading: 0.65em, spacing: 0.65em) + body +} + +// --------------------------------------------------------------------------- +// ILUSTRACOES: source, figure, table, frame, algorithm +// --------------------------------------------------------------------------- + +// Replica p{Xin}+\tabcolsep do LaTeX: largura dada = texto; soma 12pt (6pt/lado). +#let _addsep(columns) = if type(columns) == array { + columns.map(c => if type(c) == length { c + 12pt } else { c }) +} else { columns } + +// Linha "Fonte – ..." abaixo da ilustracao (tam. 10, centralizada, simples). +#let _src(body) = { + set text(size: 10pt) + set par(leading: 0.6em, first-line-indent: 0pt, justify: false) + v(3pt, weak: true) + align(center, [Fonte#cm-dash#body]) +} +#let source = _src + +// Fonte "elaborado pelo autor": reaproveita author/date definidos em thesis(). +// source: auto -> "Fonte – , " +// source: none -> sem linha de fonte +// source: -> "Fonte – " (ex.: citação a outro trabalho) +#let _self-source = state("ppgsi-self-source", none) +#let _render-source(src) = if src == none { +} else if src == auto { + context { let s = _self-source.get(); if s != none { _src(s) } } +} else { + _src(src) +} + +// "Nome do Autor, ano" — a mesma fonte que `source: auto` usa, exposta para uso +// inline (ex.: #ppgsi.myself, ou source: ppgsi.myself). +#let myself = context _self-source.get() + +#let figure(body, caption: none, source: auto, placement: none) = std.figure( + { + body + _render-source(source) + }, + caption: caption, + kind: image, + supplement: [Figura], + placement: placement, +) + +#let table( + caption: none, + source: auto, + columns: auto, + align: auto, + header: none, + ..rows, +) = std.figure( + { + std.table( + columns: _addsep(columns), + align: align, + stroke: none, + inset: (x: 6pt, y: 3pt), + std.table.hline(stroke: 0.6pt), + ..if header != none { + (std.table.header(..header), std.table.hline(stroke: 0.6pt)) + } else { () }, + ..rows.pos().flatten(), + std.table.hline(stroke: 0.6pt), + ) + _render-source(source) + }, + caption: caption, + kind: std.table, + supplement: [Tabela], + placement: none, +) + +#let frame( + caption: none, + source: auto, + columns: auto, + align: auto, + header: none, + ..rows, +) = std.figure( + { + std.table( + columns: _addsep(columns), + align: align, + stroke: 0.5pt, + inset: (x: 6pt, y: 3pt), + ..if header != none { (std.table.header(..header),) } else { () }, + ..rows.pos().flatten(), + ) + _render-source(source) + }, + caption: caption, + kind: "frame", + supplement: [Quadro], + placement: none, +) + +// Algorithm: caixa com regua acima/abaixo e linhas numeradas. +// (a norma permite leve diferenca para ilustracoes do tipo algoritmo/codigo) +#let algorithm(caption: none, source: auto, ..lines) = std.figure( + block(width: 100%, breakable: false, { + set text(size: 12pt) + set par(leading: 0.7em, first-line-indent: 0pt, justify: false) + line(length: 100%, stroke: 0.8pt) + v(3pt) + let ls = lines.pos() + grid( + columns: (auto, 1fr), + column-gutter: 0.8em, + row-gutter: 0.35em, + align: (right, left), + ..ls.enumerate().map(((i, l)) => (text(size: 10pt)[#(i + 1):], l)).flatten(), + ) + v(3pt) + line(length: 100%, stroke: 0.8pt) + _render-source(source) + }), + caption: caption, + kind: "algorithm", + supplement: [Algoritmo], + placement: none, +) + +// Código-fonte: listagem com legenda "Código N –"; o codly estiliza o raw block +// (números de linha etc.) — ver codly-init em thesis(). +#let code(body, caption: none, source: auto) = std.figure( + { + body + _render-source(source) + }, + caption: caption, + kind: "code", + supplement: [Código], + placement: none, +) + +// Citação direta longa (>3 linhas): recuo de 4cm, fonte 10, espaçamento simples, +// sem aspas, justificada; `citation` opcional ao final (ex.: prose/cite ou (AUTOR, ano, p. X)). +#let quote(body, citation: none) = block(width: 100%, inset: (left: 4cm), { + set text(size: 10pt) + set par(leading: 0.65em, spacing: 0.65em, first-line-indent: 0pt, justify: true) + body + if citation != none { [ #citation] } +}) + +// Theme do glossy que reproduz o grid 2-col da "Lista de abreviaturas e siglas". +// (entry.label precisa ser emitido para os @sigla do texto linkarem na lista) +#let _sigla-theme = ( + section: (title, body) => body, + group: (name, index, total, body) => body, + entry: (entry, index, total) => block(below: 1em, grid( + columns: (3.5em, 1fr), + column-gutter: 1cm, + [#entry.short#entry.label], entry.long, + )), +) + +// --------------------------------------------------------------------------- +// APENDICES E ANEXOS (marcadores; usam os headings nativos do Typst) +// --------------------------------------------------------------------------- + +// Marcadores: trocam o modo da pos-textual e reiniciam o contador de headings +// (letra A,B,C por novo capitulo; "1"/"1.1" por seção interna). Apos o marcador, +// escreve-se = / == / === normalmente; os show-rules cuidam da formatação ABNT. +#let appendix = { + _backmatter.update("appendix") + counter(heading).update((0,)) +} +#let annex = { + _backmatter.update("annex") + counter(heading).update((0,)) +} + +// cite / prose / references: ver biblio.typ (motor próprio ABNT). + +// --------------------------------------------------------------------------- +// PRE-TEXTUAIS +// --------------------------------------------------------------------------- + +#let _capa(logo, instituicao, autor, titulo, local, data) = { + set align(center) + set par(leading: 1.1em, first-line-indent: 0pt, justify: false) + set text(size: 12pt) + if logo != none { image(logo, width: 2.7cm) } + v(0.3cm) + instituicao + v(4cm) + autor + v(5cm) + text(weight: "bold", titulo) + v(1fr) + local + parbreak() + data + v(1cm) +} + +#let _folha-de-rosto(autor, titulo, preambulo, orientador, coorientador, local, data) = { + set align(center) + set par(leading: 1.1em, first-line-indent: 0pt, justify: false) + set text(size: 12pt) + autor + v(1fr) + v(1fr) + text(weight: "bold", titulo) + v(1fr) + // preambulo: bloco de meia largura, alinhado a direita, justificado, simples + align(left, pad(left: 50%, _single({ + set par(justify: true, leading: 0.65em, spacing: 1.3em) + preambulo + v(2em) + [#orientador] + if coorientador != none { + v(0.5em) + [#coorientador] + } + }))) + v(1fr) + local + parbreak() + data + v(1cm) +} + +#let _ficha(ficha) = { + if ficha == none { return } + page(margin: 0cm, header: none, footer: none, { + if type(ficha) == str { + image(ficha, width: 100%, height: 100%, fit: "contain") + } else { ficha } + }) +} + +// --------------------------------------------------------------------------- +// TEMPLATE PRINCIPAL +// --------------------------------------------------------------------------- + +// Normaliza uma entrada de `abstract`: conteúdo -> (body: ); dicionário -> ele mesmo. +#let _abstract-part(v) = if v == none { none } else if type(v) == dictionary { v } else { (body: v) } + +// Divide "Título: subtítulo" em (título, subtítulo); sem ":", subtítulo é none. +#let _split-title(t) = if type(t) == str and ":" in t { + let i = t.position(":") + (t.slice(0, i).trim(), t.slice(i + 1).trim()) +} else { (t, none) } + +// Referência ABNT da própria obra (gerada para o resumo/abstract quando citation: auto). +#let _work-reference(name, title, year, unit, degree, institution, location, defense) = context { + let folhas = counter(page).final().first() + let (main, sub) = _split-title(title) + let titulo = if sub != none { [*#main*: #sub] } else { [*#main*] } + [#name. #titulo. #year. #folhas #unit #degree -- #institution, #location, #defense.] +} + +#let thesis( + title: "Título do trabalho: subtítulo do trabalho", + title-en: none, + author: (given: "Fulano de", surname: "Tal"), + institution: [ + UNIVERSIDADE DE SÃO PAULO + + ESCOLA DE ARTES, CIÊNCIAS E HUMANIDADES + + PROGRAMA DE PÓS-GRADUAÇÃO EM SISTEMAS DE INFORMAÇÃO + ], + location: "São Paulo", + date: "2015", + defense-year: none, + degree: [Dissertação (Mestrado em Ciências)], + degree-en: [Dissertation (Master of Science)], + institution-ref: [Escola de Artes, Ciências e Humanidades, Universidade de São Paulo], + institution-ref-en: [School of Arts, Sciences and Humanities, University of São Paulo], + self-source: auto, + logo: "assets/usp_logo.jpg", + preamble: none, + advisor: [Orientador: Prof. Dr. Fulano de Tal], + co-advisor: [Coorientador: Prof. Dr. Fulano de Tal], + catalog-card: none, + errata: none, + approval-text: none, + committee: (), + dedication: none, + acknowledgments: none, + epigraph: none, + abstract: none, + acronyms: none, + symbols: none, + list-figures: true, + list-algorithms: true, + list-code: true, + list-frames: true, + list-tables: true, + bibliography: none, + validate: true, + body, +) = { + // ---- Resumo/abstract: normaliza entradas por idioma --------------------- + let _abs-pt = _abstract-part(if abstract != none { abstract.at("pt-br", default: none) } else { none }) + let _abs-en = _abstract-part(if abstract != none { abstract.at("en-us", default: none) } else { none }) + + // ---- Autor: nome para exibição e forma invertida da referência ---------- + let _author-str = if type(author) == dictionary { author.given + " " + author.surname } else { author } + let _author-cite = if type(author) == dictionary { [#upper(author.surname), #author.given] } else { [#author] } + let _defense = if defense-year != none { defense-year } else { date } + + // ---- Referência da própria obra (citation: auto por padrão) ------------- + let _resolve-cit(part, lang) = { + if part == none { return none } + let c = part.at("citation", default: auto) + if c == none { return none } + if c != auto { return c } + if lang == "en" { + if title-en == none { return none } + _work-reference(_author-cite, title-en, date, "p.", degree-en, institution-ref-en, location, _defense) + } else { + _work-reference(_author-cite, title, date, "f.", degree, institution-ref, location, _defense) + } + } + let _cit-pt = _resolve-cit(_abs-pt, "pt") + let _cit-en = _resolve-cit(_abs-en, "en") + + // ---- Validação dos elementos obrigatórios (ABNT) ------------------------ + if validate { + let req(cond, nome) = assert(cond, message: "Elemento obrigatório ausente: " + nome + " (use validate: false para desativar).") + req(title not in (none, ""), "título") + req(_author-str not in (none, ""), "autor") + req(advisor != none, "orientador (advisor)") + req(_abs-pt != none and _abs-pt.at("body", default: none) != none, "resumo (abstract.ptBR)") + req(_abs-en != none and _abs-en.at("body", default: none) != none, "abstract (abstract.enUS)") + req(bibliography != none, "referências (bibliography)") + } + + // ---- Metadados do PDF: palavras-chave (arrays) e data (ano) ------------- + let _doc-keywords = () + for p in (_abs-pt, _abs-en) { + let kw = if p != none { p.at("keywords", default: none) } else { none } + if type(kw) == array { _doc-keywords += kw } + } + let _doc-date = if type(date) == str and date.match(regex("^\\d{4}$")) != none { + datetime(year: int(date), month: 1, day: 1) + } else { auto } + + // ---- Estilos globais ---------------------------------------------------- + set page( + paper: "a4", + margin: (left: 3cm, right: 2cm, top: 3cm, bottom: 2cm), + header-ascent: 1cm, + header: context { + let loc = here() + let pg = loc.page() + let mark = _chapter-mark(loc) + if mark == none { return } // pre-textual: sem cabecalho + set text(size: 10pt) + let chap-here = query(heading.where(level: 1)).filter(h => h.location().page() == pg) + if chap-here.len() > 0 { + align(right, counter(page).display()) + return + } + grid( + columns: (1fr, auto), + align: (left + bottom, right + bottom), + mark, counter(page).display(), + ) + v(-0.4em) + line(length: 100%, stroke: 0.4pt) + }, + ) + set text(font: "New Computer Modern", size: 12pt, lang: "pt", region: "br", hyphenate: true) + set document(title: title, author: _author-str, keywords: _doc-keywords, date: _doc-date) + set math.equation(numbering: "(1)") + set par( + leading: 1.1em, + spacing: 1.1em, + first-line-indent: (amount: 1.25cm, all: true), + justify: true, + ) + set heading(numbering: _heading-numbering) + + // ---- Ilustracoes: legenda acima, separador travessao -------------------- + set std.figure(gap: 0.6em) + set std.figure.caption(separator: cm-dash, position: top) + show std.figure.caption: it => { + set text(size: 12pt) + set par(leading: 0.6em, first-line-indent: 0pt, spacing: 0.6em) + layout(size => context { + let number = it.counter.display(it.numbering) + let is-alg = it.kind == "algorithm" + let label = if is-alg { strong[#it.supplement #number] } else { [#it.supplement #number#cm-dash] } + let gap = if is-alg { [ ] } else { [] } + let full = label + gap + it.body + if measure(full).width <= size.width { + align(center, full) + } else { + set par(hanging-indent: measure(label + gap).width, justify: true) + full + } + }) + } + + show heading.where(level: 1): it => context { + pagebreak(weak: true) + set text(size: 12pt, weight: "bold") + set par(first-line-indent: 0pt, justify: false, leading: 0.93em) + let modo = _backmatter.at(it.location()) + block(above: 0pt, below: 22pt, width: 100%, { + if modo != none { + let letra = numbering("A", counter(heading).at(it.location()).first()) + align(center, [#_back-rotulo(modo) #letra#cm-dash#it.body]) + } else if it.numbering == none { + align(center, it.body) + } else { it } + }) + } + show heading.where(level: 2): it => context { + set text(size: 12pt, weight: "regular", style: "italic") + set par(first-line-indent: 0pt, justify: false, leading: 0.93em) + let modo = _backmatter.at(it.location()) + if modo != none { + let n = numbering("1", counter(heading).at(it.location()).at(1)) + block(above: 32pt, below: 22pt, [#n #it.body]) + } else { + block(above: 32pt, below: 22pt, it) + } + } + show heading.where(level: 3): it => context { + set text(size: 12pt, weight: "regular", style: "normal") + set par(first-line-indent: 0pt, justify: false, leading: 0.93em) + let modo = _backmatter.at(it.location()) + if modo != none { + let nums = counter(heading).at(it.location()) + let n = numbering("1.1", nums.at(1), nums.at(2)) + block(above: 32pt, below: 22pt, [#n #it.body]) + } else { + block(above: 32pt, below: 22pt, it) + } + } + + // ---- Pacotes integrados (show-rules de documento) ----------------------- + // glossy: habilita @sigla (expande na 1ª menção); codly: estiliza raw blocks; + // cheq: listas "- [ ]"/"- [x]" viram caixas. glossy só se houver siglas. + let _glossy-init = if acronyms != none { glossy.init-glossary.with(acronyms) } else { it => it } + show: _glossy-init + show: codly.codly-init.with() + show: checklist + + // título de elemento pré-textual (centralizado, negrito, sem numeração) + let pre-titulo(nome) = heading(level: 1, numbering: none, outlined: false, bookmarked: true, nome) + + // ---- Registra a fonte .bib para o motor de citações/referências --------- + if bibliography != none { register-bib(bibliography) } + + // Fonte padrão das ilustrações: ", " (ou self-source explícito). + _self-source.update(if self-source == auto { [#_author-str, #date] } else { self-source }) + + // ---- CAPA (nao contada) ------------------------------------------------- + // Nome do autor em caixa alta na capa e na folha de rosto (convenção ABNT). + _capa(logo, institution, upper(_author-str), title, location, date) + counter(page).update(0) + pagebreak() + + // ---- FOLHA DE ROSTO (= pagina 1) ---------------------------------------- + _folha-de-rosto(upper(_author-str), title, preamble, advisor, co-advisor, location, date) + pagebreak() + + // ---- FICHA CATALOGRAFICA (verso) ---------------------------------------- + _ficha(catalog-card) + + // ---- ERRATA ------------------------------------------------------------- + if errata != none { + pre-titulo[Errata] + errata + } + + // ---- FOLHA DE APROVACAO ------------------------------------------------- + if approval-text != none { + pre-titulo(hide[Folha de aprovação]) // marcador/bookmark sem titulo visivel + // (o conteudo da aprovacao nao tem titulo impresso) + } + if approval-text != none { + _single({ + set par(justify: true) + approval-text + v(3cm) + set align(center) + for member in committee { + v(1.2cm) + line(length: 10cm, stroke: 0.5pt) + member + parbreak() + } + }) + pagebreak() + } + + // ---- DEDICATORIA -------------------------------------------------------- + if dedication != none { + v(1fr) + align(center, emph(dedication)) + v(1fr) + pagebreak() + } + + // ---- AGRADECIMENTOS ----------------------------------------------------- + if acknowledgments != none { + pre-titulo[Agradecimentos] + acknowledgments + } + + // ---- EPIGRAFE ----------------------------------------------------------- + if epigraph != none { + v(1fr) + align(right, emph(epigraph)) + pagebreak() + } + + // ---- RESUMO ------------------------------------------------------------- + if _abs-pt != none { + pre-titulo[Resumo] + _single({ + set par(first-line-indent: 0pt, spacing: 18pt) + if _cit-pt != none { align(left, _cit-pt); parbreak() } + _abs-pt.at("body", default: none) + let kw = _abs-pt.at("keywords", default: none) + if kw != none { + parbreak() + if type(kw) == array { [Palavras-chave: #(kw.join(". ")).] } else { [Palavras-chave: #kw] } + } + }) + } + + // ---- ABSTRACT ----------------------------------------------------------- + if _abs-en != none { + pre-titulo[Abstract] + _single({ + set par(first-line-indent: 0pt, spacing: 18pt) + set text(lang: "en") + if _cit-en != none { align(left, _cit-en); parbreak() } + _abs-en.at("body", default: none) + let kw = _abs-en.at("keywords", default: none) + if kw != none { + parbreak() + if type(kw) == array { [Keywords: #(kw.join(". ")).] } else { [Keywords: #kw] } + } + }) + } + + // ---- LISTAS DE ILUSTRACOES ---------------------------------------------- + let lista(nome, target) = { + pre-titulo(nome) + // entrada inteira azul (prefixo + dash + título); pontilhado e página pretos + show outline.entry: it => { + let tail = if it.fill != none { box(width: 1fr, it.fill) } else { h(1fr) } + it.indented( + text(fill: _blue, { it.prefix(); cm-dash }), + text(fill: _blue, it.body()) + [ ] + tail + [ ] + it.page(), + ) + } + outline(title: none, target: target) + } + if list-figures { lista([Lista de figuras], std.figure.where(kind: image)) } + if list-algorithms { lista([Lista de algoritmos], std.figure.where(kind: "algorithm")) } + if list-code { lista([Lista de códigos], std.figure.where(kind: "code")) } + if list-frames { lista([Lista de quadros], std.figure.where(kind: "frame")) } + if list-tables { lista([Lista de tabelas], std.figure.where(kind: std.table)) } + + // ---- LISTA DE SIGLAS (renderizada pelo glossy) -------------------------- + if acronyms != none { + pre-titulo[Lista de abreviaturas e siglas] + set par(first-line-indent: 0pt) + glossy.glossary(title: "", theme: _sigla-theme, sort: false, show-all: true) + } + + // ---- LISTA DE SIMBOLOS -------------------------------------------------- + if symbols != none { + pre-titulo[Lista de símbolos] + set par(first-line-indent: 0pt) + grid( + columns: (auto, 1fr), + column-gutter: 1cm, + row-gutter: 1.2em, + ..symbols.map(((s, d)) => (s, d)).flatten(), + ) + } + + // ---- SUMARIO ------------------------------------------------------------ + pre-titulo[Sumário] + { + // sumário: linha inteira em azul (prefixo + título + pontilhado + página) + show outline.entry.where(level: 1): it => context block(above: 1em, below: 0pt, text(fill: _blue, weight: "bold", { + let modo = _backmatter.at(it.element.location()) + if modo != none { + // apêndice/anexo: prefixo "Apêndice A – " no lugar do número + let letra = numbering("A", counter(heading).at(it.element.location()).first()) + it.indented([#_back-rotulo(modo) #letra#cm-dash], it.inner()) + } else { + let e = it.indented(it.prefix(), it.inner()) + // "REFERÊNCIAS" em maiusculas no sumario (quirk do abntex bibsection) + if it.element.body == [Referências] { upper(e) } else { e } + } + })) + // seções internas de apêndice/anexo não entram no sumário + show outline.entry.where(level: 2): it => context if _backmatter.at(it.element.location()) != none { none } else { + text(fill: _blue, style: "italic", it.indented(it.prefix(), it.inner())) + } + show outline.entry.where(level: 3): it => context if _backmatter.at(it.element.location()) != none { none } else { + text(fill: _blue, it.indented(it.prefix(), it.inner())) + } + outline(title: none, depth: 3, indent: 1.2em) + } + + // ---- ELEMENTOS TEXTUAIS ------------------------------------------------- + body +} diff --git a/packages/preview/classic-ppgsi/0.1.0/template/assets/ficha-1.png b/packages/preview/classic-ppgsi/0.1.0/template/assets/ficha-1.png new file mode 100644 index 0000000000..53656cbe24 Binary files /dev/null and b/packages/preview/classic-ppgsi/0.1.0/template/assets/ficha-1.png differ diff --git a/packages/preview/classic-ppgsi/0.1.0/template/assets/figura-exemplo.png b/packages/preview/classic-ppgsi/0.1.0/template/assets/figura-exemplo.png new file mode 100644 index 0000000000..de2823ba0c Binary files /dev/null and b/packages/preview/classic-ppgsi/0.1.0/template/assets/figura-exemplo.png differ diff --git a/packages/preview/classic-ppgsi/0.1.0/template/main.typ b/packages/preview/classic-ppgsi/0.1.0/template/main.typ new file mode 100644 index 0000000000..db7823dd5c --- /dev/null +++ b/packages/preview/classic-ppgsi/0.1.0/template/main.typ @@ -0,0 +1,628 @@ +#import "@preview/classic-ppgsi:0.1.0" as ppgsi + +#show: ppgsi.thesis.with( + title: "Título do trabalho: subtítulo do trabalho", + title-en: "Work title: work subtitle", + author: (given: "Fulano de", surname: "Tal"), + location: "São Paulo", + date: "2015", + bibliography: read("referencias.bib"), + catalog-card: image("assets/ficha-1.png", width: 100%, height: 100%, fit: "contain"), + preamble: [ + Versão original + + Dissertação apresentada à Escola de Artes, Ciências e Humanidades da Universidade de São Paulo para obtenção do título de Mestre em Ciências pelo Programa de Pós-graduação em Sistemas de Informação. + + Área de concentração: Metodologia e Técnicas da Computação + + Versão corrigida contendo as alterações solicitadas pela comissão julgadora em xx de xxxxxxxxxxxxxxx de xxxx. A versão original encontra-se em acervo reservado na Biblioteca da EACH-USP e na Biblioteca Digital de Teses e Dissertações da USP (BDTD), de acordo com a Resolução CoPGr 6018, de 13 de outubro de 2011. + ], + advisor: [Orientador: Prof. Dr. Fulano de Tal], + co-advisor: [Coorientador: Prof. Dr. Fulano de Tal], + errata: [Elemento opcional para versão corrigida, depois de depositada.], + approval-text: [ + Dissertação de autoria de Fulano de Tal, sob o título *"Título do trabalho: subtítulo do trabalho"*, apresentada à Escola de Artes, Ciências e Humanidades da Universidade de São Paulo, para obtenção do título de Mestre em Ciências pelo Programa de Pós-graduação em Sistemas de Informação, na área de concentração Metodologia e Técnicas da Computação, aprovada em #h(0.3em)#box(width: 0.85cm, line(length: 100%, stroke: 0.5pt))#h(0.3em) de #h(0.3em)#box(width: 3.5cm, line(length: 100%, stroke: 0.5pt))#h(0.3em) de #h(0.3em)#box(width: 1.25cm, line(length: 100%, stroke: 0.5pt))#h(0.3em) pela comissão julgadora constituída pelos doutores: + ], + committee: ( + [Prof. Dr. \ Instituição \ Presidente], + [Prof. Dr. \ Instituição], + [Prof. Dr. \ Instituição], + [Prof. Dr. \ Instituição], + [Prof. Dr. \ Instituição], + ), + dedication: [Escreva aqui sua dedicatória, se desejar, ou remova esta página...], + acknowledgments: [ + #lorem(80) + + #lorem(80) + + #lorem(80) + ], + epigraph: ["Escreva aqui uma epígrafe, se desejar, ou remova esta página..." \ (Autor da epígrafe)], + // a referência (citation) é gerada automaticamente a partir de autor, título, + // ano, nº de folhas, grau e instituição; passe citation: [...] para sobrescrever + // ou citation: none para omitir. A versão enUS usa o title-en. + abstract: ( + pt-br: ( + body: [Escreva aqui o texto do seu resumo... (redigido em parágrafo único, no máximo em uma página, contendo no "máximo 500 palavras", e apresentando um resumo de todos o seu trabalho, incluindo objetivos, metodologia, resultados e conclusões; não inclua apenas a contextualização até chegar nos objetivos, é importante fazer um resumo de todos os capítulos do texto, até chegar à conclusão). #lorem(40)], + keywords: ("Palavra1", "Palavra2", "Palavra3"), + ), + en-us: ( + body: [Write here the English version of your "Resumo". #lorem(70)], + keywords: ("Keyword1", "Keyword2", "Keyword3"), + ), + ), + // Siglas gerenciadas pelo glossy: defina chave + forma curta + extenso, e + // referencie no texto com @chave (expande na 1ª menção, encurta nas demais). + acronyms: ( + "abnt": (short: "ABNT", long: "Associação Brasileira de Normas Técnicas"), + "usp": (short: "USP", long: "Universidade de São Paulo"), + "each": (short: "EACH", long: "Escola de Artes, Ciências e Humanidades"), + "ppgsi": (short: "PPgSI", long: "Programa de Pós-Graduação em Sistemas de Informação"), + "svm": (short: "SVM", long: "máquina de vetores de suporte"), + "api": (short: "API", long: "interface de programação de aplicações"), + "http": (short: "HTTP", long: "protocolo de transferência de hipertexto"), + "sql": (short: "SQL", long: "linguagem de consulta estruturada"), + "json": (short: "JSON", long: "notação de objetos JavaScript"), + "xml": (short: "XML", long: "linguagem de marcação extensível"), + ), + symbols: ( + ([$Gamma$], [Letra grega Gama]), + ([$Lambda$], [Lambda]), + ([$zeta$], [Letra grega minúscula zeta]), + ([$in$], [Pertence]), + ), +) + += Introdução + +#lorem(60) + +A tabela 1 é um exemplo de como apresentar tabelas de acordo com essa norma. Veja mais detalhes no anexo A deste documento. + +#ppgsi.table( + caption: [Exemplo de título de tabela], + source: ppgsi.myself, + columns: (1in, 1in, 1in, 1in), + align: left, + header: ([Cabeçalho 1], [Cabeçalho 2], [Cabeçalho 3], [Cabeçalho 4]), + ([Texto], [número], [número], [número]), + ([Texto], [número], [número], [número]), + ([Texto], [número], [número], [número]), + ([Texto], [número], [número], [número]), + ([Texto], [número], [número], [número]), +) + +#lorem(30) + +A figura 1 é um exemplo de como apresentar ilustrações de acordo com essa norma. A figura 1 também apresenta um exemplo de como incluir como "Fonte" algo que foi elaborado pelo próprio autor. + +#ppgsi.figure( + image("assets/figura-exemplo.png"), + caption: [Exemplo de título de ilustração do tipo figura, incluindo como "Fonte:" o próprio autor], + // sem "source": usa "Fonte – , " do thesis() automaticamente (próprio autor) +) + +#lorem(30) + +O quadro 1 é um exemplo de como apresentar quadros de acordo com essa norma. Observe as diferenças de formatação entre uma tabela (cf. tabela 1) e um quadro (cf. quadro 1). + +#ppgsi.frame( + caption: [Exemplo de título de quadro], + source: ppgsi.myself, + columns: (1in, 1in, 1in, 1in), + align: left, + header: ([Cabeçalho 1], [Cabeçalho 2], [Cabeçalho 3], [Cabeçalho 4]), + ([Texto], [texto], [texto], [texto]), + ([Texto], [texto], [texto], [texto]), + ([Texto], [texto], [texto], [texto]), + ([Texto], [texto], [texto], [texto]), + ([Texto], [texto], [texto], [texto]), +) + +== Uma seção secundária + +#lorem(40) + +=== Uma seção terciária + +#lorem(40) + +=== Outra seção terciária + +#lorem(40) + +=== Mais uma seção terciária + +#lorem(40) + +A figura 2 também apresenta um exemplo de como incluir em "Fonte:" uma citação para um trabalho já publicado. Nesse caso, use sempre o "prose". + +#ppgsi.figure( + image("assets/figura-exemplo.png"), + caption: [Exemplo de título de ilustração do tipo figura, que pode ser maior para apresentar mais explicações sobre o conteúdo da figura, se for o caso; e com exemplo de citação a um trabalho já publicado, seja do próprio autor ou de outro autor], + source: ppgsi.prose("teste3"), +) + +== Outra seção secundária + +#lorem(40) + +== Mais uma seção secundária + +#lorem(40) + += Outra seção primária + +#lorem(50) + +Atenção ao fazer citações a referências para garantir o uso da forma correta, considerando os seguintes exemplos: + +- Se desejar que uma citação a uma referência apareça no final da frase, use com o comando "cite". Exemplo: "Tal coisa é muito melhor do que aquela outra coisa #ppgsi.cite("teste1", "teste2")". +- Se desejar que uma citação a uma referência apareça no meio da frase, como parte da própria frase, use o comando "prose". Exemplo: "De acordo com #ppgsi.prose("teste3"), tal coisa é muito melhor do que aquela outra coisa." +- *Atenção* - nunca usar o comando "cite" para citações a referências que aparecem no meio da frase, como parte da própria frase. Exemplo - nunca fazer assim: "De acordo com #ppgsi.cite("teste3"), tal coisa é muito melhor do que aquela outra coisa." + +Citações diretas com mais de três linhas (citações longas) devem ser destacadas com recuo de 4 cm, fonte menor e espaçamento simples, sem aspas, com a citação ao final: + +#ppgsi.quote(citation: ppgsi.prose("teste3"))[ + #lorem(45) +] + +O algoritmo 1 é um exemplo de como apresentar ilustrações de acordo com essa norma. + +#ppgsi.algorithm( + caption: [Exemplo de título de ilustração do tipo algoritmo, que pode ser maior para apresentar mais explicações sobre o conteúdo do algoritmo, se for o caso], + source: ppgsi.myself, + [*procedure* #smallcaps[MyProcedure]], + $#h(1em) p a s s o-1$, + $#h(1em) p a s s o-2$, + $#h(1em) p a s s o-3$, + $#h(1em) .$, + $#h(1em) .$, + $#h(1em) p a s s o-n$, + [*end procedure*], +) + +== Uma seção secundária + +#lorem(40) + +As fórmulas 1 e 2 são exemplos de como apresentar fórmulas e equações destacadas do parágrafo normal do texto. + +$ X + Y = Z $ + +$ (X - Y) \/ 5 = n $ + +=== Uma seção terciária + +#lorem(40) + +=== Outra seção terciária + +#lorem(40) + +=== Mais uma seção terciária + +#lorem(40) + +== Outra seção secundária + +#lorem(40) + +== Mais uma seção secundária + +#lorem(40) + += Mais uma seção primária + +#lorem(50) + +== Uma seção secundária + +#lorem(40) + +=== Uma seção terciária + +#lorem(40) + +=== Outra seção terciária + +#lorem(40) + +=== Mais uma seção terciária + +#lorem(40) + +== Outra seção secundária + +#lorem(40) + +== Mais uma seção secundária + +#lorem(40) + += Mais uma outra seção primária + +#lorem(50) + +== Uma seção secundária + +#lorem(40) + +=== Uma seção terciária + +#lorem(40) + +=== Outra seção terciária + +#lorem(40) + +=== Mais uma seção terciária + +#lorem(40) + +== Outra seção secundária + +#lorem(40) + +== Mais uma seção secundária + +#lorem(40) + += Recursos de visualização e código + +Este capítulo demonstra a integração do modelo com pacotes do ecossistema Typst. As siglas são gerenciadas pelo glossy: na primeira menção aparecem por extenso e, nas seguintes, apenas a forma curta. Por exemplo, a @svm é uma técnica de aprendizado supervisionado; a @svm também serve para regressão. Acesso a dados costuma envolver @api, @http e @sql. + +== Gráficos com lilaq + +A figura 3 apresenta um gráfico de dados gerado com o pacote lilaq, embutido em uma figura comum do modelo (com legenda e linha de fonte normais). + +#ppgsi.figure( + ppgsi.lq.diagram( + width: 9cm, + height: 5.5cm, + xlabel: $x$, + ylabel: $y$, + ppgsi.lq.plot((0, 1, 2, 3, 4, 5), (0, 1, 4, 9, 16, 25), mark: "o", label: [medições]), + ), + caption: [Exemplo de gráfico de dados gerado com lilaq], + source: ppgsi.myself, +) + +== Diagramas com cetz + +A figura 4 apresenta uma rede neural feedforward totalmente conectada, desenhada com cetz, o equivalente ao TikZ no Typst. + +#ppgsi.figure( + ppgsi.cetz.canvas({ + import ppgsi.cetz.draw: * + let sizes = (3, 5, 2) + let labels = ([Entrada], [Camada oculta], [Saída]) + let fills = (rgb("#cfe3f7"), rgb("#ececec"), rgb("#d6efd6")) + let xgap = 3.4 + let ygap = 1.1 + let r = 0.34 + let pos(l, i, n) = (l * xgap, (i - (n - 1) / 2) * ygap) + // conexões (atrás dos neurônios) + for l in range(sizes.len() - 1) { + for i in range(sizes.at(l)) { + for j in range(sizes.at(l + 1)) { + line(pos(l, i, sizes.at(l)), pos(l + 1, j, sizes.at(l + 1)), stroke: 0.4pt + luma(65%)) + } + } + } + // neurônios + for l in range(sizes.len()) { + for i in range(sizes.at(l)) { + circle(pos(l, i, sizes.at(l)), radius: r, fill: fills.at(l), stroke: 0.6pt) + } + } + // rótulos das camadas + for l in range(sizes.len()) { + content((l * xgap, -3.1), text(size: 9pt, labels.at(l))) + } + }), + caption: [Exemplo de rede neural feedforward desenhada com cetz], + source: ppgsi.myself, +) + +== Listagens de código com codly + +O código 1 é um exemplo de listagem de código-fonte, estilizada automaticamente pelo codly (numeração de linhas e realce de sintaxe). + +#ppgsi.code( + caption: [Exemplo de listagem de código-fonte do tipo Código], + source: ppgsi.myself, +)[```python +def reconstruir(pontos): + """Reconstrução de superfície homeomórfica.""" + malha = alpha_shape(pontos) + return malha.simplificar() +```] + +== Listas de verificação com cheq + +Listas de tarefas podem ser escritas com a sintaxe de caixas de seleção do cheq: + +- [x] Definir o problema de pesquisa +- [x] Revisar a literatura +- [/] Coletar os dados +- [ ] Analisar os resultados + += Conclusão + +#lorem(50) + +== Uma seção secundária + +#lorem(40) + +=== Uma seção terciária + +#lorem(40) + +=== Outra seção terciária + +#lorem(40) + +=== Mais uma seção terciária + +#lorem(40) + +== Outra seção secundária + +#lorem(40) + +== Mais uma seção secundária + +#lorem(40) + +#ppgsi.references() + +#ppgsi.appendix + += Exemplo de apêndice + +#lorem(30) + +== Exemplo de seção de apêndice não apresentada no sumário + +#lorem(30) + +=== Exemplo de subseção de apêndice não apresentada no sumário + +#lorem(30) + += Exemplo de apêndice + +#lorem(30) + += Exemplo de apêndice + +#lorem(30) + +#ppgsi.annex + += Resumo das normas + +Considerando a dificuldade para formatar um texto acadêmico sem conhecimento básico do conteúdo da norma NBR 14724 "Informação e documentação -- Trabalhos acadêmicos -- Apresentação", este anexo apresenta um resumo de alguns conceitos dessa norma, conforme publicada em julho de 2011. Sugere-se a leitura completa da norma para garantir que seu documento seja completamente aderente à mesma. Em alguns casos específicos, este anexo apresenta alguns ajustes da norma especificamente para o PPgSI. + +== NBR 14724: estrutura e algumas descrições + +A estrutura de uma tese, dissertação ou qualquer outro trabalho acadêmico, deve compreender elementos pré-textuais, elementos textuais e elementos pós-textuais, que aparecem no texto na seguinte ordem: + +=== Elementos pré-textuais + +- Capa (obrigatório) +- Folha de rosto (obrigatório) +- Errata (opcional) +- Folha de aprovação (obrigatório) +- Dedicatória (opcional) +- Agradecimentos (opcional) +- Epígrafe (opcional) +- Resumo em língua vernácula (obrigatório) +- Resumo em língua estrangeira (obrigatório) +- Listas de ilustrações: lista de figuras, lista de algoritmos, lista de quadros etc. (opcional) +- Lista de tabelas (opcional) +- Lista de abreviaturas e siglas (opcional) +- Lista de símbolos (opcional) +- Sumário (obrigatório) + +=== Elementos textuais + +- Introdução +- Desenvolvimento +- Conclusão + +=== Elementos pós-textuais + +- Referências (obrigatório) +- Apêndice (opcional) +- Anexo (opcional) +- Glossário (opcional) + +== Definições relacionadas a elementos pré-textuais + +A seguir, são apresentadas algumas definições contidas na norma relacionadas a elementos pré-textuais. + +=== Capa + +Elemento obrigatório, para proteção externa e sobre o qual se imprimem informações que ajudam na identificação e uso do trabalho, na seguinte ordem: + ++ Nome completo do autor: responsável intelectual do trabalho. ++ Título principal do trabalho: deve ser claro e preciso, identificando o seu conteúdo e possibilitando a indexação e recuperação da informação. ++ Subtítulo (se houver): deve ser evidenciada sua subordinação ao título principal, precedido de dois pontos (:). ++ Número do volume (obrigatório apenas se houver mais de um volume, de forma que deve constar em cada capa a especificação do respectivo volume). ++ Local (cidade) da instituição de apresentação. ++ Ano do depósito (entrega). + +=== Folha de rosto (anverso) + +Os elementos do anverso da folha de rosto devem figurar na seguinte ordem: + ++ Nome completo do autor: responsável intelectual do trabalho. ++ Título principal do trabalho: deve ser claro e preciso, identificando o seu conteúdo e possibilitando a indexação e recuperação da informação. ++ Subtítulo (se houver): deve ser evidenciada sua subordinação ao título principal, precedido de dois pontos (:). ++ Número do volume (obrigatório apenas se houver mais de um volume). ++ Natureza (tese, dissertação e outros) e objetivo (aprovação em disciplina, grau pretendido e outros); nome da instituição a que é submetido; área de concentração. ++ Nome do orientador e, se houver, do co-orientador. ++ Local (cidade) da instituição de apresentação. ++ Ano de depósito (entrega). + +=== Folha de rosto (verso) + +No verso da folha de rosto deve constar a ficha catalográfica, conforme o Código de Catalogação Anglo-Americano -- CCAA2. + +=== Folha de aprovação + +Elemento obrigatório, que contém autor, título por extenso e subtítulo, se houver, local e data de aprovação, nome e instituição dos membros componentes da banca examinadora. + +=== Dedicatória e agradecimentos + +Elementos opcionais. Os agradecimentos devem ser dirigidos apenas àqueles que contribuíram de maneira relevante à elaboração do trabalho. + +=== Resumo na língua vernácula + +Elemento obrigatório, que consiste na apresentação concisa dos pontos relevantes de um texto; constitui-se em uma sequência de frases concisas e objetivas, e não de uma simples enumeração de tópicos, não ultrapassando 500 palavras, seguido, logo abaixo, das palavras representativas do conteúdo do trabalho, isto é, palavras-chave e/ou descritores. + +=== Resumo em língua estrangeira + +Elemento obrigatório, que consiste em uma versão do resumo em idioma de divulgação internacional (em inglês Abstract, em castelhano Resumen, em francês Résumé, por exemplo). Deve ser seguido das palavras representativas do conteúdo do trabalho, isto é, palavras-chave e/ou descritores, na respectiva língua estrangeira. + +=== Lista de figuras e lista de tabelas + +Elementos opcionais, elaborados de acordo com a ordem apresentada no texto, com cada item acompanhado do respectivo número da página. + +=== Lista de abreviaturas e siglas + +Elemento opcional. Consiste na relação alfabética das abreviaturas e siglas usadas no texto, seguidas das palavras ou expressões correspondentes grafadas por extenso. + +=== Lista de símbolos + +Elemento opcional, elaborado de acordo com a ordem apresentada no texto, com o devido significado. + +=== Sumário + +Elemento obrigatório, que consiste na enumeração das principais divisões (seções e outras partes do trabalho) dos elementos textuais e pós-textuais, na mesma ordem e grafia em que a matéria nele sucede, acompanhado do respectivo número da página. + +== Definições relacionadas a elementos textuais + +O autor deve criar quantas seções primárias (também chamadas informalmente de capítulos) desejar para tratar dos seguintes elementos textuais que são obrigatórios: introdução, desenvolvimento e conclusão. Normalmente, existe apenas uma seção primária para a introdução, uma ou mais seções primárias para o desenvolvimento, e apenas uma seção primária para a conclusão. + +== Definições relacionadas a elementos pós-textuais + +A seguir, são apresentadas algumas definições contidas na norma relacionadas a elementos pós-textuais. + +=== Apêndice + +Elemento opcional, que consiste em um texto ou documento elaborado pelo próprio autor, a fim de complementar sua argumentação, sem prejuízo da unidade nuclear do trabalho. Um apêndice deve ser identificado por uma letra maiúscula, seguida por um hífen (entre caracteres de espaço), seguido pelo respectivo título. Os apêndices devem ser identificados por letras consecutivas, a partir da letra "A" (independentemente dos anexos). + +=== Anexo + +Elemento opcional, que consiste em um texto ou documento não elaborado pelo autor, a fim de fundamentar, comprovar ou ilustrar a argumentação do autor. Um anexo deve ser identificado por uma letra maiúscula, seguida por um hífen (entre caracteres de espaço), seguido pelo respectivo título. Os anexos devem ser identificados por letras consecutivas, a partir da letra "A" (independentemente dos apêndices). + +=== Glossário + +Elemento opcional, que consiste em uma lista em ordem alfabética de palavras ou de expressões técnicas de uso restrito ou de sentido obscuro, usadas no texto, acompanhadas das respectivas definições. + +== Formas de apresentação + +A seguir, são apresentadas algumas definições contidas na norma relacionadas a formas de apresentação em geral. + +=== Formato + +O texto deve estar impresso em papel branco, formato A4 (21,0 cm 29,7 cm), apenas no anverso da folha (ou seja, na "frente" da folha), excetuando-se a folha de rosto que deve estar impressa tanto no anverso quanto no verso (com a ficha catalográfica). + +=== Projeto gráfico + +O projeto gráfico é de responsabilidade do autor. + +=== Fonte + +Usar sempre cor preta. + +Usar sempre tamanho de fonte 12, com as seguintes exceções: tamanho de fonte 10 para citações longas (com mais de três linhas), notas de rodapé, legendas de ilustração e de tabela, fontes de ilustração e de tabela, números de página; e tamanho de fonte maiores para títulos de seção. + +=== Margens + +Todas as folhas devem apresentar margens esquerda e superior de 3 cm; e margens direita e inferior de 2 cm, considerando impressão apenas no anverso (ou seja, apenas na "frente"). + +Se a impressão precisar, por algum motivo especial, ser realizada em anverso e verso, neste caso, há que se configurar as margens de forma diferente, conforme detalhes da norma ABNT; por isso solicita-se não realizar impressão em frente e verso. + +=== Espaçamento entre linhas + +Usar sempre espaçamento entre linhas de 1,5 linhas, com as seguintes exceções: espaçamento entre linhas "simples" para citações longas (com mais de três linhas), notas de rodapé, referências, resumos (em vernáculo e em língua estrangeira), legendas de ilustração e de tabela, fontes de ilustração e de tabela, ficha catalográfica, natureza do trabalho, grau pretendido, nome da instituição a que é submetido, e área de concentração; e espaçamento entre linhas "duplo" para equações e fórmulas e para separação das referências entre si. + +Os títulos das seções devem começar na margem superior da folha separados do texto que os sucede por um espaço em branco de 1,5 e, da mesma forma, os títulos das subseções devem ser separados do texto que os precede, ou que os sucede, por um espaço em branco de 1,5. + +=== Numeração das seções + +O indicativo numérico de uma seção precede seu título, alinhado à esquerda, separado por um espaço de caractere. Nos títulos sem indicativo numérico, como lista de ilustrações, sumário, resumo, referências e outros, devem ser centralizados. + +Para evidenciar a sistematização do conteúdo do trabalho, deve-se adotar a numeração progressiva para as seções do texto. Os títulos das seções primárias (chamadas informalmente de capítulos), por serem as principais divisões do texto, devem iniciar em folha distinta. Títulos das seções e subseções devem ser destacados gradativamente, usando-se os recursos de negrito, itálico ou grifo e redondo, caixa alta ou versal. + +=== Paginação + +Todas as folhas do trabalho, a partir da folha de rosto (desconsiderando a capa, mas considerando a ficha catalográfica), devem ser contadas sequencialmente, mas não numeradas. A numeração é colocada, a partir da primeira folha da dos elementos textuais (ou seja, a partir da "Introdução"), em algarismos arábicos, no canto superior direito da folha, a 2 cm da borda superior, ficando o último algarismo a 2 cm da borda direita da folha. + +Havendo apêndices e/ou anexos, suas folhas devem ser numeradas de maneira contínua e sua paginação deve dar seguimento à do texto principal, em algarismos arábicos. + +No caso de o trabalho ser constituído de mais de um volume, deve-se manter uma única sequência de numeração das folhas, do primeiro ao último volume. + +=== Equações e fórmulas + +Equações e fórmulas devem aparecer destacadas no texto, para facilitar sua leitura. + +Se as equações e fórmulas forem apresentadas na sequência normal do texto (ou seja, dentro do próprio parágrafo normal de texto), é permitido usar um espaçamento entre linhas duplo para comportar seus elementos (ou seja, expoentes, índices e outros). + +Se as equações e fórmulas forem apresentadas fora do parágrafo, então elas devem ser centralizadas e, se necessário, devem ser numeradas. Quando fragmentadas em mais de uma linha, por falta de espaço, devem ser interrompidas antes do sinal de igualdade ou depois dos sinais de adição, subtração, multiplicação e divisão. + +=== Ilustrações + +Cada tipo de ilustração (tais como figura, gráfico, algoritmo, fotografia, quadro, esquema, desenhos, esquemas, fluxogramas, mapa, organograma, planta, retrato, entre outros) tem numeração independente e consecutiva. + +Inserir a ilustração o mais próximo possível do parágrafo em que ela é citada pela primeira vez no texto; nunca inserir uma ilustração antes de ela ser citada pela primeira vez no texto. Toda ilustração inserida no trabalho deve ser citada pelo menos uma vez no texto. + +Qualquer que seja o tipo da ilustração, ela deve obrigatoriamente ter uma identificação (ou seja, um título), que deve aparecer sempre na parte superior da ilustração, precedida pela palavra que identifica seu tipo, por exemplo "Figura", seguida de seu número de ordem de ocorrência no texto em algarismo arábico, e de um hífen entre caracteres de espaço (" -- "), em fonte com tamanho 12, sem negrito, sem itálico, com apenas a primeira letra da sentença maiúscula, sem ponto final, e em espaçamento simples. Exemplo: "Figura 1 -- Título da ilustração". + +Para toda ilustração, deve ser apresentada também obrigatoriamente sua fonte (mesmo quando a fonte é o próprio autor do trabalho). A fonte deve apresentada na parte inferior da ilustração e ser informada no seguinte formato: palavra "Fonte", seguida pelo caractere dois pontos ":", seguido por um caractere de espaço, seguido pela citação de onde a ilustração foi obtida (conforme regras de citação da norma ABNT) ou seguido pelo nome completo do autor do trabalho, por uma vírgula e pelo ano de elaboração do trabalho, em fonte com tamanho 10, sem negrito, sem itálico, sem ponto final, e em espaçamento simples. + +=== Tabelas + +As tabelas têm numeração independente e consecutiva das ilustrações. + +Inserir a tabela o mais próximo possível do parágrafo em que ela é citada pela primeira vez no texto; nunca inserir uma tabela antes de ela ser citada pela primeira vez no texto. Toda tabela inserida no trabalho deve ser citada pelo menos uma vez no texto. + +Usar traços horizontais apenas para delimitar o cabeçalho da tabela e o início e o fim da tabela. Não usar traços horizontais para separar cada linha de conteúdo da tabela e também não usar traços verticais para separar cada coluna de conteúdo da tabela. + +Não confundir "tabela" com "quadro". Uma tabela deve ter dados numéricos como informação central. Outros tipos de organização de informações devem ser apresentados em quadros, que é um dos tipos de ilustração. A formatação de um quadro é muito parecida a de uma tabela, porém todos os traços horizontais e verticais devem ser apresentados. + +== Outras normas + +=== Seções + +As seções primárias são as principais divisões do texto, denominadas informalmente de "capítulos". As seções primárias podem ser divididas em seções secundárias; e as secundárias em terciárias, em formatação distinta. Não divida o texto mais do que a terceira ordem; ou seja, evite criar seções de profundidade quatro ou cinco. + +Todos títulos, de todas as seções, de todos os níveis, devem ter sempre tamanho 12. O que muda é a formatação, conforme segue abaixo. A formatação adotada para este _template_ em particular é a seguinte: + +- Seções primárias: *negrito*. +- Seções secundárias: _itálico_. +- Seções terciárias: regular. +- Seções quartenárias: [não usar]. +- Seções quinárias: [não usar]. + +São empregados algarismos arábicos na numeração. O "indicativo" de uma seção precede o título ou a primeira palavra do texto, se não houver título, separado por um espaço. + +=== Referências bibliográficas e citações às referências bibliográficas + +A norma é bastante complexa e extensa em relação às regras de referências bibliográficas e citações às referências bibliográficas, não sendo possível fazer um resumo aqui. Assim, é necessário fazer uma consulta às normas detalhadas. + +As referências devem ser apresentadas em ordem alfabética, com as citações no texto obedecendo ao sistema autor-data. Todos os documentos relacionados nas Referências devem ser citados no texto, assim como todas as citações do texto devem constar nas Referências. + += Exemplo de anexo + +#lorem(30) + += Exemplo de anexo + +#lorem(30) diff --git a/packages/preview/classic-ppgsi/0.1.0/template/referencias.bib b/packages/preview/classic-ppgsi/0.1.0/template/referencias.bib new file mode 100644 index 0000000000..1299baae09 --- /dev/null +++ b/packages/preview/classic-ppgsi/0.1.0/template/referencias.bib @@ -0,0 +1,45 @@ +@article{teste1, + author = {Nina Amenta and Sunghee Choi and Tamal K. Dey and N. Leekha}, + title = {A simple algorithm for homeomorphic surface reconstruction}, + journal = {International Journal of Computational Geometry and Applications}, + publisher = {World Scientific Publishing Co.}, + volume = {12}, + number = {1-2}, + pages = {125-141}, + year = {2002}, +} + +@article{teste2, + author = {Nina Amenta and Sunghee Choi and Tamal K. Dey and N. Leekha}, + title = {A simple algorithm for homeomorphic surface reconstruction}, + journal = {International Journal of Computational Geometry and Applications}, + publisher = {World Scientific Publishing Co.}, + volume = {12}, + number = {1-2}, + pages = {125-141}, + year = {2002}, +} + +@article{teste3, + author = {Nina Amenta and Sunghee Choi and Tamal K. Dey and N. Leekha}, + title = {A simple algorithm for homeomorphic surface reconstruction}, + journal = {International Journal of Computational Geometry and Applications}, + publisher = {World Scientific Publishing Co.}, + volume = {12}, + number = {1-2}, + pages = {125-141}, + year = {2002}, +} + +% --------------------------------------------------------------------------- +% Modelos de entrada (preencha e renomeie a chave). Mantidos como comentário +% porque o Typst rejeita campos vazios. Descomente e complete conforme o tipo. +% --------------------------------------------------------------------------- +% @article{chave, author={}, title={}, journal={}, volume={}, number={}, pages={}, year={} } +% @book{chave, author={}, title={}, edition={}, publisher={}, year={} } +% @inbook{chave, author={}, title={}, booktitle={}, publisher={}, year={}, chapter={}, pages={} } +% @inproceedings{chave, author={}, title={}, editor={}, booktitle={}, publisher={}, year={}, pages={} } +% @phdthesis{chave, author={}, title={}, school={}, year={} } +% @mastersthesis{chave, author={}, title={}, school={}, year={} } +% @techreport{chave, author={}, title={}, year={} } +% @misc{chave, author={}, title={}, year={}, url={} } diff --git a/packages/preview/classic-ppgsi/0.1.0/thumbnail.png b/packages/preview/classic-ppgsi/0.1.0/thumbnail.png new file mode 100644 index 0000000000..893472cdb5 Binary files /dev/null and b/packages/preview/classic-ppgsi/0.1.0/thumbnail.png differ diff --git a/packages/preview/classic-ppgsi/0.1.0/typst.toml b/packages/preview/classic-ppgsi/0.1.0/typst.toml new file mode 100644 index 0000000000..bf43a1a7d0 --- /dev/null +++ b/packages/preview/classic-ppgsi/0.1.0/typst.toml @@ -0,0 +1,18 @@ +[package] +name = "classic-ppgsi" +version = "0.1.0" +entrypoint = "lib.typ" +authors = ["Gabriel Francisco dos Santos Silva "] +license = "MIT" +description = "Dissertação/tese ABNT do PPgSI-EACH-USP (abntex2ppgsi)." +repository = "https://github.com/ppgsi-lab/classic-ppgsi" +keywords = ["thesis", "dissertation", "abnt", "ppgsi", "usp", "portuguese"] +categories = ["thesis"] +disciplines = ["computer-science"] +compiler = "0.13.0" +exclude = ["build.sh", "**/*.pdf"] + +[template] +path = "template" +entrypoint = "main.typ" +thumbnail = "thumbnail.png"