1
0
mirror of https://tildegit.org/sbgodin/HtmGem.git synced 2023-08-25 13:53:12 +02:00
* Enables browsing without URL Rewriting
* Unit testing
* Adds the BNF definition
* Rewriting of the French documentation
* Translation to English
* Adds debug.css
* Adds index.htm in case of Php not activated
This commit is contained in:
Christophe HENRY 2021-03-29 11:36:39 +02:00
commit 86f6ae918e
Signed by: Sbgodin
GPG Key ID: AA24252B9DD684F0
45 changed files with 2338 additions and 496 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.phpunit*

View File

@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
=> https://keepachangelog.com/en/1.0.0/ The format is based on keep a Changelog.
=> https://semver.org/spec/v2.0.0.html And this project adheres to Semantic Versioning.
## [1.3.0] - 2021-03-29
* Enables browsing without URL Rewriting
* Unit testing
* Adds the BNF definition
* Rewriting of the French documentation
* Translation to English
* Adds debug.css
* Adds index.htm in case of Php not activated
## [1.2.0] - 2021-03-19
* Removes "^" to disable text decoration line-wise.
* CSS is no longer incorporated in the HTML page.

View File

@ -1,6 +1,6 @@
# HtmGem
HtmGem is Php program whose goal is to make Gemini files reachable through HTTP. It can be used on a shared host.
HtmGem makes your **Gemini** pages reachable on the web. It can be used on a shared host.
You can see a demo on the main page of HtmGem:

56
css/base.css Normal file
View File

@ -0,0 +1,56 @@
html {
font-family: sans-serif;
}
body {
max-width: 1024px;
margin: auto;
margin-top: 0.5em;
margin-bottom: 2em;
}
h1, h2, h3, blockquote, p, pre, li, ul {
margin: 0 0 0.3rem;
padding: 0;
}
h1 { font-size: 2rem; }
h2 { font-size: 1.6rem; }
h3 { font-size: 1.2rem; }
blockquote {
margin-left: 3rem;
padding-left: 3px;
margin-right: 3rem;
}
pre {
overflow-x: auto;
font-size: 1rem;
}
a {
text-decoration: none;
}
a {
text-decoration: none;
}
@media only screen and (max-width: 1024px) {
body {
margin: 3rem;
}
h1 {
font-size: 4rem;
}
h2 {
font-size: 3.5rem;
}
h3 {
font-size: 3rem;
}
p, pre, ul, blockquote {
font-size: 2.6rem;
}
}

View File

@ -1,45 +1,22 @@
@import "base.css";
html {
font-family: sans-serif;
font-size:1rem;
background-color:#000;
}
body {
margin: 0.5em;
max-width: none;
margin: 0.5em 5em 2em 5em;
}
ul {
p, ul {
color: #ccc;
margin: 0.4rem 0;
padding: 0;
}
p, pre {
margin: 0 0 0.3rem;
padding: 0;
}
p {
color: #ccc;
text-align: justify;
text-justify: inter-word;
}
li {
margin-left: 1em;
padding: 0;
}
h1, h2, h3 {
color: #ddd;
margin: 0;
padding: 0;
}
h1 { font-size: 2rem; }
h2 { font-size: 1.8rem; }
h3 { font-size: 1.5rem; }
blockquote {
background-color: #222;
border-left: 3px solid #444;
@ -49,75 +26,15 @@ blockquote {
a {
color:#ddd;
text-decoration: none;
text-justify: none;
}
a:before {
content: "🔗 ";
}
a:visited {
color: #888;
}
a.local:before {
content: "🛩️ ";
font-weight: bold;
}
a.gemini:before {
content: "🚀 ";
}
a.gopher:before {
content: "📜 ";
}
a.https:before {
content: "🕸️ ";
font-weight: bolder;
}
a.http:before {
content: "🕸️ ";
font-weight: lighter;
}
a.mumble:before {
content: "🎤 ";
}
a.mailto:before {
content: "✉️ ";
}
pre {
color: #ccc;
scrollbar-color: #222 #000;
background-color: #222;
margin: 0 -1rem;
padding: 1rem;
overflow-x: auto;
}
@media only screen and (max-width: 1024px) {
a {
margin: -4rem;
}
body {
margin: 3rem;
}
h1 {
font-size: 4rem;
}
h2 {
font-size: 3.5rem;
}
h3 {
font-size: 3rem;
}
p, pre, ul {
font-size: 2.6rem;
}
}

5
css/debug.css Normal file
View File

@ -0,0 +1,5 @@
@import "base.css";
h1, h2, h3, p, li, pre, blockquote {
border: 1px solid lightblue;
}

View File

@ -1,46 +1,15 @@
@import "base.css";
html {
font-family: sans-serif;
font-size:1rem;
color:#1E4147;
background-color:#fafafa;
}
body {
max-width: 1024px;
margin: auto;
margin-top: 0.5em;
}
ul {
margin: 0.4rem 0;
padding: 0;
}
p, pre {
margin: 0 0 0.3rem;
padding: 0;
}
p {
text-align: justify;
text-justify: inter-word;
}
li {
margin: 0;
padding: 0;
}
h1, h2, h3 {
color: #66f;
margin: 0;
padding: 0;
}
h1 { font-size: 2rem; }
h2 { font-size: 1.6rem; }
h3 { font-size: 1.2rem; }
blockquote {
background-color: #eee;
border-left: 3px solid #444;
@ -51,8 +20,6 @@ blockquote {
a {
margin: -1.35rem;
color:#820;
text-decoration: none;
text-justify: none;
}
a:before {
@ -94,51 +61,3 @@ a.mailto:before {
content: "✉️ ";
}
pre {
overflow-x: auto;
}
@media only screen and (max-width: 1024px) {
a {
margin: -4rem;
}
body {
margin: 3rem;
}
h1 {
font-size: 4rem;
}
h2 {
font-size: 3.5rem;
}
h3 {
font-size: 3rem;
}
p, pre, ul, blockquote {
font-size: 2.6rem;
}
}
@media(prefers-color-scheme:dark) {
html {
background-color: #111;
color: #eee;
}
blockquote {
background-color: #000;
}
pre {
background-color: #222;
}
a {
color: #0087BD;
}
a:visited {
color: #802200;
}
}

View File

@ -1,17 +1,17 @@
# Changer le style daffichage
😎 Il faut avoir configuré le changement de style !
=> .. Page dinstallation
# Styles
=> index.gmi|black_wide black_wide.css
=> index.gmi|raw raw.css
=> index.gmi|simple simple.css
=> index.gmi|htmgem htmgem.css
=> index.gmi|none None
=> index.gmi|terminal terminal.css
=> index.gmi|pre code source préformaté
=> index.gmi|black_wide black_wide.css
=> index.gmi|simple simple.css
=> index.gmi|raw raw.css
=> index.gmi|debug debug.css
=> index.gmi|pre Source code
=> index.gmi|source Download source code
Simple ligne de texte
Décoration de texte : **gras** //italique// __souligné__ ~~barré~~
Lorem ipsum dolor sit amet.
//Lorem// **ipsum** __dolor__ ~~sit amet~~.
* ligne un de liste non ordonnée
* ligne deux de liste non ordonnée
@ -19,8 +19,9 @@ Décoration de texte : **gras** //italique// __souligné__ ~~barré~~
> Citation : Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
```
< Texte préformaté >
------------------
---------------------------
< Lorem ipsum dolor sit amet >
---------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
@ -43,4 +44,3 @@ Décoration de texte : **gras** //italique// __souligné__ ~~barré~~
=> mailto:adress@foo.invalid
=> mumble:adress.mumble.invalid

View File

@ -1,41 +1,25 @@
@import "base.css";
body {
max-width: 1024px;
margin: auto;
margin-top: 0.5em;
xfont-family: mono;
background-color: white;
color: black;
font-family: mono;
}
p, h1, h2, h3, ul, li, pre, blockquote {
color: black;
margin: 0;
padding: 0;
font-size: 1rem;
font-weight: normal;
}
ul {
list-style: none;
}
ul { list-style: none; }
li:before { content: "* "; }
h1:before { content: "# "; }
h2:before { content: "## "; }
h3:before { content: "### "; }
li:before {
content: "* ";
}
h1:before {
content: "# ";
}
h2:before {
content: "## ";
}
h3:before {
content: "### ";
}
blockquote :before {
content: "> ";
}
blockquote :before { content: "> "; }
pre {
scrollbar-color: lightgrey white;
@ -53,24 +37,3 @@ a, a:visited {
a:before {
content: "=> ";
}
@media only screen and (max-width: 1024px) {
a {
margin: -4rem;
}
body {
margin: 3rem;
}
h1 {
font-size: 4rem;
}
h2 {
font-size: 3.5rem;
}
h3 {
font-size: 3rem;
}
p, pre, ul {
font-size: 2.6rem;
}
}

View File

@ -1,21 +1,9 @@
body {
max-width: 1024px;
margin: auto;
margin-top: 0.5em;
}
@import "base.css";
p, h1, h2, h3 {
p, h1, h2, h3, ul, li, pre, blockquote {
margin: 0;
padding: 0;
font-weight: normal;
}
blockquote {
border-left: 3px solid #444;
margin: 1rem -1rem 1rem calc(-1rem - 3px);
padding: 1rem;
}
pre {
padding: 1rem;
overflow-x: auto;
}

View File

@ -1,41 +1,19 @@
@import "base.css";
html {
font-family: mono;
font-size: 1rem;
color: #080;
background-color: #000;
}
body {
max-width: 76em;
margin: auto;
margin-top: 0.5em;
}
ul {
margin: 0.4rem 0;
padding: 0;
}
p, pre {
margin: 0 0 0.3rem;
padding: 0;
}
li {
margin: 0;
padding: 0;
}
h1, h2, h3 {
color: #0b0;
margin: 0;
padding: 0;
}
h1 { font-size: 2rem; }
h2 { font-size: 1.8rem; }
h3 { font-size: 1.2rem; }
blockquote {
background-color: #010;
border-left: 3px solid #444;
@ -44,12 +22,17 @@ blockquote {
padding: 1rem;
}
pre {
scrollbar-color: #030 #010;
background-color: #010;
margin: 0 -1rem;
padding: 1rem;
}
a {
margin: -1.35rem;
color: #090;
font-weight: bold;
text-decoration: none;
text-justify: none;
}
a:before {
@ -90,33 +73,3 @@ a.mumble:before {
a.mailto:before {
content: "M ";
}
pre {
scrollbar-color: #030 #010;
background-color: #010;
margin: 0 -1rem;
padding: 1rem;
overflow-x: auto;
}
@media only screen and (max-width: 1024px) {
a {
margin: -3rem;
}
body {
margin: 3rem;
}
h1 {
font-size: 4rem;
}
h2 {
font-size: 3.5rem;
}
h3 {
font-size: 3rem;
}
p, pre, ul {
font-size: 2.6rem;
}
}

110
docs/BNF-en.gmi Normal file
View File

@ -0,0 +1,110 @@
# BNF
### aka Backus-Naur Form
=> https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form Wikipedia / BNF
The purpose of this document is to show the BNF that HtmGem uses and the way it determines the line type and what information it fetches from. For this, it uses **curly brackets** to explicitely show what information it takes. In addition to this, the **canonical form** shows how it should be displayed.
———————————————————— ✀ ————————————————————
textgemini = *(link / preformat / heading / ulist / quoted / plain)
; Preformat toggle starts as 'false'.
plain = **{[WSP] text} [WSP]** end-of-line
; If preformat toggle is false, wrap text to the
; width of the display. Otherwise, do no wrapping.
; canonical form = {[WSP] text}
preformat = "```" **[WSP]** [{alt-text}] **[WSP]** end-of-line
; Preformat toggle set to opposite state:
; false goes to true
; true goes to false
; While in preformat toggle is true, link, heading,
; ulist and quoted lines are NOT interpreted, but
; displayed as is to the user.
; canonical form = ``` [SP {alt-text}]
link = '=>' **[WSP]** [{URI-reference}] [**[WSP]** {text}] end-of-line
; canonical form = '=>' SP {uri-reference} [SP {text}]
heading = '#' **[WSP]** [{text}] **[WSP]** end-of-line
/ '##' **[WSP]** {text} **[WSP]** end-of-line
/ '###' **[WSP]** {text} **[WSP]** end-of-line
; canonical form = ('#' / '##' / '###') [SP {text}]
ulist = '*' **[WSP]** {text} **[WSP]** end-of-line
; canonical form = '*' SP {text}
quoted = '>' **[WSP]** {text} **[WSP]** end-of-line
; canonical form = '>' SP {text}
alt-text = text
text = ***UVCHAR**
end-of-line = [CR] LF
UVCHAR = VCHAR / UTF8-2v / UTF8-3 / UTF8-4
UTF8-2v = %xC2 %xA0-BF UTF8-tail ; no C1 control set
/ %xC3-DF UTF8-tail
; CRLF from RFC-5234
; DIGIT from RFC-5234
; SP from RFC-5234
; VCHAR from RFC-5234
; OCTET from RFC-5234
; WSP from RFC-5234
;
; UTF8-3 from RFC-3629
; UTF8-4 from RFC-3629
; UTF8-tail from RFC-3629
———————————————————— ✀ ————————————————————
This BNF was taken from the working group and adapted to HtmGem's implementation.
=> https://gitlab.com/gemini-specification/gemini-text/-/issues/7 Gitlab / Original ticket
Changes:
* white space management
* capture of text {}
* canonical form
The white spaces that end a line are never used. See the definition of //text// in the BNF, which no longer contains //SP//.
# Examples
## => links
### Normal link
> link = '=>' [WSP] [{URI-reference}] [[WSP] {text}] end-of-line
> ; canonical form = '=>' SP {uri-reference} [SP {text}]
Source: => foo.invalid text of the link
Data: '=>' {'foo.invalid'} {'text of the link'}
Canonical: => foo.invalid text of the link
Html: <a href="foo.invalid">text of the link</a>
Source: =>foo.invalid text of the link
Data: '=>' {'foo.invalid'} {'text of the link'}
Canonical: => foo.invalid text of the link
Html: <a href="foo.invalid">text of the link</a>
Source: => just_a_page
Data: '=>' {'just_a_page'} {}
Canonical: => just_a_page
Html: <a href="just_a_page">just_a_page</a>
Source: =>
Data: '=>' {''} {''}
Canonical: =>
Html: <a href="">&nbsp;</a>
## # Headings
> heading = '#' **[WSP]** [{text}] **[WSP]** end-of-line
> (…)
> ; canonical form = ('#' / '##' / '###') [SP {text}]
Source: #title
Data: '#' {"title"}
Canonical: # title
Source: # title with two spaces between title and with
Data: '#' {"title with spaces"}
Canonical: # title with two spaces between title and with

110
docs/BNF-fr.gmi Normal file
View File

@ -0,0 +1,110 @@
# BNF
### Backus-Naur Form
=> https://fr.wikipedia.org/wiki/Forme_de_Backus-Naur Wikipedia / BNF
Le but de ce document est de montrer la BNF que HtmGem utilise et la façon dont il détermine le type de ligne et quelles informations il en tire. Pour cela, il utilise des **accolades** pour montrer explicitement quelles informations il prend. De plus, la **forme canonique** montre comment ça devrait être affiché.
———————————————————— ✀ ————————————————————
textgemini = *(link / preformat / heading / ulist / quoted / plain)
; Preformat toggle starts as 'false'.
plain = **{[WSP] text} [WSP]** end-of-line
; If preformat toggle is false, wrap text to the
; width of the display. Otherwise, do no wrapping.
; canonical form = {[WSP] text}
preformat = "```" **[WSP]** [{alt-text}] **[WSP]** end-of-line
; Preformat toggle set to opposite state:
; false goes to true
; true goes to false
; While in preformat toggle is true, link, heading,
; ulist and quoted lines are NOT interpreted, but
; displayed as is to the user.
; canonical form = ``` [SP {alt-text}]
link = '=>' **[WSP]** [{URI-reference}] [**[WSP]** {text}] end-of-line
; canonical form = '=>' SP {uri-reference} [SP {text}]
heading = '#' **[WSP]** [{text}] **[WSP]** end-of-line
/ '##' **[WSP]** {text} **[WSP]** end-of-line
/ '###' **[WSP]** {text} **[WSP]** end-of-line
; canonical form = ('#' / '##' / '###') [SP {text}]
ulist = '*' **[WSP]** {text} **[WSP]** end-of-line
; canonical form = '*' SP {text}
quoted = '>' **[WSP]** {text} **[WSP]** end-of-line
; canonical form = '>' SP {text}
alt-text = text
text = ***UVCHAR**
end-of-line = [CR] LF
UVCHAR = VCHAR / UTF8-2v / UTF8-3 / UTF8-4
UTF8-2v = %xC2 %xA0-BF UTF8-tail ; no C1 control set
/ %xC3-DF UTF8-tail
; CRLF from RFC-5234
; DIGIT from RFC-5234
; SP from RFC-5234
; VCHAR from RFC-5234
; OCTET from RFC-5234
; WSP from RFC-5234
;
; UTF8-3 from RFC-3629
; UTF8-4 from RFC-3629
; UTF8-tail from RFC-3629
———————————————————— ✀ ————————————————————
Cette BNF a été adaptée à limplémentation de HtmGem depuis la version du groupe de travail.
=> https://gitlab.com/gemini-specification/gemini-text/-/issues/7 Gitlab / Original ticket
Changements :
* gestion des espaces blancs
* capture du texte {}
* forme canonique
Les espaces blancs terminant une ligne ne sont jamais utilisés. Voir la définition de //text// dans la BNF, qui ne contient plus //SP//.
# Exemples
## => liens
### Lien normal
> link = '=>' [WSP] [{URI-reference}] [[WSP] {text}] end-of-line
> ; canonical form = '=>' SP {uri-reference} [SP {text}]
Source: => foo.invalid text of the link
Data: '=>' {'foo.invalid'} {'text of the link'}
Canonical: => foo.invalid text of the link
Html: <a href="foo.invalid">text of the link</a>
Source: =>foo.invalid text of the link
Data: '=>' {'foo.invalid'} {'text of the link'}
Canonical: => foo.invalid text of the link
Html: <a href="foo.invalid">text of the link</a>
Source: => just_a_page
Data: '=>' {'just_a_page'} {}
Canonical: => just_a_page
Html: <a href="just_a_page">just_a_page</a>
Source: =>
Data: '=>' {''} {''}
Canonical: =>
Html: <a href="">&nbsp;</a>
## # En-têtes
> heading = '#' **[WSP]** [{text}] **[WSP]** end-of-line
> (…)
> ; canonical form = ('#' / '##' / '###') [SP {text}]
Source: #title
Data: '#' {"title"}
Canonical: # title
Source: # title with two spaces between title and with
Data: '#' {"title with spaces"}
Canonical: # title with two spaces between title and with

63
docs/configuration-en.gmi Normal file
View File

@ -0,0 +1,63 @@
# Advanced configuration
❗️ This page works with URL rewriting enabled ❗️
By default, the same style is used for all the pages, //htmgem/css/htmgem.css//, except when a file having the same name as the page but with the extension **.css** exists in the same directory. In such as case, it's used.
When the CSS option is activated in the configuration (see /rewrite// below) other behaviors are possible. **Beware**, it won't work with a Gemini client as HtmGem is only reachable with a web browser.
* &style=**htmgem** : Uses the default style.
* &style=**none** : The page HTML is sent without style.
* &style=**<autre nom>** : The file htmgem/css/<autre nom>.css is used as a style.
* &style=**/<path>** : The provided file (absolute path) is used as a style.
* &style=**source** : The source code of the page is sent to the browser, see below…
* &style=**pre** : The source code of the page is sent to the browser enclosed in //<pre>//, see below…
## URL rewriting to set the style to use
Modifying the web server configuration works but it's rather heavy. It's possible to test a particular style this way:
> https://site.tld/htmgem/index.php?url=/url/page.gmi&style=<…>
It's also possible to make a URL rewriting which incorporate the style:
> rewrite ^(.+\.gmi)$ /htmgem/index.php?rw=1&url=$1;
> rewrite ^(.+\.gmi)\ *\|\ *([\w_]+)$ /htmgem/index.php?rw=1&url=$1&style=$2;
For instance, when it's activated:
=> configuration-en.gmi%20|%20pre Shows the readable source code on the screen, using the markup **<pre>**.
=> configuration-en.gmi%20|%20source configuration-en.gmi | source : Downloads the source code.
### With style already included…
=> configuration-en.gmi%20|%20htmgem Style //HtmGem//, the default style
=> configuration-en.gmi%20|%20none Style //none//
=> configuration-en.gmi%20|%20terminal Style //terminal//
=> configuration-en.gmi%20|%20black_wide Style //black wide//
=> configuration-en.gmi%20|%20simple Style //simple//
=> configuration-en.gmi%20|%20raw Style //raw//
=> configuration-en.gmi%20|%20debug Style //debug//
=> ../css Style selector: the page containing the style allows to test them 😎
## Text decoration
The text decoration, which interprets the **bold** for instance, is not part of GemText definition. The text decoration applies everywhere except on the titles and preformated texts.
### Disable the text decoration
It's possible to:
* disable and enable the text decoration with a line **^^^**,
* add what follows to the URL **rewriting**:
> &textDecoration=0
## BNF / Syntax
HtmGem uses a precise implementation of the GemText BNF. It indicates exactly what text portions are to be used.
=> BNF-en.gmi BNF
=> tutogemtext-en.gmi How to build GemText pages?
———————————————————— ————————————————————
Amongst the distributed files and directories, only the ones below are useful for HtmGem:
* **htmgem/*.php** : These files translate the GemText to HTML.
* **htmgem/css/htmgem.css** : If it's missing, the display will be without style — literally.
* **htmgem/css/…** : Keep the styles you use.
The others can be deleted (included this present file //configuration-en.gmi//) although they are not harmful.

63
docs/configuration-fr.gmi Normal file
View File

@ -0,0 +1,63 @@
# Configuration avancée
❗️ Cette page fonctionne avec la réécriture dURL activée ❗️
Par défaut, le même style est utilisé pour toutes les pages, //htmgem/css/htmgem.css//, sauf lorsquun fichier ayant le même nom que la page mais avec lextension **.css** existe dans le même répertoire. Dans ce cas, il est utilisé.
Lorsque loption css est activé dans la configuration (voir //rewrite// plus bas) dautres comportements sont possibles. **Attention**, cela ne fonctionnera pas avec un client Gemini puisque HtmGem nest accessible que via un navigateur web.
* &style=**htmgem** : Utilise le style par défaut.
* &style=**none** : La page HTML est envoyée sans style.
* &style=**<autre nom>** : Le fichier htmgem/css/<autre nom>.css est utilisé en tant que style.
* &style=**/<path>** : Le fichier indiqué (chemin absolu) est utilisé en tant que style.
* &style=**source** : Le code source de la page est envoyée au navigateur, voir ci-après…
* &style=**pre** : Le code source de la page est envoyée au navigateur encadré par des //<pre>//, voir ci-après…
## Réécriture dURL pour préciser le style à utiliser
Modifier la configuration du serveur web fonctionne mais est assez lourd. On peut tester un style en particulier de la façon suivante :
> https://site.tld/htmgem/index.php?url=/url/page.gmi&style=<…>
Il est aussi possible de faire une réécriture dURL qui intègre le style :
> rewrite ^(.+\.gmi)$ /htmgem/index.php?rw=1&url=$1;
> rewrite ^(.+\.gmi)\ *\|\ *([\w_]+)$ /htmgem/index.php?rw=1&url=$1&style=$2;
Par exemple, lorsque ce sera activé :
=> configuration-fr.gmi%20|%20pre Produit le code source de façon lisble à lécran en utilisant la balise **<pre>**.
=> configuration-fr.gmi%20|%20source configuration-fr.gmi | source : Téléverse le code source.
### Avec les styles déjà fournis…
=> configuration-fr.gmi%20|%20htmgem Style //HtmHem//, le style par défaut
=> configuration-fr.gmi%20|%20none Style //none//
=> configuration-fr.gmi%20|%20terminal Style //terminal//
=> configuration-fr.gmi%20|%20black_wide Style //black wide//
=> configuration-fr.gmi%20|%20simple Style //simple//
=> configuration-fr.gmi%20|%20raw Style //brut//
=> configuration-fr.gmi%20|%20debug Style //debug//
=> ../css Sélecteur de style : la page contenant les styles permet de les essayer 😎
## Décoration du texte
La décoration du texte, qui interprête le **gras** par exemple, ne fait pas partie de la définition de GemText. La décoration du texte sapplique partout sauf sur les titres et blocs préformatés.
### Désactiver la décoration du texte
On peut :
* désactiver et activer la décoration du texte avec une ligne **^^^**,
* ajouter ce qui suit à la **réécriture** dURL :
> &textDecoration=0
## BNF / Syntax
HtmGem utilise une implémentation précise de la BNF de GemText. Il indique exactement quelle portions de texte doivent être utilisées.
=> BNF-fr.gmi BNF
=> tutogemtext-fr.gmi Comment faire des pages GemText ?
———————————————————— ————————————————————
Parmi les fichiers et répertoires distribués, seuls sont utiles pour le fonctionnement de HtmGem :
* **htmgem/*.php** : Ces fichiers se chargent de traduire le GemText en HTML.
* **htmgem/css/htmgem.css** : Sil manque, laffichage sera dépourvu de style — littéralement.
* **htmgem/css/…** : Conservez les styles que vous utilisez.
Les autres peuvent être supprimés (y compris ce présent fichier //configuration-fr.gmi//) bien quils ne présentent aucun danger.

9
docs/index.gmi Normal file
View File

@ -0,0 +1,9 @@
# Developers' documentation
=> BNF-en.gmi BNF / Backus-Naur Form
=> https://gmi.sbgodin.fr/htmgem Project main page
=> https://tildegit.org/Sbgodin/htmgem Source code, comments
=> https://gemini.circumlunar.space Main Gemini capsule
=> ../CHANGELOG.gmi Change log
=> ../COPYING.gmi Licence Gnu Affero General Public License v3 — 19 november 2007

42
docs/installation-en.gmi Normal file
View File

@ -0,0 +1,42 @@
# HtmGem, installation
To run HtmGem — after having copied the files — there is nothing to do but to add the URL rewriting rules.
## Prerequisites
* Php v7.3 minimum
* Module **php-mbstring** to manage unicode
* A web server (Apache and Nginx tested)
* Module **mod-rewrite** to handle the Gemini pages
## Installation
### Download
=> https://tildegit.org/sbgodin/HtmGem/archive/master.zip Stable version
=> https://tildegit.org/Sbgodin/htmgem Project repository
### Nginx
```
# This text must be placed in the server's configuration
index index.gmi index.php index.html
rewrite ^(.+\.gmi)$ htmgem/index.php?rw=1&url=$1;
```
### Apache
```
# This text can be placed at the root of the web site in a file ".htaccess".
DirectoryIndex index.gmi index.php index.html
RewriteEngine on
RewriteRule ^(.+\.gmi)$ htmgem/index.php?rw=1&url=$1
```
Afterwards,
* When a file ends by **.gmi.** is asked, HtmGem will display it in the browser.
* When only the directory is asked (http://site.tld/path) the file //index.gmi// will be automatically choosen.
=> tutogemtext-en.gmi How to build GemText pages?
## Advanced configuration
Add additional styles as a link parameter or adapt the text decoration:
=> configuration-en.gmi Advanced configuration

42
docs/installation-fr.gmi Normal file
View File

@ -0,0 +1,42 @@
# HtmGem, installation
Pour faire fonctionner HtmGem — après avoir copié les fichiers — il ne reste quà ajouter les règles de réécriture dURL (//URL Rewriting//).
## Prérequis
* Php v7.3 minimum
* Module **Php-mbstring** pour gérer lunicode
* Un serveur web (Apache et Nginx testés)
* Module **mod-rewrite** pour prendre en charge les pages Gemini
## Installation
### Téléchargement
=> https://tildegit.org/sbgodin/HtmGem/archive/master.zip Version stable
=> https://tildegit.org/Sbgodin/htmgem Dépôt du projet
### Nginx
```
# Ce texte doit être placé dans la configuration du serveur.
index index.gmi index.php index.html
rewrite ^(.+\.gmi)$ htmgem/index.php?rw=1&url=$1;
```
### Apache
```
# Ce texte peut se placer à la racine du site dans un fichier ".htaccess".
DirectoryIndex index.gmi index.php index.html
RewriteEngine on
RewriteRule ^(.+\.gmi)$ htmgem/index.php?rw=1&url=$1
```
Par la suite,
* Quand un fichier se terminant par **.gmi** sera demandé, HtmGem laffichera dans le navigateur.
* Quand seul le répertoire sera demandé (http://site.tld/path) le fichier //index.gmi// sera automatiquement choisi.
=> tutogemtext-fr.gmi Comment faire des pages GemText ?
## Configuration avancée
Ajoutez des styles supplémentaires en paramètre de lien ou adaptez la décoration du texte :
=> configuration-fr.gmi Configuration avancée

74
docs/tutogemtext-en.gmi Normal file
View File

@ -0,0 +1,74 @@
# GemText tutorial
Gemini is a protocol, a syntax, servers and clients. Its syntax is the GemText. Its principle is that it's the Gemini browser of the user which decides about the display. The font, the size, the page background, everything. One of the goal is to focus on the text and some other details explained below.
The paragraph you just read is on one physical line, cut by the program you use in several logical lines to fit your screen. Between this text line and the preceding one, there's an empty line to mark the paragraph change.
Here, I just did a line wrap. The margin should be lower, but it depends upon the program you are using.
The titles of level one, two and three are first written as they are physically on this page, then on the line after they are displayed normally by the Gemini browser:
# Title level 1
# Title level 1
## Title level 2
## Title level 2
### Title level 3
### Title level 3
# Citations
> Text citation. The line can be as long as needed, it's your program that must cut the line to display it. One physical line can be long, but there's no need to wrap the line.
> Text citation. The line can be as long as needed, it's your program that must cut the line to display it. One physical line can be long, but there's no need to wrap the line.
# Preformated blocks
```
The preformated blocks are lines enclosed by ``` on one line before the block and a ``` after the block.
```
```
The preformated blocks are lines enclosed by ``` on one line before the block and a ``` after the block.
```
# Unordered lists
* The unordered lists are lines beginning by * one after the others.
* They can be used to enumerate.
* However, GemText doesn't recognize the ordered lists.
* The unordered lists are lines beginning by * one after the others.
* They can be used to enumerate.
* However, GemText doesn't recognize the ordered lists.
# The links
There can be only one link on a line. And the line is dedicated to! Here's for instance a link to the site centralizing at the moment the information about Gemini:
=> gemini://gemini.circumlunar.space/docs/specification.gmi Gemini specifications
=> gemini://gemini.circumlunar.space/docs/specification.gmi Gemini specifications
=> https://gemini.circumlunar.space/docs/specification.gmi
=> https://gemini.circumlunar.space/docs/specification.gmi
# Text decoration
The text decoration is not part of Gemini's specifications.
This **line** uses the //text decoration// which can ~~strike through~~ or __underline__ words.
This **line** uses the //text decoration// which can ~~strike through~~ or __underline__ words.
It's possible to disable and enable the text decoration with **^^^** on a line.
And voilà! You know everything 🥳
———————————————————— ————————————————————
## HtmGem
HtmGem allows to host Gemini pages and publish them on a web server with **Php**. When opening a page ***.gmi**, it translates it for the web browser. This page is displayed this way. It allows to use the Gemini syntax (GemText) on the web.
=> https://gmi.sbgodin.fr/htmgem
### License of this page
This page is under the free licence **CC BY-SA 2.0**.
=> https://creativecommons.org/licenses/by-sa/2.0/en/ Text under license CC BY-SA 2.0
=> gemini://gmi.sbgodin.fr/ gemini://gmi.sbgodin.fr/ ⸻ Christophe HENRY

View File

@ -1,4 +1,4 @@
# Tutorial GemText
# Tutoriel GemText
Gemini est un protocole, une syntaxe, des serveurs et des clients. Sa syntaxe est le GemText. Son principe est que cest le navigateur Gemeni de lutilisateur qui décide de laffichage. La police de caractère, la taille, le fond décran, tout. Lun des buts recherchés est de se concentrer sur le texte et quelques autres détails abordés ci-après.
@ -24,10 +24,10 @@ Les titres de niveau un, deux puis trois sont dabord écrits ci-après tel qu
# Blocs préformatés
```
Les blocs préformatés sont des lignes encadrées par un ``` sur une ligne avant le bloc et un ``` après le bloc. Les lignes contenant ``` ne sont pas affichées :
Les blocs préformatés sont des lignes encadrées par un ``` sur une ligne avant le bloc et un ``` après le bloc.
```
```
Les blocs préformatés sont des lignes encadrées par un ``` sur une ligne avant le bloc et un ``` après le bloc. Les lignes contenant ``` ne sont pas affichées :
Les blocs préformatés sont des lignes encadrées par un ``` sur une ligne avant le bloc et un ``` après le bloc.
```
# Listes non-ordonnées
@ -44,7 +44,7 @@ Les blocs préformatés sont des lignes encadrées par un ``` sur une ligne avan
Il ne peut exister quun lien par ligne. Et la ligne est dédiée à ça ! Voici par exemple un lien vers le site centralisant pour le moment les informations sur Gemini :
=> gemini://gemini.circumlunar.space/docs/specification.gmi Spécifications de Gemini
=> gemini://gemini.circumlunar.space/docs/specification.gmi Spécifications de Gemini
=> gemini://gemini.circumlunar.space/docs/specification.gmi Spécifications de Gemini
=> https://gemini.circumlunar.space/docs/specification.gmi
=> https://gemini.circumlunar.space/docs/specification.gmi
@ -58,8 +58,7 @@ Cette **ligne** utilise la //décoration du texte// qui peut ~~barrer~~ ou __sou
On peut désactiver et activer la décoration du texte avec **^^^** sur une ligne.
Et voilà ! Vous savez tout ce qui est à savoir 🥳 Les spécifications complètes sont sur le site de Gemini :
=> https://gemini.circumlunar.space/docs/specification.gmi
Et voilà ! Vous savez tout 🥳
———————————————————— ————————————————————
@ -70,9 +69,6 @@ HtmGem permet dhéberger des pages Gemini et de les publier sur un serveur we
### License de cette page
Cette page est sous licence libre **CC BY-SA 2.0 FR**.
=> https://creativecommons.org/licenses/by-sa/2.0/fr/ Texte de la licence CC BY-SA 2.0 FR
Cette page est sous licence libre **CC BY-SA 2.0**.
=> https://creativecommons.org/licenses/by-sa/2.0/fr/ Texte sous licence CC BY-SA 2.0
=> gemini://gmi.sbgodin.fr/ gemini://gmi.sbgodin.fr/ ⸻ Christophe HENRY
### Navigation
=> index.gmi

138
index.gmi
View File

@ -1,133 +1,13 @@
# HtmGem, voir Gemini via le web
# HtmGem
Ceci est la page dinstallation et de présentation d**HtmGem**.
=> tutogemtext.gmi Cliquez ici pour voir le tutoriel pour écrire des pages Gemini.
=> docs/installation-fr.gmi Installation de HtmGem, en français
HtmGem rend vos pages **Gemini** accessibles sur le web. Il fonctionne aussi en hébergement mutualisé.
=> docs/tutogemtext-fr.gmi Tutoriel GemText
HtmGem permet dhéberger des pages Gemini et de les publier sur un serveur web muni de **Php**. À louverture dune page ***.gmi**, il la traduit pour le navigateur web. Cette présente page est affichée de cette façon. Gemini utilise son propre protocole, format, clients et serveurs ; HtmGem permet den utiliser le format (Gemtext) via le web.
=> docs/installation-en.gmi HtmGem installation, in English
HtmGem makes your **Gemini** pages reachable on the web. It can be used on a shared host.
=> docs/tutogemtext-en.gmi GemText tutorial
```
Gemini est un nouveau protocole internet qui :
* est plus lourd que gopher,
* est plus léger que le web,
* nen remplacera aucun,
* vise le rapport puissance sur poids maximum,
* prend la vie privée très sérieusement.
```
=> https://gemini.circumlunar.space/
=> https://tildegit.org/sbgodin/HtmGem/archive/master.zip Téléchargez la branche courante pour linstaller
=> https://tildegit.org/Sbgodin/htmgem Code source, rapports de bug, commentaires…
=> https://gmi.sbgodin.fr/htmgem Page principale de HtmGem via le web
=> gemini://gmi.sbgodin.fr/htmgem Page principale de HtmGem via Gemini
=> CHANGELOG.gmi Journal des modifications (//changelog//)
=> COPYING.gmi GNU Affero General Public License (AGPLv3)
———————————————————— ————————————————————
# Installation
Pour faire fonctionner HtmGem — après avoir copié les fichiers — il ne reste quà ajouter une règle de ré-écriture dURL (//URL Rewriting//). Si vous pouvez lire ce texte en ayant demandé //htmgem.php// avec le navigateur, il ne reste que cette dernière étape à franchir 😄
## Prérequis
* Php v7.3 minimum
* Module **Php-mbstring** pour gérer lunicode
* Un serveur web (Apache et Nginx testés)
* Module **mod-rewrite** pour intercepter les pages Gemini
### Nginx
```
# Ce texte doit être placé dans la configuration du serveur.
index index.php index.gmi index.html
rewrite ^(.+\.gmi)$ htmgem/?url=$1;
```
### Apache
```
# Ce texte peut se placer à la racine du site dans un fichier ".htaccess".
DirectoryIndex index.php index.gmi index.html
RewriteEngine on
RewriteRule ^(.+\.gmi)$ htmgem/?url=$1
```
Par la suite,
* Quand un fichier se terminant par **.gmi** sera demandé, HtmGem le traduira à la volée en HTML.
* Quand seul le répertoire sera demandé (http://site.tld/path) le fichier //index.gmi// sera automatiquement choisi.
Le paramétrage dApache et de Nginx est similaire. Par la suite, la syntaxe Nginx sera utilisée.
## Tester HtmGem
Il est supposé que HtmGem est installé à la racine du site dans un répertoire //HtmGem//. Sinon, il faudra simplement adapter les liens.
Chargez cette présente page directement, en cliquant ci-après.
=> index.gmi
Enfin, pour vérifier que le fichier //index.gmi// est automatiquement appelé quand le fichier **.gmi** nest pas indiqué :
=> /htmgem
Linstallation est terminée 🥳 La suite du texte donne des informations complémentaires, et nest pas nécessaire dans limmédiat. Les fichiers **.gmi** que vous créerez seront disponibles dès maintenant.
=> tutogemtext.gmi Inspirez-vous du tutoriel
———————————————————— ————————————————————
# Configuration avancée
Par défaut, le style est incorporé dans chaque page récupérée par le navigateur web. Le même style est utilisé pour toutes les pages, //htmgem/css/htmgem.css//, sauf lorsquun fichier ayant le même nom que la page mais avec lextension **.css** existe dans le même répertoire. Dans ce cas, il est utilisé.
Lorsque loption css est activé dans la configuration (voir //rewrite// plus haut) dautres comportements sont possibles. **Attention**, cela ne fonctionnera pas avec un client Gemini puisque HtmGem nest accessible que via un navigateur web.
* &style=**htmgem** : Utilise le style par défaut, mais en tant que fichier externe.
* &style=**none** : La page HTML est envoyée sans style.
* &style=**<autre nom>** : Le fichier htmgem/css/<autre nom>.css est utilisé en tant que style externe.
* &style=**/<path>** : Le fichier indiqué (chemin absolu) est utilisé en tant que style externe.
* &style=**source** : Le code source de la page est envoyée au navigateur, voir ci-après…
* &style=**pre** : Le code source de la page est envoyée au navigateur encadré par des //<pre>//, voir ci-après…
## Réécriture dURL pour préciser le style à utiliser
Modifier la configuration du serveur web fonctionne mais est assez lourd. On peut tester un style en particulier de la façon suivante :
> https://site.tld/htmgem/index.php?url=/url/page.gmi&style=<…>
Il est aussi possible de faire une réécriture dURL qui intègre le style :
> rewrite ^(.+\.gmi)$ /htmgem/?url=$1;
> rewrite ^(.+\.gmi)\ *\|\ *([\w_]+)$ /htmgem/?url=$1&style=$2;
Par exemple, lorsque ce sera activé :
=> index.gmi%20|%20source Le lien index.gmi | source Produit le code source, pas bien lisible à lécran. À utiliser avec //wget//.
=> index.gmi%20|%20pre Produit le code source de façon lisble à lécran en utilisant la balise **<pre>**.
=> index.gmi Ouvre la page avec le style par défaut, avec le style importé dans len-tête.
=> css Sélecteur de style : une page de démo pour essayer chaque style 😎
### Avec les styles déjà fournis
=> index.gmi%20|%20htmgem Ouvre la page avec le style par défaut (//htmgem.css//), mais le style est importé dans len-tête.
=> index.gmi%20|%20none Ouvre la page courante avec le style //none//. Aucune CSS utilisée.
=> index.gmi%20|%20terminal Style //terminal//
=> index.gmi%20|%20black_wide Style //black wide//
=> index.gmi%20|%20simple Style //simple//
## Décoration du texte
La décoration du texte, qui interprête le **gras** par exemple, ne fait pas partie de la définition de GemText. La décoration du texte sapplique partout sauf sur les titres et blocs préformatés.
### Désactiver la décoration du texte
On peut :
* désactiver et activer la décoration du texte avec une ligne **^^^**,
* ajouter ce qui suit à la **réécriture** dURL :
> &textDecoration=0
———————————————————— ————————————————————
# Quand tout marche…
Parmi les fichiers et répertoires distribués, seuls sont utiles pour le fonctionnement de HtmGem :
* **htmgem/index.php** : Il se charge de traduire le gemtext en HTML.
* **htmgem/css/htmgem.css** : Sil manque, laffichage sera dépourvu de style — littéralement.
* **htmgem/css/… : Conservez les styles que vous utilisez.
Les autres peuvent être supprimés (y compris ce présent fichier //index.gmi//) bien quils ne présentent aucun danger.
=> docs/index.gmi **Developers' documentation**
The documentation (in English) for the developers's stands here. Please read them carefully before doing anything on the source code.

19
index.html Normal file
View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<title>HtmGem</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link type='text/css' rel='StyleSheet' href='css/htmgem.css'>
</head>
<body>
<h1>HtmGem</h1>
<p>&nbsp;</p>
<h3>Php required</h3>
<p><a class='http' href='index.php'>🔄 index.php</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>Help</h3>
<p><a class='https' href='https://gmi.sbgodin.fr/htmgem'>https://gmi.sbgodin.fr/htmgem</a></p>
</body>
</html>

View File

@ -4,11 +4,12 @@ require_once "lib-htmgem.php";
# The url argument is always absolute compared to the document root.
$url = @$_REQUEST["url"];
$urlRewriting = @$_REQUEST["rw"]=="1";
/* Installation page
*
* Accessing directly /htmgem will make display the self-hosted documentation
* contained in "index.gmi". If it's removed, diplay an empty page with a
* contained in "index.gmi". If it's removed, display an empty page with a
* comment
*/
if (empty($url)) {
@ -16,20 +17,25 @@ if (empty($url)) {
http_response_code(403);
die("<!-- index.gmi missing -->");
}
$t = new \htmgem\GemTextTranslate_html(@file_get_contents("index.gmi"));
$t = new \htmgem\GemTextTranslate_html(@file_get_contents("index.gmi"), true, "/htmgem");
echo $t->getFullHtml();
exit();
}
$documentRoot = $_SERVER['DOCUMENT_ROOT'];
if (!preg_match("/\.gmi$/", $url)) {
if ($url[-1] == "/")
$url = $url."index.gmi";
else
$url = $url."/index.gmi";
}
# Removes the headling and trailling slashes, to be sure there's not any.
$filePath = rtrim($_SERVER['DOCUMENT_ROOT'], "/")."/".ltrim($url, "/");
switch(true) {
case false:
case !realPath($filePath):
case !preg_match("/\.gmi$/", $url): # not finishing by .gmi
case strpos($filePath, $documentRoot)!==0: # not in web directory
$go404 = true;
// Says 404 even if the file exists to not give any information.
@ -96,7 +102,11 @@ EOL;
exit();
}
$t = new \htmgem\GemTextTranslate_html($fileContents, $textDecoration);
if ($urlRewriting)
$baseUrl = null;
else
$baseUrl = dirname($url);
$t = new \htmgem\GemTextTranslate_html($fileContents, $textDecoration, $baseUrl);
if ("none" == $style) {
$t->addCss("");
} elseif ("/" == @$style[0]) {

View File

@ -10,6 +10,8 @@ mb_regex_encoding("UTF-8");
* @param str $fileContents the gemtext to parse
*/
function gemtextParser($fileContents) {
if (empty($fileContents)) return array();
$fileContents = rtrim($fileContents); // removes last empty line
$fileLines = explode("\n", $fileContents);
$mode = null;
$current = array();
@ -30,11 +32,11 @@ function gemtextParser($fileContents) {
if ('^^^' == $line3) {
yield array("mode" => "^^^");
} elseif ("#" == $line1) {
preg_match("/^(#{1,3})\s*(.+)/", $line, $matches);
yield array("mode" => $matches[1], "title" => trim($matches[2]));
preg_match("/^(#{1,3})\s*(.+)?/", $line, $matches);
yield array("mode" => $matches[1], "title" => trim(@$matches[2]));
} elseif ("=>" == $line2) {
preg_match("/^=>\s*([^\s]+)(?:\s+(.*))?$/", $line, $matches);
yield array("mode" => "=>", "link" => trim($matches[1]), "text" => trim(@$matches[2]));
yield array("mode" => "=>", "link" => trim(@$matches[1]), "text" => trim(@$matches[2]));
} elseif ("```" == $line3) {
preg_match("/^```\s*(.*)$/", $line, $matches);
$current = array("mode" => "```", "alt" => trim($matches[1]), "texts" => array());
@ -49,7 +51,7 @@ function gemtextParser($fileContents) {
$mode = "*";
} else {
// text_line
yield array("mode"=>"", "text" => trim($line));
yield array("mode"=>"", "text" => rtrim($line));
}
} else {
if ("```"==$mode) {
@ -58,7 +60,7 @@ function gemtextParser($fileContents) {
$current = array();
$mode = null;
} else {
$current["texts"] []= $line; // No trim() as its a preformated text!
$current["texts"] []= rtrim($line); // No ltrim() as its a preformated text!
}
} elseif (">"==$mode) {
if (">" == $line1) {
@ -102,55 +104,67 @@ function gemtextParser($fileContents) {
class GemtextTranslate_gemtext {
function __construct($parsedGemtext) {
$this->parsedGemtext = $parsedGemtext;
if (empty($parsedGemtext)) $parsedGemtext = "";
// to delete the last empty lines
$parsedGemtext = rtrim($parsedGemtext);
// The text must be parsed
$this->parsedGemtext = gemtextParser($parsedGemtext);
$this->translate();
}
protected function translate() {
ob_start();
$output = "";
foreach ($this->parsedGemtext as $node) {
$mode = $node["mode"];
switch($mode) {
case "":
echo $node["text"]."\n";
$output .= $node["text"]."\n";
break;
case "*":
foreach ($node["texts"] as $text) {
echo "* $text\n";
$output .= "* $text\n";
}
break;
case "```":
print("```\n");
$alt = $node["alt"];
if (empty($alt))
$output .= "```\n";
else
$output .= "``` $alt\n";
foreach ($node["texts"] as $text) {
echo "$text\n";
$output .= "$text\n";
}
print("```\n");
$output .= "```\n";
break;
case ">":
foreach ($node["texts"] as $text) {
echo "> $text\n";
if (empty($text))
$output .= ">\n";
else
$output .= "> $text\n";
}
break;
case "=>":
$linkText = $node["text"];
$link = $node["link"];
if (!empty($linkText)) $linkText = " $linkText";
print("=> ".$node["link"].$linkText."\n");
if (!empty($link)) $link = " $link";
$output .= "=>".$link.$linkText."\n";
break;
case "#":
case "##":
case "###":
print("$mode ".$node["title"]."\n");
$output .= "$mode ".$node["title"]."\n";
break;
case "^^^":
print("^^^\n");
$output .= "^^^\n";
break;
default:
die(