Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import tempfile | |
| from pathlib import Path | |
| import base64 | |
| import os | |
| import sys | |
| sys.path.append(os.path.join(os.path.dirname(__file__), "./src")) | |
| from verificaUD import verificaUD | |
| print("Verifica-UD running") | |
| translations = { | |
| '🇧🇷': { | |
| 'title': 'Verifica-UD', | |
| 'subtitle': 'Um verificador de textos de Português Brasileiro anotados segundo as diretrizes das Universal Dependencies', | |
| 'input_label': 'Escolha um arquivo .conllu de até 200MB para iniciar a verificação', | |
| 'buscando': 'Buscando', | |
| 'intro': 'O Verifica-UD faz uma verificação estrutural, léxica e sintática da anotação de textos do Português brasileiro, seguindo o modelo das <a href="https://universaldependencies.org" target="_blank">Universal Dependencies</a>. O Verifica-UD foi desenvolvido dentro do projeto <a href="https://sites.google.com/icmc.usp.br/poetisa" target="_blank">POeTiSA</a>.', | |
| 'to_cite': 'Clique aqui para citar o Verifica-UD', | |
| 'not_conllu': 'Este arquivo não está no formato correto.', | |
| 'no_file': '... à espera de um arquivo .conllu', | |
| 'file_uploaded': 'Arquivo recebido corretamente', | |
| 'download': 'Baixe o relatório completo.', | |
| 'file_name': 'Nome do arquivo', | |
| 'sentences': 'Número total de sentenças', | |
| 'err': 'erros', | |
| 'wrn': 'avisos', | |
| 'errFound': 'Erros encontrados', | |
| 'wrnFound': 'Avisos emitidos sobre possíveis erros', | |
| 'structural': 'estrutural(is)', | |
| 'lexical': 'lexical(is)', | |
| 'sintatical': 'sintático(s)', | |
| 'sentencesOk': 'Número de sentenças sem erros', | |
| 'sentencesClean': 'Número de sentenças sem erros ou avisos', | |
| 'struct_err': 'Erros estruturais', | |
| 'struct_wrn': 'Avisos estruturais', | |
| 'tagger_err': 'Erros léxicais', | |
| 'tagger_wrn': 'Avisos lexicais', | |
| 'parser_err': 'Erros sintáticos', | |
| 'parser_wrn': 'Avisos sintáticos', | |
| 'options': 'Escolha o tipo de verificação', | |
| 'struct': 'Apenas verificação estrutural', | |
| 'tagger': 'Verificação estrutural e lexical', | |
| 'parser': 'Verificação estrutural, lexical e sintática', | |
| 'result': 'Sumário de resultados', | |
| 'list_er_wr': 'Mensagens de erros e avisos em ordem de ID da sentença no arquivo', | |
| 'congrats': 'Nenhum erro ou aviso encontrado!', | |
| 'dev': 'Desenvolvido por' | |
| }, | |
| '🇺🇸': { | |
| 'title': 'Verifica-UD', | |
| 'subtitle': 'A verifier for Universal Dependencies annotation in Brazilian Portuguese', | |
| 'input_label': 'Entre um arquivo .conllu para verificar:', | |
| 'buscando': 'Buscando', | |
| 'intro': 'Verifica-UD faz uma verificação estrutural, léxica e morfosintática para anotação de textos em Português brasileiro, seguindo o modelo internacional do <a href="https://universaldependencies.org" target="_blank">Universal Dependencies</a>. Verifica-UD faz parte do projeto <a href="https://sites.google.com/icmc.usp.br/poetisa" target="_blank">POeTiSA</a>.', | |
| 'to_cite': 'Para citar o Verifica-UD', | |
| 'not_conllu': 'Este arquivo não está no formato correto.', | |
| 'no_file': 'Entre o nome de um arquivo .conllu', | |
| 'file_uploaded': 'File uploaded successfully', | |
| 'download': 'Baixe o relatório completo.', | |
| 'file_name': 'Nome do arquivo', | |
| 'sentences': 'Número total de sentenças', | |
| 'err': 'erros', | |
| 'wrn': 'avisos', | |
| 'errFound': 'Erros encontrados:', | |
| 'wrnFound': 'Avisos emitidos sobre possíveis erros:', | |
| 'structural': 'estruturais', | |
| 'lexical': 'lexicais', | |
| 'sintatical': 'sintáticos/morfosintáticos', | |
| 'sentencesOk': 'Número de sentenças sem erros', | |
| 'sentencesClean': 'Número de sentenças sem erros ou avisos', | |
| 'struct_err': 'Erros estruturais', | |
| 'struct_wrn': 'Avisos estruturais', | |
| 'tagger_err': 'Erros léxicais', | |
| 'tagger_wrn': 'Avisos lexicais', | |
| 'parser_err': 'Erros sintáticos', | |
| 'parser_wrn': 'Avisos sintáticos', | |
| 'options': 'Escolha o tipo de verificação', | |
| 'struct': 'Apenas verificação estrutural', | |
| 'tagger': 'Verificação estrutural e lexical', | |
| 'parser': 'Verificação estrutural, lexical e sintática', | |
| 'result': 'Sumário de resultados', | |
| 'list_er_wr': 'Erros e avisos encontrados', | |
| 'congrats': 'Nenhum erro ou aviso encontrado!', | |
| 'dev': 'Developed by' | |
| }, | |
| '🇫🇷': { | |
| 'title': 'Verifica-UD', | |
| 'subtitle': 'Um verificador de arquivos .conllu para textos anotados em Português Brasileiro', | |
| 'input_label': 'Entre um arquivo .conllu para verificar:', | |
| 'buscando': 'Buscando', | |
| 'intro': 'Verifica-UD faz uma verificação estrutural, léxica e morfosintática para anotação de textos em Português brasileiro, seguindo o modelo internacional do <a href="https://universaldependencies.org" target="_blank">Universal Dependencies</a>. Verifica-UD faz parte do projeto <a href="https://sites.google.com/icmc.usp.br/poetisa" target="_blank">POeTiSA</a>.', | |
| 'to_cite': 'Para citar o Verifica-UD', | |
| 'not_conllu': 'Este arquivo não está no formato correto.', | |
| 'no_file': 'Entre o nome de um arquivo .conllu', | |
| 'file_uploaded': 'Arquivo recebido corretamente', | |
| 'download': 'Baixe o relatório completo.', | |
| 'file_name': 'Nome do arquivo', | |
| 'sentences': 'Número total de sentenças', | |
| 'err': 'erros', | |
| 'wrn': 'avisos', | |
| 'errFound': 'Erros encontrados:', | |
| 'wrnFound': 'Avisos emitidos sobre possíveis erros:', | |
| 'structural': 'estruturais', | |
| 'lexical': 'lexicais', | |
| 'sintatical': 'sintáticos/morfosintáticos', | |
| 'sentencesOk': 'Número de sentenças sem erros', | |
| 'sentencesClean': 'Número de sentenças sem erros ou avisos', | |
| 'struct_err': 'Erros estruturais', | |
| 'struct_wrn': 'Avisos estruturais', | |
| 'tagger_err': 'Erros léxicais', | |
| 'tagger_wrn': 'Avisos lexicais', | |
| 'parser_err': 'Erros sintáticos', | |
| 'parser_wrn': 'Avisos sintáticos', | |
| 'options': 'Escolha o tipo de verificação', | |
| 'struct': 'Só verificação estrutural', | |
| 'tagger': 'Verificação estrutural e lexical', | |
| 'parser': 'Verificação estrutural, lexical e sintática', | |
| 'result': 'Sumário de resultados', | |
| 'list_er_wr': 'Erros e avisos encontrados', | |
| 'congrats': 'Nenhum erro ou aviso encontrado!', | |
| 'dev': 'Développé par' | |
| }, | |
| '🇮🇹': { | |
| 'title': 'Verifica-UD', | |
| 'subtitle': 'Um verificador de arquivos .conllu para textos anotados em Português Brasileiro', | |
| 'input_label': 'Entre um arquivo .conllu para verificar:', | |
| 'buscando': 'Buscando', | |
| 'intro': 'Verifica-UD faz uma verificação estrutural, léxica e morfosintática para anotação de textos em Português brasileiro, seguindo o modelo internacional do <a href="https://universaldependencies.org" target="_blank">Universal Dependencies</a>. Verifica-UD faz parte do projeto <a href="https://sites.google.com/icmc.usp.br/poetisa" target="_blank">POeTiSA</a>.', | |
| 'to_cite': 'Para citar o Verifica-UD', | |
| 'not_conllu': 'Este arquivo não está no formato correto.', | |
| 'no_file': 'Entre o nome de um arquivo .conllu', | |
| 'file_uploaded': 'Arquivo recebido corretamente', | |
| 'download': 'Baixe o relatório completo.', | |
| 'file_name': 'Nome do arquivo', | |
| 'sentences': 'Número total de sentenças', | |
| 'err': 'erros', | |
| 'wrn': 'avisos', | |
| 'errFound': 'Erros encontrados:', | |
| 'wrnFound': 'Avisos emitidos sobre possíveis erros:', | |
| 'structural': 'estruturais', | |
| 'lexical': 'lexicais', | |
| 'sintatical': 'sintáticos/morfosintáticos', | |
| 'sentencesOk': 'Número de sentenças sem erros', | |
| 'sentencesClean': 'Número de sentenças sem erros ou avisos', | |
| 'struct_err': 'Erros estruturais', | |
| 'struct_wrn': 'Avisos estruturais', | |
| 'tagger_err': 'Erros lexicais', | |
| 'tagger_wrn': 'Avisos lexicais', | |
| 'parser_err': 'Erros sintáticos', | |
| 'parser_wrn': 'Avisos sintáticos', | |
| 'options': 'Escolha o tipo de verificação', | |
| 'struct': 'Apenas verificação estrutural', | |
| 'tagger': 'Verificação estrutural e lexical', | |
| 'parser': 'Verificação estrutural, lexical e sintática', | |
| 'result': 'Sumário de resultados', | |
| 'list_er_wr': 'Erros e avisos encontrados', | |
| 'congrats': 'Nenhum erro ou aviso encontrado!', | |
| 'dev': 'Sviluppato da' | |
| }, | |
| '🇪🇸': { | |
| 'title': 'Verifica-UD', | |
| 'subtitle': 'Um verificador de arquivos .conllu para textos anotados em Português Brasileiro', | |
| 'input_label': 'Entre um arquivo .conllu para verificar:', | |
| 'buscando': 'Buscando', | |
| 'intro': 'Verifica-UD faz uma verificação estrutural, léxica e morfosintática para anotação de textos em Português brasileiro, seguindo o modelo internacional do <a href="https://universaldependencies.org" target="_blank">Universal Dependencies</a>. Verifica-UD faz parte do projeto <a href="https://sites.google.com/icmc.usp.br/poetisa" target="_blank">POeTiSA</a>.', | |
| 'to_cite': 'Para citar o Verifica-UD', | |
| 'not_conllu': 'Este arquivo não está no formato correto.', | |
| 'no_file': 'Entre o nome de um arquivo .conllu', | |
| 'file_uploaded': 'Arquivo recebido corretamente', | |
| 'download': 'Baixe o relatório completo.', | |
| 'file_name': 'Nome do arquivo', | |
| 'sentences': 'Número total de sentenças', | |
| 'err': 'erros', | |
| 'wrn': 'avisos', | |
| 'errFound': 'Erros encontrados:', | |
| 'wrnFound': 'Avisos emitidos sobre possíveis erros:', | |
| 'structural': 'estruturais', | |
| 'lexical': 'lexicais', | |
| 'sintatical': 'sintáticos/morfosintáticos', | |
| 'sentencesOk': 'Número de sentenças sem erros', | |
| 'sentencesClean': 'Número de sentenças sem erros ou avisos', | |
| 'struct_err': 'Erros estruturais', | |
| 'struct_wrn': 'Avisos estruturais', | |
| 'tagger_err': 'Erros léxicais', | |
| 'tagger_wrn': 'Avisos lexicais', | |
| 'parser_err': 'Erros sintáticos', | |
| 'parser_wrn': 'Avisos sintáticos', | |
| 'options': 'Escolha o tipo de verificação', | |
| 'struct': 'Apenas verificação estrutural', | |
| 'tagger': 'Verificação estrutural e lexical', | |
| 'parser': 'Verificação estrutural, lexical e sintática', | |
| 'result': 'Sumário de resultados', | |
| 'list_er_wr': 'Erros e avisos encontrados', | |
| 'congrats': 'Nenhum erro ou aviso encontrado!', | |
| 'dev': 'Desarrollado por' | |
| } | |
| } | |
| def img_to_bytes(img_path): | |
| img_bytes = Path(img_path).read_bytes() | |
| encoded = base64.b64encode(img_bytes).decode() | |
| return encoded | |
| def img_to_html(img_path, img_style='max-width: 100%;'): | |
| img_html = f"<img src='data:image/png;base64,{img_to_bytes(img_path)}' style='{img_style}'>" | |
| return img_html | |
| st.markdown(""" | |
| <style> | |
| [data-testid="collapsedControl"]::after { | |
| content: " Interface Seetings"; | |
| margin-left: 5px; | |
| } | |
| [data-testid="stDownloadButton"] > button { | |
| background: linear-gradient(135deg, #45A049, #3E8E41) !important; | |
| color: #ffffff !important; | |
| border: none !important; | |
| border-radius: 10px !important; | |
| padding: 10px 18px !important; | |
| font-weight: 700 !important; | |
| box-shadow: 0 6px 18px rgba(69, 160, 73, 0.25) !important; | |
| transition: transform 0.06s ease, box-shadow 0.2s ease !important; | |
| } | |
| [data-testid="stDownloadButton"] > button:hover { | |
| transform: translateY(-1px) !important; | |
| box-shadow: 0 10px 24px rgba(6, 182, 212, 0.35) !important; | |
| } | |
| [data-testid="stDownloadButton"] > button:active { | |
| transform: translateY(0) !important; | |
| box-shadow: 0 4px 12px rgba(0,0,0,0.2) !important; | |
| } | |
| body { | |
| background-color: #ffffff !important; | |
| color: #000000 !important; | |
| } | |
| textarea { | |
| background-color: #f0fff0 !important; /* light green background */ | |
| color: #333333 !important; /* dark text */ | |
| font-size: 16px !important; | |
| font-family: 'Courier New', monospace !important; | |
| border: 2px solid #45A049 !important; /* green border */ | |
| border-radius: 8px !important; | |
| padding: 10px !important; | |
| box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1) !important; | |
| } | |
| /* Customize expander header */ | |
| [data-testid="stExpander"] > div:first-child { | |
| color: #000000; | |
| background-color: #ffffff; | |
| padding: 0px; | |
| border-radius: 8px; | |
| font-weight: bold; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| st.set_page_config( | |
| page_title="Verifica-UD", | |
| layout="centered", | |
| initial_sidebar_state="collapsed" | |
| ) | |
| # language sidebar | |
| lang_options = { | |
| "🇧🇷 Português": "🇧🇷", | |
| "🇺🇸 English": "🇺🇸", | |
| "🇫🇷 Français": "🇫🇷", | |
| "🇮🇹 Italiano": "🇮🇹", | |
| "🇪🇸 Español": "🇪🇸" | |
| } | |
| selected = st.sidebar.radio("🌐 Interface", list(lang_options.keys())) | |
| t = translations[lang_options[selected]] | |
| # choices sidebar | |
| verif_options = { | |
| t['parser']: "p", | |
| t['tagger']: "t", | |
| t['struct']: "s" | |
| } | |
| v_selected = st.sidebar.radio(t['options'], list(verif_options.keys())) | |
| t_struct, t_tagger, t_parser = True, True, True | |
| if (v_selected == 's'): | |
| t_struct, t_tagger, t_parser = True, False, False | |
| elif (v_selected == 't'): | |
| t_struct, t_tagger, t_parser = True, True, False | |
| elif (v_selected == 'p'): | |
| t_struct, t_tagger, t_parser = True, True, True | |
| # Streamlit app title | |
| st.markdown(f"<h1 style='text-align:center;'>{t['title']}</h1>", unsafe_allow_html=True) | |
| #st.title(t["title"]) | |
| st.markdown("<h6 style='text-align:center; margin-top:-20px;'>"+t["subtitle"]+"</h6><br>", unsafe_allow_html=True) | |
| # introduction | |
| #st.write(t["intro"]+"<br><br>", unsafe_allow_html=True) | |
| logo_html = img_to_html("./img/verificaUD.png", img_style="width:120px; margin-right:20px; margin-top:-10px;") | |
| intro_combined = f""" | |
| <div style="display:flex; align-items:flex-start;"> | |
| {logo_html} | |
| <div style="flex: 1; text-align: justify; font-size: 1.1em; line-height: 1.2em;">{t['intro']}</div> | |
| </div><br> | |
| """ | |
| st.markdown(intro_combined, unsafe_allow_html=True) | |
| # --- File Upload --- | |
| uploaded_file = st.file_uploader(t['input_label'], type=None) | |
| # --- Run Button --- | |
| if uploaded_file: | |
| st.success("✅ "+t['file_uploaded']) | |
| # Save to a temporary file | |
| with tempfile.NamedTemporaryFile(delete=False) as tmp_file: | |
| tmp_file.write(uploaded_file.read()) | |
| tmp_path = tmp_file.name | |
| rep_path = tmp_file.name+".rep.txt" | |
| # --- Call Verifica-UD Function --- | |
| def process_file(file_path, rep_path, t_struct, t_tagger, t_parser): | |
| if (t_parser): | |
| mode = "p" | |
| elif (t_tagger): | |
| mode = "t" | |
| elif (t_struct): | |
| mode = "s" | |
| else: | |
| mode = "p" | |
| verificaUD(file_path, rep_path, mode) | |
| with open(rep_path, 'r', encoding='utf-8', errors='ignore') as f: | |
| content = f.read() | |
| lines = content.split("\n") | |
| conlluName = lines[0][9:] | |
| bits = lines[2].split() | |
| sentNumber = bits[1] | |
| toknNumber = bits[3][:-1] | |
| bits = lines[3].split() | |
| sentNoErro = bits[3] | |
| bits = lines[4].split() | |
| sentNoErWr = bits[5] | |
| bits = lines[5].split() | |
| struct_err = bits[2] | |
| struct_wrn = bits[5] | |
| bits = lines[6].split() | |
| tagger_err = bits[2] | |
| tagger_wrn = bits[5] | |
| bits = lines[7].split() | |
| parser_err = bits[2] | |
| parser_wrn = bits[5] | |
| result = { | |
| "conlluName": conlluName, | |
| "sentNumber": sentNumber, | |
| "toknNumber": toknNumber, | |
| "sentNoErro": sentNoErro, | |
| "sentNoErWr": sentNoErWr, | |
| "struct_err": struct_err, | |
| "struct_wrn": struct_wrn, | |
| "tagger_err": tagger_err, | |
| "tagger_wrn": tagger_wrn, | |
| "parser_err": parser_err, | |
| "parser_wrn": parser_wrn, | |
| "list_er_wr": "\n".join(map(str, lines[10:])), | |
| "toggles": [t_struct, t_tagger, t_parser] | |
| } | |
| return result, content.replace(file_path, uploaded_file.name) | |
| output, content = process_file(tmp_path, rep_path, t_struct, t_tagger, t_parser) | |
| # --- Display Output --- | |
| st.subheader(t['result']) | |
| total_err = int(output['struct_err'])+int(output['tagger_err'])+int(output['parser_err']) | |
| total_wrn = int(output['struct_wrn'])+int(output['tagger_wrn'])+int(output['parser_wrn']) | |
| st.write(f"{t['sentences']}: {output['sentNumber']} ({output['toknNumber']} tokens)") | |
| st.write(f"{t['errFound']}: ({output['struct_err']} {t['structural']}, {output['tagger_err']} {t['lexical']}, {output['parser_err']} {t['sintatical']})") | |
| st.write(f"{t['wrnFound']}: ({output['struct_wrn']} {t['structural']}, {output['tagger_wrn']} {t['lexical']}, {output['parser_wrn']} {t['sintatical']})") | |
| # Build the table rows dynamically | |
| rows = [] | |
| if t_struct: | |
| rows.extend([ | |
| f"<tr><td>{t['struct_err']}</td><td>{output['struct_err']} tokens</td><td>{t['struct_wrn']}</td><td>{output['struct_wrn']} tokens</td></tr>"]) | |
| if t_tagger: | |
| rows.extend([ | |
| f"<tr><td>{t['tagger_err']}</td><td>{output['tagger_err']} tokens</td><td>{t['tagger_wrn']}</td><td>{output['tagger_wrn']} tokens</td></tr>"]) | |
| if t_parser: | |
| rows.extend([ | |
| f"<tr><td>{t['parser_err']}</td><td>{output['parser_err']} tokens</td><td>{t['parser_wrn']}</td><td>{output['parser_wrn']} tokens</td></tr>"]) | |
| # Combine rows into a full table | |
| table_html = f""" | |
| <table style="width:100%; border-collapse: collapse;"> | |
| <thead> | |
| <tr style="background-color:#f2f2f2;"> | |
| <th colspan="2"; style="text-align:left; padding: 8px;">{output["sentNoErro"]} ({t["sentencesOk"]})</th><th colspan="2"; style="text-align:left; padding: 8px;">{output["sentNoErWr"]} ({t["sentencesClean"]})</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| {''.join(rows)} | |
| </tbody> | |
| </table> | |
| """ | |
| # Display the table | |
| st.markdown(table_html, unsafe_allow_html=True) | |
| if (total_err+total_wrn > 0): | |
| # --- Display errors and warnings text area --- | |
| st.write(t['list_er_wr']) | |
| #rawText = st.text_area(t['list_er_wr']+f'({total_err} {t["err"]} - {total_wrn} {t["wrn"]}):\n', output["list_er_wr"], height=300) | |
| colors = ["#16793C", "#14874E", "#1A49B7", "#504AA4"] | |
| lines = output["list_er_wr"].strip().split("\n") | |
| html_lines = [] | |
| for line in lines: | |
| fields = line.split("\t") | |
| styled_fields = [] | |
| styled_fields.append(f'<span style="color:{colors[0]}; font-weight:bold;">{fields[0]}</span>') | |
| styled_fields.append(f'<span style="color:{colors[1]};">{fields[1]}</span>') | |
| position = fields[2].index(":") | |
| code_msg = [fields[2][:position], fields[2][position+1:]] | |
| #code_msg = fields[2].split(": ") | |
| styled_fields.append(f'<span style="color:{colors[2]}; font-weight:bold;">{code_msg[0]}:</span>') | |
| styled_fields.append(f'<span style="color:{colors[3]};">{code_msg[1]}</span><br>') | |
| html_lines.append(" ".join(styled_fields)) | |
| # Combine into scrollable box | |
| styled_html = f""" | |
| <div style=" | |
| background-color: #f9f9f9; | |
| border: 1px solid #ccc; | |
| border-radius: 8px; | |
| padding: 10px; | |
| height: 200px; | |
| overflow-y: scroll; | |
| font-family: monospace; | |
| white-space: pre-wrap; | |
| "> | |
| {''.join(html_lines)} | |
| </div> | |
| """ | |
| st.markdown(styled_html, unsafe_allow_html=True) | |
| # --- Download Option --- | |
| #st.download_button(label=t['download'], | |
| # data=content, | |
| # file_name=uploaded_file.name.replace(".conllu",".rep.txt"), | |
| # mime="text/plain") | |
| with st.container(): | |
| st.markdown('<div class="custom-download-button">', unsafe_allow_html=True) | |
| st.download_button( | |
| label="📥 "+t['download'], | |
| data=content, | |
| file_name=uploaded_file.name.replace(".conllu",".rep.txt"), | |
| mime="text/plain", | |
| key="download_report") | |
| st.markdown('</div>', unsafe_allow_html=True) | |
| else: | |
| st.write(f"{t['congrats']}") | |
| # Clean up temp file | |
| os.remove(tmp_path) | |
| else: | |
| st.info(t['no_file']) | |
| # To cite expander | |
| st.write("<br>", unsafe_allow_html=True) | |
| with st.expander(t["to_cite"], expanded=False): | |
| st.markdown( | |
| """ | |
| <small> | |
| LOPES, L.; DURAN, M. S.; PARDO, T. A. S. Verifica UD - A verifier for Universal Dependencies | |
| annotation in Portuguese. In: Proc. of the UDFest-BR 2023, 2023. | |
| DOI: https://doi.org/10.5753/stil.2023.25485<br> | |
| <i>Links</i>: <a href='https://sol.sbc.org.br/index.php/stil/article/view/25485' target='_blank'><i>URL</i></a> - <a href='https://doi.org/10.5753/stil.2023.25485' target='_blank'><i>DOI</i></a><br> | |
| <i>BibTeX</i>: | |
| </small> | |
| """, | |
| unsafe_allow_html=True) | |
| st.code(""" | |
| @inproceedings{Lopes2023VerificaUD, | |
| author = 'LOPES, L. and DURAN, M. S. and PARDO, T. A. S.', | |
| title = 'Verifica UD - A verifier for Universal Dependencies annotation in Portuguese', | |
| booktitle = 'Proc. of the UDFest-BR 2023', | |
| series = 'UDFest-BR', | |
| year = 2023, | |
| pages = '1-8', | |
| url = 'https://sol.sbc.org.br/index.php/stil/article/view/25485', | |
| }""") | |
| st.write("<br>", unsafe_allow_html=True) | |
| # Footer / Footnote | |
| with st.container(): | |
| logorow1 = st.columns([3,4,1,4,1,4,3]) | |
| with logorow1[1]: | |
| st.markdown("<a href='https://www.icmc.usp.br/' target='_blank'>"+img_to_html('./img/icmc.png')+"</a>",unsafe_allow_html=True) | |
| with logorow1[3]: | |
| st.markdown("<a href='https://c4ai.inova.usp.br/pt/inicio/' target='_blank'>"+img_to_html('./img/c4ia.png')+"</a>",unsafe_allow_html=True) | |
| with logorow1[5]: | |
| st.markdown("<a href='https://sites.google.com/view/nilc-usp/' target='_blank'>"+img_to_html('./img/nilc-removebg.png','max-width:80%')+"</a>",unsafe_allow_html=True) | |
| logorow2 = st.columns([1,4,1,4,1,5,1,4,1]) | |
| with logorow2[1]: | |
| st.markdown("<a href='https://inova.usp.br/' target='_blank'>"+img_to_html('./img/inova_nobackground.png')+"</a>",unsafe_allow_html=True) | |
| with logorow2[3]: | |
| st.markdown("<a href='https://softex.br/' target='_blank'>" + img_to_html('./img/softex_nobackground.png') + "</a>",unsafe_allow_html=True) | |
| with logorow2[5]: | |
| st.markdown("<a href='https://www.gov.br/mcti/pt-br' target='_blank'>" + img_to_html('./img/mcti_nobackground.png') + "</a>",unsafe_allow_html=True) | |
| with logorow2[7]: | |
| st.markdown("<a href='https://www.motorola.com.br/' target='_blank'>"+img_to_html('./img/motorola_nobackground.png', 'max-width:70%; object-position: center bottom')+"</a>",unsafe_allow_html=True) | |
| creditrow = st.columns([3,18,3]) | |
| with creditrow[1]: | |
| st.markdown('<p style="text-align: center;margin-top:10px"> '+t["dev"]+' Lucelene Lopes\ | |
| <a href="https://github.com/LuceleneL" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-github" viewBox="0 0 16 16">\ | |
| <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8"/>\ | |
| </svg></a> <br> open source <a href="https://opensource.org/licenses/MIT" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a></p>',unsafe_allow_html=True) | |