#!/usr/bin/env python3

import argparse,os,random,re,sys

ap=argparse.ArgumentParser(description="Reading from standard input and writing to standard output, scramble the interior of each word found along the way. That might yield something like this: Radeing from stnraadd iupnt and wnitrig to strdanad optuut, srcbamle the iironetr of each word funod aonlg the way.")
ap.add_argument('-n',dest="newline",action="store_false",help="Suppress the newline printed between the scrambled version of any command line words and the strambled version of any text on standard input.")
ap.add_argument('words',nargs=argparse.REMAINDER,help="Any words found on the command line will precede in the output any text found on standard input.")
opt=ap.parse_args()

if not opt.words and sys.stdin.isatty():
  ap.print_help()
  sys.exit(0)

word_pat=re.compile(r'[A-Za-z]+')

def parse_line(s):
  """Return a list of words in the given string separated by the strings
  that separate them. A word is any contiguous group of alphabetic
  characters. Separator strings are anything else."""

  result=[]
  i=k=0
  for m in re.finditer(word_pat,s):
    j,k=m.span()
    if i<j:
      result.append(s[i:j])
    result.append(s[j:k])
    i=k
  if i<len(s):
    result.append(s[k:])
  return result

def scramble_interior(s):
  """For any string of at least four characters, return that string with
  the interior characters mixed randomly."""

  n=len(s)-2
  if n<2:
    return s
  return s[0]+''.join(random.sample(s[1:-1],n))+s[-1]

# Handle any words on our command line.
if opt.words:
  for s in parse_line(' '.join(opt.words)):
    if s[0].isalpha():
      sys.stdout.write(scramble_interior(s))
    else:
      sys.stdout.write(s)
  if opt.newline or sys.stdin.isatty():
    sys.stdout.write('\n')

# Process standard input, but only if it's being redirected.
if not sys.stdin.isatty():
  for line in sys.stdin:
    for s in parse_line(line):
      if s[0].isalpha():
        sys.stdout.write(scramble_interior(s))
      else:
        sys.stdout.write(s)
