---
include:
  - nav.yml
---
question: |
  Upload a translation file
fields:
  - Translation file: translation_file
    datatype: file
    accept: |
      ".xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
---
code: |
  import pandas as pd
  df = pd.read_excel(translation_file.path())
---
code: |
  import mako.template
  import mako.runtime
  import re
  
  mako.runtime.UNDEFINED = DAEmpty()
  from mako import exceptions
  errors = []
  empty_rows = []
  for index, row in df.fillna('').iterrows():
    if 'tr_text' not in row:
      message("Is this definitely a translation file? Missing column 'tr_text'")
    
    # Row in XLSX file is 1 indexed, and it has a header row
    row_num = index + 2
    row_text = row['tr_text']
    question_id = row['question_id']
    
    if row_text == '':
      empty_rows.append(row_num)
    
    if '$ {' in row['tr_text']:
      errors.append((f"Error on row {row_num}, id: {question_id}", "Space between { and $"))
      
    # If these regexs get too slow, we can move them out of the for loop  
    
    # e.g. " # Some Heading" at start of line
    indented_heading = re.compile(r'^\s+#', re.MULTILINE)
    if indented_heading.search( row_text ):
      errors.append(( f'Warning on row { row_num }, id: { question_id }', 'A heading made with "#" may have extra spaces before it' ))
    
    # e.g. "%if True:" or "%other" at start of line
    percent_no_space = re.compile(r'^%\w', re.MULTILINE)
    if percent_no_space.search( row_text ):
      errors.append(( f'Warning on row { row_num }, id: { question_id }', 'No space between % and the following letter.' ))
    
    # e.g. "%   if True:"
    percent_too_many_spaces = re.compile(r'^%\s\s+', re.MULTILINE)
    if percent_too_many_spaces.search( row_text ):
      errors.append(( f'Warning on row { row_num }, id: { question_id }', 'Too many spaces after %.' ))
    
    num_opening_curly_brackets = row_text.count( '{' )
    num_closing_curly_brackets = row_text.count( '}' )
    if num_closing_curly_brackets > num_opening_curly_brackets:
      errors.append(( f'Warning on row { row_num }, id: { question_id }', 'A term or Mako code may be missing its opening "{"' ))
    if num_opening_curly_brackets > num_closing_curly_brackets:
      errors.append(( f'Warning on row { row_num }, id: { question_id }', 'A term or Mako code may be missing its closing "}"' ))
    
    num_opening_parens = row_text.count( '(' )
    num_closing_parens = row_text.count( ')' )
    if num_closing_parens > num_opening_parens:
      errors.append(( f'Warning on row { row_num }, id: { question_id }', 'An opening "(" may be missing' ))
    if num_opening_parens > num_closing_parens:
      errors.append(( f'Warning on row { row_num }, id: { question_id }', 'A closing ")" may be missing' ))
    
    ## Not sure these kinds of quotes are so crucial
    #num_opening_quotes = row_text.count( '“' )
    #num_closing_quotes = row_text.count( '”' )
    #if num_closing_quotes > num_opening_quotes:
    #  errors.append(( f'Warning on row { row_num }, id: { question_id }', 'An opening quote (“) may be missing' ))
    #if num_opening_quotes > num_closing_quotes:
    #  errors.append(( f'Warning on row { row_num }, id: { question_id }', 'A closing quote (”) may be missing' ))
    
    # e.g. 'some quote"'
    num_plain_quotes = row_text.count( '"' )
    if num_plain_quotes % 2 > 0:
      errors.append(( f'Warning on row { row_num }, id: { question_id }', 'A plain quotation mark (") may be missing. A text editor or spreadsheet may have accidentally reformatted it into fancier quotes.' ))
    
    try: 
      mytemplate = mako.template.Template(row['tr_text'])
      content = mytemplate.render()
    except:
      # Row in XLSX file is 1 indexed, and it has a header row
      errors.append((f"Error on row {row_num}, id: {row['question_id']}",exceptions.text_error_template().render()))
  del mytemplate
  load_all_errors = True
---
need:
  - load_all_errors
mandatory: True
question: |
  % if len(errors):
  ${ len(errors) } potential errors found
  % else:
  No errors found
  % endif 
subquestion: |
  % if len(errors):
  % for row in errors:
  #### ${ row[0] }
  ```
  ${ row[1] }
  ```
  
  % endfor
  % endif
  
  % if len(empty_rows):
  #### ${ len(empty_rows) } untranslated strings found
  
  Rows ${ comma_and_list(empty_rows) } have untranslated text.
  % endif
  