Mohamed Hani Programming
All projects

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

RuleWhat happensInOut
(hex) (bin)The word before is converted from hexadecimal or binary to decimal1E (hex)30
(up) (low) (cap)The word before becomes uppercase, lowercase or capitalisedgo (up)GO
(up, n)The same, applied to the previous n wordsso exciting (up, 2)SO EXCITING
Punctuation. , ! ? : ; attach to the word before, with one space afterthere ,andthere, and
Punctuation groups... and !? stay togetherthinking ... Youthinking... You
QuotesA pair of ' marks wraps the words between them with no inner spaces' awesome ''awesome'
Articlesa becomes an before a vowel or ha amazing rockan amazing rock

How it's built

Processing pipeline

  1. Check argumentsExactly two file names
  2. Read input fileos.ReadFile
  3. Split into linesEach line handled alone
  4. Split into wordsstrings.Fields
  5. Apply modifiershex, bin, up, low, cap
  6. Fix articlesa to an
  7. Fix punctuationattach and group
  8. Fix quotespair and attach
  9. Join and writeos.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 reads A apple.
  • Articles before punctuation, so the rule matches a clean a rather than a, after punctuation is attached.
  • Punctuation before quotes, so raincoat . ' becomes raincoat. first and then raincoat.', 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.

FileResponsibilityKey functions
main.goEntry point: checks arguments, reads the input file, writes the output file, reports errorsmain run
process.goSplits text into lines and runs the rules on each line in orderprocessText processLine
modifiers.goRecognises and applies (hex), (bin), (up), (low), (cap) and their counted formsapplyModifiers parseModifier changePreviousWords convertToDecimal capitalize
articles.goChanges a to anfixArticles startsWithVowelOrH
punctuation.goAttaches punctuation and keeps groups togetherfixPunctuation splitLeadingPunctuation
quotes.goPairs quote marks and attaches them to the words insidefixQuotes isQuoteMark
main_test.goUnit tests7 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.

SituationBehaviourReason
(up, 5) with only two words before itChanges the two words that existNo crash; does as much as it can
(up, -1) or (foo)Left in the text unchangedNot a valid instruction, so the program does not guess
zz (hex), not a valid numberInstruction removed, word kept as writtenThe user's text is never destroyed
hello , world (up, 2)HELLO, WORLDA lone comma is not counted as a word
don'tUnchangedAn apostrophe inside a word is not a quote mark
Text over several linesEach line processed separately, line breaks keptAn 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.

TestWhat it proves
TestProcessTextAll 48 text cases, from input to expected output
TestRunWithFilesThe real program reads and writes files, using a temporary folder that Go removes afterwards
TestRunErrorsFailure cases: zero, one or three arguments, a missing input file and an output file that cannot be written
TestUsageMessageTextThe usage message is exactly right
TestParseModifier, TestConvertToDecimal, TestCapitalizeHelper 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 file with the reason
  • Output file cannot be written: prints cannot write output file with 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, errors and fmt.
  • Version control with Git, committing at each working milestone.
  • The source code is hosted on 01 Talent Academy's Git server.