#! /usr/bin/python

##################################################
#
# My english is not very well. Where there is '??'
# I haven't found the real words or phrase.
#
# Actual information:
# Friss információk: www.szgti.bmf.hu/~ahorvath/feladatsor
#
# It's a python program. It makes exercise-series.
# There is Python in the most of linux CD-s.
# For windows, macintosh etc.: www.python.org
#
# Kezdeti próbálkozások egy feladatsor feldolgozó programhoz
# A szükséges formátum:
#
# \begin{feladat}[<feladat_sorszám>]
# <A_feladat_szövege>
# \megold{<A_megoldás_szövege>}
# \end{feladat}
#
#  Horváth Árpád 2001.
#
####################################################

import re  # I need it for work with regular expression.

########################################################
#
#  Default values. Change it, if you want.
#  Alapbeállítások. Változtasd meg, ha gondolod.
#
########################################################
#The numbers of exercises
#If it is empty, the program will ask it:
exercise_numbers=[
		['A',1,5,21,2],
		['B',6,4,2,11]
		]
# If you want to give numbers in the programm
# remove the '#' in the beginning of the next line:
# exercise_numbers=[]

# If it is an empty string, the programm will ask it.
file='test-fsor.tex'
# file=''

##########################################################
#
# Hungarian dictionary (old version)
# _ask : questions
# _mesg : messages
# _keys : expected characters to do something
#
#
##########################################################

dict={'exercise':'feladat',
 'exercises':'feladatok',
 'num_ask':'%s. feladat sorszáma: ',
 'group_ask':'%s. csoport neve ? ',
 'num':'Hány feladatra van szükséged? ',
 'file_ask':'Melyik fájlból válogassak? ',
 'menu_ask': 'Melyik menüpontot választod ? ',
 'menu':['Feladatok kiiratása',
	 'Feladatsorszámok tesztelése'],
 'not_num':'Ez nem egész szám, próbáld újra!',
 'not_in':'Nem megfelelő számot írtál, próbáld újra!',
 'group_name':'%s csoport',
 'out_mesg':'Ha az összes csoporttal végzett írjon "ki" szót!\nHa egy csoport sorszámaival végzett, irjon u (utolsó) betűt.',
 'out_keys':['ki','KI'],
 'end_keys':['u','U'],
 'bad_arg_mesg':'%s :hibás argumentum a %d. sorban',
 'bad_mesg':'Nem jó értéket írtál!',
 'exerc_num_mesg':'A megtalált feladatsorszámok:'}

menu_message='Válasszon a menüből'
menue=[
      ('feladatok Kiiratása','1'),
      ('feladatsorszámok Tesztelése','2')]

out_keys=dict['out_keys']
end_keys=dict['end_keys']

##################################
#
#  New version of language section
#
##################################
# 1. Environments and control sequences
env={'exercise':'feladat',
	'solution':'megold'}
# 2. Asks
ask={	'group_numbers':'Hány csoport legyen? ',
	'group':'%s. csoport neve? (Enter = %s) ',
	'exercise':'%s. feladat sorszáma? (Enter = vége) ',
	'menu':'Melyik menüpontot választod? ',
	'file_ask':'Melyik fájlból válogassak? ',
	}
# 3. Messages (errors too)
mesg={	'bad_arg':'%s :hibás argumentum a %d. sorban',
	'bad_value':'Nem jó értéket írtál!',
	'exerc_num':'A megtalált feladatsorszámok:'}


###########################
#
#  Functions
#
###########################

def write_exercise(n):
  "prints the exercise number n"
  exercise=['\n', '%%***'+`j`+'***\n']
  # first_row=-1 # Did not get the first row.
  begin=r"\\begin\s*\{\s*"+dict['exercise']+r"\s*}\s*\[\s*"+`n`+r"\s*]"
  end=r"\\end\s*\{\s*"+dict['exercise']+r"\s*}"

  i=0
  # Search for the exercise
  while i < len(lines):  # get it: false
      s=re.search(begin,lines[i])
      if s:
        break
      i = i + 1

  # Writes the first row
  a=s.span()[0]
  #In 'a' is the index of the begin of the exercise
  exercise.append(lines[i][a:])
  first_row=i

  # Writes the rest
  s=re.search(end,exercise[-1])  
  if s:    #It is a one-line exercise
    b=s.span()[1]
    exercise[-1]=exercise[-1][:b]+'\n' # It writes it until the end.
  else:
    # Writes the multi-line exercise
    i=i+1 # Next row 
    s=re.search(end,lines[i])
    while not s:
       exercise.append(lines[i])   
       i=i+1
       s=re.search(end,lines[i])
     
    # Writes the last line  of the multi-line exercise
    exercise.append(lines[i][:s.span()[1]]+'\n')

  writelines(exercise)
  #print exercise  # This line is just for test.


def writelines(list):
  """It writes the elements of the list. 
  If it is a list of rows. Write the multi-line text."""
  for i in range(len(list)):
    print list[i],

def ask_exercises():
  """ If you have not exercise numbers in the list
      exercise_numbers it asks for them. 
  """
  exercise_numbers=[]
  print dict['out_mesg']
  group=''
  i=1
  while 1:
    group=raw_input(dict['group_ask'] % i)
    if group == '':
      break
    i=i+1
    list=[group] 
    print 'lista: ',list
    # num=0   I think I don't need this row
    j=1
    while 1:
      num_string=raw_input(dict['num_ask'] % j)    
      if num_string == '':
           break 
      try: 
        num=int(num_string)
        list.append(num)
        j=j+1
      except ValueError:
           print dict['bad_mesg']   
    print list
    exercise_numbers.append(list)
  return exercise_numbers

def menu():
  "Writes the menu, and gets the number of the item"
  # Prints items
  print menu_message 
  for pair in menue:
    print  "%s : %s" % (pair[1],pair[0])
  while 1:
    try:
      answ=raw_input(dict['menu_ask'])
      a=int(answ)
      if a==1 or a==2:
        return a
      else:
	print dict['not_in']
    except:
	print dict['not_num']
  

def make_intervals(list):
  """   Sort the list and changes e.g. 11,12,13 to  '11-13'
  (It is an interval.)
  It stores the no uniq numbers too."""
  list.sort()
  not_uniq={}
  index_of_the_first = 0
  previous=list[0]
  for i in list[1:]:
	if previous == i:
		# Not uniq! It stores the number of the ??occurences.
		not_uniq[i] = list.count[i] 
	elif previous + 1 != i:  # This element can be just in an another interval.
		if index_of_the_first != i-1:  # It was a real interval. ??I make change the list.
		  list[index_of_the_first:i] = [`list[index_of_the_first]`+'-'+`list[i-1]`]
		index_of_the_first = i  
  if index_of_the_first != i:
	# I don't forget the last element.
	list[index_of_the_first:i] = [`list[index_of_the_first]`+'-'+`list[i-1]`

def test_exercise_numbers():
  """ It will Write the double numbers and the greatest number. """
  begin=r"\\begin\s*\{\s*"+dict['exercise']+r"\s*}\s*\[(.*)]"
  numbers=[]
  bad_arguments=[]
  for i in range(len(lines)):
      s=re.search(begin,lines[i])
      if s:
        argument=s.group(1)
	try: numbers.append(int(argument),i+1)
	except: bad_arguments.append(argument,i+1)
	numbers.sort()  # It will be 'make_intervals(numbers)'.
  print dict['exerc_num_mesg'],
  for i in numbers:
    print i[0],
  print 

  # If there are bad arguments (which is not integer)
  # writes them.
  if len(bad_arguments) > 0:
    # print dict['bad_arg_mesg'],
    for i in bad_arguments:
      print dict['bad_arg_mesg'] % i

################################
#
#    Main programm 
#
################################

# Opens and reads the file
if len(file)==0:
  file=raw_input(dict['file_ask'])
f=open(file, 'r')
lines=f.readlines()

test_exercise_numbers()

m=menu()
if m==1: # first menu item: write exercises
  # Write the exercises you need
  if len(exercise_numbers) == 0:
    exercise_numbers=ask_exercises()
  # Write exercises
  print '%%*****'+dict['exercises']+'***************'
  for group in exercise_numbers:
         print '\n\\subsection{'+dict['group_name'] % group[0]+'} %*****',
	 for j in group[1:]:
	   write_exercise(j)

elif m==2: # second menu item
  test_exercise_numbers()








