->The Tragedy of Macbeth<-
Pseudo-code, compresses Macbeth to 0 bytes

Counter-example (yeah, almost joke) submission intended to point out the flaws with the question.  (the C# was a bit long both in source size and resulting output)

if argument is "compress"
  compare entire input file to the Tragedy of Macbeth
  if equal, then output empty file
  else if input is non-empty,
    then RLE-encode input stream on chr(127) only and output that
  else [if input is empty]
    then RLE-encode a string of zero times chr(127)
else if argument is "decompress"
  if input is empty
  then output the Tragedy of Macbeth
  else RLE-decode input file on chr(127) only and output back


With this approach, Macbeth is brought down to as short a file as possible. Other text input is usually passed untouched, at worst gains a byte per chr(127) which tend not to occur in actual text.