Initial commit
This commit is contained in:
commit
870b440e87
14
Dockerfile
Normal file
14
Dockerfile
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
FROM jess/inkscape
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y python-lxml python-numpy wget pstoedit unzip
|
||||||
|
|
||||||
|
RUN wget https://golang.org/dl/go1.16.2.linux-amd64.tar.gz && rm -rf /usr/local/go && tar -C /usr/local -xzf go1.16.2.linux-amd64.tar.gz && ln -s /usr/local/go/bin/go /usr/local/bin/go && go version
|
||||||
|
|
||||||
|
RUN wget "https://fonts.google.com/download?family=Fira%20Sans|Lobster|Pacifico|Permanent%20Marker|Roboto|Ceviche%20One|Press%20Start%202P|UnifrakturMaguntia|Zilla%20Slab%20Highlight|Londrina%20Shadow" -O /usr/share/fonts/fonts.zip
|
||||||
|
RUN cd /usr/share/fonts && unzip fonts.zip
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
ADD go.mod go.sum main.go index.html template.svg ./
|
||||||
|
RUN go build -o main main.go
|
||||||
|
|
||||||
|
ENTRYPOINT ["/app/main"]
|
19
LICENSE
Normal file
19
LICENSE
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
MIT License Copyright (c) 2020 - present Marcus Noble
|
||||||
|
|
||||||
|
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 (including the next
|
||||||
|
paragraph) 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.
|
61
Makefile
Normal file
61
Makefile
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
.DEFAULT_GOAL := default
|
||||||
|
|
||||||
|
IMAGE ?= docker.cluster.fun/averagemarcus/text-to-dxf:latest
|
||||||
|
|
||||||
|
.PHONY: test # Run all tests, linting and format checks
|
||||||
|
test: lint check-format run-tests
|
||||||
|
|
||||||
|
.PHONY: lint # Perform lint checks against code
|
||||||
|
lint:
|
||||||
|
@echo "⚠️ 'lint' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: check-format # Checks code formatting and returns a non-zero exit code if formatting errors found
|
||||||
|
check-format:
|
||||||
|
@echo "⚠️ 'check-format' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: format # Performs automatic format fixes on all code
|
||||||
|
format:
|
||||||
|
@echo "⚠️ 'format' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: run-tests # Runs all tests
|
||||||
|
run-tests:
|
||||||
|
@echo "⚠️ 'run-tests' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: fetch-deps # Fetch all project dependencies
|
||||||
|
fetch-deps:
|
||||||
|
@echo "⚠️ 'fetch-deps' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: build # Build the project
|
||||||
|
build: lint check-format fetch-deps
|
||||||
|
@echo "⚠️ 'build' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: docker-build # Build the docker image
|
||||||
|
docker-build:
|
||||||
|
@docker build --tag $(IMAGE) .
|
||||||
|
|
||||||
|
.PHONY: docker-publish # Push the docker image to the remote registry
|
||||||
|
docker-publish:
|
||||||
|
@docker push $(IMAGE)
|
||||||
|
|
||||||
|
.PHONY: run # Run the application
|
||||||
|
run: docker-build
|
||||||
|
@docker run -it -p 8080:8080 $(IMAGE)
|
||||||
|
|
||||||
|
.PHONY: ci # Perform CI specific tasks to perform on a pull request
|
||||||
|
ci:
|
||||||
|
@echo "⚠️ 'ci' unimplemented"
|
||||||
|
|
||||||
|
.PHONY: release # Release the latest version of the application
|
||||||
|
release:
|
||||||
|
@kubectl --namespace text-to-dxf set image deployment text-to-dxf web=docker.cluster.fun/averagemarcus/text-to-dxf:$(SHA)
|
||||||
|
|
||||||
|
.PHONY: help # Show this list of commands
|
||||||
|
help:
|
||||||
|
@echo "text-to-dxf"
|
||||||
|
@echo "Usage: make [target]"
|
||||||
|
@echo ""
|
||||||
|
@echo "target description" | expand -t20
|
||||||
|
@echo "-----------------------------------"
|
||||||
|
@grep '^.PHONY: .* #' Makefile | sed 's/\.PHONY: \(.*\) # \(.*\)/\1 \2/' | expand -t20
|
||||||
|
|
||||||
|
default: test build
|
52
README.md
Normal file
52
README.md
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
![text-to-dxf](logo.png)
|
||||||
|
|
||||||
|
> Create a .dxf file containing the provided text
|
||||||
|
|
||||||
|
Available at https://text-to-dxf.cluster.fun/
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
Runs a webserver that takes in an `?text=` query string and then returns it as a .dxf.
|
||||||
|
|
||||||
|
Optionally a `?font=` can be provided, current available fonts are:
|
||||||
|
|
||||||
|
* Roboto
|
||||||
|
* Fira Sans
|
||||||
|
* Lobster
|
||||||
|
* Pacifico
|
||||||
|
* Permanent Marker
|
||||||
|
* Ceviche One
|
||||||
|
* Londrina Shadow
|
||||||
|
* Press Start 2P
|
||||||
|
* UnifrakturMaguntia
|
||||||
|
* Zilla Slab Highlight
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker run -it --rm -p 8080:8080 docker.cluster.fun/averagemarcus/text-to-dxf
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building from source
|
||||||
|
|
||||||
|
With Docker:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make docker-build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
* [inkscape](https://inkscape.org/)
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
If you find a bug or have an idea for a new feature please raise an issue to discuss it.
|
||||||
|
|
||||||
|
Pull requests are welcomed but please try and follow similar code style as the rest of the project and ensure all tests and code checkers are passing.
|
||||||
|
|
||||||
|
Thank you 💛
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
See [LICENSE](LICENSE)
|
5
go.mod
Normal file
5
go.mod
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module text-to-dxf
|
||||||
|
|
||||||
|
go 1.16
|
||||||
|
|
||||||
|
require github.com/spf13/afero v1.6.0
|
20
go.sum
Normal file
20
go.sum
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||||
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
|
||||||
|
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
105
index.html
Normal file
105
index.html
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset='utf-8'>
|
||||||
|
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>text-to-dxf</title>
|
||||||
|
|
||||||
|
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 473.7 473.7' stroke='%2327162a' stroke-width='2'%3E%3Ccircle cx='236.8' cy='236.8' r='236.8' fill='%2371cad1'/%3E%3Cpath d='M144.3 93.7a16 16 0 00-16 16v255.6a16 16 0 0016 16H328a16 16 0 0016-16V167.7l-77-74H144.3z' fill='%23ef71a8'/%3E%3Cg%3E%3Cpath d='M344 167.7h-61a16 16 0 01-16-16v-58l77 74z' fill='%23ef71a8'/%3E%3Cpath d='M263.8 271.6c0 10.2-8.2 18.4-18.4 18.4H110.8a18.4 18.4 0 01-18.4-18.4v-56.3c0-10.2 8.2-18.4 18.4-18.4h134.6c10.2 0 18.4 8.2 18.4 18.4v56.3z' fill='%23ef71a8'/%3E%3C/g%3E%3Cg%3E%3Cpath d='M135 226.6h9.8c2.6 0 4.8.3 6.7.8 1.8.4 3.5 1.3 5 2.6 3.9 3.4 5.8 8.5 5.8 15.3a30 30 0 01-.6 6.1 16.9 16.9 0 01-5 9 13 13 0 01-7 3.4c-1.4.2-3 .3-4.7.3h-9.9c-1.4 0-2.4-.2-3.1-.6a3 3 0 01-1.4-1.8c-.2-.7-.3-1.7-.3-3v-27.4c0-1.6.4-2.8 1.1-3.6.7-.7 2-1 3.5-1zm2.9 6v25.5h5.7l3-.1c.7 0 1.5-.3 2.2-.5a6 6 0 002-1.2c2.6-2.1 3.8-5.8 3.8-11 0-3.8-.5-6.5-1.6-8.4a7.4 7.4 0 00-4.2-3.5 20 20 0 00-5.9-.8h-5z' fill='%23fff'/%3E%3Cpath d='M167.6 256.8l8.4-12.2-7-10.9c-.7-1-1.2-2-1.5-2.7-.4-.8-.5-1.5-.5-2.2 0-.7.3-1.4 1-2 .6-.5 1.3-.8 2.3-.8 1 0 1.8.3 2.4 1 .6.6 1.4 1.7 2.5 3.4l5.6 9.1 6-9.1 1.3-2c.3-.5.6-1 1-1.3.3-.4.7-.6 1-.8.4-.2 1-.3 1.4-.3 1 0 1.8.3 2.4.9.6.5.9 1.2.9 2 0 1.1-.7 2.7-2 4.6l-7.4 11 8 12.3 1.5 2.7c.3.7.5 1.4.5 2 0 .6-.1 1.2-.4 1.6s-.7 1-1.2 1.2a3.5 3.5 0 01-3.6 0c-.5-.3-1-.7-1.2-1.1l-1.8-2.6-6.5-10.4-7 10.7a80.3 80.3 0 01-2 2.8 3.6 3.6 0 01-2.8 1c-.9 0-1.6-.2-2.2-.8-.7-.5-1-1.4-1-2.4 0-1.3.7-2.8 2-4.7z' fill='%23fff'/%3E%3Cpath d='M223 232.5h-15v9.6h12.6c1.1 0 2 .2 2.6.8.5.5.8 1.2.8 2s-.3 1.6-.9 2.1c-.5.5-1.4.8-2.5.8H208V260c0 1.6-.4 2.8-1.1 3.5-.7.8-1.6 1.2-2.7 1.2s-2-.4-2.8-1.2c-.7-.8-1-2-1-3.5v-28.8c0-1.1.1-2 .5-2.7a3 3 0 011.5-1.5c.7-.3 1.5-.5 2.6-.5h18a4 4 0 012.6.8c.6.6.9 1.3.9 2.2 0 .8-.3 1.6-.9 2-.6.6-1.5.9-2.7.9z' fill='%23fff'/%3E%3C/g%3E%3C/svg%3E">
|
||||||
|
|
||||||
|
<meta property="og:title" content="text-to-dxf">
|
||||||
|
<meta property="og:site_name" content="text-to-dxf">
|
||||||
|
<meta property="og:url" content="https://text-to-dxf.cluster.fun">
|
||||||
|
<meta property="og:description" content="Create .dxf for the given text">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta name="twitter:creator" content="@Marcus_Noble_" />
|
||||||
|
<meta name="twitter:image" content="https://opengraph.cluster.fun/opengraph/?siteTitle=&title=&tags=&image=https%3A%2F%2Fcdn.githubraw.com%2FAverageMarcus%2Ftext-to-dxf%2Fmain%2Flogo.png&twitter=Marcus_Noble_&github=AverageMarcus%2Ftext-to-dxf&website=https%3A%2F%2Ftext-to-dxf.cluster.fun&bgColor=%23ffffff&fgColor=%23263943">
|
||||||
|
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.css">
|
||||||
|
<link rel="stylesheet" href="https://githubraw.com/AverageMarcus/milligram/master/dist/milligram.min.css">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
#font, #text {
|
||||||
|
font-family: Roboto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@500&family=Lobster&family=Pacifico&family=Permanent+Marker&family=Roboto:wght@400;700&display=swap" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="heading-fancy">
|
||||||
|
text-to-dxf
|
||||||
|
<svg style="height: 50px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 473.7 473.7" stroke="#27162a" stroke-width="4"><circle cx="236.8" cy="236.8" r="236.8" fill="#71cad1"/><path d="M144.3 93.7a16 16 0 00-16 16v255.6a16 16 0 0016 16H328a16 16 0 0016-16V167.7l-77-74H144.3z" fill="#ef71a8"/><g><path d="M344 167.7h-61a16 16 0 01-16-16v-58l77 74z" fill="#ef71a8"/><path d="M263.8 271.6c0 10.2-8.2 18.4-18.4 18.4H110.8a18.4 18.4 0 01-18.4-18.4v-56.3c0-10.2 8.2-18.4 18.4-18.4h134.6c10.2 0 18.4 8.2 18.4 18.4v56.3z" fill="#ef71a8"/></g><g><path d="M135 226.6h9.8c2.6 0 4.8.3 6.7.8 1.8.4 3.5 1.3 5 2.6 3.9 3.4 5.8 8.5 5.8 15.3a30 30 0 01-.6 6.1 16.9 16.9 0 01-5 9 13 13 0 01-7 3.4c-1.4.2-3 .3-4.7.3h-9.9c-1.4 0-2.4-.2-3.1-.6a3 3 0 01-1.4-1.8c-.2-.7-.3-1.7-.3-3v-27.4c0-1.6.4-2.8 1.1-3.6.7-.7 2-1 3.5-1zm2.9 6v25.5h5.7l3-.1c.7 0 1.5-.3 2.2-.5a6 6 0 002-1.2c2.6-2.1 3.8-5.8 3.8-11 0-3.8-.5-6.5-1.6-8.4a7.4 7.4 0 00-4.2-3.5 20 20 0 00-5.9-.8h-5z" fill="#fff"/><path d="M167.6 256.8l8.4-12.2-7-10.9c-.7-1-1.2-2-1.5-2.7-.4-.8-.5-1.5-.5-2.2 0-.7.3-1.4 1-2 .6-.5 1.3-.8 2.3-.8 1 0 1.8.3 2.4 1 .6.6 1.4 1.7 2.5 3.4l5.6 9.1 6-9.1 1.3-2c.3-.5.6-1 1-1.3.3-.4.7-.6 1-.8.4-.2 1-.3 1.4-.3 1 0 1.8.3 2.4.9.6.5.9 1.2.9 2 0 1.1-.7 2.7-2 4.6l-7.4 11 8 12.3 1.5 2.7c.3.7.5 1.4.5 2 0 .6-.1 1.2-.4 1.6s-.7 1-1.2 1.2a3.5 3.5 0 01-3.6 0c-.5-.3-1-.7-1.2-1.1l-1.8-2.6-6.5-10.4-7 10.7a80.3 80.3 0 01-2 2.8 3.6 3.6 0 01-2.8 1c-.9 0-1.6-.2-2.2-.8-.7-.5-1-1.4-1-2.4 0-1.3.7-2.8 2-4.7z" fill="#fff"/><path d="M223 232.5h-15v9.6h12.6c1.1 0 2 .2 2.6.8.5.5.8 1.2.8 2s-.3 1.6-.9 2.1c-.5.5-1.4.8-2.5.8H208V260c0 1.6-.4 2.8-1.1 3.5-.7.8-1.6 1.2-2.7 1.2s-2-.4-2.8-1.2c-.7-.8-1-2-1-3.5v-28.8c0-1.1.1-2 .5-2.7a3 3 0 011.5-1.5c.7-.3 1.5-.5 2.6-.5h18a4 4 0 012.6.8c.6.6.9 1.3.9 2.2 0 .8-.3 1.6-.9 2-.6.6-1.5.9-2.7.9z" fill="#fff"/></g></svg>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
Create a .dxf file for the given text
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<form method="GET" action="/" class="column column-80 column-offset-10">
|
||||||
|
<fieldset>
|
||||||
|
<label>
|
||||||
|
Font
|
||||||
|
<select id="font" name="font">
|
||||||
|
<option value="Roboto">Roboto</option>
|
||||||
|
<option value="Fira Sans">Fira Sans</option>
|
||||||
|
<option value="Lobster">Lobster</option>
|
||||||
|
<option value="Pacifico">Pacifico</option>
|
||||||
|
<option value="Permanent Marker">Permanent Marker</option>
|
||||||
|
<option value="Ceviche One">Ceviche One</option>
|
||||||
|
<option value="Londrina Shadow">Londrina Shadow</option>
|
||||||
|
<option value="Press Start 2P">Press Start 2P</option>
|
||||||
|
<option value="UnifrakturMaguntia">UnifrakturMaguntia</option>
|
||||||
|
<option value="Zilla Slab Highlight">Zilla Slab Highlight</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Text
|
||||||
|
<textarea id="text" name="text"></textarea>
|
||||||
|
</label>
|
||||||
|
<input type="submit" value="Create" />
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
Source code available on <a href="https://github.com/AverageMarcus/text-to-dxf" target="_blank" rel="noopener noreferrer">GitHub</a>, <a href="https://gitlab.com/AverageMarcus/text-to-dxf" target="_blank" rel="noopener noreferrer">GitLab</a>, <a href="https://bitbucket.org/AverageMarcus/text-to-dxf/" target="_blank" rel="noopener noreferrer">Bitbucket</a> & <a href="https://git.cluster.fun/AverageMarcus/text-to-dxf" target="_blank" rel="noopener noreferrer">my own Gitea server</a>.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="column column-60 column-offset-20">
|
||||||
|
<footer>
|
||||||
|
Made with
|
||||||
|
<svg height="20" class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 449.3 449.3" xmlns:xlink="http://www.w3.org/1999/xlink"><title>love</title><g><path d="M0 162.7c1.5-7.7 2.7-15.4 4.5-23A125.5 125.5 0 0132 88a136.3 136.3 0 0162.7-40.6c8.3-2.9 17.7-3.2 26.6-3.7a134 134 0 0155.6 6.6c14.9 5.7 30 11 41 23.6 17-20 36.4-36.3 60-46.4 12-5.2 25.7-6.9 38.7-9.4a79.4 79.4 0 0140.3 3.2 96.4 96.4 0 0143.2 26 209.8 209.8 0 0137.8 55.4 133.2 133.2 0 0111 65.7c-3.2 42.2-21 79-41.5 114.8a431.2 431.2 0 01-47.6 64.3c-19.6 23-39.7 45.7-59.6 68.5-3.7 4.3-7.2 9-11.7 12.4-7.3 5.4-15.9 4.9-23.8 1.5-21.9-9.2-43.8-18.5-65.3-28.5a520.1 520.1 0 01-98-58.7c-28.2-21.5-55.5-44.3-74-75.3a183.8 183.8 0 01-25-61.4c-1-6.2-1.6-12.6-2.4-18.8v-24.5zM138 281l2.5.1c0 2.1.3 4.3 0 6.3l-9 55.5c-.3 1.6 0 4.2 1 5 5.8 4.1 11.8 7.8 17.9 11.8l11-59.7 2.5.3c3.7 21.6-6.3 42-7.6 63.5l19.4 9.6c.5-18 2.2-35 6.9-51.6 1.3 4 1.5 8 1.2 12-.7 11.2-1 22.5-2.6 33.7-1 7.3 1.9 10.6 8 13.3 27 11.7 54.1 23.5 81 35.7 5.5 2.5 8.8 1.5 12.6-2.9 12.5-14.4 25.7-28.1 38-42.7 17.2-20.2 34.5-40.5 50.5-61.7 29.5-39.2 52.7-81.7 61-131 3.6-21.7 2-43-5.6-63.5a176 176 0 00-33.9-54.5 84.8 84.8 0 00-38-26 91.2 91.2 0 00-44.2-2.5c-13 2-25.6 5.1-37.2 12.3a208.6 208.6 0 00-45.9 37c-5.7 6.3-7.8 6.4-15 1.4-5.7-4-11-8.8-17.2-11.9-15.1-7.5-30.7-14.4-48-14.9-13.7-.4-28-2-41.2 1-36 8.4-62.7 30-80.3 62.8a111 111 0 00-11.7 56.6c.3 10 1.4 20 2.2 29.9 7-18.9 11-38.3 19.7-56.3.6 3 .6 6 0 8.7l-14.5 53.2c-.7 2.6-2 5.7-1.2 8 2.7 8.4 6.2 16.6 9.4 24.8 0-20 13.7-63.9 21.8-66.8 0 .6.3 1.1.2 1.6a11936 11936 0 01-17 64c-.3 1.4-1.6 2.6-2.9 4.5l9.7 17a573 573 0 0120-67.3l2.9.7c-1 5-1.5 10-2.8 14.9-4.7 17.2-9.6 34.3-14.2 51.5-.7 2.5-1.5 6-.3 7.8 3.6 5.6 8 10.7 12.4 16.1 1.8-8.6 3.1-16.6 5.2-24.4 3.1-11.5 6.6-22.9 10.2-34.3.8-2.6 2.7-5 4-7.4l2 .8c-.1 1.6-.1 3.4-.5 5l-12.2 47.4c-4.6 17.9-4.3 18.9 7.8 29.4 2.2 1.8 4.5 3.5 7 5.3 3.7-31 12.5-64.7 18.4-68-.3 3.5-.3 6.6-.9 9.6l-12.7 58.8c-.3 1.2-.7 3-.1 3.5 4.7 4.4 9.6 8.6 14.5 12.9 3.5-21.4 7.6-41.7 13.6-61.6 3.4 8.7.6 17-.8 25.2-1.9 11.6-4.5 23.1-6.5 34.7-.4 2.3-.4 6 1 7 4.8 4.2 10.3 7.4 16 11.3 3.9-21.5 5.5-42.6 12.6-62.5z"/><path d="M323.2 180.5a24 24 0 01-24.5-19.7c-2-9.7.7-20.2 15-27 16.6-7.8 38.3 2.3 41.6 19.5 1.2 6.6-1.6 12.1-6 16.3a35.1 35.1 0 01-26 11z"/><path d="M138.9 167.1a31 31 0 0125 12.7 22 22 0 01-13.6 34.9 29.9 29.9 0 01-31-9.9c-6-7-7.6-15.3-4.1-24.1 3.7-9.5 12-12 21-13.5.8-.2 1.8 0 2.7 0z"/><path d="M233.2 202c-18.5-.4-33.7-13.6-34-29.7 0-4.2.4-8 5.4-8.7 4.5-.7 6.6 2.3 8 6 2.3 6.6 5.5 12.4 12.4 15.4 7.5 3.2 14 1.5 20.4-3.3 6.2-4.7 6.4-11 4.7-17.5-1.4-5.2.4-8.4 4.7-10.2 4.3-1.7 9 1.3 10.9 6.2 7.2 19.8-5.7 34.6-22.8 40.2-3 1-6.5 1-9.7 1.6z"/><path d="M201.2 384.7c-.9-2-2.7-4.2-2.5-6.2 1.2-14 2.8-28.1 4.4-42.2 0-.9.7-1.7 1-2.6l2.6 1.1-3.1 49.1-2.4.8z"/><path d="M222 387.4c-4.8-5.7-5-15-1-37.8 3.1 3 4 30.5 1 37.8z"/><path d="M240.9 361.7l-1.4 20.2c-4.8-3.3-4.6-11.9-.2-20.4l1.6.2z"/><path d="M257.4 380.4c-4.1-5.2-3.7-9.7 1-14.7l-1 14.7z"/></g></svg>
|
||||||
|
by <a href="https://marcusnoble.co.uk" class="fancy-link">Marcus Noble</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.getElementById('font').addEventListener('change', function() {
|
||||||
|
document.getElementById('font').style.fontFamily = document.getElementById('font').value;
|
||||||
|
document.getElementById('text').style.fontFamily = document.getElementById('font').value;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
104
main.go
Normal file
104
main.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/afero"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed index.html template.svg
|
||||||
|
var content embed.FS
|
||||||
|
|
||||||
|
var port = os.Getenv("PORT")
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rand.Seed(time.Now().UTC().UnixNano())
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if port == "" {
|
||||||
|
port = "8080"
|
||||||
|
}
|
||||||
|
|
||||||
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
text := r.URL.Query().Get("text")
|
||||||
|
font := r.URL.Query().Get("font")
|
||||||
|
|
||||||
|
if text == "" {
|
||||||
|
body, _ := content.ReadFile("index.html")
|
||||||
|
w.Write(body)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dxf, err := createDXF(text, font)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(w, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("Converted to DXF")
|
||||||
|
|
||||||
|
w.Header().Add("Content-Type", "application/octet-stream")
|
||||||
|
w.Header().Add("Content-Length", fmt.Sprint(len(dxf)))
|
||||||
|
w.Header().Add("Content-Disposition", fmt.Sprintf("inline; filename=%s.dxf", randomString(7)))
|
||||||
|
fmt.Fprintf(w, string(dxf))
|
||||||
|
})
|
||||||
|
|
||||||
|
fmt.Println(http.ListenAndServe(":"+port, nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
func createDXF(text, font string) ([]byte, error) {
|
||||||
|
fs := afero.NewOsFs()
|
||||||
|
afs := &afero.Afero{Fs: fs}
|
||||||
|
svgFile, _ := afs.TempFile(".", "*.svg")
|
||||||
|
epsFile, _ := afs.TempFile(".", "*.eps")
|
||||||
|
dxfFile, _ := afs.TempFile(".", "*.dxf")
|
||||||
|
|
||||||
|
err := template.
|
||||||
|
Must(
|
||||||
|
template.
|
||||||
|
New("template.svg").
|
||||||
|
Funcs(template.FuncMap{
|
||||||
|
"offset": func(i int) int {
|
||||||
|
return i * 30
|
||||||
|
},
|
||||||
|
"font": func() string {
|
||||||
|
return font
|
||||||
|
},
|
||||||
|
}).
|
||||||
|
ParseFS(content, "template.svg")).
|
||||||
|
Execute(svgFile, strings.Split(text, "\n"))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command("inkscape", "-E", epsFile.Name(), svgFile.Name())
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cmd = exec.Command("pstoedit", "-q", "-dt", "-f", "dxf:-polyaslines -mm", epsFile.Name(), dxfFile.Name())
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return afs.ReadFile(dxfFile.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
func randomString(n int) string {
|
||||||
|
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||||
|
|
||||||
|
s := make([]rune, n)
|
||||||
|
for i := range s {
|
||||||
|
s[i] = letters[rand.Intn(len(letters))]
|
||||||
|
}
|
||||||
|
return string(s)
|
||||||
|
}
|
7
template.svg
Normal file
7
template.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg style="width: 100%; margin: 0 auto;background: #ffffff;" preserveAspectRatio="xMinYMid meet">
|
||||||
|
{{range $i, $val := .}}
|
||||||
|
<text font-family="{{ font }}" fill="#000000" font-size="35" y="{{offset $i}}">{{ $val }}</text>
|
||||||
|
{{end}}
|
||||||
|
</svg>
|
After Width: | Height: | Size: 392 B |
Loading…
Reference in New Issue
Block a user