go-reloaded
A command-line text editor in Go that reads a file, applies editing instructions written inside the text, cleans up the formatting, and writes the result to a new file.
- Type
- Command-line tool
- Language
- Go, standard library only
- Built at
- 01 Talent Academy, project 1 of 60
- Date
- October 2026
- Team
- Solo project
- Tests
- 48 cases, 7 test functions
Overview
The task was to build a small auto-correction tool. A text file contains notes to the
editor written inline, such as (up, 2) meaning "put the last two words in
capitals", along with common formatting mistakes like spaces before commas or "a"
where "an" belongs. The program has to carry out every instruction, fix the mistakes,
remove the instructions, and save clean text.
It runs from the terminal with an input file and an output file:
Rungo run . sample.txt result.txt
Example
Init (cap) was the best of times, it was the worst of times (up) , it was the age of wisdom
OutIt was the best of times, it was the worst of TIMES, it was the age of wisdom
What it handles
| Rule | What happens | In | Out |
|---|---|---|---|
(hex) (bin) | The word before is converted from hexadecimal or binary to decimal | 1E (hex) | 30 |
(up) (low) (cap) | The word before becomes uppercase, lowercase or capitalised | go (up) | GO |
(up, n) | The same, applied to the previous n words | so exciting (up, 2) | SO EXCITING |
| Punctuation | . , ! ? : ; attach to the word before, with one space after | there ,and | there, and |
| Punctuation groups | ... and !? stay together | thinking ... You | thinking... You |
| Quotes | A pair of ' marks wraps the words between them with no inner spaces | ' awesome ' | 'awesome' |
| Articles | a becomes an before a vowel or h | a amazing rock | an amazing rock |
How it's built
Processing pipeline
- Check argumentsExactly two file names
- Read input file
os.ReadFile - Split into linesEach line handled alone
- Split into words
strings.Fields - Apply modifiershex, bin, up, low, cap
- Fix articlesa to an
- Fix punctuationattach and group
- Fix quotespair and attach
- Join and write
os.WriteFile
Steps 5 to 8 are the editing rules, run on every line in this fixed order.
Why the rules run in this order
- Modifiers first, because they remove instructions and change words, and every later rule must see the final words. In
a (up) apple, the article rule only works once the text readsA apple. - Articles before punctuation, so the rule matches a clean
arather thana,after punctuation is attached. - Punctuation before quotes, so
raincoat . 'becomesraincoat.first and thenraincoat.', which is the correct result.
Code structure
Seven Go files. Each rule is a small function, grouped into files by responsibility. main only calls run(args), which returns an error instead of exiting, so the tests can run the whole program directly.
| File | Responsibility | Key functions |
|---|---|---|
main.go | Entry point: checks arguments, reads the input file, writes the output file, reports errors | main run |
process.go | Splits text into lines and runs the rules on each line in order | processText processLine |
modifiers.go | Recognises and applies (hex), (bin), (up), (low), (cap) and their counted forms | applyModifiers parseModifier changePreviousWords convertToDecimal capitalize |
articles.go | Changes a to an | fixArticles startsWithVowelOrH |
punctuation.go | Attaches punctuation and keeps groups together | fixPunctuation splitLeadingPunctuation |
quotes.go | Pairs quote marks and attaches them to the words inside | fixQuotes isQuoteMark |
main_test.go | Unit tests | 7 test functions |
Design decisions
The brief did not cover every situation. Where it was silent, I chose behaviour that never loses the user's text and matches what a person would expect.
| Situation | Behaviour | Reason |
|---|---|---|
(up, 5) with only two words before it | Changes the two words that exist | No crash; does as much as it can |
(up, -1) or (foo) | Left in the text unchanged | Not a valid instruction, so the program does not guess |
zz (hex), not a valid number | Instruction removed, word kept as written | The user's text is never destroyed |
hello , world (up, 2) | HELLO, WORLD | A lone comma is not counted as a word |
don't | Unchanged | An apostrophe inside a word is not a quote mark |
| Text over several lines | Each line processed separately, line breaks kept | An instruction on one line should not change words on another |
Testing and error handling
The tests live in main_test.go and run with go test. The main
test is table-driven: 48 cases, each with a name, an input and the expected output,
checked by a single loop. They cover every example from the brief plus edge cases found
while testing, such as an empty file, extra spaces, counts larger than the words
available, invalid numbers, mixed punctuation like ?! and two quoted
phrases on one line. Code is formatted with gofmt and checked with
go vet.
| Test | What it proves |
|---|---|
TestProcessText | All 48 text cases, from input to expected output |
TestRunWithFiles | The real program reads and writes files, using a temporary folder that Go removes afterwards |
TestRunErrors | Failure cases: zero, one or three arguments, a missing input file and an output file that cannot be written |
TestUsageMessageText | The usage message is exactly right |
TestParseModifier, TestConvertToDecimal, TestCapitalize | Helper functions on their own, so a failure points straight to the cause |
Errors are reported clearly, with exit code 1
- Wrong number of arguments: prints
usage: go run . <input file> <output file> - Input file missing or unreadable: prints
cannot read input filewith the reason - Output file cannot be written: prints
cannot write output filewith the reason - Empty input produces an empty output file, and Windows line endings are handled
Notes
- Uses only Go's standard library:
os,strings,strconv,unicode,errorsandfmt. - Version control with Git, committing at each working milestone.
- The source code is hosted on 01 Talent Academy's Git server.