[feat] Insertion of Gopher specific content and ommition of web-only content

This commit is contained in:
Josip Tišljar Mataušić
2026-05-21 17:46:52 +02:00
parent c5fb1169b0
commit 7b6e641ce4
2 changed files with 107 additions and 4 deletions
+77
View File
@@ -0,0 +1,77 @@
### Compiling
This program compiles like any other ordinary Go project, simply **run** `go build .` in the project directory.
### Usage
```shell
gemtext2gophermap input.gmi output_gophermap [max line length (default 70)] [preprocessor insertion map file]
```
## Example
### Input Gemtext
_input.gmi_
````gemtext
Everything until the first <!--break--> in the map file will be put in place of the insert-gopher tag.
```html
<!--insert-gopher-->
```
The following <script> tag will be removed because it is between to web-only tags.
```html
<!--web-only-->
```
```html
<script>
console.log("joj")
</script>
```
```html
<!--web-only-->
```
> Here, the contents after the first break in the map file will be put
```html
<!--insert-gopher-->
```
````
### A map file
_map.txt_
```gophermap
<?php
echo "i" . date(DATE_RFC2822) . "\t/FAKE\tNULL\t0";
?>
<!--break-->
iIf your Gopher server supports running PHP it should have printed the current date. /FAKE NULL 0
```
### Command
```shell
gemtext2gophermap input.gmi - 70 map.txt
```
If `-` is passed instead of `input/output` file name `stdin/stdout` will be used. Reading the **map file from stdin** is **not supported**.
### Output
```gophermap
iEverything until the first <!--break--> in the map file will be put in /FAKE NULL 0
iplace of the insert-gopher tag. /FAKE NULL 0
<?php
echo "i" . date(DATE_RFC2822) . "\t/FAKE\tNULL\t0";
?>
iThe following <script> tag will be removed because it is between to /FAKE NULL 0
iweb-only tags. /FAKE NULL 0
i> Here, the contents after the first break in the map file will be put /FAKE NULL 0
iIf your Gopher server supports running PHP it should have printed the current date. /FAKE NULL 0
```
+28 -2
View File
@@ -12,13 +12,16 @@ import(
type State struct {
out io.Writer
maxLineLength int
insertionMap []string
insertionIndex int
isInCodeBlock bool
wasPreviousLink bool
isWebOnly bool
}
func main() {
if len(os.Args) < 3 {
fmt.Printf("Usage: %s input.gmi output_gophermap [max line length (default 69)]\n", os.Args[0])
fmt.Printf("Usage: %s input.gmi output_gophermap [max line length (default 70)] [preprocessor insertion map file]\n", os.Args[0])
return
}
@@ -52,7 +55,17 @@ func main() {
outputWriter = os.Stdout
}
s := State{outputWriter, 69, false, false}
preprocessorMap := []string{}
if len(os.Args) >= 5 {
data, err := os.ReadFile(os.Args[4])
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
preprocessorMap = strings.Split(string(data), "<!--break-->")
}
s := State{outputWriter, 70, preprocessorMap, 0, false, false, false}
if len(os.Args) >= 4 {
maxLineLength, err := strconv.Atoi(os.Args[3])
if err != nil {
@@ -72,6 +85,17 @@ var gopherTypeCharParams = GopherTypeCharParams{
}
func (s *State) handleElement(e p.Element) {
if strings.HasPrefix(e.Text(), "<!--web-only-->") {
s.isWebOnly = !s.isWebOnly
return
}
if s.isWebOnly { return }
if strings.HasPrefix(e.Text(), "<!--insert-gopher-->") {
s.out.Write([]byte(s.insertionMap[s.insertionIndex]))
s.insertionIndex += 1
return
}
switch (e.Type()) {
case p.ElementTypes.Text():
if e.Text() == "" { return }
@@ -110,5 +134,7 @@ func (s *State) handleElement(e p.Element) {
s.isInCodeBlock = !s.isInCodeBlock
s.wasPreviousLink = false
}
if e.Text() != "" {
s.out.Write([]byte("\n"))
}
}