A maroto way to create PDFs. Maroto is inspired in Bootstrap and uses gofpdf. Fast and simple.

Overview

Maroto

GoDoc Travis Codecov Go Report Card Mentioned in Awesome Go

A Maroto way to create PDFs. Maroto is inspired in Bootstrap and uses Gofpdf. Fast and simple.

Maroto definition: Brazilian expression, means an astute/clever/intelligent person.

You can write your PDFs like you are creating a site using Bootstrap. A Row may have many Cols, and a Col may have many components. Besides that, pages will be added when content may extrapolate the useful area. You can define a header which will be added always when a new page appear, in this case, a header may have many rows, lines or tablelist.

Installation

  • With go get:
go get -u github.com/johnfercher/maroto

Features

result

Constructors

Grid System

Components To Use Inside a Col

Components To Use Outside a Row

Components To Wrap Row, TableList and Line

Saving PDF

Customizations

  • Properties: most of the components has properties which you can use to customize appearance and behavior.
  • SetBorder: Used to draw rectangles in every row and column
  • SetBackgroundColor: Used to change the background color of one cell.
  • SetPageMargins: Customize the page margins
  • SetAliasNbPages: Set placeholder to use in texts for total count of pages
  • SetFirstPageNb: Set first number for page numbering
  • AddUTF8Font: Add a custom utf8 font
  • SetProtection
  • SetDefaultFontFamily: Define a default font family, useful to use with a custom font.
  • Automatic New Page: New pages are generated automatically when needed.
  • 100% Unicode

Roadmap

Examples

In the PDFs folder there are the PDFs generated using Maroto, and in the examples folder there are subfolders with the code to generate the PDFs. There are examples of: barcode, billing, certificate, custom pdf size, image inside grid, qrcode inside grid, sample with almost all features together, text inside grid, custom utf8 fonts and a label zpl.

result

Code

This is part of the example billing.

// Billing example
package main

import (
	"fmt"
	"github.com/johnfercher/maroto/pkg/color"
	"github.com/johnfercher/maroto/pkg/consts"
	"github.com/johnfercher/maroto/pkg/pdf"
	"github.com/johnfercher/maroto/pkg/props"
	"os"
	"time"
)

func main() {
	begin := time.Now()

	darkGrayColor := getDarkGrayColor()
	grayColor := getGrayColor()
	whiteColor := color.NewWhite()
	header := getHeader()
	contents := getContents()

	m := pdf.NewMaroto(consts.Portrait, consts.A4)
	m.SetPageMargins(10, 15, 10)
	//m.SetBorder(true)

	m.RegisterHeader(func() {
		m.Row(20, func() {
			m.Col(3, func() {
				_ = m.FileImage("internal/assets/images/biplane.jpg", props.Rect{
					Center:  true,
					Percent: 80,
				})
			})

			m.ColSpace(6)

			m.Col(3, func() {
				m.Text("AnyCompany Name Inc. 851 Any Street Name, Suite 120, Any City, CA 45123.", props.Text{
					Size:        8,
					Align:       consts.Right,
					Extrapolate: false,
				})
				m.Text("Tel: 55 024 12345-1234", props.Text{
					Top:   12,
					Style: consts.BoldItalic,
					Size:  8,
					Align: consts.Right,
				})
				m.Text("www.mycompany.com", props.Text{
					Top:   15,
					Style: consts.BoldItalic,
					Size:  8,
					Align: consts.Right,
				})
			})
		})
	})

	m.RegisterFooter(func() {
		m.Row(20, func() {
			m.Col(12, func() {
				m.Text("Tel: 55 024 12345-1234", props.Text{
					Top:   13,
					Style: consts.BoldItalic,
					Size:  8,
					Align: consts.Left,
				})
				m.Text("www.mycompany.com", props.Text{
					Top:   16,
					Style: consts.BoldItalic,
					Size:  8,
					Align: consts.Left,
				})
			})
		})
	})

	m.Row(10, func() {
		m.Col(12, func() {
			m.Text("Invoice ABC123456789", props.Text{
				Top:   3,
				Style: consts.Bold,
				Align: consts.Center,
			})
		})
	})

	m.SetBackgroundColor(darkGrayColor)

	m.Row(7, func() {
		m.Col(3, func() {
			m.Text("Transactions", props.Text{
				Top:   1.5,
				Size:  9,
				Style: consts.Bold,
				Align: consts.Center,
			})
		})
		m.ColSpace(9)
	})

	m.SetBackgroundColor(whiteColor)

	m.TableList(header, contents, props.TableList{
		HeaderProp: props.TableListContent{
			Size:      9,
			GridSizes: []uint{3, 4, 2, 3},
		},
		ContentProp: props.TableListContent{
			Size:      8,
			GridSizes: []uint{3, 4, 2, 3},
		},
		Align:                consts.Center,
		AlternatedBackground: &grayColor,
		HeaderContentSpace:   1,
		Line:                 false,
	})

	m.Row(20, func() {
		m.ColSpace(7)
		m.Col(2, func() {
			m.Text("Total:", props.Text{
				Top:   5,
				Style: consts.Bold,
				Size:  8,
				Align: consts.Right,
			})
		})
		m.Col(3, func() {
			m.Text("R$ 2.567,00", props.Text{
				Top:   5,
				Style: consts.Bold,
				Size:  8,
				Align: consts.Center,
			})
		})
	})

	m.Row(15, func() {
		m.Col(6, func() {
			_ = m.Barcode("5123.151231.512314.1251251.123215", props.Barcode{
				Percent: 0,
				Proportion: props.Proportion{
					Width:  20,
					Height: 2,
				},
			})
			m.Text("5123.151231.512314.1251251.123215", props.Text{
				Top:    12,
				Family: "",
				Style:  consts.Bold,
				Size:   9,
				Align:  consts.Center,
			})
		})
		m.ColSpace(6)
	})

	err := m.OutputFileAndClose("internal/examples/pdfs/billing.pdf")
	if err != nil {
		fmt.Println("Could not save PDF:", err)
		os.Exit(1)
	}

	end := time.Now()
	fmt.Println(end.Sub(begin))
}

Others

Stargazers over time

Stargazers over time

Issues
  • allow uncentralized qr/bar-codes

    allow uncentralized qr/bar-codes

    Description allows uncentralized barcode/qrcode potential fix for codecov issue occured here: https://github.com/johnfercher/maroto/pull/103 - @johnfercher pls mark as invalid https://github.com/johnfercher/maroto/pull/94 - @johnfercher pls mark as invalid

    Related Issue resolve #59 resolve #60

    Checklist

    check with "x", if applied to your change

    • [x] All methods associated with structs has func (s *struct) method() {} name style.
    • [x] Wrote unit tests for new/changed features.
    • [x] Updated docs/doc.go
    • [x] Updated pkg/pdf/example_test.go
    • [x] Updated README.md
    • [x] New public methods has comments upside them explaining what it does
    • [x] Executed go fmt github.com/johnfercher/maroto/... to format all files
    hacktoberfest 
    opened by SuddenGunter 12
  • fix/issues/57-58 Cannot define an uncentralized images

    fix/issues/57-58 Cannot define an uncentralized images

    Description

    • Gopkg.lock was committed accidently, will undo it in different branch and recreate PR. This is just a draft
    • This PR allows to define uncentralized FileImage (and base64Image also cause they share same API. Also I suppose barcode centralization can be resolved later with this code also).
    • main.go included only for demo purposes so you can test it locally
    • It mostly works, see code in main.go and generated PDF: 1571082952_2255_14102019_315x880 I'm satisfied with left alignment, but top (y position) makes me worry a little bit. From what I see - it moves out of a row. Is this the correct behaviour or image must not move out of row? What should I do then if for example image height is 50px, row size is 100 px and user suggest to position image with top alignment 55px (so 5px is out of image). Crop it? Stick it to the bottom of the row?

    I haven't added any unit tests and didn't update any docs because it's just a draft of my proposal

    Related Issue resolve #57 resolve #58

    Checklist

    • [x] All methods associated with structs has func (s *struct) method() {} name style.
    • [x] Wrote unit tests for new/changed features.
    • [x] Updated docs/doc.go
    • [x] Updated pkg/pdf/example_test.go
    • [x] Updated README.md
    • [x] New public methods has comments upside them explaining what it does
    hacktoberfest 
    opened by SuddenGunter 11
  • Add custom page margins

    Add custom page margins

    Description

    • Added a new method on the Maroto PDF interface to allow backwards compatibility instead of adding extra parameter to NewMaroto

    This PR makes it possible to set other margins than the standard (10, 10, 10)

    Picture of sample1 modified with SetPageMargins. 30 left, 20 top and 0 right. m.SetPageMargins(30, 20, 0) Skärmavbild 2019-12-31 kl  11 14 07

    Related Issue resolve #123

    Checklist

    check with "x", if applied to your change

    • [ ] All methods associated with structs has func (s *struct) method() {} name style.
    • [x] Wrote unit tests for new/changed features.
    • [ ] Updated docs/doc.go
    • [x] Updated pkg/pdf/example_test.go
    • [x] Updated README.md
    • [x] Updated all examples inside internal/examples
    • [x] New public methods has comments upside them explaining what it does
    • [x] Executed go fmt github.com/johnfercher/maroto/... to format all files
    opened by happsie 9
  • Make top margin be able to be zero. --Issue #192

    Make top margin be able to be zero. --Issue #192

    Problem

    I can't define top margin as zero

    Issue #192

    To Reproduce Code to reproduce the behavior:

    package main
    
    import (
    	"fmt"
    	"fruitfulpdf/data"
    	"github.com/johnfercher/maroto/pkg/color"
    	"github.com/johnfercher/maroto/pkg/consts"
    	"github.com/johnfercher/maroto/pkg/pdf"
    	"github.com/johnfercher/maroto/pkg/props"
    	"os"
    )
    
    func main() {
    	m := pdf.NewMaroto(consts.Portrait, consts.A4)
    	m.SetPageMargins(0, 0, 0)
    
    	buildHeading(m)
    
    	if err := m.OutputFileAndClose("pdfs/fruits.pdf"); err != nil {
    		fmt.Println("Couldn't save PDF: ", err)
    		os.Exit(1)
    	}
    	fmt.Println("PDF saved successfully")
    }
    
    func buildHeading(m pdf.Maroto) {
    	m.SetBackgroundColor(color.Color{
    		Red:   3,
    		Green: 166,
    		Blue:  166,
    	})
    	m.Row(10, func() {
    		m.Col(12, func() {
    			m.Text("Products", props.Text{
    				Top:    2,
    				Size:   13,
    				Color:  color.NewWhite(),
    				Family: consts.Arial,
    				Style:  consts.Bold,
    				Align:  consts.Center,
    			})
    		})
    	})
    }
    

    I just think it's because inside this method it only changes the s.marginTop when the top value is greater than ten, so the minimum top margin will EVER be ten and it's not customizable follow the code.

    The need to have it greater than ten is because in NewMarotoCustomSize the margin will be ten by default, and in the SetPageMargins it will not change at all for the top margin, so we need a marginTop in PdfMaroto to make some calculus.

    // SetPageMargins overrides default margins (10,10,10)
    // the new page margin will affect all PDF pages
    func (s *PdfMaroto) SetPageMargins(left, top, right float64) {
    	if top > 10 {
    		s.marginTop = top - 10
    	}
    
    	s.Pdf.SetMargins(left, 10.0, right)
    }
    

    The SetPageMargins was supposed to override the default margins, but it does not override the top margin anyway, but it is calculated in someplace with a sum.

    Sometimes, in part of the code as in the method GetPageMargins, the maroto top margin is added to the pdf top margin. Idk if it could occur in other pieces of code.

    func (s *PdfMaroto) GetPageMargins() (left float64, top float64, right float64, bottom float64) {
    	left, top, right, bottom = s.Pdf.GetMargins()
    	top += s.marginTop
    
    	return
    }
    

    My suggestion is to make have no condition to set the s.marginTop value in another method, so we can use this without break the current code

    Something like

    // SetPageMargins overrides default margins (10,10,10)
    // the new page margin will affect all PDF pages
    func (s *PdfMaroto) SetPageMargins(left, top, right float64) {
            s.marginTop = top - 10
    	s.Pdf.SetMargins(left, 10.0, right)
    }
    
    func (s *PdfMaroto) SetTopPageMargin(top float64) {
    	s.marginTop = top - 10
    }
    

    Solution

    Remove >10 conditional, and creating new methods to set margins individually, and use constant to default margin value,

    in analysis 
    opened by EddieSCJ 8
  • Add custom page size option when creating documents

    Add custom page size option when creating documents

    Is your feature request related to a problem? Please describe. Currently Maroto uses only gofpdf.New to create documents with the few predefined page sizes. (A4, A5, Letter etc.)

    Describe the solution you'd like Use gofpdf.NewCustom to allow custom page sizes. Refactor NewMaroto() to accept custom width and height or create a second method for custom documents.

    new feature help wanted good first issue 
    opened by sanderaido 8
  • INVALID feature/59-allow-uncentralized-barcode-and-qrcode

    INVALID feature/59-allow-uncentralized-barcode-and-qrcode

    Description allows uncentralized barcode/qrcode main.go only for testing, will be remove when pr would be ready for review. Result pdf for current main.go: 1571337654_2140_17102019_343x765 Same main.go on current dev: 1571337775_2142_17102019_288x658

    I see 2 related issues:

    • why qr code so blurry?
    • why barcode ignores proportion (16x9 vs 4x3)?

    Related Issue resolve #59 resolve #60

    Checklist

    check with "x", if applied to your change

    • [x] All methods associated with structs has func (s *struct) method() {} name style.
    • [x] Wrote unit tests for new/changed features.
    • [ ] Updated docs/doc.go
    • [ ] Updated pkg/pdf/example_test.go
    • [ ] Updated README.md
    • [ ] New public methods has comments upside them explaining what it does
    • [ ] Executed go fmt github.com/johnfercher/maroto/... to format all files
    invalid 
    opened by SuddenGunter 7
  • feature/forced-line-breaks

    feature/forced-line-breaks

    Description

    • This enables forced line breaks in calls to Text() where a '\n' is present.

    Related Issue

    Checklist

    check with "x", if applied to your change

    • [x] All methods associated with structs has func (s *struct) method() {} name style.
    • [x] Wrote unit tests for new/changed features.
    • [ ] Updated docs/doc.go
    • [ ] Updated pkg/pdf/example_test.go
    • [ ] Updated README.md
    • [ ] Updated all examples inside internal/examples
    • [ ] New public methods/structs/interfaces has comments upside them explaining they responsibilities
    • [ ] Executed make dod with none issues pointed out by golangci-lint and goreportcard-cli
    opened by felix 6
  • Why a dot is printed instead of `→`?

    Why a dot is printed instead of `→`?

    Describe the bug

    I'm trying to insert this character in pdf with m.Text() with no luck. A . is printed instead.

    Why?

    Additional details:

    • OS: Windows 10
    • github.com/johnfercher/maroto v0.36.1
    question wontfix 
    opened by frederikhors 6
  • It does not support Chinese and Arabic characters.

    It does not support Chinese and Arabic characters.

    I needed to create a document in pdf format with texts in different languages ​​(Chinese, Arabic). Although the Text component uses func (_m *Pdf) UnicodeTranslatorFromDescriptor(cpStr string) func(string) string function, it does not support Chinese or Arabic symbols, and converts them to points in the document created.

    image

    image

    opened by gonzalezlrjesus 5
  • Migrate to Go 1.13 in travis  tests

    Migrate to Go 1.13 in travis tests

    Is your feature request related to a problem? Please describe. 2 months as it's out, I think we should adopt it and run all tests against this version so library users had no issues with newer version of Go.

    Describe the solution you'd like change line with Go version in travis.yml

    Describe alternatives you've considered do not migrate, but I see no issues why don't.

    help wanted good first issue technical debit hacktoberfest 
    opened by SuddenGunter 5
  • All 3 examples broken (panic: runtime error: invalid memory address or nil pointer dereference)

    All 3 examples broken (panic: runtime error: invalid memory address or nil pointer dereference)

    Hello,

    the 3 examples expect to be run from the root directory of the maroto repository. If they are run in another directory, they crash.

    For example:

    $ pwd
    maroto/bin
    
    $ ./sample1
    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0xb0 pc=0x11d4d5d]
    goroutine 1 [running]:
    github.com/jung-kurt/gofpdf.(*ImageInfoType).Width(...)
    	/Users/mmolteni/sync/src/go/pkg/mod/github.com/jung-kurt/[email protected]/def.go:248
    ...
    

    The simplest possible fix is not to ignore errors :-). For example:

     func main() {
        m := pdf.NewMaroto(consts.Portrait, consts.A4)
        //m.SetBorder(true)
    
    -   byteSlices, _ := ioutil.ReadFile("internal/assets/images/biplane.jpg")
    +   byteSlices, err := ioutil.ReadFile("internal/assets/images/biplane.jpg")
    +   if err != nil {
    +       fmt.Println("Got error while opening file:", err)
    +       os.Exit(1)
    +   }
    
    opened by marco-m 5
  • PDF file in IOS is broken

    PDF file in IOS is broken

    Describe the bug Scenario: I am using golang as backend and React as frontend. So in my system react calls for the pdf generator through graphql endpoint and golang generates the pdf and return it to react. now the generated pdf works file in windows and android but as soon as i use Iphone to test it out, the pdf is broken. Could you give me an insight if it could be a problem with the library or may be its a frontend issue so i need to look there?

    • OS: [e.g. IOS]

    Additional context image

    opened by SahaPratik6267 0
  • Emoji fallback support

    Emoji fallback support

    Is your feature request related to a problem? Please describe. When we use the default font, emojis are displayed as □ however, if we use our custom font emojis cause a nil panic.

    Describe the solution you'd like Either dedicated emoji fonts built in or a way to add emoji separate to our normal typeface.

    Describe alternatives you've considered Setting emoji-based fonts as default, this lead to all text being shown as □

    opened by ModdingFriendly 0
  • Possibility to change author, company, keywords and others metadata of a pdf document

    Possibility to change author, company, keywords and others metadata of a pdf document

    A pdf document has properties. However it seems that you can't edit those yet in Maroto. It would be great to have a possibility to define those when creating a pdf. Thank you for consideration and keep up the excellent work.

    opened by Jeannot-Muller 0
  • [FR] TableList: support for text style in individual cell

    [FR] TableList: support for text style in individual cell

    It would be great to apply extra text.Style for individual data cells in TableList.

    Example table to produce with TableList:

    | Col 1 | Col 2 | | --- | --- | | Foo | custom cell style | | Bar | another style | | Baz | Nothing special here |

    opened by Vovan-VE 0
  • TableList wrong row height calculation with Unicode content

    TableList wrong row height calculation with Unicode content

    Describe the bug TableList while calculating row height based on text content internally converts text to cp1252: https://github.com/johnfercher/maroto/blob/609811dca909f444babbb9ab3a520cbb2f080ed4/internal/text.go#L72 https://github.com/jung-kurt/gofpdf/blob/a2a0e7f8a28b2eabe1a32097f0071a0f715a8102/util.go#L275-L277

    That converts any characters out of cp1252 to dots . including for example Cyrillic characters. And so instead of long 3-lines Cyrillic text it has 1-2 lines of dots and spaces like .. . ...... ..... As the result, some rows in the result document may have wrong height.

    Related code:

    m.TableList(
    	[]string{"Lorem", "Ipsum"},
    	[][]string{
    		{"Foo bar", "Lorem ipsum dolor sit amet consectepture adipisicing elit sed do eiusmod tempor incididunt ut labore."},
    		{"Lorem ipsum", "Съешь ещё этих мягких французских булок, да выпей же чаю. Съешь ещё этих мягких французских булок."},
    		{"space", "nothing here"},
    		{"dots", "..... ... .... ...... ........... ....., .. ..... .. .... ..... ... .... ...... ........... ......"},
    	},
    	props.TableList{
    		HeaderProp: props.TableListContent{
    			Size:      8,
    			GridSizes: []uint{2, 3},
    		},
    		ContentProp: props.TableListContent{
    			Size:      8,
    			GridSizes: []uint{2, 3},
    		},
    		VerticalContentPadding: 1,
    		Line:                   true,
    	},
    )
    

    image

    Notice: 4th row's content has same content with dots, as 2nd row's content internally before height calculation. So, row 4 is how row 2 calculated: 2 lines. However, 1st row has correct height to fit 3 lines.

    Expected behavior Correct row height.

    Additional info

    • maroto 0.37.0
    • go 1.16.2
    • May be related to #212.
    opened by Vovan-VE 0
Releases(v0.38.0)
Owner
Johnathan Fercher
Developer, gamer, master of science, enthusiast of robotics and open source contributor. More about: https://github.com/johnfercher/public
Johnathan Fercher
A simple template using Fiber for me to bootstrap API services quickly.

Fiber Template A simple template using Fiber for me to bootstrap API services quickly. Features Fiber GORM air for hot reloading ... and possibly more

Victor Neo 0 Dec 16, 2021
"to be defined" - a really simple way to create text templates with placeholders

tbd "to be defined" A really simple way to create text templates with placeholders. This tool is deliberately simple and trivial, no advanced features

Luca Sepe 20 Aug 6, 2022
Api-go-template - A simple Go API template that uses a controller-service based model to build its routes

api-go-template This is a simple Go API template that uses a controller-service

Pedro Espíndula 1 Feb 18, 2022
Toothpaste is a simple templating engine for Go web applications, inspired by Blade/Twig

A simple HTML templating engine in Go inspired by Twig. Currently supports Variables, Escaping, If statements, Templating and Functional variables.

Mats 3 Jul 24, 2022
Amber is an elegant templating engine for Go Programming Language, inspired from HAML and Jade

amber Notice While Amber is perfectly fine and stable to use, I've been working on a direct Pug.js port for Go. It is somewhat hacky at the moment but

Ekin Koc 896 Aug 13, 2022
Simple and fast template engine for Go

fasttemplate Simple and fast template engine for Go. Fasttemplate performs only a single task - it substitutes template placeholders with user-defined

Aliaksandr Valialkin 624 Aug 6, 2022
A scaffold to quickly create a go project

OpenMix 出品:https://openmix.org Mix CLI 一个快速创建 go 项目的脚手架 A scaffold to quickly create a go project Installation 安装 go get -u github.com/mix-go/mixcli

Mix Go 20 Jul 12, 2022
Create cross-platform GUI apps with Golang + Elm!

README About Create GUI apps with Wails + Elm! Dev env requirements setup a golang toolchain setup a wails toolchain install elm-live globally: npm in

Benjamin Thomas 18 Jun 29, 2022
A handy, fast and powerful go template engine.

Hero Hero is a handy, fast and powerful go template engine, which pre-compiles the html templates to go code. It has been used in production environme

Lime 1.5k Jul 30, 2022
Fast, powerful, yet easy to use template engine for Go. Optimized for speed, zero memory allocations in hot paths. Up to 20x faster than html/template

quicktemplate A fast, powerful, yet easy to use template engine for Go. Inspired by the Mako templates philosophy. Features Extremely fast. Templates

Aliaksandr Valialkin 2.5k Aug 6, 2022
A sane and simple Go REST API template.

Gosane ??‍♀️ A sane and simple Go REST API template. Clone me and edit me to fit your usecase. What is Gosane? Gosane is a cloneable API template to g

Farley 82 Jun 30, 2022
Simple system for writing HTML/XML as Go code. Better-performing replacement for html/template and text/template

Simple system for writing HTML as Go code. Use normal Go conditionals, loops and functions. Benefit from typing and code analysis. Better performance than templating. Tiny and dependency-free.

Nelo Mitranim 4 Apr 13, 2022
Go-basic-skeleton - Simple and basic skeleton for go projects

Go Bootstrap (base/skeleton) Introduction This is a repository intended to serve

Kenrique Ortega 2 Mar 16, 2022
Code your next Go web project with (a) Mojito! No matter if its an API or a website, go-mojito assists you with dependency injection, simple routing, custom request / response objects and template rendering

Go-Mojito is a super-modular library to bootstrap your next Go web project. It can be used for strict API-only purposes as well as server-side renderi

Infinytum 17 May 1, 2022
Simple template suitable for building a webapp backend MVP written in go

A Simple Go Project Template - Suited for Webapp MVPs A simple go project structure setup with all dependencies you need to get your MVP off the groun

El Donaldo 29 Nov 14, 2021
A simple project for demonstrating Temporal with the Go SDK

Temporal Go Project Template This is a simple project for demonstrating Temporal with the Go SDK. The full 20 minute guide is here: https://docs.tempo

Manish Sharma 0 Nov 11, 2021
A simple project for demonstrating Temporal with the Go SDK

Temporal Go Project Template This is a simple project for demonstrating Temporal with the Go SDK. The full 20 minute guide is here: https://docs.tempo

Todd Underwood 0 Oct 4, 2021
This is a simple GoLang script template.

This is a simple GoLang script template.

Vladimir Glusic 0 Jan 29, 2022
Article spinning and spintax/spinning syntax engine written in Go, useful for A/B, testing pieces of text/articles and creating more natural conversations

GoSpin Article spinning and spintax/spinning syntax engine written in Go, useful for A/B, testing pieces of text/articles and creating more natural co

Miles Croxford 39 Aug 7, 2022