User:Kotbot/Source/Editfiles

From Wikipedia, the free encyclopedia

  1. CONSTANTS
  1. Polish unicode characters and keyboard equivs

unicll=[['\xC4\x85','a'],['\xC4\x87','c'],['\xC4\x99','e'],['\xC5\x82','l'],

        ['\xC5\x84','n'],['\xC3\xB3','o'],['\xC5\x9B','s'],['\xC5\xBA','x'],
        ['\xC5\xBC','z'],['\xC4\x84','A'],['\xC4\x86','C'],['\xC4\x98','E'],
        ['\xC5\x81','L'],['\xC5\x83','N'],['\xC3\x93','O'],['\xC5\x9A','S'],
        ['\xC5\xB9','X'],['\xC5\xBB','Z']]
  1. generic suffixes and prefixes

gensufl=['County','Voivodeship','National Park','Landscape Park',

        'Park Narodowy','Park Krajobrazowy']

genprel=['Gmina ','Wojew\xC3\xB3dztwo ','Powiat ','Park Narodowy ',

        'Park Krajobrazowy ']

def wri(A,finame='blog'):

   """Writes string/no./list/list of lists to file, with newline(s)"""
   """Semi-colons betw. list items, file name needs no .txt, default blog"""
   if type(A) in (tuple,list):
       ll=[A] if len(A)>0 and type(A[0]) not in (tuple,list) else A
   else:
       ll=A
   ll2fi(ll,finame)
   return
  1. CONVERSION FUNCTIONS

def a2p(a):

   """If list or tuple, returns tuple. Else returns 1-tuple."""
   return tuple(a) if type(a) in (tuple,list) else (a,)
  1. lists and strings

def l2s(L,sep=';'):

   """Converts list to string, semicolon default separator"""
   os=
   for x in L[:-1]:
       os=os+str(x)+sep
   os=os+(str(L[-1]) if len(L)>0 else )
   return os

def l2txt(L,sep=', ',f=' and ',ff=', and '):

   """Makes a text list with e.g. commas & and."""
   """If sep a number then uses , & and & ff if L has more than sep"""
   if type(sep)==int:
       f=ff if len(L)>sep else f; sep=', '
   os=
   if len(L)==0:
       return 
   if len(L)==1:
       return str(L[0])
   for a in L[:-2]:
       os=os+str(a)+sep
   return os+L[-2]+f+L[-1]

def s2l(s,seps=';'):

   """Converts string to list, semicolon def sep (can be alternative seps)"""
   l=[]; t=
   for ch in s:
       if ch in seps:
           l.append(t); t=
       else:
           t=t+ch
   l.append(t)
   return l

def s2pairl(st,seps):

   """Convs string to list of (term,sep) pairs (should end with sep)"""
   L=[]; os=
   for ch in st:
       if ch in seps:
           L=L+[(os,ch)]; os=
       else:
           os=os+ch
   return L
  1. files

def newunifile(finame,intro=):

   """Creates unicode file with intro as first line, if file nonexistent"""
   """Returns 1 if created, else -1"""
   full=finame if '.' in finame else finame+'.txt'
   try:
       fi=open(full)
   except:
       nf=open(full,'w')
       nf.write('\xef\xbb\xbf'+(intro if intro!= else finame+' file')+'\n')
       nf.close()
       return 1
   fi.close()
   return -1

def fi2ll(finame):

   """Converts file with semicolon-separated lines to list of lists"""
   """Returns -1 if no such file"""
   ll=[]; full=finame if '.' in finame else finame+'.txt'
   try:
       fi=open(full)
   except:
       return -1
   for line in fi:
       s=line
       if s!= and s[-1]=='\n':
           s=s[:-1]
       ll.append(s2l(s))
   fi.close()
   return ll[1:]

def ll2fi(ll,finame):

   """Writes (appends) list of lists to file as semicolon-separated lines"""
   full=finame if '.' in finame else finame+'.txt'
   fi=open(full,'a')
   for L in ll:
       fi.write(l2s(L)+'\n')
   fi.close()
   return 'end'
  1. lettering

def u9(st):

   """Adds Polish diacritics in place of following q (z' for xq) """
   u=
   for n in range(len(st)):
       ch=st[n]
       uch=llc(unicll,1,ch,0)
       if uch==(-1,) or n>len(st)-2 or st[n+1]!='q':
           u=u+ch if ch!='q' else u
       else:
           u=u+uch
   return u

def rom(uni):

   """Removes Polish diacritics from a string of unicode characters"""
   ro=; n=0
   while n<len(uni):
       kch=llc(unicll,0,uni[n:n+2],1)
       if kch==(-1,):
           ro=ro+uni[n]; n=n+1
       else:
           rch='z' if kch=='x' else 'Z' if kch=='X' else kch
           ro=ro+rch; n=n+2
   return ro  

def romq(uni):

   """Replaces Polish diacritics with letter+q"""
   ro=; n=0
   while n<len(uni):
       kch=llc(unicll,0,uni[n:n+2],1)
       if kch==(-1,):
           ro=ro+uni[n]; n=n+1
       else:
           ro=ro+kch+'q'; n=n+2
   return ro  

def uper(st):

   """Inserts percents after two-byte unicode chars"""
   os=; uf=0
   for ch in st:
       os=os+ch
       if ch>='\x80':
           if uf>0:
               os=os+'%'; uf=0
           else:
               uf=1
   return os

def simultransform(L,st):

   """Transforms string acc. to list of pairs, with loop cut-off"""
   """Handles unicode, no % allowed"""
   s=uper(st)
   for n in range(len(st)*10):
       for ab in L:
           if uper(ab[0]) in s:
               fl=1; s=s.replace(uper(ab[0]),uper(ab[1]))
   return s.replace('%',)
           

def transformby(LL,st):

   """Transforms st acc. to a list of lists of pairs"""
   for L in LL:
       st=simultransform(L,st)
   return st

def replaces(L,st):

   """Does non-reiterated replaces acc. to list of pairs (no unicode)"""
   for ab in L:
       st=st.replace(ab[0],ab[1])
   return st

def j2J(st):

   """Replaces any small letters in string by capitals (incl. Polish)"""
   L=[('a','A'),('b','B'),('c','C'),('d','D'),('e','E'),('f','F'),('g','G'),
      ('h','H'),('i','I'),('j','J'),('k','K'),('l','L'),('m','M'),('n','N'),
      ('o','O'),('p','P'),('q','Q'),('r','R'),('s','S'),('t','T'),('u','U'),
      ('v','V'),('w','W'),('x','X'),('y','Y'),('z','Z'),
      ('\xC4\x85','\xC4\x84'),('\xC4\x87','\xC4\x86'),('\xC4\x99','\xC4\x98'),
      ('\xC5\x82','\xC5\x81'),('\xC5\x84','\xC5\x83'),('\xC3\xB3','\xC3\x93'),
      ('\xC5\x9B','\xC5\x9A'),('\xC5\xBA','\xC5\xB9'),('\xC5\xBC','\xC5\xBB')]
   return replaces(L,st)

def st2St(st):

   """Capitalises first character of string"""
   if st==:
       return 
   if llf(unicll,0,st[:2])>-1:
       return j2J(st[:2])+st[2:]
   return j2J(st[0])+st[1:]
           

def J2j(st):

   """Replaces any capital letters in string by lower case (incl. Polish)"""
   L=[('A','a'),('B','b'),('C','c'),('D','d'),('E','e'),('F','f'),('G','g'),
      ('H','h'),('I','i'),('J','j'),('K','k'),('L','l'),('M','m'),('N','n'),
      ('O','o'),('P','p'),('Q','q'),('R','r'),('S','s'),('T','t'),('U','u'),
      ('V','v'),('W','w'),('X','x'),('Y','y'),('Z','z'),
      ('\xC4\x84','\xC4\x85'),('\xC4\x86','\xC4\x87'),('\xC4\x98','\xC4\x99'),
      ('\xC5\x81','\xC5\x82'),('\xC5\x83','\xC5\x84'),('\xC3\x93','\xC3\xB3'),
      ('\xC5\x9A','\xC5\x9B'),('\xC5\xB9','\xC5\xBA'),('\xC5\xBB','\xC5\xBC')]
   return replaces(L,st)
  1. SEARCHING AND MATCHING

def allin(a,b):

   """?Are all chars/els of a in b"""
   for x in a:
       if x not in b:
           return False
   return True

def starts1(S,sta):

   """?Does S start with sta/any of sta (also returns which)"""
   stp=a2p(sta)
   for st in stp:
       if S[:len(st)]==st:
           return True,st
   return False,

def starts(S,sta):

   """?Does S start with sta/any of sta"""
   return starts1(S,sta)[0]

def ends1(S,sta):

   """?Does S end with sta/any of sta (also returns which)"""
   stp=a2p(sta)
   for st in stp:
       if st== or S[-len(st):]==st:
           return True,st
   return False,

def ends(S,sta):

   """?Does S end with sta/any of sta"""
   return ends1(S,sta)[0]

def sf1(S,sta):

   """Returns first index of sta/any of sta in S; not found=-1 (also which)"""
   for n in range(len(S)):
       bo,st=starts1(S[n:],sta)
       if bo:
           return n,st
   return -1,

def sf(S,sta):

   """Returns first index of sta/any of sta in S; not found=-1"""
   return sf1(S,sta)[0]

def sfj(S,sta):

   """As sf but jumps to after what was found"""
   n,st=sf1(S,sta)
   if n<0:
       return -1
   return n+len(st)

def sflast1(S,sta):

   """Returns last index of sta/any of sta in S; not found=-1 (also which)"""
   for n in range(len(S),-1,-1):
       bo,st=starts1(S[n:],sta)
       if bo:
           return n,st
   return -1,

def sflast(S,sta):

   """Returns last index of sta/any of sta in S; not found=-1"""
   return sflast1(S,sta)[0]

def sfr1(S,f,sta):

   """As sf1(), but skips first f chars of S"""
   """If f is neg or not found then returns -1, """
   if f<0:
       return -1,                      
   reln,st=sf1(S[f:],sta)
   if reln<0:
       return -1,
   return f+reln,st

def sfr(S,f,sta):

   """As sf(), but skips first f chars of S"""
   """If f is neg or not found then returns -1"""
   if f<0:
       return -1                       
   reln=sf(S[f:],sta)
   if reln<0:
       return -1                       
   return f+reln

def sfrj(S,f,sta):

   """As sfr but jumps to after what was found"""
   if f<0:
       return -1                       
   reln,st=sf1(S[f:],sta)
   if reln<0:
       return -1
   return f+reln+len(st)

def sflastr(S,f,sta):

   """As sflast but considers only first f chars of S"""
   """If f is neg or not found then returns -1"""
   if f<0:
       return -1                       
   return sflast(S[:f],sta)

def nin(S,sta):

   """How many of sta in S"""
   m=0; N=0
   if type(sta)!=str and  in sta or sta==:
       return -1
   while m>-1:
       m=sfrj(S,m,sta)
       N=N+1 if m>-1 else N
   return N

def envirs(S,sta,back,forth):

   """Returns all environments (back and forth defined how big) of sta in S"""
   m=0; os=
   while m>-1:
       m=sfr(S,m+1,sta)
       nl=sflastr(S,m,'\n')
       Sc=S if nl==-1 else S[nl+1:]
       mm=m if nl==-1 else m-nl-1
       if m>-1:
           os=os+upto(Sc[max(mm-back,0):mm+forth],'\n')+'\n'
   return os
  1. in lists and lists of lists

def listf(L,a):

   """Index of first (any of) a in list, or -1"""
   ind=-1
   p=a2p(a); n=0; ind=-1
   while n<len(L) and ind ==-1:
       if L[n] in p:
           ind=n
       n=n+1
   return ind

def llf(Ll,col,a):

   """Index of first occurrence of (any of) a in given col of list of lists Ll"""
   """Returns -1 if not found"""
   p=a2p(a); n=0; ind=-1
   while n<len(Ll) and ind ==-1:
       if len(Ll[n])>col and Ll[n][col] in p:
           ind=n
       n=n+1
   return ind

def llfu(Ll,col,a):

   """Index of only occurrence of (any of) a in given col of list of lists Ll"""
   """Returns -1 if not found, -2 if not unique"""
   ind=llf(Ll,col,a)
   if ind<0:
       return -1
   ind2=llf(Ll[ind+1:],col,a)
   if ind2>-1:
       return -2
   return ind

def llc(Ll,cola,a,colb):

   """colb equivalent of first (any of) a in cola; (-1,) if not found"""
   """returns empty string if no column b entry"""
   ind=llf(Ll,cola,a)
   if ind<0:
       return (ind,)
   if len(Ll[ind])<=colb:
       return 
   return Ll[ind][colb]

def llcu(Ll,cola,a,colb):

   """colb equivalent of unique (any of) a in cola; (-1,) if not found"""
   """(-2,) if not unique. Returns empty string if no column b entry"""
   ind=llfu(Ll,cola,a)
   if ind<0:
       return (ind,)
   if len(Ll[ind])<=colb:
       return 
   return Ll[ind][colb]

def lll(Ll,col,a):

   """First whole line with (any of) a in col. Returns [-1] if not found"""
   ind=llf(Ll,col,a)
   if ind<0:
       return [ind]
   return Ll[ind]

def lllu(Ll,col,a):

   """Unique whole line with (any of) a in col. Returns [-1] if not found"""
   """[-2] if not unique"""
   ind=llfu(Ll,col,a)
   if ind<0:
       return [ind]
   return Ll[ind]
  1. NUMBER MANIPULATION

def isn(st):

   """Is st a pure integer?"""
   if starts(st,'-') and st!='-0':
       st=st[1:]
   if st== or not allin(st,'0123456789') or starts(st[:-1],'0'):
       return False
   return True

def isx(st):

   """Is st a pure English int or decimal?"""
   k=sf(st,'.')
   if k<0:
       return isn(st)
   if not isn(st[:k]) and st[:k]!='-0' or k==len(st)-1:
       return False
   return allin(st[k+1:],'0123456789')

def numan(s,dec,co):

   """Analyses a string as numbers"""
   """Returns list of nos., list of intervenings, result (-1.1 for err)"""
   d='0123456789'; st=
   for k in range(len(s)):
       if k==0 or len(s)<k+4 or s[k] not in co or not(allin(s[k+1:k+4],d)) or \
          s[k-1] not in d or len(s)>k+4 and s[k+4] in d:
           st=st+s[k]
       else:
           co=s[k]
   st=replaces([('\xe2\x80\x93','-'),('\xe2\x80\x94','-'),
                   ('–','-'),('—','-')],st)
   st=st+'X'; wl=[]; nl=[]; w=; ns=; f=0; res=0
   pre='-.' if '.' in dec else '-'
   for k in range(len(st)):
       if f==0:
           if st[k] in d or (st[k] in pre and nl==[] and k+1<len(st) and
                             st[k+1] in d and (k==0 or st[k-1]==' ')):
               if allin(w,' ') and wl!=[] or ends(w,('-.',' .')):
                   res=-1.1
               wl.append(w); ns=st[k]; f=1
           else:
               w=w+st[k]
       else:
           if st[k] in d:
               ns=ns+st[k]
           elif st[k] in dec:
               ns=ns+'.'
           else:
               if res>=0 and isn(ns):
                   res=res+1
               elif res>=0 and isx(ns):
                   res=res+0.1
               else:
                   res=-1.1
               nl.append(ns); w=st[k]; f=0
   return nl,wl+[w[:-1]],res

def nco(xs):

   """Puts commmas into English number"""
   os=xs; pti=sf(os,'.')
   if pti==-1:
       pti=len(os)
   while pti>3:
       os=os[:pti-3]+','+os[pti-3:]; pti=pti-3
   return os

def sround(xs,n):

   """Rounds a string number to n dec places, 0 gives an int"""
   if not isx(xs):
       return xs
   x=eval(xs); sgn=1
   if x<0:
       x=-x; sgn=-1
   for k in range(n):
       x=x*10.0
   xm=int(x+0.5)+0.1
   for k in range(n):
       xm=xm/10.0
   r=str(xm); a=sf(r,'.')
   if a>-1:
       r=r[:a+n+1] if n>0 else r[:a]
   return r if sgn==1 else '-'+r

def nword(nn):

   """Converts to a word if integer 1-9, else just to a string"""
   n=eval(nn) if type(nn)==str and isn(nn) else nn
   if n in range(1,10):
       return ['one','two','three','four','five','six','seven','eight',
                   'nine'][n-1]
   return str(n)
   
  1. STRING MANIPULATION

def notrail(st,a):

   """Removes (any of) a from end of string, iteratively"""
   tf=True
   while tf:
       tf,s=ends1(st,a)
       if tf:
           if s==:
               return st
           st=st[:-len(s)]
   return st
   

def notrailsp(st):

   """Removes spaces from the end of string"""
   return notrail(st,' ')

def noinit(st,a):

   """Removes (any of) a from start of string, iteratively"""
   tf=True
   while tf:
       tf,s=starts1(st,a)
       if tf:
           if s==:
               return st
           st=st[len(s):]
   return st

def noinitsp(st):

   """Removes spaces from the start of string"""
   return noinit(st,' ')

def noextrsp(st):

   """Removes spaces from start and end of string"""
   return notrailsp(noinitsp(st))

def noex(st):

   """Removes spaces and newlines from start and end"""
   return notrail(noinit(st,(' ','\n')),(' ','\n'))

def upto(st,ta):

   """If st contains (any of) ta, returns what goes before, less end spaces"""
   n=sf(st,ta)
   if n<0:
       return st
   return notrailsp(st[:n])

def elimbr(S,op,cl):

   """Eliminates anything between op and cl from string (e.g. nocomm)"""
   st=S; m=0
   if op== or cl==:
       return st
   while m>-1 and m<len(st):
       n=sfrj(st,m,op); m=sfrj(st,n,cl)
       if n>-1:
           if m>-1:
               st=st[:n-len(op)]+st[m:]; m=n-len(op)
           else:
               st=st[:n-len(op)]
   return st

def allbr(S,op,cl):

   """Lists everything appearing betw op and cl in string"""
   L=[]; n=0; ck=[]
   while n<len(S):
       if starts(S[n:],cl) and ck!=[]:
           L.append(S[ck[-1]:n]); n=n+len(cl); ck=ck[:-1]
       elif starts(S[n:],op):
           n=n+len(op); ck.append(n)
       else:
           n=n+1
   return L
       

def ifpl(n,plst='s',sst=):

   """returns s or other pl if n not 1, else empty or other sing"""
   if n==1:
       return sst
   return plst
  1. SORTING and list/dbase manipulation

def less(x,y):

   """?Is x less than y (nos. by value then strings wo diacritics)"""
   x=eval(x) if type(x)==str and isx(x) else x
   y=eval(y) if type(y)==str and isx(y) else y
   if type(y)==str and type(x)!=str:
       return True
   if type(x)==str and type(y)!=str:
       return False
   if type(y)!=str:
       return x<y
   a=rom(x); b=rom(y); c=J2j(a); d=J2j(b)
   if a==b:
       return x<y
   if c==d:
       return a<b
   return c<d

def insert(L,x):

   """Inserts item in list, in order"""
   n=0
   while n<len(L) and not(less(x,L[n])):
       n=n+1
   return L[:n]+[x]+L[n:]

def sort(L):

   """Sorts list"""
   OL=[]
   for p in L:
       OL=insert(OL,p)
   return OL

def reverse(L):

   """Reverses list"""
   OL=[]
   for p in L:
       OL=[p]+OL
   return OL

def colsless(cs,p,q):

   """?Is p less than q by cs (tuple of +-col nos.,-9999=-0)"""
   for cabs in a2p(cs):
       if cabs<0:
           c=0 if cabs==-9999 else -cabs; ff=True; tt=False
       else:
           c=cabs; tt=True; ff=False
       if c>=len(q) and c<len(p):
           return ff
       if c>=len(p) and c<len(q):
           return tt
       if c<len(p) and c<len(q) and less(p[c],q[c]):
           return tt
       if c<len(p) and c<len(q) and less(q[c],p[c]):
           return ff
   return False

def insbycols(L,cs,p):

   """Inserts list/tuple in list, in order defined by cs"""
   n=0
   while n<len(L) and not(colsless(cs,p,L[n])):
       n=n+1
   return L[:n]+[p]+L[n:]

def sortbycols(L,cs):

   """Returns list of lists/tuples sorted by columns cs"""
   OL=[]
   for p in L:
       OL=insbycols(OL,cs,p)
   return OL

def selcol(L,c):

   """Returns column c as a simple list"""
   OL=[]
   for p in L:
       if c<len(p):
           OL.append(p[c])
   return OL

def selcols(L,cs):

   """Returns only columns cs of L"""
   OL=[]
   for p in L:
       op=[]
       for c in a2p(cs):
           if c<len(p):
               op.append(p[c])
       OL.append(op)
   return OL

def selrows(L,col,a):

   """Selects from L only the rows which have (any of) a in given col."""
   OL=[]
   for p in L:
       if col<len(p) and p[col] in a2p(a):
           OL.append(p)
   return OL

def colmm(L,col):

   """Max and min in col of L"""
   mx='__<<>'; mn='__<<>'
   for p in L:
       if col<len(p) and (mx=='__<<>' or less(mx,p[col])):
           mx=p[col]
       if col<len(p) and (mn=='__<<>' or less(p[col],mn)):
           mn=p[col]
   return mx,mn
  1. COORDINATES

def dcoo2xy(dcoo):

   """Converts dollar-sep coordinate string to decimal coords"""
   cl=dss2l(dcoo)
   x=eval(cl[0])+eval(cl[1])/60.0+(eval(cl[2])/3600.0 if cl[2]!= else 0)
   y=eval(cl[3])+eval(cl[4])/60.0+(eval(cl[5])/3600.0 if cl[5]!= else 0)
   return x,y

def kmdir(x,y,X,Y):

   """Returns distance and direction of (x,y) from (X,Y) (within Poland)"""
   import math    
   vx=(x-X)*110.946
   vy=(y-Y)*111.319*math.cos(math.radians((x+X)/2))
   d=int(math.sqrt(vx*vx+vy*vy))+1
   if vx>2.42*abs(vy):

pt='north'

   elif -vx>2.42*abs(vy):

pt='south'

   elif vy>2.42*abs(vx):

pt='east'

   elif -vy>2.42*abs(vx):

pt='west'

   else:

pta='north' if vx>0 else 'south' ptb='east' if vy>0 else 'west' pt=pta+'-'+ptb

   return d,pt

def kmdrat(x,y,X,Y):

   """Returns dist, dircode and ratio of (x,y) from (X,Y) (within Poland)"""
   import math    
   if x==X and y==Y:
       return 0,0,0
   vx=(x-X)*110.946
   vy=(y-Y)*111.319*math.cos(math.radians((x+X)/2))
   d=int(math.sqrt(vx*vx+vy*vy))+1
   if vx>1.5*abs(vy):

pt=0; rat=vy/vx #0=north, 1=NE etc.

   elif -vx>1.5*abs(vy):

pt=4; rat=vy/vx

   elif vy>1.5*abs(vx):

pt=2; rat=-vx/vy

   elif -vy>1.5*abs(vx):

pt=6; rat=-vx/vy

   elif vx>0 and vy>0:

pt=1; rat=vy/vx

   elif vx<0 and vy>0:

pt=3; rat=vy/vx

   elif vx<0 and vy<0:

pt=5; rat=vy/vx

   else: # ie. if vx>0 and vy<0

pt=7; rat=vy/vx

   return d,pt,rat

def kmtxt(dc,dcb,Min,Max,aId):

   """Makes text e.g. 8 km north, of dc from dcb"""
   """aId starts with a to abbreviate units; rest logged if out of range"""
   x,y=dcoo2xy(dc); X,Y=dcoo2xy(dcb)
   dis,pt=kmdir(x,y,X,Y)
   if dis<Min or dis>Max:
       wri(aId[1:]+' DISTANCE WRONG?')
   os='{{convert/LoffAon' if aId[0]=='a' else )
   return os+'DbSoff|'+str(dis)+'||mi|0'+('|s=|r=re

|u=km |n=kilometre |t=kilometre |o=mi |b=1000 |j=3-0}} '+pt

  1. READING FROM WIKI

def wpraw(la,Art):

   """Gets raw WP article"""
   import urllib
   ur=urllib.urlopen('http://'+la+'.wikipedia.org/w/index.php?title='+
                     Art.replace(' ','_')+'&action=raw')
   raw=ur.read(); ur.close()
   return raw

def wcraw(Art):

   """Gets raw commons article"""
   import urllib
   ur=urllib.urlopen('http://commons.wikimedia.org/w/index.php?title='+
                     Art.replace(' ','_')+'&action=raw')
   raw=ur.read(); ur.close()
   return raw

def isim(name):

   """?Is ready-trimmed name an image in commons"""
   if '.' not in name:
       return False
   return wcraw('Image:'+name)!=

def nocomm(text):

   """Removes comments from wikipedia text"""
   return elimbr(text,)

def redtarg(txt):

   """redirect target in txt or empty string"""
   tx=nocomm(txt)
   n=sf(tx,('#REDIRECT[[','#redirect[[','#Redirect[[',
              '#REDIRECT [[','#redirect [[','#Redirect [['))
   nn=sfrj(tx,n,'[[')
   m=sfr(tx,nn,']]')
   if m<0 or not allin(tx[:n],' \n'):
       return 
   return noextrsp(tx[nn:m])

def namtag(st):

   """Breaks st into name (to ( or ,) and tag (else st and emptystring)"""
   nam=upto(st,(',','('))
   if nam==st:
       return st,
   n,ch=sf1(st,(',','('))
   if ch==',':
       return nam, noinitsp(st[n+1:])
   n1=len(notrailsp(st))-1
   if st[n1]==')':
       return nam,st[n+1:n1]
   return nam,st[n+1:]

def nam(st):

   """Main name part of string, less tag"""
   return namtag(st)[0]

def tag(st):

   """Tag after comma or in brackets"""
   return namtag(st)[1]

def essnam(st):

   """Removes generic part of name"""
   na=nam(st)
   for p in gensufl:
       if ends(na,p):
           return upto(na,p)
   for q in genprel:
       if starts(na,q):
           return noextrsp(na[len(q):])
   return na

def wplinkto(st):

   """Make WP (piped) link, not displaying the tag"""
   name=nam(st)
   if name==st:
       return ''+st+''
   return ''+name+''

def esslinkto(st):

   """Make WP (piped) link, displaying only essence of name"""
   name=essnam(st)
   if name==st:
       return ''+st+''
   return ''+name+''

def targdisp(link):

   """The _T_arget and display text of wp link (removes extr spaces)"""
   s=link
   n=sfj(s,'[[')
   if n>-1:
       s=s[n:]
       n1=sf(s,']]')
       if n1>-1:
           s=s[:n1]
   m=sf(s,'|')
   if m==-1:
       targ=noextrsp(s); disp=targ
   else:
       targ=noextrsp(s[:m]); disp=noextrsp(s[m+1:])
   targ=st2St(noextrsp(targ.replace('_',' ')))
   return targ,disp

def target(link):

   return targdisp(link)[0]

def display(link):

   return targdisp(link)[1]

def imnam(st):

   """Returns image filename only"""
   st2=noinit(st,(' ','[','Image:','image:','grafika:','Grafika:'))
   st3=noextrsp(upto(st2,('|',']')))
   return st3 if '.' in st3 else 

def insbydisp(L,link):

   """Inserts wp link in list so display texts are in rom alph order"""
   n=0
   while n<len(L) and not(less(display(link),display(L[n]))):
       n=n+1
   return L[:n]+[link]+L[n:]

def alllinks(tx):

   """Finds all links in text, lists them as triples"""
   L=allbr(nocomm(tx),'',''); OL=[]
   for a in L:
       t,d=targdisp(a)
       if ':' not in t:
           OL.append([t,d,'w'])
       else:
           p=upto(t,':')
           if p in ('Image','Grafika'):
               OL.append([imnam(t),,'i'])
           elif p in ('Category','Kategoria'):
               OL.append([t,,'c'])
           elif len(p)>1 and allin(a[0]+p[1:],'abcdefghijklmnopqrstuvwxyz'):
               OL.append([a[0]+t[1:],,'l'])
           else:
               print a,p
   return OL

def allims(tx):

   """Return list of trimmed and commons-checked image names from text"""
   L=selcol(selrows(alllinks(tx),2,'i'),0); OL=[]
   for na in L:
       if isim(na):
           OL.append(na)
   return OL
  1. templates

def alltems(tx):

   """Finds all templates in text, lists them as 1+(pairs) lists"""
   L=allbr(nocomm(tx),'Template:',''); OL=[]
   for a in L:
       s=a+'|'; n=0; ck=0; CK=0; AL=[]; par=1
       while '|' in s:
           m,b=sfr1(s,n,('Template:','','','','|'))
           if b=='{{':
               ck=ck+1; n=m+2
           elif b=='[[':
               CK=CK+1; n=m+2
           elif b=='}}' and ck>0:
               ck=ck-1; n=m+2
           elif b==']]' and CK>0:
               CK=CK-1; n=m+2
           elif ck+CK==0 or m==len(s)-1:
               if AL==[]:
                   AL=[st2St(noex(s[:m]))]
               else:
                   e=sf(s[:m],'=')
                   if e<0:
                       AL.append((str(par),noex(s[:m]))); par=par+1
                   else:
                       AL.append((noex(s[:e]),noex(s[e+1:m])))
               s=s[m+1:]; n=0
           else:
               n=n+1
       OL.append(AL)
   return OL

def fval(tx,tem,flds):

   """List values assigned to specified field(s) of a template, in text"""
   L=alltems(tx); A=lll(L,0,tem); OL=[]
   if A==[-1]:
       return  if type(flds)==(str) else (,)*len(flds)
   for f in a2p(flds):
       v=llc(A,0,f,1)
       OL.append( if v==(-1,) else v)
   return OL[0] if len(OL)==1 else OL
   

def l2tem(iteml):

   """Converts list of strings or (field,val) pairs to template text"""
   """Final space means no new line after"""
   txt='{{'
   for item in iteml:
       if type(item) in (tuple,list):
           txt=txt+item[0]+' ='+(' ' if item[1] else )+item[1]
       else:
           txt=txt+item
       txt=txt+('| ' if ends(txt,' ') else '\n| ')
   txt=notrail(txt,(' ','|','\n'))+' }}'
   return txt

def temconv(tx,tem,cl,df,df2=):

   """Converts template list based on command list and default action"""
   """Action (or third elt of command): abc (to do if not/empty/full)"""
   """A=asis D=del E=empty F=fill R=replace(2nd elt is pairs) L=checklink"""
   L=alltems(tx); A=lll(L,0,tem)
   if A==[-1]:
       return 
   OL=[A[0]]; A=A[1:]
   for p in cl:
       m=llf(A,0,p[0])
       OL=OL+temcom(p[0],p[1],p[2],0 if m<0 else A[m][1])
       if m>=0:
           A[m]=A[m][:1]
   for k in range(len(A)):
       if len(A[k])>1:
           kk=k+1
           while kk<len(A) and llf(OL[1:],0,A[kk][0])<0:
               kk=kk+1
           uu=llf(OL[1:],0,A[kk][0])+1 if kk<len(A) else len(OL)
           OL=OL[:uu]+temcom(A[k][0],df2,df,A[k][1])+OL[uu:]
   return l2tem(OL)

def temcom(fld,v,c,e):

   """For above. field name, action value, command abc, existing (or 0)"""
   if e==0:
       return temact(fld,v,c[0],)
   else:
       return temact(fld,v,c[1] if e== else c[2],e)

def temact(fld,v,a,e):

   """As above, one letter action"""
   if a=='A':
       return [(fld,e)]
   if a=='D':
       return []
   if a=='E':
       return [(fld,)]
   if a=='F':
       return [(fld,v)]
   if a=='R':
       return [(fld,replaces(v,e))]
   if a=='L':
       return [(fld,e if e==display(e) or wpraw('en',target(e))!=
                else display(e))]

def IPA(st):

   """converts Polish string to IPA representation"""
   s=romq(J2j(st)).replace('-',' ')
   s=replaces([(' w ',' w'),(' z ',' z')],' '+s)[1:]
   s=replaces([('ia','Ja'),('ie','Je'),('io','Jo'),('iu','Ju')],s)
   s=replaces([('sJ','sq'),('zJ','xq'),('cJ','cq'),('nJ','nq'),
                     ('zq','Z'),('aq','o9'),('eq','e9')],s)
   s=replaces([('si','sqi'),('zi','xqi'),('ci','cqi')],s)
   s=replaces([('dZ','d1'),('dxq','d2'),('dz','d0')],s)
   s=replaces([('sz','S'),('cz','C'),('rz','R'),('ch','h')],s)
   s=replaces([('9b','mb'),('9c','nc'),('9C','nC'),('9d','nd'),
             ('9g','ng'),('9k','nk'),('9l','l'),('9p','mp'),('9t','nt')],s)
   s=replaces([('lqa','lQa'),('lqe','lQe'),('lqo','lQo'),('lqu','lQu'),
               ('lqy','lQy'),(' lq','lQ')],' '+s)[1:]
   s=replaces([(' ','$ '),('c','$c$'),('C','$C$'),('f','$f$'),
                     ('h','$h$'),('k','$k$'),('p','$p$'),('s','$s$'),
                     ('S','$S$'),('t','$t$'),('$q','q$'),('xq','X')],s)+'$'
   s=replaces([(' nad$ $',' nat $'),(' nad$ ',' nad ')],s)
   s=simultransform([('b$','$p$'),('d$','$t$'),('d0$','$c$'),('d1$','$C$'),
                     ('d2$','$cq$'),('g$','$k$'),('w$','$f$'),('$w','$f$'),
                     ('z$','$s$'),('$z','$s$'),('Z$','$S$'),('$Z','$S$'),
                     ('R$','$K$'),('$R','$K$'),
                     ('X$','$sq$'),('$X','$sq$')],s).replace('$',)
   use=0; fix=0; pts=[]; vo=0; n=len(s)-1
   while n>=0:
       if vo<2:
           vo=vo+1 if s[n] in 'aeiouy' else vo; mm=n
       elif vo==2:
           if s[n] in 'aeiouy':
               vo=3; pts.append(mm); use=1
           elif fix==0:
               if s[n] in 'bcCdfghjkmnpsStwXzZrRKl':
                   mm=n; fix=-1 if s[n] in 'rRKl' else 1
           elif fix==-1:
               if  s[n] in 'rRKljmncC' or s[n]=='d' and s[n+1] in '012':
                   fix=1
               elif s[n] in 'bdfghkpsStwXzZ':
                   mm=n; fix=1
       n=n-1
       if n<0 or s[n]==' ':
           if vo in (1,2):
               pts.append(n+1); use=1 if vo==2 else use
           vo=0; fix=0
   if use>0:
       for k in pts:
           s=s[:k]+"'"+s[k:]
   s=s.replace("o'dl","od'l")
   s=replaces([("'nad ",",nad "),("'nat ",",nat ")],s) 
   s=replaces([('Xe','XE'),('sqe','sqE'),('cqe','cqE'),('d2e','d2E'),
               ('nqe','nqE'),('oq','u'),('R','Z'),('K','S')],s)
   if 'e' in s:
       s=replaces([('Ej','Fj'),('E','e'),('F','E')],s)
    1. s=replaces([('e','\xc9\x9b'),('E','e'),('o','\xc9\x94'),('9','\xcc\x83'),
    2. ('y','\xc9\xa8'),('w','v'),('lq','w'),('h','x'),
    3. ('nq','\xc9\xb2'),('c','t+s'),('C','t+S'),('d0','d+z'),
    4. ('d1','d+Z'),('d2','d+X'),('+','\xe2\x80\x8b\xcd\xa1'),
    5. ('sq','\xc9\x95'),('S','\xca\x82'),('X','\xca\x91'),
    6. ('Z','\xca\x90'),('J','j')],s)
   mhl=[(' ','-'),('o9','\xc4\x85'),('e9','\xc4\x99'),('C','cz'),
        ('cq','\xc4\x87'),('d0','dz'),
        ('d1','d\xc5\xbc'),('d2','d\xc5\xba'),('E','e1'),('J','j'),
        ('lQ','\xc5\x82'),('lq','U'),('nq','\xc5\x84'),('S','sz'),
        ('sq','\xc5\x9b'),('X','\xc5\xba'),('Z','\xc5\xbc')]
   os='[[Help:IPA chart for Polish|]][[Help:IPA chart for Polish|]]'

def linesof(txt):

   """decomposes text into lines"""
   ol=[]; os=
   for ch in txt:
       if ch=='\n':
           ol.append(os); os=
       else:
           os=os+ch
   if os!=:
       ol.append(os)
   return ol
         

def tscsinart(txt):

   """Returns navbox/cat section of art; also start and end+1 points"""
   n=sf(txt,'\n[[Category:'); os=
   if n==-1:
       return ,-1,-1
   al=linesof(txt[:n+1]); bl=linesof(txt[n+1:])
   for b in bl:
       bb=noextrsp(b)
       if bb== or starts(bb,'[[Category:') or \
          starts(bb,'Template:') and ends(bb,''):
           os=os+b+'\n'
   k=len(al); kk=k
   while k>0 and k>kk-2:
       k=k-1
       bb=noextrsp(al[k])
       if k==kk-1 and bb== or starts(bb,'[[Category:') or \
          starts(bb,'Template:') and ends(bb,''):
           for ki in range(kk-1,k-1,-1):
               os=al[ki]+'\n'+os
           kk=k
   i=sf(txt,os)
   return os,i,i+len(os)