document some stuff.
This commit is contained in:
151
CONTRIBUTING.md
Normal file
151
CONTRIBUTING.md
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
# Contributing to go-rst
|
||||||
|
|
||||||
|
## Adding New Node Types
|
||||||
|
|
||||||
|
### 1. Define the Node Type
|
||||||
|
First, add your new node type in `pkg/nodes/types.go`:
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
NodeText NodeType = iota
|
||||||
|
NodeHeading
|
||||||
|
NodeParagraph
|
||||||
|
NodeMeta
|
||||||
|
NodeDirective
|
||||||
|
NodeCode
|
||||||
|
YourNewNodeType // Add your new node type here
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Create Node Structure
|
||||||
|
In `pkg/nodes/nodes.go`, define your new node structure:
|
||||||
|
|
||||||
|
```go
|
||||||
|
type YourNewNode struct {
|
||||||
|
BaseNode
|
||||||
|
// Add specific fields for your node type
|
||||||
|
SpecificField string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewYourNewNode(specific string) Node {
|
||||||
|
return &YourNewNode{
|
||||||
|
BaseNode: BaseNode{
|
||||||
|
nodeType: YourNewNodeType,
|
||||||
|
},
|
||||||
|
SpecificField: specific,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Update Parser Components
|
||||||
|
|
||||||
|
#### a. Add Pattern (if needed)
|
||||||
|
In `pkg/parser/patterns.go`, add a new regex pattern:
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Patterns struct {
|
||||||
|
// Existing patterns...
|
||||||
|
yourNewPattern *regexp.Regexp
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPatterns() *Patterns {
|
||||||
|
return &Patterns{
|
||||||
|
// Existing patterns...
|
||||||
|
yourNewPattern: regexp.MustCompile(`your-pattern-here`),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### b. Add Token Type
|
||||||
|
In `pkg/parser/lexer.go`, add a new token type:
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
// Existing token types...
|
||||||
|
TokenYourNew TokenType = iota
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### c. Update Lexer
|
||||||
|
Modify the `Tokenize` method in `pkg/parser/lexer.go` to recognize your new pattern:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *Lexer) Tokenize(line string) Token {
|
||||||
|
// Existing checks...
|
||||||
|
|
||||||
|
if l.patterns.yourNewPattern.MatchString(line) {
|
||||||
|
return Token{
|
||||||
|
Type: TokenYourNew,
|
||||||
|
Content: // Extract relevant content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default case...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### d. Update Parser
|
||||||
|
In `pkg/parser/parser.go`, add handling for your new token type:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (p *Parser) processToken(token, prevToken Token, currentNode nodes.Node) nodes.Node {
|
||||||
|
switch token.Type {
|
||||||
|
// Existing cases...
|
||||||
|
case TokenYourNew:
|
||||||
|
return nodes.NewYourNewNode(token.Content)
|
||||||
|
}
|
||||||
|
return currentNode
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Add Renderer Support
|
||||||
|
In `pkg/renderer/html.go`, implement HTML rendering for your new node type:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (r *HTMLRenderer) renderNode(node nodes.Node) string {
|
||||||
|
switch node.Type() {
|
||||||
|
// Existing cases...
|
||||||
|
case nodes.YourNewNodeType:
|
||||||
|
return r.renderYourNewNode(node.(*nodes.YourNewNode))
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *HTMLRenderer) renderYourNewNode(node *nodes.YourNewNode) string {
|
||||||
|
return fmt.Sprintf("<your-tag>%s</your-tag>", node.SpecificField)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Testing
|
||||||
|
|
||||||
|
1. Add test cases in appropriate test files
|
||||||
|
2. Create example RST documents showcasing your new node type
|
||||||
|
3. Verify translation handling if applicable
|
||||||
|
|
||||||
|
### Best Practices
|
||||||
|
|
||||||
|
1. **Type Safety**: Use Go's type system effectively
|
||||||
|
2. **Error Handling**: Return meaningful errors
|
||||||
|
3. **Documentation**: Add godoc comments to all public types and functions
|
||||||
|
4. **Testing**: Write comprehensive tests for new functionality
|
||||||
|
5. **Performance**: Consider memory allocation and processing efficiency
|
||||||
|
|
||||||
|
### Translation Support
|
||||||
|
|
||||||
|
If your node type contains translatable content:
|
||||||
|
|
||||||
|
1. Ensure the content is passed through the translator in the parser
|
||||||
|
2. Update example PO files to demonstrate translation capabilities
|
||||||
|
3. Add translation tests
|
||||||
|
|
||||||
|
### Pull Request Process
|
||||||
|
|
||||||
|
1. Fork the repository
|
||||||
|
2. Create a feature branch
|
||||||
|
3. Implement your changes
|
||||||
|
4. Add tests and documentation
|
||||||
|
5. Submit a pull request with a clear description
|
||||||
|
|
||||||
|
### Questions?
|
||||||
|
|
||||||
|
Feel free to open an issue for discussion before implementing major changes.
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 idk
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
82
README.md
Normal file
82
README.md
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
# go-rst
|
||||||
|
|
||||||
|
A Go library for parsing and rendering reStructuredText (RST) documents with translation support.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- RST to HTML conversion
|
||||||
|
- Translation support via PO files
|
||||||
|
- Clean and extensible API
|
||||||
|
- Pretty HTML output
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get i2pgit.org/idk/go-rst
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Command Line Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go-rst -rst example/doc.rst -po example/translations.po -out output.html
|
||||||
|
```
|
||||||
|
|
||||||
|
### Library Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"i2pgit.org/idk/go-rst/pkg/parser"
|
||||||
|
"i2pgit.org/idk/go-rst/pkg/renderer"
|
||||||
|
"i2pgit.org/idk/go-rst/pkg/translator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Read RST content
|
||||||
|
content, err := ioutil.ReadFile("doc.rst")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize translator with PO file (optional)
|
||||||
|
trans, err := translator.NewPOTranslator("translations.po")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create parser with translator
|
||||||
|
p := parser.NewParser(trans)
|
||||||
|
|
||||||
|
// Parse RST content
|
||||||
|
nodes := p.Parse(string(content))
|
||||||
|
|
||||||
|
// Create HTML renderer
|
||||||
|
r := renderer.NewHTMLRenderer()
|
||||||
|
|
||||||
|
// Render to HTML
|
||||||
|
html := r.RenderPretty(nodes)
|
||||||
|
|
||||||
|
// Save or use the HTML
|
||||||
|
fmt.Println(html)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
For more detailed information about adding new node types or contributing to the project, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
This project uses:
|
||||||
|
- [gotext](https://github.com/leonelquinteros/gotext) for PO file handling
|
||||||
|
- [gohtml](https://github.com/yosssi/gohtml) for HTML prettifying
|
7
go.mod
7
go.mod
@ -2,4 +2,9 @@ module i2pgit.org/idk/go-rst
|
|||||||
|
|
||||||
go 1.23.1
|
go 1.23.1
|
||||||
|
|
||||||
require github.com/leonelquinteros/gotext v1.7.0
|
require (
|
||||||
|
github.com/leonelquinteros/gotext v1.7.0
|
||||||
|
github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4
|
||||||
|
)
|
||||||
|
|
||||||
|
require golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
|
||||||
|
3
go.sum
3
go.sum
@ -1,11 +1,14 @@
|
|||||||
github.com/leonelquinteros/gotext v1.7.0 h1:jcJmF4AXqyamP7vuw2MMIKs+O3jAEmvrc5JQiI8Ht/8=
|
github.com/leonelquinteros/gotext v1.7.0 h1:jcJmF4AXqyamP7vuw2MMIKs+O3jAEmvrc5JQiI8Ht/8=
|
||||||
github.com/leonelquinteros/gotext v1.7.0/go.mod h1:qJdoQuERPpccw7L70uoU+K/BvTfRBHYsisCQyFLXyvw=
|
github.com/leonelquinteros/gotext v1.7.0/go.mod h1:qJdoQuERPpccw7L70uoU+K/BvTfRBHYsisCQyFLXyvw=
|
||||||
|
github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4 h1:0sw0nJM544SpsihWx1bkXdYLQDlzRflMgFJQ4Yih9ts=
|
||||||
|
github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4/go.mod h1:+ccdNT0xMY1dtc5XBxumbYfOUhmduiGudqaDgD2rVRE=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
2
main.go
2
main.go
@ -69,7 +69,7 @@ func main() {
|
|||||||
r := renderer.NewHTMLRenderer()
|
r := renderer.NewHTMLRenderer()
|
||||||
|
|
||||||
// Render HTML
|
// Render HTML
|
||||||
html := r.Render(nodes)
|
html := r.RenderPretty(nodes)
|
||||||
|
|
||||||
// Write output
|
// Write output
|
||||||
err = ioutil.WriteFile(*outFile, []byte(html), 0644)
|
err = ioutil.WriteFile(*outFile, []byte(html), 0644)
|
||||||
|
36
output.html
36
output.html
@ -1,16 +1,26 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Welcome to My Documentation</h1>
|
<h1>
|
||||||
<h2>Translations</h2>
|
Welcome to My Documentation
|
||||||
<p>Welcome to My Documentation
|
</h1>
|
||||||
This is a sample RST document that demonstrates translations.
|
<h2>
|
||||||
Translations</p>
|
Translations
|
||||||
<p>Este texto será traducido
|
</h2>
|
||||||
Some regular text here.</p>
|
<p>
|
||||||
<p>Otra sección traducible</p>
|
Welcome to My Documentation
|
||||||
</body>
|
This is a sample RST document that demonstrates translations.
|
||||||
|
Translations
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Este texto será traducido
|
||||||
|
Some regular text here.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Otra sección traducible
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
@ -8,6 +8,7 @@ import (
|
|||||||
"html"
|
"html"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/yosssi/gohtml"
|
||||||
"i2pgit.org/idk/go-rst/pkg/nodes"
|
"i2pgit.org/idk/go-rst/pkg/nodes"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -148,3 +149,12 @@ func (r *HTMLRenderer) renderDirective(directive *nodes.DirectiveNode) {
|
|||||||
html.EscapeString(directive.RawContent())))
|
html.EscapeString(directive.RawContent())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func (r *HTMLRenderer) RenderPretty(nodes []nodes.Node) string {
|
||||||
|
// First get the regular HTML output
|
||||||
|
rawHTML := r.Render(nodes)
|
||||||
|
|
||||||
|
// Let gohtml handle the formatting
|
||||||
|
prettyHTML := gohtml.Format(rawHTML)
|
||||||
|
|
||||||
|
return prettyHTML
|
||||||
|
}
|
Reference in New Issue
Block a user