-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(spaced): Add spaced utility (#1)
- Loading branch information
Showing
15 changed files
with
541 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
kind: pipeline | ||
name: default | ||
|
||
platform: | ||
os: linux | ||
arch: amd64 | ||
|
||
steps: | ||
- name: lint + test | ||
image: golang:1.11.2 | ||
commands: | ||
- go get -u golang.org/x/lint/golint | ||
- ./scripts/lint-test.sh | ||
when: | ||
event: | ||
exclude: | ||
- pull_request | ||
- tag | ||
|
||
- name: build + package | ||
image: golang:1.11.2 | ||
commands: | ||
- apt-get update && apt-get install --assume-yes zip | ||
- ./scripts/build-package.sh | ||
environment: | ||
OUTDIR: /tmp/dist | ||
volumes: | ||
- name: dist | ||
path: /tmp/dist | ||
when: | ||
event: | ||
exclude: | ||
- pull_request | ||
- tag | ||
|
||
- name: publish | ||
image: node:10.14.0 | ||
commands: | ||
- npx semantic-release | ||
environment: | ||
GITHUB_TOKEN: | ||
from_secret: github/public_repo | ||
# https://github.com/npm/uid-number/issues/7 | ||
NPM_CONFIG_UNSAFE_PERM: true | ||
volumes: | ||
- name: dist | ||
path: /tmp/dist | ||
when: | ||
branch: | ||
- master | ||
event: | ||
- push | ||
|
||
volumes: | ||
- name: dist | ||
temp: {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
.temp/ | ||
.vscode/ | ||
dist/ | ||
vendor/ | ||
|
||
.DS_Store | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
repositoryUrl: [email protected]:72636c/hyperspaced | ||
branch: master | ||
|
||
ci: true | ||
debug: true | ||
|
||
plugins: | ||
- '@semantic-release/commit-analyzer' | ||
- '@semantic-release/release-notes-generator' | ||
- - '@semantic-release/github' | ||
- assets: '/tmp/dist/**' | ||
failComment: false | ||
failTitle: false | ||
labels: false | ||
releasedLabels: false | ||
successComment: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,54 @@ | ||
# H Y P E R S P A C E D | ||
|
||
[![Build Status](https://cloud.drone.io/api/badges/72636c/hyperspaced/status.svg)](https://cloud.drone.io/72636c/hyperspaced) | ||
|
||
Command line utilities to improve the aesthetics of your favourite phrases with | ||
automatic space insertion (ASI). | ||
|
||
## Usage | ||
|
||
### CLI | ||
|
||
Prerequisites: | ||
|
||
- Go 1.11+ | ||
|
||
```shell | ||
go install ./cmd/spaced | ||
``` | ||
|
||
```shell | ||
echo 'gofmt urself' | spaced | ||
``` | ||
|
||
### Go | ||
|
||
```go | ||
import ( | ||
"github.com/72636c/hyperspaced" | ||
) | ||
|
||
hyperspaced.Spaced("gofmt urself") | ||
``` | ||
|
||
## Meta | ||
|
||
### CI/CD pipeline | ||
|
||
Builds and releases are automated with [Drone](https://drone.io/), which is | ||
impressively _"powered by blazing fast bare-metal servers"_, and more | ||
importantly _"written in Go"_. | ||
|
||
### Local scripts | ||
|
||
```shell | ||
./scripts/build-package.sh | ||
``` | ||
|
||
```shell | ||
./scripts/lint-test.sh | ||
``` | ||
|
||
### Mouseprint | ||
|
||
_This is a shameless rip-off of <https://www.npmjs.com/package/letter-spacing>._ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/72636c/hyperspaced/internal/text" | ||
"github.com/72636c/hyperspaced/internal/text/transform" | ||
) | ||
|
||
func main() { | ||
err := text.LineFilter(transform.Spaced) | ||
if err != nil { | ||
fmt.Fprintln(os.Stderr, "error: ", err) | ||
os.Exit(1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module github.com/72636c/hyperspaced | ||
|
||
require golang.org/x/text v0.3.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package hyperspaced | ||
|
||
import ( | ||
"github.com/72636c/hyperspaced/internal/text/transform" | ||
) | ||
|
||
// Spaced inserts a space between each character in a string. | ||
func Spaced(str string) string { | ||
return transform.Spaced(str) | ||
} | ||
|
||
// SpacedN inserts n spaces between each character in a string. | ||
func SpacedN(str string, n int) string { | ||
return transform.SpacedN(str, n) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package text | ||
|
||
import ( | ||
"unicode" | ||
"unicode/utf8" | ||
|
||
"golang.org/x/text/unicode/norm" | ||
) | ||
|
||
// Char represents a character. Whatever that means. | ||
type Char []rune | ||
|
||
func (char Char) String() (str string) { | ||
for _, r := range char { | ||
str += string(r) | ||
} | ||
|
||
return | ||
} | ||
|
||
// SplitString splits a string into a slice of characters. | ||
// | ||
// It's obviously not perfect; don't @ me. | ||
func SplitString(str string) []Char { | ||
var iter norm.Iter | ||
iter.InitString(norm.NFC, str) | ||
|
||
chars := make([]Char, 0) | ||
runes := make([]rune, 0) | ||
|
||
for !iter.Done() { | ||
r, _ := utf8.DecodeRune(iter.Next()) | ||
|
||
if areSeparate(runes, r) { | ||
chars = append(chars, Char(runes)) | ||
runes = []rune{r} | ||
} else { | ||
runes = append(runes, r) | ||
} | ||
} | ||
|
||
if len(runes) == 0 { | ||
return chars | ||
} | ||
|
||
return append(chars, Char(runes)) | ||
} | ||
|
||
func areSeparate(runes []rune, next rune) bool { | ||
if len(runes) == 0 { | ||
return false | ||
} | ||
|
||
previous := runes[len(runes)-1] | ||
|
||
return !isNull(previous) && | ||
!isJoinControl(previous) && | ||
!isJoinControl(next) && | ||
!isModifierSymbol(next) && | ||
!isVariationSelector(next) | ||
} | ||
|
||
// https://www.fileformat.info/info/unicode/char/0000/index.htm | ||
func isNull(r rune) bool { | ||
return r == '\u0000' | ||
} | ||
|
||
// http://unicode.org/reports/tr44/#Join_Control | ||
func isJoinControl(r rune) bool { | ||
return unicode.In(r, unicode.Join_Control) | ||
} | ||
|
||
// http://www.fileformat.info/info/unicode/category/Sk/list.htm | ||
func isModifierSymbol(r rune) bool { | ||
return unicode.In(r, unicode.Sk) | ||
} | ||
|
||
// http://www.unicode.org/charts/PDF/UFE00.pdf | ||
func isVariationSelector(r rune) bool { | ||
return unicode.In(r, unicode.Variation_Selector) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package text_test | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/72636c/hyperspaced/internal/text" | ||
) | ||
|
||
func Test_SplitString(t *testing.T) { | ||
testCases := []struct { | ||
description string | ||
input string | ||
expected []text.Char | ||
}{ | ||
{ | ||
description: "Empty String", | ||
input: "", | ||
expected: []text.Char{}, | ||
}, | ||
{ | ||
description: "One Letter", | ||
input: "f", | ||
expected: []text.Char{text.Char{'f'}}, | ||
}, | ||
{ | ||
description: "Two Letters", | ||
input: "hi", | ||
expected: []text.Char{text.Char{'h'}, text.Char{'i'}}, | ||
}, | ||
{ | ||
description: "Accent Normalisation", | ||
input: "e\u0301", | ||
expected: []text.Char{text.Char{'Γ©'}}, | ||
}, | ||
{ | ||
description: "Separate Emoji", | ||
input: "\U0001f30f\u2696", | ||
expected: []text.Char{text.Char{'π'}, text.Char{'β'}}, | ||
}, | ||
{ | ||
// https://emojipedia.org/family-man-light-skin-tone-woman-light-skin-tone-girl-light-skin-tone-baby-light-skin-tone/ | ||
description: "Sequenced Emoji", | ||
input: "\U0001f468\U0001f3fb\u200d\U0001f469\U0001f3fb\u200d\U0001f467\U0001f3fb\u200d\U0001f476\U0001f3fb", | ||
expected: []text.Char{text.Char{'π¨', 'π»', '\u200d', 'π©', 'π»', '\u200d', 'π§', 'π»', '\u200d', 'πΆ', 'π»'}}, | ||
}, | ||
{ | ||
// https://emojipedia.org/female-sleuth/ | ||
description: "Female Variant Selector", | ||
input: "\U0001f575\ufe0f\u200d\u2640\ufe0f", | ||
expected: []text.Char{text.Char{'π΅', '\ufe0f', '\u200d', 'β', '\ufe0f'}}, | ||
}, | ||
{ | ||
// https://emojipedia.org/female-technologist/ | ||
description: "Join Control", | ||
input: "\U0001f469\u200d\U0001f4bb", | ||
expected: []text.Char{text.Char{'π©', '\u200d', 'π»'}}, | ||
}, | ||
{ | ||
// https://emojipedia.org/man-type-6/ | ||
description: "Skin Tone Modifier", | ||
input: "\U0001f468\U0001f3ff", | ||
expected: []text.Char{text.Char{'π¨', 'πΏ'}}, | ||
}, | ||
} | ||
|
||
for _, testCase := range testCases { | ||
t.Run(testCase.description, func(t *testing.T) { | ||
actual := text.SplitString(testCase.input) | ||
if !reflect.DeepEqual(actual, testCase.expected) { | ||
t.Errorf("expected %+v, received %+v", testCase.expected, actual) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package text | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"os" | ||
) | ||
|
||
// TransformLine is a function that transforms a line of text. | ||
type TransformLine func(string) string | ||
|
||
// LineFilter transforms lines of text as they pass from stdin to stdout. | ||
func LineFilter(transform TransformLine) error { | ||
scanner := bufio.NewScanner(os.Stdin) | ||
|
||
for scanner.Scan() { | ||
output := transform(scanner.Text()) | ||
|
||
_, err := fmt.Println(output) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return scanner.Err() | ||
} |
Oops, something went wrong.