PathrockNetwork Gno Explorer
HomeBlocksTransactionsRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/moul/x/daily/piglatin/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
moul / x / daily / piglatin
Files
3 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/moul/x/daily/piglatin/v0
gno
0.9

Files (3)

  • README.mdmarkdown
  • gnomod.tomltoml
  • piglatin.gnogno
piglatin.gnogno
1// Package piglatin ports the classic "Pig Latin" translator — a staple Go2// beginner exercise — to gno.land as a reusable pure package.3//4// Rules implemented (the standard English game):5//   - A word that starts with a vowel gets "way" appended:   "apple" -> "appleway"6//   - A word that starts with one or more consonants has that leading7//     consonant cluster moved to the end, followed by "ay":  "string" -> "ingstray"8//   - "y" acts as a consonant only when it is the first letter of the word9//     ("yellow" -> "ellowyay"); elsewhere it counts as a vowel ("myth" -> "ythmay").10//   - Original capitalization of the word is preserved (title-case in, title-case11//     out): "Hello" -> "Ellohay".12//   - Trailing/leading punctuation attached to a word is preserved in place:13//     "Hello," -> "Ellohay,".14//15// Everything is pure strings/unicode — deterministic and reproducible on-chain.16//17// A live demo of this package (an interactive sentence translator) is at18// [r/moul/x/daily/piglatindemo](/r/moul/x/daily/piglatindemo/v0).19package piglatin2021import (22	"strings"23	"unicode"24)2526const suffixVowel = "way"27const suffixConsonant = "ay"2829func isVowel(r rune) bool {30	switch unicode.ToLower(r) {31	case 'a', 'e', 'i', 'o', 'u':32		return true33	}34	return false35}3637// isLetter reports whether r is an ASCII/unicode letter (word character).38func isLetter(r rune) bool {39	return unicode.IsLetter(r)40}4142// translateWord converts a single "core" alphabetic word (no surrounding43// punctuation) to Pig Latin, preserving its capitalization pattern.44func translateWord(word string) string {45	if word == "" {46		return word47	}48	runes := []rune(word)4950	// Find the leading consonant cluster. 'y' is a consonant only in position 0.51	start := 052	for i, r := range runes {53		if isVowel(r) {54			break55		}56		// 'y' after the first letter behaves like a vowel: stop the cluster.57		if i > 0 && unicode.ToLower(r) == 'y' {58			break59		}60		start = i + 161	}6263	var out []rune64	if start == 0 {65		// Starts with a vowel.66		out = append(out, runes...)67		out = append(out, []rune(suffixVowel)...)68	} else if start >= len(runes) {69		// All consonants (no vowel found), e.g. "shh" — just append "ay".70		out = append(out, runes...)71		out = append(out, []rune(suffixConsonant)...)72	} else {73		out = append(out, runes[start:]...)74		out = append(out, runes[:start]...)75		out = append(out, []rune(suffixConsonant)...)76	}7778	return applyCase(word, string(out))79}8081// applyCase re-applies the capitalization shape of the original word to the82// translated word. Two common shapes are handled: ALL CAPS and Title-case;83// everything else is returned lowercase.84func applyCase(orig, translated string) string {85	origRunes := []rune(orig)86	if len(origRunes) == 0 {87		return translated88	}8990	// Count letters and uppercase letters in the original.91	letters, uppers := 0, 092	for _, r := range origRunes {93		if unicode.IsLetter(r) {94			letters++95			if unicode.IsUpper(r) {96				uppers++97			}98		}99	}100101	low := strings.ToLower(translated)102	switch {103	case letters > 0 && uppers == letters && letters > 1:104		// ALL CAPS -> keep upper.105		return strings.ToUpper(low)106	case unicode.IsUpper(origRunes[0]):107		// Title-case -> capitalize first letter of the result.108		tr := []rune(low)109		if len(tr) > 0 {110			tr[0] = unicode.ToUpper(tr[0])111		}112		return string(tr)113	default:114		return low115	}116}117118// splitAffixes separates a token into (leading punctuation, core word,119// trailing punctuation) where the core is the contiguous run of letters120// (apostrophes inside are kept as part of the core, e.g. "don't").121func splitAffixes(token string) (string, string, string) {122	runes := []rune(token)123	i := 0124	for i < len(runes) && !isLetter(runes[i]) {125		i++126	}127	j := len(runes)128	for j > i && !isLetter(runes[j-1]) {129		j--130	}131	if i >= j {132		return token, "", "" // no letters at all133	}134	return string(runes[:i]), string(runes[i:j]), string(runes[j:])135}136137// TranslateToken translates a single whitespace-delimited token, preserving138// any punctuation glued to its edges.139func TranslateToken(token string) string {140	lead, core, trail := splitAffixes(token)141	if core == "" {142		return token143	}144	return lead + translateWord(core) + trail145}146147// Translate applies Pig Latin to every word in the sentence while preserving148// the original whitespace between words.149func Translate(sentence string) string {150	var b strings.Builder151	var word strings.Builder152	flush := func() {153		if word.Len() > 0 {154			b.WriteString(TranslateToken(word.String()))155			word.Reset()156		}157	}158	for _, r := range sentence {159		if unicode.IsSpace(r) {160			flush()161			b.WriteRune(r)162			continue163		}164		word.WriteRune(r)165	}166	flush()167	return b.String()168}169

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.