0.1.0 initial commit

This commit is contained in:
Yusur 2026-02-12 13:30:53 +01:00
commit 96ee2c4b79
8 changed files with 268 additions and 0 deletions

9
.gitignore vendored Normal file
View file

@ -0,0 +1,9 @@
vendor/
node_modules/
.*.swp
**~
.\#*
\#*\#
.ht*
!.htaccess
composer.lock

3
.htaccess Normal file
View file

@ -0,0 +1,3 @@
Options -Indexes

20
composer.json Normal file
View file

@ -0,0 +1,20 @@
{
"name": "yusurko/caluta7",
"type": "project",
"version": "0.1.0",
"require": {
"league/commonmark": "^2.8",
"symfony/yaml": "^8.0"
},
"autoload": {
"psr-4": {
"Yusurko\\Caluta7\\": "src/"
}
},
"authors": [
{
"name": "Yusur Princeps",
"email": "sakuragasaki46@gmail.com"
}
]
}

60
index.php Normal file
View file

@ -0,0 +1,60 @@
<?php
require 'vendor/autoload.php';
use Yusurko\Caluta7\PageLoader;
$link = $_GET['link'] ?? 'index';
$pl = new PageLoader();
$pl->load($link);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Caluta, Inc.</title>
<style>
:root {
--fg-main: #e8eef2;
--bg-main: #121821;
--bg-alt: #313840;
}
body {
background-color: var(--bg-main);
color: var(--fg-main);
font-family: 'Inter', sans-serif;
margin: 0;
}
#site__header {
background-color: var(--bg-alt);
padding: 13px;
}
#site__header h1 {
margin: 0;
font-size: 1.5em;
}
main {
padding: 13px;
margin: auto;
max-width: 1000px;
}
</style>
</head>
<body>
<header id="site__header">
<h1><img src="/caluta_flag.png" alt="" /> Caluta, Inc.</h1>
</header>
<main>
<article>
<header>
<h1><?= htmlspecialchars($pl->getTitle()); ?></h1>
</header>
<?= $pl->getHtml(); ?>
</article>
</main>
</body>
</html>

1
pages/.htaccess Normal file
View file

@ -0,0 +1 @@
Require all denied

38
pages/dict.md Normal file
View file

@ -0,0 +1,38 @@
Jytky Kalpy: Lemeryj
(r9: dictionary for the language of Jytlynd)
* **-s** / part. / suffix for genitive
* **-tza** / part. / suffix for past
* **-tzu** / part. / suffix for continuous or te-form
* **am** / pp. / by, to (dative)
* **amgwan** / v. / to remember (used at past tense)
* **atempty** / v. / to attempt
* **em** / v. / to be
* **ersjalky** / a. / Imerchali
* **gryvary** / n. / script, alphabet
* **gryvy** / v. / to grief, vandalize
* **hynd** / n. / dog
* **i** / pp. / in
* **je** / p. / I
* **jotky** / a. / Jutish (of Jotlond)
* **jytky** / a. / Jutish (of Jytlynd)
* **kalpy** / n. / tongue, language
* **kedo** / c. / but
* **kopy** / v. / to buy
* **lem** / a. / seven
* **lemeryj** / n. / dictionary
* **lemy** / n. / word
* **lynd** / a. / land, territory
* **man** / n. / man, male
* **nym** / n. / name
* **oj** / p. / it
* **oksygyn** / n. / oxygen
* **pergwan** / v. / to forget (used at past tense)
* **som** / a. / some
* **supry** / a. / good, super
* **trok** / n. / crime
* **tzyjar** / n. / animal (also as insult)
* **vatry** / a. / bad, gross, not aight
* **yky** / v. / to go
* **yvyly** / a. / evil, silly

5
pages/index.md Normal file
View file

@ -0,0 +1,5 @@
Lorem ipsum dolor sit amet
«𝐴 𝑚𝑎𝑙𝑖 𝑒𝑠𝑡𝑟𝑒𝑚𝑖, 𝑒𝑠𝑡𝑟𝑒𝑚𝑎 𝑑𝑒𝑠𝑡𝑟𝑎» (𝐽𝑜𝑎𝑛 𝐿𝑖𝑒𝑏𝑒𝑟𝑡)

132
src/PageLoader.php Normal file
View file

@ -0,0 +1,132 @@
<?php
namespace Yusurko\Caluta7;
use Symfony\Component\Yaml\Yaml;
use League\CommonMark\CommonMarkConverter;
define('PAGES_PATH', dirname(__DIR__) . '/pages');
class PageLoader {
protected string $name, $title;
protected mixed $error;
protected $updatedAt;
protected string $raw_content;
public function __construct() {
}
public function load(string $name, bool $full = true): bool {
if (!$name || strpos($name, '/') !== false || strpos($name, '*') !== false) {
$this->error = 'BAD_ARGUMENT';
return false;
}
$this->name = $name;
$filename = PAGES_PATH . "/$name.md";
if (!file_exists($filename)) {
$this->error = "NOT_FOUND";
return false;
}
$this->updatedAt = filemtime($filename);
$fp = fopen($filename, 'r');
if (!$fp) {
$this->error = "FORBIDDEN";
return false;
}
$title_line = false;
$raw_meta_lines = array();
$into_meta = false;
while (($line = trim(fgets($fp))) !== false) {
if ($title_line === false && $line !== '---') {
$title_line = $line;
} elseif ($line === '---') {
$into_meta = !$into_meta;
} elseif ($into_meta) {
$raw_meta_lines[] = $line;
} else {
if (!$title_line) {
$title_line = $name;
}
break;
}
}
if ($full) {
$raw_content = '';
while($chunk = fread($fp, 8192)) {
$raw_content .= $chunk;
}
$this->raw_content = $raw_content;
}
$this->title = $title_line;
$raw_meta = implode("\n", $raw_meta_lines);
$this->meta = @Yaml::parse($raw_meta);
if ($this->raw_content) {
//$this->preprocess($this->raw_content);
}
return true;
}
public function getHtml() {
if (!$this->raw_content) return false;
$md = new CommonMarkConverter();
$content = $md->convert($this->raw_content);
return "<div class=\"parser-output\">$content</div>";
}
public function getTitle() {
return $this->title;
}
public function getUrl() {
if ($this->isIndex()) {
return "/";
}
return "/{$this->name}";
}
public function getError() {
if (!$this->error) {
return false;
} elseif ($this->error === 'NOT_FOUND') {
return [
'status' => 404,
'message' => 'Not found'
];
} elseif ($this->error === 'FORBIDDEN') {
return [
'status' => 403,
'message' => 'Access Denied'
];
} elseif ($this->error === 'BAD_ARGUMENT') {
return [
'status' => 400,
'message' => 'Bad Request'
];
} else {
return [
'status' => 500,
'message' => 'Unknown Error'
];
}
}
public function isIndex () {
return $this->name === 'index';
}
}