♪ Nove pesme su objavljene: No (house) i Choline (tehno)

Ovaj sajt pokreće Rust (programski jezik)

Nakon čitanja "Why Is This Site Built With C" članka, koji sam našao na portalu Hacker News, shvatio sam da je autor verovatno prešao igricu u svetu statičnih generatora sadržaja. Da, imamo hugo i zola programe ali oni (često) menjaju svoje funkcije i konfiguracije.

Pošto mi nije logično da ne ažuriram programe koje nisam ja kreirao, pomislio sam da li bi bilo moguće da napravim sličan program kao i autor gorenavedenog članka ali u drugom programskom jeziku. Npr, Rust programskom jeziku.

Ispostavilo se da je moguće i ne tako teško ako imate prave alate i tačne ideje. Uz pomoć Gemini 2.5 Pro modela, dobio sam novu mašinu za izradu sajtova. Funkcionalnost sam već imao u mnogim drugim projektima ali autor članka koji me je inspirisao naglašava sledeće:

1. Starting a post must be as easy as typing into a blank file
2. The website must be statically generated. And Fast.
3. There should be little to none dependencies for generating the website.
4. It needs to last for at least the next 10 years.

Rust sve to može isto kao i C sa tim što sam hteo da probam malo moderniji jezik čiji kompiler ima poneku mogućnost bez dodatnih instalacija, biblioteka i sl. cargo, koji je sistem za pravljenje u Rust-u me je oduševio:

I to je to. Samo kompilovanje može i samo preko rustc ali sam hteo da imam i par zgodnih alata za proveru.

Uslov 1: Otvoriš uređivač teksta i kreneš da pišeš

Samo treba da se otvori bilo koji program i da se krene pisati *.md. Prvi red dokumenta tretiramo kao <h1> ukoliko # postoji kao prvi karakter. Sve od drugog reda pa do kraja dokumenta je tekst uz jedan izuzetak: drugi red je rezervisan za datum (YYYY-MM-DD) ukoliko se koristi argument --blog-dir za taj direktorijum. "Blog" je obična lista koja je sortirana obrnuto hronološki i ima RSS izvor/feed.

Uslov 2: Internet prezentacija (sajt) treba da bude statički generisana. Brzo

Način na koji radi ovaj program je vrlo sličan veb serverima koji prikazuju sadržaj nekog direktorijuma kada nemate index.html datoteku u direktorijumu: prikazuje listu datoteka i direktorijuma. Jedina je razlika što ova skripta dozvoljava da imate bilo koji tip datoteke u direktorijumu ali će generisani index.html prikazivati samo dokumenta koja su konvertovana iz Markdowna u HTML format. Za sve ostalo će biti napravljen index.html koji će omogućiti posetiocima da lakše i brže vide sadržaj koji postoji.

Postojeće index.html datoteke neće biti izbrisane već samo kopirane i spremne za prikaz.

Uslov 3: Broj zavisnosti treba da bude minimalan

Ceo program se sastoji iz jedne binarne datoteke koja je manja od jednog megabajta. Imamo podosta argumenata koje korisnik može da iskoristi prilikom rada čime smo pokrili slučajeve čestog kompilovanja. Uradite to jednom svaki put kada izađe nova verzija ili jednom u 4 godine? Ne volim datoteke kao konfiguracije, argumenti mi deluju dugovečnije(?)

Ali, autor skreće pažnju na jedan problem:

The problem is that writing a markdown parser isn't the most trivial enterprise.

Ovo je tačno ali može da se poboljša situacija ako ukoliko se poštuju pravila pisanja čistih Markdown dokumenata bez nepotrebnog ukrašavanja i "pizzazz"-a.

Da bih živeo lakše, implementirane su različite Markdown transformacije koje su bliže cmark implementaciji tzv. CommonMark specifikacije. To je jedini program za koji znam da može da istrpi najčudnije MD kombinacije i koji ima mnogo testova. Koristio sam ga godinama i nepogrešiv je. Iako je bazičan i neproširen set pravila, ono što radi obavlja bez greške.

Skripta koju koristim tj. program(čić) je sličan:

Pa tako imamo podršku za osnovne Markdown transformacije i par proširenja (deo iz README.md dokumenta):

Standardni Markdown

Prošireni

Prosto je ali radi! I ne: nema podrške za rad sa slikama. To mi je mnogo lakše da ručno ispišem kada zatreba nego da pokušavam 12 časova da dođem do iole dobro parsera markdown slika, koji nudi opciju da koristite i srcset, jxl, avif i webp a da nije statičan i da vam pomaže.

Uslov 4: Program treba da traje barem 10 godina

Mislim da je originalna ideja vezana za stabilnost u "FreeBSD" stilu: da ista konfiguracija radi 10 godina bez izmena. Malo sistema i programa nudi tako nešto. FreeBSD je jedan sistem koji nudi tako nešto u srži. Takođe dwm i surf. I još neki programi za komandnu liniju.

Tvorci teže ka tome da rade na idejama i da ne traće vreme ne na bilo šta oko tih ideja. Miksujete muziku? Program ne treba da menja interfejs svakih 12 meseci. Pišete računarske programe? Ne mora razvojno okruženje da dobija nove dugmiće svakih 30 dana.

Neko će može reći da je Rust mlad programski jezik i da se i dalje razvija pa nema smisla praviti nešto što će da traje. Ja verujem da to važi za svaki programski jezik. Intel je skoro objavio novu verziju (2025) Fortran prevodioca! Rust daje mogućnost da u Cargo.toml datoteci definišete najnižu verziju programskog jezika i mogućnosti koje su podržane u istom:

[package]
name = "Foo"
version = "0.1.182"
edition = "2024"

U Rust dokumentaciji piše da je ovo lak način da definišete minimalnu verziju prevodioca i programskog jezika a samim tim i funkcije koje su podržane. U mom slučaju, program možda ne bi bio kompilovan sa verzijom "2018". Zgodan dodatak da ne mislim o tome i ne kucam iznova rustc --edition 2024 src/main.rs -o sgr u terminalu.

Proširenja originalne ideje

Neke mogućnosti nedostaju u originalnom programu pa sam morao da tražim određena proširenja. C program ,koji me je inspirisao, je jako prost i takođe zahteva mnogo ručnog rada kako bi se napravilo nešto funkcionalno. Kontrola je dobra stvar ali se postavlja pitanje zašto je taj C program bolji od grep, cat i bash heredoc kombinacija koje rade 20 godina bez promene.

Neke od dodatih funkcija koje su dodate za ovaj sajt sam dokumentovao u README.md samog Rust projekta:

Lista argumenata i specijalnih datoteka mnogo bolje prikazuje listu mogućnosti:

Usage:
  sgr [OPTIONS]

Options:
  -h, --help                           Show this help message
  -v, --version                        Show script version
  -V, --verbose                        Enable verbose output during build
  --source <PATH>                      Specify source directory (default: WEBSITE_SOURCES_UT)
  --public <PATH>                      Specify public output directory (default: WEBSITE_PUBLIC_DIR_UT)
  --enable-maintenance                 Enable maintenance mode. Overrides most other options to generate a single maintenance page.
  --maintenance-message <TEXT>         Custom message (Markdown) for the maintenance page. Used with --enable-maintenance.
  --author <NAME>                      Set author name for footer (default: "Anon")
  --start-year <YEAR>                  Set start year for footer (default: 2024)
  --current-year <STR>                 Set current year string for footer (default: "today")
  --title-prefix <TXT>                 Set prefix for HTML titles (default: "FooBarian")
  --site-address <URL>                 Set base URL for site links in feed (default: "http://localhost:8000/")
  --root-desc <TEXT>                   Add description paragraph below H1 on root index page.
  --html-lang <CODE>                   Set the HTML lang attribute (ISO 639-1, default: "en")
  --blog-dir <PATH>                    Relative path within source to treat as blog posts (extracts dates, generates feed).
  --feed-items <NUM>                   Max number of items in RSS feed (default: 10).
  --disable-csp-nonce                  Disable CSP nonce injection (less secure if inline styles used).
  --use-cache-busters                  Add cache-busting query string (?v=...) to favicon links.
  --og-image <PATH>                    Relative path to image for og:image meta tag.
  --preprocess-escapes                 Replace \*, \_, \[, \], \`, \~, \ etc. with HTML entities before parsing.
  --head-html <HTML>                   Raw HTML string to inject inside <head>.
  --blog-repeat-rss-threshold <NUM>    Min number of items needed on blog index to show RSS link at bottom (default: 15).
  --no-external-link-icon              Disable the '↗' icon after external links.
  --enable-inpage-lang                 Enable per-page lang. Use `{{language:CODE}}` on its own line, after H1/Date or as 1st line.
  --site-notice <TEXT>                 Display TEXT (processed for inline Markdown) in a notice box at the top of every page.
  --theme-bg <COLOR>                   Set the primary background color for the light theme (default: "#f5f5f4"). The dark theme background will be derived from the foreground color.
  --theme-fg <COLOR>                   Set the primary foreground (text) color for the light theme (default: "#0c0a09"). The dark theme foreground will be derived from the background color.

Special Files:
  - If '.sgr-exclude' exists in a SOURCE directory, its parent index links to it, contents copied, no internal processing.
  - Markdown files starting with a dot (e.g., `.my-draft.md`) are ignored during processing and copying (useful for drafts).
  - Most files/directories starting with '.' (e.g., `.git`, `.draft.md`) are skipped.
    However, these specific hidden entries ARE processed:
      * .htaccess
      * .well-known
  - If 'about.md'/'author.md' etc. exists in SOURCE root, footer links author name.
  - index.md files provided by the user will override generated index pages.
  - Files in --blog-dir SHOULD have 'YYYY-MM-DD' or 'YYYY/MM/DD' on the second line for feed generation.

git log ovog Rust projekta, koji za sada nije javno objavljen, možete pratiti na mojoj git-project-tracker strani.