Skip to content

Commit

Permalink
Add support for prefixes
Browse files Browse the repository at this point in the history
  • Loading branch information
jdkato committed Feb 26, 2024
1 parent 7d9342b commit 9623646
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 16 deletions.
19 changes: 18 additions & 1 deletion strcase/opt.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,17 @@ type IndicatorFunc func(word string, idx int) bool

// CaseOpts is a struct that holds the options for a CaseConverter.
type CaseOpts struct {
vocab []string
// A prefix to match before converting the string.
//
// Example:
//
// a. This is a sentence.
prefix string

// A list of words to specifying how to capitalize them.
vocab []string

// A function that determines whether or not a word should be capitalized.
indicator IndicatorFunc
}

Expand All @@ -31,3 +41,10 @@ func UsingIndicator(indicator IndicatorFunc) CaseOptFunc {
opts.indicator = indicator
}
}

// UsingPrefix sets the prefix for the CaseConverter.
func UsingPrefix(prefix string) CaseOptFunc {
return func(opts *CaseOpts) {
opts.prefix = prefix
}
}
12 changes: 11 additions & 1 deletion strcase/sentence.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package strcase

import (
"fmt"
"regexp"
"strings"

"github.com/errata-ai/regexp2"
Expand Down Expand Up @@ -37,6 +38,7 @@ func NewSentenceConverter(opts ...CaseOptFunc) *SentenceConverter {

sent.vocab = base.vocab
sent.indicator = base.indicator
sent.prefix = base.prefix

return sent
}
Expand All @@ -45,6 +47,14 @@ func NewSentenceConverter(opts ...CaseOptFunc) *SentenceConverter {
func (sc *SentenceConverter) Convert(s string) string {
var made []string

prefix := ""
if sc.prefix != "" {
if prefixRe := regexp.MustCompile(sc.prefix); prefixRe.MatchString(s) {
prefix = prefixRe.FindString(s)
s = strings.TrimPrefix(s, prefix)
}
}

ps := `[\p{N}\p{L}*]+[^\s]*`
if len(sc.vocab) > 0 {
ps = fmt.Sprintf(`\b(?:%s)\b|%s`, strings.Join(sc.vocab, "|"), ps)
Expand All @@ -71,7 +81,7 @@ func (sc *SentenceConverter) Convert(s string) string {
}
}

return strings.Join(made, " ")
return prefix + strings.Join(made, " ")
}

func (sc *SentenceConverter) inVocab(s string) string {
Expand Down
19 changes: 11 additions & 8 deletions strcase/sentence_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var vocabCases = []testCase{
{"macOS 15: What's new", "macOS 15: What's new"},
{"Configuration", "Configuration"},
{"Six NASA Instruments Will Fly to Moon on Intuitive Machines Lander", "Six NASA instruments will fly to Moon on intuitive machines lander"},
{"b. Next title text", "b. Next title text"},
}

func TestSentence(t *testing.T) {
Expand All @@ -34,14 +35,16 @@ func TestSentence(t *testing.T) {
}

func TestVocab(t *testing.T) {
tc := strcase.NewSentenceConverter(strcase.UsingVocab([]string{
"Vale Server",
"\bI\b",
"macOS",
"[Cc]onfig",
"NASA",
"Moon",
}))
tc := strcase.NewSentenceConverter(
strcase.UsingVocab([]string{
"Vale Server",
"\bI\b",
"macOS",
"[Cc]onfig",
"NASA",
"Moon",
}),
strcase.UsingPrefix(`^[a-z]\.\s`))

for _, test := range vocabCases {
sent := tc.Convert(test.Input)
Expand Down
11 changes: 10 additions & 1 deletion strcase/title.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,29 @@ func NewTitleConverter(style IgnoreFunc, opts ...CaseOptFunc) *TitleConverter {

title.vocab = base.vocab
title.indicator = base.indicator
title.prefix = base.prefix

return title
}

// Convert returns a copy of the string s in title case format.
func (tc *TitleConverter) Convert(s string) string {
prefix := ""
if tc.prefix != "" {
if prefixRe := regexp.MustCompile(tc.prefix); prefixRe.MatchString(s) {
prefix = prefixRe.FindString(s)
s = strings.TrimPrefix(s, prefix)
}
}

idx, pos := 0, 0
t := sanitizer.Replace(s)
end := len(t)

tags := tagger.Tag(splitRE.FindAllString(strings.ToLower(s), -1))
widx := -1

return splitRE.ReplaceAllStringFunc(s, func(m string) string {
return prefix + splitRE.ReplaceAllStringFunc(s, func(m string) string {
widx += 1

sm := strings.ToLower(m)
Expand Down
13 changes: 8 additions & 5 deletions strcase/title_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,17 @@ var vocabTitles = []testCase{
{"Getting started with iOS 15", "Getting Started With iOS 15"},
{"Understanding json and yaml", "Understanding JSON and YAML"},
{"Develop File-Proxy Plugin", "Develop File-Proxy Plugin"},
{"b. Next title text", "b. Next Title Text"},
}

func TestTitleVocab(t *testing.T) {
tc := strcase.NewTitleConverter(strcase.APStyle, strcase.UsingVocab([]string{
"iOS",
"JSON",
"YAML",
}))
tc := strcase.NewTitleConverter(strcase.APStyle,
strcase.UsingVocab([]string{
"iOS",
"JSON",
"YAML",
}),
strcase.UsingPrefix(`^[a-z]\.\s`))

for _, test := range vocabTitles {
sent := tc.Convert(test.Input)
Expand Down

0 comments on commit 9623646

Please sign in to comment.