diff --git a/packages/preview/ape/0.3.1/README.md b/packages/preview/ape/0.3.1/README.md new file mode 100644 index 000000000..16bf0287a --- /dev/null +++ b/packages/preview/ape/0.3.1/README.md @@ -0,0 +1,93 @@ +# Ape for Typst + + + +Tired of documents that look like they were formatted by a troop of baboons? Try Ape for Typst! + + + +This Typst package provides a comprehensive set of tools for structuring and styling academic course documents across various disciplines. It simplifies the process of creating good looking and consistent layouts, allowing students to focus on content creation. + + + +**Key Features:** + + + +* **Flexible Title Numbering:** Offers a variety of numbering styles for headings and subheadings + +* **Table of Contents Customization:** Provides enhanced outline + +* **Front Page Design:** Offers a pre-designed front page templates + +* **Easy Integration:** Simple to integrate into your Typst documents with clear and concise functions and components. + +* **Helpful function:** function to highlight information (in boxes), shortcuts, plotting, etc. + + + + + + +**Functionalities:** + + +* Starting a new document +```typst +#import "@preview/ape:0.3.1": * + +#show: doc.with( + lang: "en", + + title: "Title", + authors: ("Author1", "Author2"), + style: "numbered", + + title-page: true, + outline: true, + smallcaps: true, +) +``` + + +*Exemple 1 : (Style : numbered)* +![Exemple 1](exemples/Exemple1.png) + +*Exemple 2 : (Style : colored)* + +*Soon...* + + +## Further informations +Some shortcuts are currently only available in french. + +* Available style + - Numbered + - Plain + - Colored + - Presentation + +* Formatting Functions + - `para(name, content)`: Create a named paragraph with custom content + - `rq(content)`: Create a "Remarque" (note) paragraph + - `ex(content)`: Create an "Exemple" (example) paragraph + - `arrow-list(items)`: Create a list with arrow bullets + - `inbox(content)`: Create a box with gray background and border + - There are a lot of varient accesible with `inbox2`, `inbox3`, `inbox4` + +* Drawing and Plotting + - `plotting(functions, domain, samples, steps, axis-style, axis, size)`: Plot mathematical functions with customizable options + - `point(coordinates)`: Draw a point at given coordinates + - `point-name(coordinates, name, offset)`: Draw a named point with custom offset + - `quadratic(a, b, c)`: Calculate roots of quadratic equation + - `base(coordinates, name1, name2, angle)`: Draw a base with custom angle + - `spring(x0, y0, xf, yf, repetitions, amplitude)`: Draw a spring + +* Mathematical Shortcuts + - `recurrence(property, domain, initialization, heredity, conclusion)`: Format mathematical recurrence proofs + - `dt`, `dx`, `dtheta`: Differential notations + - `ar(content)`: Arrow notation + - `nar(content)`: Norm of arrow notation + - `dot2`, `dot3`: Double and triple dot notations + - `grad`: Gradient notation + - `cste`: Constant notation \ No newline at end of file diff --git a/packages/preview/ape/0.3.1/document/apply-style.typ b/packages/preview/ape/0.3.1/document/apply-style.typ new file mode 100644 index 000000000..787536c54 --- /dev/null +++ b/packages/preview/ape/0.3.1/document/apply-style.typ @@ -0,0 +1,27 @@ +#import "styles/numbered.typ": * +#import "styles/colored.typ": * +#import "styles/plain.typ": * +#import "styles/presentation.typ": * + +#let apply-style(style, content) = { + set heading(numbering: "I)1)a)i)") + + if style == "numbered" { + return numbered(content) + } else if style == "colored" { + return colored(content) + } else if style == "plain" { + return plain(content) + } else if style == "presentation" { + return presentation(content) + } else { + return numbered(content) + } +} + +#let get-small-title(style, title) = { + import "styles/" + style + ".typ" as current-style + + return current-style.get-small-title(title) + +} \ No newline at end of file diff --git a/packages/preview/ape/0.3.1/document/code-display.typ b/packages/preview/ape/0.3.1/document/code-display.typ new file mode 100644 index 000000000..08e52cf22 --- /dev/null +++ b/packages/preview/ape/0.3.1/document/code-display.typ @@ -0,0 +1,55 @@ +#import "../tools/miscellaneous.typ": content-to-string + +#let code-display(content) = { + // Code + + show raw: it => context { + if ("py", "python", "ocaml", "ml").contains(it.lang) { + let breakableVar = false + let lines = (..it.lines,) + + while lines.len() > 0 and content-to-string(lines.first()).trim() == "" { + lines.remove(0) + } + while lines.len() > 0 and content-to-string(lines.last()).trim() == "" { + lines.remove(-1) + } + + if (it.lines.len() >= 15) { + breakableVar = true + } + + + + block( + clip: true, + radius: calc.min(9pt, 4pt + 2pt * lines.len()), + stroke: text.fill.lighten(50%) + 0.5pt, + align( + center, + block( + breakable: breakableVar, + grid( + columns: (measure([#lines.len()]).width + 10pt, 20fr), + column-gutter: 0pt, + inset: ((left: 5pt, right: 5pt, rest: 3pt), (left: 10pt, rest: 3pt)), + align: (horizon + left, left), + fill: (text.fill.lighten(75%), text.fill.lighten(88%)), + [], + [], + ..for i in range(lines.len()) { + let l = lines.at(i) + (str(i + 1), l.body) + }, + [], + [], + ), + ), + ), + ) + } else { + it + } + } + content +} diff --git a/packages/preview/ape/0.3.1/document/doc.typ b/packages/preview/ape/0.3.1/document/doc.typ new file mode 100644 index 000000000..49bf453aa --- /dev/null +++ b/packages/preview/ape/0.3.1/document/doc.typ @@ -0,0 +1,75 @@ +#import "outline.typ": * +#import "apply-style.typ": * +#import "header-footer.typ": * +#import "front-pages.typ": * +#import "../tools/shortcuts.typ": * +#import "code-display.typ": * +#import "../tools/formatting.typ": * + + += Documents + +/* +Style : +- Numbered +- Colored +- Plain +*/ + +#let doc( + lang: "fr", + title: "Titre", + authors: (), + style: "numbered", + title-page: false, + outline: false, + smallcaps: true, + content, +) = context { + set text(lang: lang, font: "New Computer Modern") + + show: apply-style.with(style) + + let (first-real-page, custom-outline) = get-outline(lang, smallcaps) + + show: header-footer.with(style, smallcaps, first-real-page, authors) + + front-pages(style, smallcaps, title, title-page, authors, outline, custom-outline) + + show: shows-shortcuts + show: code-display + + // Pre-set + + set table( + inset: 10pt, + stroke: 0.4pt + text.fill.lighten(20%), + align: center + horizon, + fill: (x, y) => if (x == 0) or (y == 0) { text.fill.lighten(90%) }, + ) + + + + + + set grid(column-gutter: 10pt, align: horizon) + + + show image: it => { + align(center, it) + } + + show table: it => { + block(clip: true, radius: 0.75em, stroke: it.stroke, it) + } + // content + set par(justify: true) + + [= audhzifoduiygzbcjlxmwmwpadpozieuhgb] + + counter(heading).update(0) + + + content +} + diff --git a/packages/preview/ape/0.3.1/document/front-pages.typ b/packages/preview/ape/0.3.1/document/front-pages.typ new file mode 100644 index 000000000..a4505d7ec --- /dev/null +++ b/packages/preview/ape/0.3.1/document/front-pages.typ @@ -0,0 +1,72 @@ +#import "apply-style.typ" : get-small-title + +#let front-pages(style, small-caps, title, title-page, authors, outline, custom-outline) = { + let sc(c) = { + if small-caps == true { + return smallcaps(c) + } else { + return c + } + } + + + + if title-page { + align( + center + horizon, + [ + #{ + if type(title) == text { + text(size: 6em, [*#title*]) + } else { + [ + #par(leading: 0.38em, text(size: 5em, hyphenate: false, (strong(title.at(1))))) + #v(-3em) + #par(text(size: 3.25em, hyphenate: false, (title.at(0)))) + ] + } + } + #v(1em) + #{ + if type(authors) == array { + if authors.len() > 0 { + [ + #text(size: 1.55em, sc(authors.at(0))) + \ + ] + } + if authors.len() > 1 { + [ + #text(size: 1.55em, authors.slice(1).map(sc).join(" - ")) + ] + } + } else { + [ + #text(size: 1.55em, sc(authors)) + ] + } + } + + + + ], + ) + + pagebreak() + if outline { + custom-outline + pagebreak() + } + + get-small-title(style, title) + } else { + if outline { + custom-outline + pagebreak() + } + + get-small-title(style, title) + + v(15pt) + } +} diff --git a/packages/preview/ape/0.3.1/document/header-footer.typ b/packages/preview/ape/0.3.1/document/header-footer.typ new file mode 100644 index 000000000..e46e4459a --- /dev/null +++ b/packages/preview/ape/0.3.1/document/header-footer.typ @@ -0,0 +1,48 @@ +#import "../tools/miscellaneous.typ": to-array +#let header-footer(style, small-caps, first-real-page, authors, content) = { + + + + if style == "presentation" { + return content + } + + let sc(c) = { + if small-caps == true { + return smallcaps(c) + } else { + return c + } + } + + + set page( + header: context { + if (counter(page).get().at(0) > first-real-page and to-array(authors).len() > 0) { + [ + #set text(size: 9pt) + #grid( + columns: (1fr, 2fr), + align(left, sc(to-array(authors).at(0))), align(right, to-array(authors).slice(1).map(sc).join(" - ")), + ) + #place(dy: 3.5pt, line(length: 100%, stroke: 0.5pt + text.fill)) + ] + } + }, + + footer: context { + if (counter(page).get().at(0) >= first-real-page) { + [ + #place(dy: -0.25cm, line(length: 100%, stroke: 0.5pt + text.fill)) + #set align(center) + + + _Page #counter(page).display() / #counter(page).final().at(0)_ + + ] + } + }, + ) + + content +} diff --git a/packages/preview/ape/0.3.1/document/outline.typ b/packages/preview/ape/0.3.1/document/outline.typ new file mode 100644 index 000000000..dd4142b21 --- /dev/null +++ b/packages/preview/ape/0.3.1/document/outline.typ @@ -0,0 +1,106 @@ +#import "../tools/miscellaneous.typ": content-to-string +#let get-outline(lang, small-caps) = { + let sc(c) = { + if small-caps == true { + return smallcaps(c) + } else { + return c + } + } + + let first-real-page = 0 + let custom-outline = { + set text(hyphenate: true) + + align( + center, + [ + + #{ + if lang == "fr" { + text( + size: 2.6em, + sc[ + *Table des matières* + ], + ) + } else { + text( + size: 2.6em, + sc[ + *Table of content* + ], + ) + } + } + ], + ) + + + let depthsMap = (1,) * 20 + + set par(justify: true, spacing: 5pt) + + + grid( + columns: (auto, 20fr, 1fr), + column-gutter: (12pt, 5pt), + row-gutter: 9pt, + align: (left, left, bottom), + + ..for e in query(heading) { + if first-real-page == 0 { + first-real-page = e.location().page() + } + + if content-to-string(e) != "audhzifoduiygzbcjlxmwmwpadpozieuhgb" { + let dotFill(c, correctif) = context { + layout(size => { + let w = size.width + correctif + + let filled = box(width: w, c + box(width: 1fr, repeat[.])) + + [#filled] + }) + } + + + if e.depth == 1 { + ( + numbering("I", depthsMap.at(0)), + link(e.location(), dotFill([*#e.body*], 0pt)), + [#link(e.location(), str(e.location().page()))], + ) + + + depthsMap.at(0) += 1 + depthsMap = (depthsMap.at(0),) + (1,) * 20 + } else { + let style = "1." + if (e.depth == 3) { style = "a." } + if e.depth == 4 { style = "i." } + + ( + [], + link( + e.location(), + grid( + columns: ((e.depth - 1) * 2em, 100% - ((e.depth - 1) * 2em)), + align: (right, left), + column-gutter: 10pt, + [#numbering(style, depthsMap.at(e.depth - 1))], box(clip: false)[#dotFill(e.body, -10pt)], + ), + ), + [#link(e.location(), str(e.location().page()))], + ) + + depthsMap.at(e.depth - 1) += 1 + depthsMap = depthsMap.slice(0, e.depth) + (1,) * 15 + } + } + } + ) + } + + return (first-real-page, custom-outline) +} diff --git a/packages/preview/ape/0.3.1/document/styles/colored.typ b/packages/preview/ape/0.3.1/document/styles/colored.typ new file mode 100644 index 000000000..f895f102e --- /dev/null +++ b/packages/preview/ape/0.3.1/document/styles/colored.typ @@ -0,0 +1,57 @@ +#import "../../tools/miscellaneous.typ": content-to-string +#let colored(content) = { + set text(12pt, fill: blue.darken(50%), weight: "extrabold") + + + show heading: it => { + if content-to-string(it) == "audhzifoduiygzbcjlxmwmwpadpozieuhgb" { + return none + } + + let cl = blue.darken(20% - 20% * (it.level - 1)) + + block(breakable: false)[ + #h(20pt * (it.depth - 1)) + #{ text(fill: cl)[*▸*] } + #text(fill: cl, it.body) + #place( + dy: -6pt + measure(it.body).height, + line( + length: 100%, + stroke: ( + thickness: calc.max(1pt, calc.min(4pt, 4pt - 1pt * it.level)), + paint: gradient.linear(cl, cl.lighten(70%)), + cap: "round", + ), + ), + ) + #v(7pt) + ] + } + + content +} + +#let get-small-title(title) = context { + + + return { + line(length: 100%, stroke: 2pt + text.fill) + text( + font: "Noto Sans Georgian", + align( + left, + if type(title) == array [ + ▸ *#emph(text(size: 1.5em, title.at(0)))* + #align(center, text(size: 2em)[ *#title.at(1)* ]) + ] else [ + *#title* + ], + ), + ) + + + line(length: 100%, stroke: 2pt + text.fill) + v(15pt) + } +} diff --git a/packages/preview/ape/0.3.1/document/styles/numbered.typ b/packages/preview/ape/0.3.1/document/styles/numbered.typ new file mode 100644 index 000000000..2a4fd9e82 --- /dev/null +++ b/packages/preview/ape/0.3.1/document/styles/numbered.typ @@ -0,0 +1,52 @@ +#import "../../tools/miscellaneous.typ": content-to-string +#let numbered(content) = { + set text(10pt) + + set heading(numbering: "I)1)a)i)") + + show heading: it => { + if content-to-string(it) == "audhzifoduiygzbcjlxmwmwpadpozieuhgb" { + return none + } + set par(spacing: 15pt) + if it.numbering != none { + let n = it.level - 1 + set text(size: 15pt - 1pt * n) + + block( + sticky: true, + h(1cm * n) + + underline([ + #counter(heading).display(it.numbering).split(")").at(-2)) + #it.body + + ]), + ) + } + } + + content +} + + +#let get-small-title(title) = context { + return { + line(length: 100%) + text( + size: 2em, + font: "Noto Sans Georgian", + align( + center, + if type(title) == array [ + *#title.at(0) - #title.at(1)* + ] else [ + *#title* + ], + ), + ) + + + line(length: 100%) + v(15pt) + } +} diff --git a/packages/preview/ape/0.3.1/document/styles/plain.typ b/packages/preview/ape/0.3.1/document/styles/plain.typ new file mode 100644 index 000000000..69ce2816a --- /dev/null +++ b/packages/preview/ape/0.3.1/document/styles/plain.typ @@ -0,0 +1,37 @@ +#import "../../tools/miscellaneous.typ": content-to-string +#let plain(content) = { + set text(10pt) + + show heading: it => { + if content-to-string(it.body) == "audhzifoduiygzbcjlxmwmwpadpozieuhgb" { + return none + } + + block(sticky: true, underline(it.body)) + } + + content +} + + +#let get-small-title(title) = context { + return { + line(length: 100%) + text( + size: 2em, + font: "Noto Sans Georgian", + align( + center, + if type(title) == array [ + *#title.at(0) - #title.at(1)* + ] else [ + *#title* + ], + ), + ) + + + line(length: 100%) + v(15pt) + } +} diff --git a/packages/preview/ape/0.3.1/document/styles/presentation.typ b/packages/preview/ape/0.3.1/document/styles/presentation.typ new file mode 100644 index 000000000..b949e03a1 --- /dev/null +++ b/packages/preview/ape/0.3.1/document/styles/presentation.typ @@ -0,0 +1,49 @@ +#import "../../tools/miscellaneous.typ": content-to-string +#let presentation(content) = { + set text(fill: white, size: 18pt) + + + set page( + paper: "presentation-4-3", + fill: black.lighten(27%), + + footer: context [ + #block( + fill: blue.lighten(20%), + outset: (left: 70pt, right: 70pt), + width: 100%, + height: 100%, + + + align( + horizon, + grid( + columns: (1fr, 1fr, 1fr), + align: (left, center, right), + [Nom/Prenom ? ], + [], + [ + _Page #counter(page).display() / #counter(page).final().at(0)_ + + ], + ), + ), + ) + ], + ) + + show heading: it => { + if content-to-string(it) != "audhzifoduiygzbcjlxmwmwpadpozieuhgb" { + pagebreak(weak: true) + place(dy: -25pt, box(radius: 15pt, fill: green.darken(10%), outset: (left: 100pt, right: 60pt, rest: 20pt), it)) + v(1cm) + } + } + + + content +} + +#let get-small-title(title) = context { + return "" +} diff --git a/packages/preview/ape/0.3.1/exemples/Exemple.typ b/packages/preview/ape/0.3.1/exemples/Exemple.typ new file mode 100644 index 000000000..17cb19ff8 --- /dev/null +++ b/packages/preview/ape/0.3.1/exemples/Exemple.typ @@ -0,0 +1,2 @@ +#import "../lib.typ" : * + diff --git a/packages/preview/ape/0.3.1/exemples/Exemple1.png b/packages/preview/ape/0.3.1/exemples/Exemple1.png new file mode 100644 index 000000000..3c9c8a1a6 Binary files /dev/null and b/packages/preview/ape/0.3.1/exemples/Exemple1.png differ diff --git a/packages/preview/ape/0.3.1/exemples/Exemple1.typ b/packages/preview/ape/0.3.1/exemples/Exemple1.typ new file mode 100644 index 000000000..8619b33a2 --- /dev/null +++ b/packages/preview/ape/0.3.1/exemples/Exemple1.typ @@ -0,0 +1,166 @@ +#import "../lib.typ": * + + +#show: doc.with( + title: ("Chapter 4", "Hilbert Spaces and Functional Analysis"), + authors: ("Prof. Smith", "Advanced Mathematics Course"), + style: "numbered", + outline: true, + title-page: true, + smallcaps: true, + lang: "en", +) + += Introduction to Hilbert Spaces + +#para("Definition")[A Hilbert space H is a complete inner product space. That is, it is a vector space with an inner product that is also complete with respect to the distance function induced by the inner product.] + +#inbox[ + The inner product $angle.l x, y angle.r$ induces a norm through: + $norm(x) = root(angle.l x, x angle.r)$ +] + +== Fundamental Properties + +=== The Projection Theorem + +#ex[In a Hilbert space H, for any closed subspace M and any point x ∈ H, there exists a unique point y ∈ M such that: +$norm(x - y) = inf_(z in M) norm(x - z)$ +] + +#plotting( + ( + ( + fn: x => x*calc.sin(x)/2, + domain: (-5, 5), + projection: ( + x: (2,), + y: (2,), + ), + ), + ), + domain: (-5, 5), + steps: (1, 1), + axis: ($x$, $y$), +) + +=== Orthogonal Decomposition + +#rq[For any closed subspace M of a Hilbert space H: +- H = M ⊕ M^⊥ +- Every element x ∈ H can be uniquely written as x = y + z where y ∈ M and z ∈ M^⊥] + +#ex[Consider the space $L^2([0,1])$ with the subspace of constant functions: +$M = {f in L^2([0,1]) | f "is constant"}$ +] + +== Operators on Hilbert Spaces + + +#inbox2[ + A bounded linear operator T on a Hilbert space H is: + - *Self-adjoint* if $angle.l T x,y angle.r = angle.l x,T y angle.r$ for all x,y ∈ H + - *Compact* if it maps bounded sets to relatively compact sets + - *Normal* if $T T^* = T^* T$ +] + +=== The Spectral Theorem + +#recurrence( + p: "For any compact self-adjoint operator T on a Hilbert space H", + d: "λ ∈ σ(T)", + ini: [ + There exists an orthonormal basis {$e_n$} of H consisting of eigenvectors of T: + $T e_n = lambda_n e_n$ + where $lambda_n$ are the eigenvalues of T. + ], + hd: [ + Moreover, if T is compact: + - The spectrum σ(T) is countable + - 0 is the only possible accumulation point of σ(T) + - Each non-zero λ ∈ σ(T) is an eigenvalue of finite multiplicity + ], + cl: [ + This allows us to represent T as: + $T = sum_(n=1)^∞ lambda_n angle.l dot, e_n angle.r e_n$ + ] +) + += Applications in Quantum Mechanics + +#para("Definition")[The state space of a quantum system is modeled by a complex Hilbert space H, where: +- Physical observables are represented by self-adjoint operators +- The evolution of the system is given by the Schrödinger equation] + +#arrow-list( + [Wave functions are elements of $L^2(RR^3)$], + [The momentum operator is $P = -i bar nabla$], + [The position operator is multiplication by x] +) + += Python Implementation + +#para("Code")[Here is a Python implementation of the concepts presented above:] +```python +import numpy as np +from scipy.integrate import quad +from scipy.linalg import eigh +import matplotlib.pyplot as plt + +class HilbertSpace: + """Class representing a Hilbert space L²([a,b])""" + + def __init__(self, a=0, b=1): + self.a = a + self.b = b + + def inner_product(self, f, g): + """Calculation of the inner product in L²""" + return quad(lambda x: f(x) * np.conjugate(g(x)), + self.a, self.b)[0] + + def norm(self, f): + """Calculation of the induced norm""" + return np.sqrt(self.inner_product(f, f)) + + def project(self, f, subspace_basis): + """Projection onto a closed subspace""" + projection = lambda x: 0 + for basis_fn in subspace_basis: + coeff = self.inner_product(f, basis_fn) + projection = lambda x, p=projection: ( + p(x) + coeff * basis_fn(x) + ) + return projection + +# Example of use +H = HilbertSpace(-np.pi, np.pi) + +# Fourier basis +e1 = lambda x: 1/np.sqrt(2*np.pi) +e2 = lambda x: np.cos(x)/np.sqrt(np.pi) +e3 = lambda x: np.sin(x)/np.sqrt(np.pi) + +# Function to project +f = lambda x: x**2 + +# Projection onto the space spanned by {e1, e2, e3} +proj_f = H.project(f, [e1, e2, e3]) + +# Visualization +x = np.linspace(-np.pi, np.pi, 200) +plt.figure(figsize=(10, 6)) +plt.plot(x, [f(xi) for xi in x], 'b-', label='Original function') +plt.plot(x, [proj_f(xi) for xi in x], 'r--', + label='Projection (truncated Fourier series)') +plt.legend() +plt.grid(True) +plt.title('Projection in L²([-π,π])') +``` + +This implementation illustrates: +#arrow-list( + [The structure of a Hilbert space with its inner product], + [The projection theorem onto a closed subspace], + [The approximation by Fourier series] +) diff --git a/packages/preview/ape/0.3.1/exemples/Exemple2.typ b/packages/preview/ape/0.3.1/exemples/Exemple2.typ new file mode 100644 index 000000000..b623ff31c --- /dev/null +++ b/packages/preview/ape/0.3.1/exemples/Exemple2.typ @@ -0,0 +1,147 @@ +//#import "@preview/ape:0.3.0": * +#import "../lib.typ": * +#show: doc.with( + lang: "fr", + title: ("Chapitre 1", "Bases OCAML"), + authors: "Auteur", + style: "colored", // numbered, colored, plain + title-page: true, + outline: true, + smallcaps: true, +) + + +Intransigeant, pas de mélange de type/transtypage ! + +Commentaire (\* contenu \*) + + + +#table( + columns: (1fr, 2fr), + table.cell(colspan: 2)[Raccourcis clavier], + [ +Ctrl-c Ctrl-s enter],[ démarrer OCaml dans emcas +] +,[Ctrl-x Ctrl-s],[sauvegarde du fichier courant +],[ +Ctrl-c Ctrl-e],[ exécuter de la ligne courante +],[ +Ctrl-c Ctrl-b],[exécuter tout le fichier +]) + + += Integer & Float +- Pour additionner les entier : +, etc... + +- Pour additionner les flottants, il faut utiliser un opérateur spécial : +. + + + +Changer de type : float_of_int + +Les fonctions usuelles mathématiques prennent en entrée uniquement des float ! + += Booléens + +Priorité opératoire : NOT > AND > OR + + + +#table(columns: (1fr, 2fr), table.cell(colspan: 2)[*Opérateur*], [ET], [&&], [OU], [||], [=], [Comparaison/égalité (Et non affectation !)], [<>], [Différence (inégalité)], + +) + += String + +Pas de différence notoire + +#table(columns: (1fr, 2fr), table.cell(colspan: 2)[*Opérateur*], [^], [Opérateur de concaténation], +[String.length "abc"], [Renvoie la taille de la chaîne de caractère], +) + + + += Char + +Type caractère (1 seul caractère...) + += Déclaration de variable + + + +```ocaml +let a = 3;; +``` +Les variables ne sont pas stockés dans la mémoire. En réalité les occurrences sont remplacés directement par la variable. +Ainsi, on ne peut pas les modifier., elle sont immuables. + + += Fonctions + +```ocaml +(*Définition de la fonction*) +let f a = a + 2;; + +(*Appel de la fonction*) +f 3;; +``` +Les fonctions sont typés ! (Ici, int $-->$ int) + +Les returns n'existent pas en ocaml. + +On peut définir une fonction avec de multiple paramètre : +```ocaml +let f a b = a + b;; +``` +Le type sera int $-->$ int (C'est conditionné par l'opérateur + spécifique au integer) + +Il peut y avoir un indeterminé, par exemple : + + ```ocaml + let f a = a ;; + ``` + +Cette fonction renvoie le paramètre d'entrée, peut importe son type. + + +Les fonctions sont des valeurs comme des autres. + +Les fonctions à deux variables sont des fonctions qui revoient des fonctions qui revoient des nombres (ou des chaines de caractère) + + + += Alternative + +```ocaml +let a = 1;; +let b = 2;; + +let res = if a < b then true else false;; +``` +Après un if il faut obligatoirement mettre un then ET un else + +Dans le if et le else, il faut renvoyer le même type (ici, booléen) + +Pas de true ou 1 par exemple. + +Ici la variable _res_ est représentant de l'expression _if ... false ;;_ + += Fonction récursives +```ocaml +let rec facto n = + if n = 0 then + 1 + else n * facto(n -1) +``` + + + + + + + + + + + diff --git a/packages/preview/ape/0.3.1/figure/drawing.typ b/packages/preview/ape/0.3.1/figure/drawing.typ new file mode 100644 index 000000000..bd79e08f5 --- /dev/null +++ b/packages/preview/ape/0.3.1/figure/drawing.typ @@ -0,0 +1,78 @@ +== Cetz drawing +#import "@preview/cetz:0.3.1" + +#let cetz-style = { + import cetz.draw: * + set-style( + stroke: 0.8pt, + mark: (transform-shape: false, fill: black), + ) +} + + +=== Point +#let point(c) = { + import cetz.draw: * + circle(c, radius: 0.05, fill: black) +} + + +#let point-name((x, y), nom: " ", dc: (-0.3, -0.3)) = { + import cetz.draw: * + let (dx, dy) = dc + + circle((x, y), radius: 0.05, fill: black) + content((x + dx, y + dy), nom) +} + + +=== Quadratic +#let quadratic(a, b, c) = { + let Delta = b * b - 4 * a * c + + return ( + (-b - calc.sqrt(Delta)) / (2 * a), + (-b + calc.sqrt(Delta)) / (2 * a), + ) +} + + +=== Base +#let base((x_0, y_0), name1: " ", name2: " ", angle: 0deg) = { + import cetz.draw: * + + + line((x_0, y_0), (x_0 + calc.cos(angle), y_0 + calc.sin(angle))) + line((x, y), (x + calc.sin(angle)), y + calc.cos(angle)) + content(((x + calc.cos(angle)), y + calc.sin(angle) + 0.3), [name1]) + content(((x + calc.sin(angle)), y + calc.cos(angle) + 0.3), [name2]) +} +// A revoir + + +=== Spring +#let spring(x0, y0, xf, yf, rep, amp) = { + import calc: * + import cetz.draw: * + let dist = amp + if x0 == xf { + line((x0, y0), (x0 + amp, y0 - (y0 - yf) / (4 * rep))) + for n in range(2 * rep - 1) { + line( + (pow(-1, n) * dist, y0 - (2 * n + 1) * (y0 - yf) / (4 * rep)), + (pow(-1, n + 1) * dist, y0 - (2 * n + 3) * (y0 - yf) / (4 * rep)), + ) + } + line((xf - dist, yf + (y0 - yf) / (4 * rep)), (xf, yf)) + } else if y0 == yf { + line((x0, y0), (x0 - (x0 - xf) / (4 * rep), y0 + amp)) + + for n in range(2 * rep - 1) { + line( + (x0 - (2 * n + 1) * (x0 - xf) / (4 * rep), y0 + dist * calc.pow(-1, n)), + (x0 - (2 * n + 3) * (x0 - xf) / (4 * rep), y0 + dist * calc.pow(-1, n + 1)), + ) + } + line((xf + (x0 - xf) / (4 * rep), yf - dist), (xf, yf)) + } +} diff --git a/packages/preview/ape/0.3.1/figure/plotting.typ b/packages/preview/ape/0.3.1/figure/plotting.typ new file mode 100644 index 000000000..2f98fbcb9 --- /dev/null +++ b/packages/preview/ape/0.3.1/figure/plotting.typ @@ -0,0 +1,155 @@ +#import "@preview/cetz:0.3.1" +#import "@preview/cetz-plot:0.1.0": plot + +#let plotting( + functions, + /* + ( + ( + fn: + x => x, + domain: (start, end), + projection: (x: ((0, "0"),), y: ((0, "1"),)), + stroke: color, + ), + fn: x => x, + domain: (start, end), + projection: (x: ((0, "0"),), y: ((0, "1"),)), + stroke: color, + + ) + */ + domain: (-0.3, 5), + samples: 200, + steps: (none, none), + axis-style: "school-book", + axis: ("x", "y"), // axis name + size: (14, 7), // blueprint size +) = { + import calc: * + import cetz.draw: * + + let domain-min-x = domain.at(0) + for function in functions { + if function.keys().contains("domain") { + if function.domain.at(0) < domain-min-x { + domain-min-x = function.domain.at(0) + } + } + } + + let domain-max-x = domain.at(0) + for function in functions { + if function.keys().contains("domain") { + if function.domain.at(0) > domain-max-x { + domain-max-x = function.domain.at(0) + } + } + } + + let size-domain = domain-max-x - domain-min-x + + let amplitude-y = { + let max-total = 0 + let min-total = 0 + let precision = ceil(samples / 5) + for function in functions { + if function.keys().contains("fn") and function.keys().contains("domain") { + let m = (function.fn)(function.domain.at(0)) + let m-temp = m + for i in range(precision) { + if ((function.fn)(domain.at(0) + i * (domain.at(1) - domain.at(0)) / precision) > m-temp) { + m-temp = (function.fn)(domain.at(0) + i * (domain.at(1) - domain.at(0)) / precision) + } + if ((function.fn)(domain.at(0) + i * (domain.at(1) - domain.at(0)) / precision) < m-temp) { + m-temp = (function.fn)(domain.at(0) + i * (domain.at(1) - domain.at(0)) / precision) + } + } + if m > -0.2 { m = -0.2 } + if m-temp < 0.2 { m-temp = 0.2 } + if m-temp > max-total { + max-total = m-temp + } + if m < min-total { + min-total = m + } + } + } + round((max-total - min-total) / 2 * 100) / 100 + } + + let sgn(x) = { + if x == 0 { return 1 } + return abs(x) / x + } + + let projection-x(function, x, label) = { + plot.add-vline(x, max: function(x), min: 0, style: (stroke: (dash: "dashed"))) + if label.len() > 0 { + plot.annotate({ + content((x, -(0.1 * sgn(function(x))) * 1 / (size.at(1) / 7) * amplitude-y), [#label]) + }) + } + } + + let projection-y(function, x, label) = { + plot.add-hline(function(x), max: x, min: 0, style: (stroke: (dash: "dashed"))) + if label.len() > 0 { + plot.annotate({ + content((0, function(x)), [#label]) + }) + } + } + + return cetz.canvas({ + set-style(axes: (stroke: .5pt, tick: (stroke: .5pt))) + + plot.plot( + size: size, + x-tick-step: steps.at(0), + y-tick-step: steps.at(1), + axis-style: axis-style, + x-label: axis.at(0), + y-label: axis.at(1), + x-min: domain.at(0), + x-max: domain.at(1), + { + for function in functions { + if function.keys().contains("fn") { + let dm = if function.keys().contains("domain") { function.domain } else { domain } + let st = if function.keys().contains("stroke") { function.stroke } else { black } + + plot.add( + function.fn, + domain: dm, + style: (stroke: st), + samples: samples, + ) + + if function.keys().contains("projection") { + if function.projection.keys().contains("x") { + for x in function.projection.x { + if type(x) == array { + projection-x(function.fn, x.at(0), x.at(1)) + } else { + projection-x(function.fn, x, "") + } + } + } + + if function.projection.keys().contains("y") { + for y in function.projection.y { + if type(y) == array { + projection-y(function.fn, y.at(0), y.at(1)) + } else { + projection-y(function.fn, y, "") + } + } + } + } + } + } + } + ) + }) +} diff --git a/packages/preview/ape/0.3.1/lib.typ b/packages/preview/ape/0.3.1/lib.typ new file mode 100644 index 000000000..296d178da --- /dev/null +++ b/packages/preview/ape/0.3.1/lib.typ @@ -0,0 +1,8 @@ +#import "document/doc.typ" : * + + +#import "tools/formatting.typ" : * +#import "tools/shortcuts.typ" : * + +#import "figure/drawing.typ" : * +#import "figure/plotting.typ" : * \ No newline at end of file diff --git a/packages/preview/ape/0.3.1/thumbnail.png b/packages/preview/ape/0.3.1/thumbnail.png new file mode 100644 index 000000000..4292528a3 Binary files /dev/null and b/packages/preview/ape/0.3.1/thumbnail.png differ diff --git a/packages/preview/ape/0.3.1/tools/formatting.typ b/packages/preview/ape/0.3.1/tools/formatting.typ new file mode 100644 index 000000000..4a4c71db9 --- /dev/null +++ b/packages/preview/ape/0.3.1/tools/formatting.typ @@ -0,0 +1,76 @@ +// Paragraph +#let para(nom, content) = context { + grid( + columns: 2, + column-gutter: 3pt, + align: left + top, + [_#nom _ : ], content + h(100%), + ) +} + +#let rq(content) = { + para("Remarque", content) +} + +#let ex(content) = { + para("Exemple", content) +} + + +// List +#let arrow-list(..item) = { + grid( + columns: (auto, 1fr), + align: left, + column-gutter: 4pt, + row-gutter: 10pt, + ..for i in item.pos() { + ([$-->$], i) + } + ) +} + + +// Inbox +#let inbox(content) = context { + box( + width: 100%, + stroke: text.fill.lighten(40%) + 0.6pt, + fill: text.fill.lighten(90%), + inset: 15pt, + radius: 5pt, + + content, + ) +} + +#let inbox2(contenu) = context { + block(width: 100%, fill: text.fill.lighten(90%), stroke: (left: 3pt + text.fill.lighten(50%), rest: 0pt), inset: (left: 10pt, right: 10pt, rest:6pt), contenu) +} + + +#let inbox3(content) = context { + import calc: * + let c = block(inset: (left: 10pt, right: 10pt), content) + + + layout(size => { + let inbox-height = max(25pt, min(size.width * 0.15, pow(1.5, measure(c).width / size.width) * 4pt)) + + + box([#{ + place(line(length: inbox-height, angle: 90deg)) + + align(left, line(length: inbox-height * 2)) + + c + + place(line(start: (100%, 0%), length: inbox-height, angle: -90deg)) + line(start: (100% - inbox-height * 2, 0%), length: inbox-height * 2) + }]) + }) +} + +#let inbox4(contenu) = context { + block(stroke: (left: 1pt + text.fill, rest: 0pt), inset: (top: 2pt, bottom: 2pt,left: 10pt,), contenu) +} diff --git a/packages/preview/ape/0.3.1/tools/miscellaneous.typ b/packages/preview/ape/0.3.1/tools/miscellaneous.typ new file mode 100644 index 000000000..39f09a46f --- /dev/null +++ b/packages/preview/ape/0.3.1/tools/miscellaneous.typ @@ -0,0 +1,21 @@ +#let content-to-string(content) = { + if type(content) == str { + content + } else if content.has("text") { + content.text + } else if content.has("children") { + content.children.map(content-to-string).join("") + } else if content.has("body") { + content-to-string(content.body) + } else { + "" + } +} + +#let to-array(content) = { + if type(content) == array { + return content + }else { + return (content,) + } +} diff --git a/packages/preview/ape/0.3.1/tools/shortcuts.typ b/packages/preview/ape/0.3.1/tools/shortcuts.typ new file mode 100644 index 000000000..151b7cfe6 --- /dev/null +++ b/packages/preview/ape/0.3.1/tools/shortcuts.typ @@ -0,0 +1,58 @@ +// Raccourcis +#let shows-shortcuts(content) = { + show "SCH": align( + center, + box(fill: gray.lighten(70%), inset: 2cm, stroke: 0.65pt, text(size: 20pt)[#emoji.warning *Schema* #emoji.warning]), + ) + + show "ARL": place( + dx: -2.7cm, + dy: -1cm, + circle(stroke: 1pt, radius: 1.5cm, fill: red.lighten(20%), outset: -0.5cm)[ + #set align(center + horizon) + #set text(black, size: 12pt, font: "TeX Gyre Chorus") + + *Nécessite\ relecture* + ] + ) + + content +} + +// ... + +#let tab = [\ #h(32pt) #sym.triangle.filled.r] +#let sep = context line(length: 100%, stroke: 0.65pt + text.fill) + +// Mathématiques +#let recurrence(p: "Propriété", d: $n in NN$, ini: "", hd: "", cl: "") = { + [ + Montrons par récurrence que la propriété $P(n) : $ "#p" est vraie pour tout #d + + - #underline[Initialisation :] #ini + - #underline[Hérédité :] #hd + - #underline[Conclusion :] #cl + ] +} + +#let congru = $eq.triple$ + +// Physique +#let dt = $dif t$ +#let dx = $dif x$ +#let dtheta = $dif theta$ + +#let ar = math.arrow +#let nar(c) = math.norm(math.arrow(c)) + +#let dot2 = math.dot.double +#let dot3 = math.dot.triple + +#let grad = ar("grad") + +#let cste = $"Cste"$ + +#let RTSG = "Référentiel terrestre supposé galiléen" +#let TEC = "Théorème de l'énergie cinétique" + + diff --git a/packages/preview/ape/0.3.1/typst.toml b/packages/preview/ape/0.3.1/typst.toml new file mode 100644 index 000000000..74910fdbd --- /dev/null +++ b/packages/preview/ape/0.3.1/typst.toml @@ -0,0 +1,10 @@ +[package] +name = "ape" +version = "0.3.1" +compiler = "0.12.0" +entrypoint = "lib.typ" +authors = ["Izan"] +license = "MIT" +exclude = ["exemples"] +description = "Stop monkeying around with your layouts! Get sophisticated with Ape for Typst." +categories = ["layout", "utility","report"] \ No newline at end of file