Yuming123/Reference-checker
0
1# app.py2import gradio as gr3import re4import pandas as pd5from docx import Document6 7# Extract unique citation pairs (Name, Year) + full text from the thesis document8def extract_citations_from_docx(doc_path):9 document = Document(doc_path)10 full_text = []11 12 # Extract text from paragraphs13 for para in document.paragraphs:14 full_text.append(para.text)15 16 # Extract text from tables17 for table in document.tables:18 for row in table.rows:19 for cell in row.cells:20 # Avoid duplication21 if cell.text not in full_text:22 full_text.append(cell.text)23 text = ' '.join(full_text)24 25 # Regular expressions for various citation formats (according to APA7)26 patterns = [27 r'\b([A-Z][a-z]+) et al\. \((\d{4})\)', # Narrative citation, More than three authors: e.g., Munikar et al. (2019)28 r'\b([A-Z][a-z]+) \((\d{4})\)', # Narrative citation, Single / Two Author Citation e.g., Park (2023), Li and Hu (2024)29 r'\(([A-Z][a-z]+) et al\., (\d{4})\)', # Parenthetical citation, More than three authors: e.g., (Liu et al., 2023)30 r'\(([A-Z][a-z]+) & ([A-Z][a-z]+), (\d{4})\)', # Parenthetical citation, Two Authors Citation e.g., (Batrinca & Treleaven, 2015)31 r'\(([A-Z][a-z]+), (\d{4})\)', # Parenthetical citation, Single Author Citation: e.g., (Weber, 1987)32 r"\b\(([A-Z][a-z]+( et al.)?,\s\d{4};?\s?)+\)\b", # Multiple Citations, e.g., (Weber, 1987; Orlikowski & Iacono, 2001; Li et al., 2024)33 r"\b\([A-Z][a-z]+,\s\d{4}[a-z]?(,\s\d{4}[a-z]?)?\)\b" # Same Author Multiple Works e.g., (Smith, 2020a, 2020b)34 ]35 36 citations = set()37 for pattern in patterns:38 matches = re.findall(pattern, text)39 for match in matches:40 if len(match) == 2:41 citations.add((match[0], match[1]))42 elif len(match) > 2:43 if ';' in match[0]:44 sub_matches = re.findall(r'([A-Z][a-z]+)[^,;]*?, (\d{4})', match[0])45 for sub_match in sub_matches:46 citations.add((sub_match[0], sub_match[1]))47 else:48 citations.add((match[1], match[2]))49 elif ';' in match:50 sub_matches = re.findall(r'([A-Z][a-z]+)[^,;]*?, (\d{4})', match)51 for sub_match in sub_matches:52 citations.add((sub_match[0], sub_match[1]))53 54 return citations, text55 56# Extract references from the reference list in the Excel file57def references_from_excel(excel_path):58 df = pd.read_excel(excel_path, header=None)59 references = [str(cell) for cell in df[0] if pd.notna(cell)]60 return references61 62# Extract references in the format of (Name, Year)63def extract_references_from_excel(excel_path):64 df = pd.read_excel(excel_path, header=None)65 references = []66 67 for cell in df[0][1:]:68 if pd.isna(cell):69 continue70 cell_text = str(cell)71 name_match = re.match(r'([A-Z][a-z]+)', cell_text)72 year_match = re.search(r'\((\d{4})\)', cell_text)73 if name_match and year_match:74 references.append((name_match.group(1), year_match.group(1)))75 76 return references77 78# Check if thesis citations are present in the reference list79def check_citations_in_references(citations, references):80 citations_not_in_references = []81 for name, year in citations:82 found = False83 for cell in references:84 if name in cell and year in cell:85 found = True86 break87 if not found:88 citations_not_in_references.append((name, year))89 90 return citations_not_in_references91 92# Check if references are present in the thesis text93def check_references_in_citations(references, text):94 references_not_in_text = []95 96 for name, year in references:97 same_bracket_pattern = fr'\({name}[^)]*?{year}[^)]*?\)'98 same_bracket_pattern2 = fr'\(([^\)]*{name}[^,;]*?,\s*{year}[^)]*)\)'99 name_followed_by_year_pattern = fr'\b{name}\b(?:[^\(\)]*?\(\s*{year}\s*\))'100 101 if not (re.search(same_bracket_pattern, text) or re.search(same_bracket_pattern2, text) or re.search(name_followed_by_year_pattern, text)):102 references_not_in_text.append((name, year))103 104 return references_not_in_text105 106# Gradio interface function107def analyze_files(doc_file, excel_file):108 citations, text = extract_citations_from_docx(doc_file.name)109 references_all = references_from_excel(excel_file.name)110 references = extract_references_from_excel(excel_file.name)111 112 citations_not_in_references = check_citations_in_references(citations, references_all)113 references_not_in_text = check_references_in_citations(references, text)114 115 result = ""116 if citations_not_in_references:117 result += "Citations in the thesis not found in the reference list:\n"118 result += '\n'.join([f"{name} ({year})" for name, year in citations_not_in_references]) + "\n"119 else:120 result += "All citations in the thesis were found in the reference list.\n"121 122 if references_not_in_text:123 result += "\nReferences in the list not found in the thesis:\n"124 result += '\n'.join([f"{name} ({year})" for name, year in references_not_in_text]) + "\n"125 else:126 result += "All references in the list were found in the thesis.\n"127 128 return result129 130# Gradio UI setup131iface = gr.Interface(132 fn=analyze_files,133 inputs=[gr.File(label="Upload .docx file"), gr.File(label="Upload .xlsx file")],134 outputs="text",135 title="Citation and Reference Checker",136 description="Please upload your thesis (without Reference list) as .docx file, and an .xlsx reference list to check for citation and reference consistency."137)138 139iface.launch(share=True)140 