Initial ASK question data
All checks were successful
Validate QAML / validate (push) Successful in 1s

This commit is contained in:
2026-06-06 21:16:55 +02:00
commit 1b180bce3c
8 changed files with 236 additions and 0 deletions

17
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,17 @@
## Co zmieniasz?
- [ ] poprawiam treść pytania
- [ ] poprawiam odpowiedź
- [ ] dodaję nowe pytanie
- [ ] dodaję/zmieniam obrazek w `img/`
- [ ] usuwam duplikat albo błąd
## Źródło / uzasadnienie
Opisz krótko skąd pochodzi poprawka albo dlaczego obecna wersja jest błędna.
## Checklist
- [ ] każde pytanie i każda odpowiedź mieści się w jednej linii
- [ ] każda odpowiedź zaczyna się od `-` albo `-|`
- [ ] obrazki użyte jako `img/...` istnieją w repozytorium

15
.github/workflows/deploy.yml.template vendored Normal file
View File

@@ -0,0 +1,15 @@
name: Deploy Quiz Data
on:
push:
branches: [main]
jobs:
deploy:
runs-on: qaml-deploy
steps:
- uses: actions/checkout@v4
- name: Validate pytania.txt
run: php tools/validate_qaml.php pytania.txt
- name: Deploy data
run: deploy-quiz-data SYSTEM_NAME

14
.github/workflows/validate.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
name: Validate QAML
on:
pull_request:
push:
branches: [main]
jobs:
validate:
runs-on: qaml-validate
steps:
- uses: actions/checkout@v4
- name: Validate pytania.txt
run: php tools/validate_qaml.php pytania.txt

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
ip.txt
ip.txt.old
*.log
*.bak
*.old
.DS_Store

88
README.md Normal file
View File

@@ -0,0 +1,88 @@
# ASK-Machen
Repozytorium zawiera bazę pytań do quizu ASK-Machen.
W repozytorium znajdują się dane quizu: `pytania.txt` oraz opcjonalnie katalog `img/` z obrazkami używanymi w pytaniach. Kod aplikacji nie jest częścią tego repozytorium.
## Jak zgłaszać poprawki
Poprawki zgłaszamy przez Pull Request.
Logowanie w systemie nie wymaga weryfikacji e-mail. Można podać dowolne dane; system jest w pełni anonimowy.
Najczęstsze dobre zmiany:
- poprawienie literówki,
- oznaczenie prawidłowej odpowiedzi jako `-|`,
- usunięcie błędnej odpowiedzi,
- dopisanie źródła w komentarzu `//`,
- dodanie brakującego obrazka do `img/`.
Nie zmieniaj formatu pliku na pełny Markdown, JSON, CSV ani HTML. To repozytorium używa prostego formatu QAML opisanego niżej.
## QAML
QAML, czyli Question Answer Markdown Lines, to prosty liniowy format zapisu pytań testowych wielokrotnego wyboru.
Parser interpretuje wyłącznie początki linii:
- linia pytania,
- linia odpowiedzi błędnej,
- linia odpowiedzi poprawnej,
- komentarz,
- pusta linia.
Treść pytania i odpowiedzi może zawierać Markdown, HTML oraz inline LaTeX, ale parser traktuje je jako zwykły tekst.
## Minimalny przykład
```text
// Przykładowa sekcja
Zaznacz zdania prawdziwe
- To jest odpowiedź błędna.
-| To jest odpowiedź poprawna.
- To jest kolejna odpowiedź błędna.
```
## Reguły składni
### Pytanie
Pytaniem jest każda niepusta linia, która nie zaczyna się od `-` ani `//`.
Pytanie musi mieścić się w jednej linii.
### Odpowiedź błędna
Odpowiedź błędna zaczyna się od pojedynczego myślnika `-`.
```text
- Odpowiedź błędna
-Odpowiedź błędna
```
### Odpowiedź poprawna
Odpowiedź poprawna zaczyna się od `-|`.
```text
-| Odpowiedź poprawna
-|Odpowiedź poprawna
```
### Liczba poprawnych odpowiedzi
Format dopuszcza dowolną liczbę poprawnych odpowiedzi, w tym zero poprawnych odpowiedzi albo wszystkie odpowiedzi poprawne.
### HTML i obrazki
HTML jest dopuszczony jako część treści pytania lub odpowiedzi.
Jeżeli `pytania.txt` odwołuje się do obrazka przez `img/...`, plik musi istnieć w katalogu `img/` w tym repozytorium.
## Walidacja lokalna
```bash
php tools/validate_qaml.php pytania.txt
```

1
img/.gitkeep Normal file
View File

@@ -0,0 +1 @@

5
pytania.txt Normal file
View File

@@ -0,0 +1,5 @@
// ASK-Machen — pytanie startowe
ASK-Machen używa formatu QAML?
- Nie
-| Tak

90
tools/validate_qaml.php Normal file
View File

@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
$file = $argv[1] ?? 'pytania.txt';
$baseDir = dirname(__DIR__);
$path = $baseDir . '/' . $file;
if (!is_file($path)) {
fwrite(STDERR, "File not found: {$file}\n");
exit(1);
}
$lines = file($path, FILE_IGNORE_NEW_LINES);
$errors = [];
$question = null;
$questionLine = 0;
$answers = 0;
$questionCount = 0;
$finishQuestion = static function () use (&$errors, &$question, &$questionLine, &$answers, &$questionCount): void {
if ($question === null) {
return;
}
if ($answers === 0) {
$errors[] = "Line {$questionLine}: question has no answers.";
}
$questionCount++;
$question = null;
$questionLine = 0;
$answers = 0;
};
foreach ($lines as $i => $rawLine) {
$lineNo = $i + 1;
$line = trim($rawLine);
if ($line === '' || str_starts_with($line, '//')) {
continue;
}
if (!str_starts_with($line, '-')) {
$finishQuestion();
$question = $line;
$questionLine = $lineNo;
continue;
}
if ($question === null) {
$errors[] = "Line {$lineNo}: answer appears before any question.";
continue;
}
if (str_starts_with($line, '-|')) {
$answer = trim(substr($line, 2));
} else {
$answer = trim(substr($line, 1));
}
if ($answer === '') {
$errors[] = "Line {$lineNo}: answer is empty.";
}
$answers++;
}
$finishQuestion();
$content = file_get_contents($path) ?: '';
preg_match_all('/<img\s+[^>]*src=["\']([^"\']+)["\'][^>]*>/i', $content, $matches);
foreach ($matches[1] ?? [] as $src) {
if (str_starts_with($src, 'img/') && !is_file($baseDir . '/' . $src)) {
$errors[] = "Missing image referenced from pytania.txt: {$src}";
}
}
if ($questionCount === 0) {
$errors[] = 'No questions found.';
}
if ($errors !== []) {
foreach ($errors as $error) {
fwrite(STDERR, $error . PHP_EOL);
}
exit(1);
}
echo "OK: {$questionCount} questions validated.\n";